Clart is an object-oriented mildly esoteric programming language designed and implemented by User:PolySaken.
Clart programs are composed of instructions, which in turn are constructed from a control character, followed by some parameters, followed by a semicolon. Some instructions are preprocessed; these commands cannot be executed during the program itself and are usually used only once before the program is executed.
Parameters are simply separated by spaces.
A typical clart instruction looks like:
C param1 param2 param_n;
Where C is the control character to be used.
Some instructions, however, are just a control character with no parameters. These instructions do not require a semicolon and are usually to denote the end of something, that being an if statement, function, program, etc.
The available control characters are:
|Character||No. of Parameters||Function||Preprocessed|
|:||1||Create a label named using the first parameter (local to function or file)||Y|
|^||1||Jump to the label named as the first parameter||N|
|B||0||Jump to the line after the last jump instruction||N|
|?||n||Set the execute flag to false if any parameter evaluates to false. This command ends with a colon, NOT a semicolon.||N|
|E||0||Set the execute flag to true||N|
|F||n > 1||Define the first parameter to be the name of a function, with the other parameters as param names||N|
|X||0||End function definition||N|
|.||n > 1||Execute the function referred to by param1, and pass in the following parameters||N|
|R||1||Return a value (inside functions)||N|
|>||n||Print all parameters||N|
|<||1||Take user input and set the variable referred to by param1||N|
|!||2||Define constant param1 with value param2 (local to function or file)||Y|
|$||2||Set var param1 with value param2||N|
|&||n||Clone object referred to by param1 into new vars named with following parameters||N|
|+||1||Import a file (cannot be done programmatically)||Y|
|C||n > 1||Same as F, but the defined function supports property assignments||N|
|N||0||End definition of function defined with c||N|
|P||2||Define a property named with param1 to the value of param2 (only usable inside functions defined with c)||N|
|~||n > 1||Same as '.' but for functions defined with c||N|
|Q||0||End the program||N|
Clart requires the labels start and end to be defined for any file except in specific circumstances. The constant 'version' must also be defined, which must be equal to 1.1 or lower. If the value is greater than 1.1, an error saying to 'use the new interpreter' will be generated. This interpreter does not yet exist, but is planned to involve a less procedural fixed syntax.
Some constants, when defined, produce special results. A list of special constants:
|simple||if defined and true: start and end labels, and version constant can be omitted.|
|debug||if defined and true: program will print a JSON table of its environment.|
|fallback||if defined: undefined names will have this value.|
|prompt||if defined: this value will be printed when < is used.|
The 'execute flag' is a boolean value which functions like a primitive if statement; When false, all commands except for E are skipped. It can be set to false using the ? command, by including a parameter that evaluates to false, such as 0 or [0=1]. The E command will reset the flag to true.
Parameters can be one of many types, including variable names, string or number literals, calculable expressions, and constant names. To reference a variable, simply use its name. String literals are surrounded by single quotes:
And support the escape codes \n and \t, which will be replaced by a newline and a tab respectively. Number literals can be an integer or a float, and can be positive or negative. Constant names must be prefixed with a !, but are otherwise just a name.
In Clart, 'expressions' are a special type of literal that allows the program to perform calculations. They are composed of two values, surrounded by square brackets, and separated by an operator, for example:
Only the second value may be another expression, if the first value is an expression it will raise an error. All other parameter types are used as normal, except for string literals. They must be prepended with a single double-quote, and all spaces must be replaced with backslashes:
Actual spaces will be ignored.
These operators are allowed:
|+||Adds the two values together.|
|-||Subtracts the second value from the first.|
|*||Multiplies the two values together.|
|/||Divides the first value by the second.|
|^||Raises the first value to the power of the second.|
|=||Returns true if the values are equal, else false.|
|>||Returns true if value 1 is greater, else false.|
|<||Returns true if value 1 is smaller, else false.|
|@||Floor-divides the first value by the second.|
|&||Ceiling-divides the first value by the second.|
||||Returns a random int between value 1 and value 2.|
These operators use python-like type casting, allowing things like string*int, etc.
Standard functions have impermanent values; their local variables are erased once their execution ends. They cannot be nested inside other functions. 'Data functions' are identical to normal functions except for the presence of the P setter, which allows 'properties' to be defined which persist across all calls of the function. Standard functions can be nested inside datafunctions.
All functions can be called using expressions, for example:
C someObj cmd; # create a datafunction 'someObj' F init; # define init as a method of someObj P var 'somestring'; # set property var X F print; # define method 'print' > var; # output var X .[cmd+"]; # call the function passed in, expression syntax required N
~someObj init; # special syntax for datafunctions allows raw names instead of strings ~someObj print;
While leaving out the init call would cause an 'undefined name' error. Extending this concept allows OOP; this functionality is used in stdl.clart, the standard import supplied with the interpreter, in order to create an Array object which can be cloned using &Array new_var; and then used like a stack object.
Comments are prepended by a # and are single-line.
Clart comes with a 'Standard Library' (usually 'stdl.clart') which supplies basic tools such as Array in order to make the prototype paradigm chosen by Clart more useful to programmers.
Assume '!simple 1;' to be true for all the following.
< n; ? [n=1]: ^loop E > 0; Q :loop > 1; ^loop
< txt; > txt;
Array object (from standard library):
C Array cmd value value_b; !fallback ; F pass; P len 0; X F append v; $ plen [len+1] P ["i+plen] [v+"]; P len [plen+0]; X F set k v; $ plen [len+1] P ["i+k] [v+"]; P len [plen+0]; X F get k; &["i+k] val; R val; ^r X .[cmd+"] [value+"] [value_b+"]; :r R return; Q N ~Array pass; #initial setup
Github Repository - Includes a more tutorial-like documentation, an interpreter, and a 'standard library' containing an Array prototype object, and a default file template.
Clart represents a first foray into creating esolangs, so is largely experimentation-driven. However, Clart does have a motivation: To create a language that looks like it sounds. Specifically, clart is an old english word meaning 'sticky mud; filth.' The Name was chosen first, then the syntax was built around it, in attempt to make the language look and feel like wading through foul-smelling sticky mud.