Prolix
Paradigm(s) | Multi paradigm: object oriented, procedural (imperative), functional, structured |
---|---|
Designed by | User:_morlus |
Appeared in | 12/16/2023 |
Computational class | Unknown |
Major implementations | Join discord to download! |
Influenced by | Bash, sh, Batch, PowerShell, Lua, Self, SNOBOL |
File extension(s) | .prlx |
Prolix (/ˈprəʊ.lɪks/; meaning lengthy, too many words) is an esoteric programming language, lightweight, high-level, multi-paradigm programming language set by @_morlus (Discord) or Morlus. Currently, the Prolix project has modified both the features and syntax of the language, but it remains intact in some keywords and still has a certain difficulty as an esoteric programming language.
In version 2.0 of Prolix (01/02/2024), it changed so much that I'm not sure if it really meant the word "Prolix" or shouldn't have made a new syntax for the programming language "Prolix"!
Prolix is also a dynamically typed programming language (in version 1.1 and earlier, Prolix was a statically typed programming language and it created many programming obstacles) and garbage-collected, especially In particular, Prolix also supports many programming paradigms such as structured (especially procedural), object-oriented, and functional programming.
Join my small discord community here: https://discord.gg/tMaBPAPKca
Features
Prolix is simply an esoteric language that makes it very difficult or complicated for programmers to understand, making a program written in it look very virtual and not understand how it works or make it difficult for you to understand. while writing the program. But even though it is an esoteric programming language, it does not mean it is useless because this is a programming language that only has a few features, but it can be written into a missing feature that Prolix does not have like other current programming languages.
Prolix supports creating objects, classes and functions, and also supports extending Prolix with C/C++. Prolix also ensures the protection of special attributes in an object when outputting the object (including pre-created or modified attributes in the object).
Syntax
The classic "Hello, World!" program can be written as follows:
$io:write "Hello, World!\n";
A comment in Prolix starts with a #
and runs to the end of the line, similar to Python, Ruby, Perl, Bash, PHP. But Prolix does not support multi-line comment so you can use a string to make a multi-line comment because Prolix string ignore new lines.
# This is a comment :O " This is a multi-line comment :skull: " # Or you can make a multi-line comment like Python :moai: """ Hello :skull: """ # Even like this :skull: (But all the string quotes must be odd) """""""""""" :skull::skull::skull::skull::skull::skull::skull: """"""""""""
Because Prolix does not support function instead of class so a example about function factorial looks like this:
class factorial :__edit__ { $math:eq $factorial:key "number"; if $math:result { class vars; vars $vars; $vars:x 1; $vars:i 1; $math:sub $factorial:number 2; $vars:m $math:result; $math:result $vars:i; loop $vars:m { $math:mul $vars:x $math:result; } $factorial:result $math:result; } }
More simple version of the above example:
class factorial :__edit__ { $math:eq $factorial:key "number"; if $math:result { $math:sub $factorial:number 2; class vars :x 1 :i 1 :m $math:result; $math:result $vars:i; loop $vars:m { $math:mul $vars:x $math:result; } $factorial:result $math:result; } }
Control flow
Prolix has one type of conditional test: if {}
But there's no not or and
and even comparison operators also if statement only accept one argument for checking condition and execute expression.
if $something:attribute { # statement body } if 1 { # 1 is true } if 0 { # 0 is false } if "hi" { # "hi" is true } if "" { # "" is false }
Prolix only has one type of loop is loop {}
so there is no infinity loop but you still can make a huge number loop to make the loop repeatly like forever loop (Deprecated):
loop 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 { # INFINITY LOOP!! }
To make a infinity loop in version 2.0.1+
by this:
loop -1 # if the loop number is negative then it will loop forever { # Infinity loop }
Loops can also be nested (put inside of another loop).
$math:result 0; loop 5 { loop 5 { $math:add $math result 1; } } $io:write $math:result :write "\n";
Classes
Prolix class (or object) is kind of weird because Prolix does not support function so by calling a method of object you must put it all in attribute __edit__
to check if that object attributes got edited and result what attribute edited into __key__
class print :__edit__ {
$math:eq $output:__key__ "obj";
if $math:result {
$io:write $output:obj :write "\n";
}
}
print $print; # Create new object
$print:obj "Hello, World!"; # Edit object attribute and the class will started call attribute __edit__
# Expected output: Hello, World!
Tables
A table is a collection of key and data pairs, where the data is referenced by key.
Tables are created using the object $table
or the arguments given to a object attribute:
$table:create; # The table will stored in the $table "result" attribute
$io:write "Hello!" 123 0.5; # Expected output: table: 0x......
Tables are always passed by reference (see Call by sharing). A key (index) can be any value except table:
$table:create; $table:set $table:result "x" 20; $table:set $table:result 123 "hi"; # Accessing table entries $table:get $table:result "x"; $io:write $table:result :write "\n"; # Expected output: 20
Tables are automatically assigned a numerical key, enabling them to be used as an array data type.
class test; test $test; $test:table "Hello" "World!" "Sup"; $table:length $test:table; $io:write $table:result :write "\n"; # Expected output: 3 $table:get $test:table 1; $io:write $table:result :write "\n"; # Expected output: World!
A table can be an array of groups.
class test; test $test; $test:table {$io:write "Hello\n";} {$io:write "Yo!";}; $table:length $test:table; $io:write $table:result :write "\n"; # Expected output: 2 $table:get $test:table 0; $utils:do $table:result; # Expected output: Hello
Groups
It is like a function but does not have any arguments, so it is called a group
because it is a group of many lines of code.
$utils:do { $io:write "Hello, World!\n"; } # Expected output: Hello, World!
Object-oriented programming
Prolix is an esoteric language but has support for object-oriented programming as well as current non-esoteric languages but it has a special syntax as an esoteric language.
Creating a basic vector object:
class Vector :__edit__ { $math:eq $Vector:__key__ "set"; if $math:result { $table:get $Vector:set 0; $Vector:x $table:result; $table:get $Vector:set 1; $Vector:y $table:result; $table:get $Vector:set 2; $Vector:z $table:result; } $math:eq $Vector:__key__ "magnitude"; if $math:result { $math:pow $Vector:x 2 :x $math:result; $math:pow $Vector:y 2 :y $math:result; $math:pow $Vector:z 2 :z $math:result; $math:add $math:x $math:y; $math:add $math:result $math:z; $math:sqrt $math:result; $Vector:result $math:result; } } Vector $vec :set 0 1 0; # Create a vector $vec:magnitude; # Call attribute magnitude $io:write $vec:result :write "\n"; # Expected output: 1.0 $io:write $vec:x :write "\n"; # Access a member object and expected output: 0
Extending Prolix with C or C++
Adding new integrated modules to Prolix is pretty easy if you know how to program in C. Such extensions can do two things that cannot be done directly in Prolix: they can deploy new types of integrated objects, and they can call C library functions and system calls.
Let’s look at an example function in a file called square.c
:
int square(int i) { return i * i; }
Before we can call this function from the Prolix code, we need to compile it. When compiling code, we need to move the flag so that we can import the created file. To compile the C code, we run the following command:
gcc -fPIC -o clib.dll square.c
This will produce a file called clib.dll
that we can import into our Prolix script. Let's place the square.prlx
script in the same directory:
$cdll open "clib.dll"; $cdll load "square" 2; $io:write $cdll:result :write "\n"; # Expected output: 4
What happens above is we enter cdll
so that we can use $cdll:open
to load the dynamic link library as a module in Prolix. The loaded clib.dll
module is stored in the $cdll:__source__
attribute. Then the C function, or in our case the function, can be called as follows: $cdll:load "square"...
.
Standard Libraries
In version 2.0 and later, Prolix has tended to have fewer built-in objects to optimize Prolix and the interpreter software. So here is a table of built-in objects:
Built-in Object | Description |
---|---|
cdll |
Used to extend Prolix in C through libraries from C and read C code files through dynamic link library files. |
garbagecollect |
An automatic memory management that uses garbage collection based on certain algorithms that is in-built in Prolix. |
io |
I/O library is used for reading and manipulating standard input/output and files in Prolix. |
math |
This library provides basic mathematical functions. It provides all its mathematical functions and operator functions. Functions with the annotation "integer/float" give integer results for integer arguments and float results for float (or mixed) arguments. Rounding functions ($math:round , $math:ceil , $math:floor , and $math:modf ) result an integer when the result fits in the range of an integer, or a float otherwise.
|
string |
This library provides generic functions for string manipulation. |
table |
This library provides generic functions for table manipulation. It provides all its functions inside the $table object (or table class).
|
utils |
This library provides generic functions for other things like custom error reporting, string execution, getting object type, validation, etc. |
cdll
Used to extend Prolix in C through libraries from C and read C code files through dynamic link library files.
cdll:open
Used to read dynamic link library files and convert them into cdll
objects and stored in the __source__
attribute so that the cdll:load
function can Read and run functions from the C library.
$cdll:open <source : str>;
cdll:load
When a .dll
file is read and converted and saved to the __source__
attribute, this function will read and run the function from the converted file.
$cdll load <function : str> <arguments: any...>;
garbagecollect
An automatic memory management that uses garbage collection based on certain algorithms that is in-built in Prolix.
Prolix uses the occasionally running garbage collector to collect dead objects when they are no longer accessible from the prolix program.
All objects including objects, tables, groups, classes, strings, etc. must be managed automatically. Prolix uses a trace collector and incremental scanning that uses two numbers to control its garbage collection cycle, which is to pause the garbagemaker and multiply the step coefficient of the garbulk collector. These values are calculated in percentage terms and values of 100 are usually equal to 1 internally.
garbagecollect:enabled
This is an attribute and not really a function, but it is used to enable/disable automatic garbage collection.
$garbagecollect:enabled <value : boolean (not actual type)>;
garbagecollect:paused
Pause the garbage collector used to control the previous time that the trash collector needs to wait; it is called back by Prolix's automatic memory management feature.
$garbagecollect:paused <value : boolean (not actual type)>;
garbagecollect:count
Result the current collection counts as a table of count0, count1, count2
.
$garbagecollect:count;
garbagecollect:pausecount
Result the number of objects in the permanent generation.
$garbagecollect:pausecount;
garbagecollect:collect
Collect and result amount of garbage collection.
$garbagecollect:collect;
garbagecollect:istracked
Result 1
if the object is currently tracked by the garbage collector, 0
otherwise.
$garbagecollect:istracked <object : any>;
io
I/O library is used for reading and manipulating standard input/output and files in Prolix.
io:write
Used to write data to the working file or, if there is no working file, write data to the console.
$io:write <object : any>;
io:append
Similar to function io:write
but only has a different use: if there is a working file, it will add data instead of rewriting all the data.
$io:append <object : any>;
io:read
Reading the file and the result of the file data or not will read the user input in the console but there are many different modes.
$io:read;
Reading user input with modes:
Mode | Description |
---|---|
%s |
Read full line of user input |
%n |
Read a number of user input |
%c |
Read a character of user input |
integer |
Read provided characters amount of user input |
$io:read <mode>;
You can do read more user inputs like this:
$io read "%s%n";
io:open
Open the file via the provided file path and after being provided it will be converted into a file
object and saved into the __cwf__
attribute and if there is an existing working file then will report an error.
$io:open <source : str>;
io:close
Close the working file and if there is no working file, an error message will be reported.
$io:close;
math
This library provides basic mathematical functions. It provides all its mathematical functions and operator functions. Functions with the annotation "integer/float" give integer results for integer arguments and float results for float (or mixed) arguments. Rounding functions ($math:round, $math:ceil, $math:floor, and $math:modf) result an integer when the result fits in the range of an integer, or a float otherwise.
math:abs
Results the absolute value of x. (integer/float)
$math:abs <x : num>;
math:acos
Results the arc cosine of x (in radians).
$math:acos <x : num>;
math:add
Results the value x + y.
$math:add <x : num> <y : num>;
math:asin
Results the arc sine of x (in radians).
$math:asin <x : num>;
math:atan
Results the arc tangent of y/1 (in radians).
$math:atan <x : num>;
math:ceil
Results the smallest integral value larger than or equal to x.
$math:ceil <x : num>;
math:cos
Results the cosine of x (assumed to be in radians).
$math:cos <x : num>;
math:cosh
Results the hyperbolic cosine of x.
$math:cosh <x : num>;
math:deg
Converts the angle x from radians to degrees.
$math:deg <x : num>;
math:div
Results the value x / y.
$math:div <x : num> <y : num>;
math:eq
Results the value x == y.
$math:eq <x : num> <y : num>;
math:exp
Results the value e^x (where e is the base of natural logarithms).
$math:exp <x : num>;
math:factorial
Returns the factorial of x.
$math:factorial <x : num>;
math:floor
Results the largest integral value smaller than or equal to x.
$math:floor <x : num>;
math:frexp
Returns the mantissa and the exponent, of x.
$math:frexp <x : num>;
math:fmod
Result the remainder of the division of x by y that rounds the quotient towards zero. (integer/float).
$math:fmod <x : num> <y : num>;
math:ge
Results the value x >= y.
$math:ge <x : num> <y : num>;
math:gt
Results the value x > y.
$math:gt <x : num> <y : num>;
math:le
Results the value x <= y.
$math:le <x : num> <y : num>;
math:log
Result the logarithm of x in the given base. The default for base is e (so that the function result the natural logarithm of x).
$math:log <x : num>;
math:log10
Returns the base-10 logarithm of x.
$math:log10 <x : num>;
math:lt
Results the value x < y.
$math:lt <x : num> <y : num>;
math:mod
Result the value x % y.
$math:mod <x : num> <y : num>;
math:modf
Result the integral part of x and the fractional part of x. Its second result is always a float.
$math:modf <x : num>;
math:mul
Results the value x * y.
$math:mul <x : num> <y : num>;
math:ne
Results the value x != y.
$math:ne <x : num> <y : num>;
math:neg
Results the value -x.
$math:neg <x : num>;
math:not
Results the value !x.
$math:not <x : num>;
math:pow
Results the value x^y.
$math:pow <x : num> <y : num>;
math:rad
Converts the angle x from degrees to radians.
$math:rad <x : num>;
math:random
Result inclusive random integer of between x and y.
$math:random <x : num> <y : num>;
math:randomseed
Sets x as the "seed" for the random number generator: equal seeds produce equal sequences of numbers.
$math:randomseed <x : num>;
math:round
Results the rounded value of x.
$math:round <x : num>;
math:sin
Results the sine of x (assumed to be in radians).
$math:sin <x : num>;
math:sinh
Results the hyperbolic sine of x.
$math:sinh <x : num>;
math:sqrt
Results the square root of x.
$math:sqrt <x : num>;
math:sub
Results the value x - y.
$math:sub <x : num> <y : num>;
math:tan
Results the tangent of x (assumed to be in radians).
$math:tan <x : num>;
math:tanh
Results the hyperbolic tangent of x.
$math:tanh <x : num>;
string
This library provides generic functions for string manipulation.
string:concat
Combine all strings into one string and if the given argument is not a string, it will also be converted to a string and then combined.
$string:concat <object : any...>;
string:upper
Converts a string into upper case.
$string:upper <string : str>;
string:lower
Converts a string into lower case.
$string:lower <string : str>;
string:reverse
Converts a string into reversed string.
$string:reverse <string : str>;
string:length (Deprecated in 2.0.1+
)
Results a length of string.
$string:length <string : str>;
string:char
Results a char of string by index.
$string:length <string : str> <index : num>;
string:repeat
Results a repeated string by amount.
$string:repeat <string : str> <amount : num>;
string:replace
Results a string where a specified value is replaced with a specified value.
$string:replace <string : str> <old : str> <new : str>;
string:split
Splits the string at the specified separator, and returns a table.
$string:replace <string : str> <separator : str>;
string:find
Searches the string for a specified value and returns the position of where it was found.
$string:replace <string : str> <value : str>;
string:sub
Returns the substring of string that starts at start
and continues until end
$string:sub <string : str> <start : num> <end : num>;
string:format
Returns the formated string.
$string:format <string : str> <arguments : any...>;
The Prolix format string is replaced by all '%' contained in the string of each argument.
$string:format "Hello, %!" "World"; # Expected string: "Hello, World!" $string:format "My name is % and I am % years old." "John" 21; # Expected string: "My name is John and I am 21 years old." $string:format "The symbol '\%' is %." "cool"; # Expected string: "The symbol '%' is cool."
string:unicode (Added in 2.0.1
)
Used to convert ASCII code into a character.
$string:unicode <char : str>
string:ordinal (Added in 2.0.1
)
Used to convert a character into ASCII code.
$string:ordinal
table
This library provides generic functions for table manipulation. It provides all its functions inside the $table
object (or table
class).
table:create
Create a new table and put it in attribute result
$table:create;
table:set
Set a new entry for the provided table.
$table:set <object : table> <key : any> <value : any>;
table:remove
Remove a provided entry key in the provided table.
$table:set <object : table> <key : any>;
table:get
Get a entry key from the provided entry key in the provided table then put it into attribute result
.
$table:get <object : table> <key : any>;
table:get
Get a entry key from the provided entry key in the provided table then put it into attribute result
.
$table:get <object : table> <key : any>;
table:length (Deprecated in 2.0.1+
)
Results the length of the provided table.
$table:length <object : table>;
table:push
Push a value into the provided table with index is the old size of the table.
$table:push <object : table> <value : any>;
table:clear
Clear all entry in the provided table.
$table:clear <object : table>;
table:combine
Combine two provided tables.
$table:combine <object : tableA> <object : tableB>;
table:find
Find the entry index from entry value and results in attribute result
.
$table:combine <object : table> <value : any>;
table:foreach
Execute group for each entry and it is store key and value in attribute key
and value
$table:foreach <object : table> <func : group>;
Here's a example:
$table:create;
$table:set $table:result 0 "Hi";
$table:set $table:result 1 "Yo";
$table:set $table:result 2 "Sup";
$table:set $table:result 3 "Hello";
$table:foreach $table:result {
$io:write $table:key :write ' ' :write $table:value :write '\n';
}
Expected output:
0 Hi
1 Yo
2 Sup
3 Hello
utils
This library provides generic functions for other things like custom error reporting, string execution, getting object type, validation, etc.
utils:exec
Execute prolix code by string.
$utils:exec <string : str>
utils:tostr
Convert object into string.
$utils:tostr <object : any>
utils:tonum
Convert object into number.
$utils:tonum <object : any>
utils:type
Results the type of the object.
$utils:tonum <object : any>
utils:assert
Assert the object if True, report error otherwise.
$utils:assert <object : any>
utils:error
Report a error with custom message.
$utils:error <message : any>
utils:do
Execute group
and if result the table with success and error message.
$utils:do <func : group>
Example:
$utils:do {
$math:div 2 0;
}
$table:get $utils:result 0;
$io:write $table:result; # Expected output: 0
# Because 2 cannot divide with 0 so the "group" report error but the "$utils:do" ignore it.
utils:exit (Added in 2.0.1
)
Exit program instantly.
$utils:exit;
utils:length (Added in 2.0.1
)
Get length of the object provided (except num
)
$utils:length <object : any>
utils:tick (Added in 2.0.1
)
Get how long the program has been running in seconds.
$utils:tick;