Leszek
Leszek (pronounced lesheck) is a non-imperative esoteric programming language, based on the string-rewriting paradigm. It has no jumps, no loops, no variables nor stack. It was created in 2006 by User:Janek37.
Syntax
Programs in Leszek are sequences of expressions, like <expr1><expr2>...<exprn>. An expression is one of: single non-backslash character (n.b.c.), two consecutive backslashes "\\" (values of such expressions are themselves), or an operator with its parameters. Parameters are often other expression and sometimes integers. The format of an integer is following: <decimal_digits>".", for example "1234.", "007."(which means the same as "7."), "." (an equivalent for "0."). Integers cannot be negative. An integer parameter can take one of two forms: a sequence of characters forming a number in the format explained above or a single expression which value has a prefix forming a vaild integer, for example an expression which returns "01234.syf", "5." or ".iuhgnol" (they are interpreted respectively as 1234, 5, 0).
Operators
Operators are used to build expression which return some values (always of type string) and possibly having some side effects (like sending some string to output). Operators are always composed from two characters, first of which is a backslash.
- \C is the main operator. It takes two parameters: an escaped n.b.c. and an integer, for example "\C\%3.". The first parameter defines a delimiter. The value of expression "\C\dn." is a string cut from the current source string, starting from the character following the nth occurence of non-escaped delimiter "d" to the character preceding the next occurence. We assume that 0-th occurence of every character is just before the first character in source string and every n-th occurence of a character which occurs less than n times is just after the last character. Some examples:
abc\C\a1.bac -> Value of "\C\a1." is "bc\C\a1.b" bcd\C\a.dcba -> Value of "\C\a." is "bcd\C\a.dcb". aaa\C\a3.bbb -> Value of "\C\a3." is "\C\a3.bbb". \C\a3.aa -> Value of "\C\a3." is "".
- \L takes the same parameters as \C and returns the number of character which would be returned if it was \C operator. The result is in the integer-dot format without leading zeros.
- \T takes two expressions as parameters and returns the concatenation of their values.
- \G takes an integer parameter n and then n expressions, and returns the concatenation of them all.
- \A takes two expressions as parameters and returns the value of the first expression.
- \D takes two expressions as parameters and returns the value of the second expression.
- \E is something like a conditional operator. It takes three expressions. If the first is not empty, returned is value of the second, otherwise returned is the value of the third. In each of \A, \D, \E operators, the ignored expression can't have any side effects.
- \N doesn't take parameters and always returns an empty string.
- \= takes two expressions and returns "1" if they return equal values. Otherwise it returns an empty string.
- \&, \|, \! perform logical operations (respectively and, or, not) on their parameters. Expression returning an empty string is false, else it is true. Returned value is "1" or "". Note that in \& an \| both parameters are always computed (so they can have side effects).
- \I takes no parameters, when evaluated gets a character from the input and returns it. If the character was a backslash, it returns "\\".
- \M works like \I, but it gets an integer from the input and returns it in the integer-dot format without leading zeros.
- \O takes an expression and returns nothing. As a side effect it sends the value of that expression to the output. If the parameter was "\\", it sends "\". It is recursional, for example "\O\T\T\\ab" sends "\ab" to the output. But if the source was "\\a\O\C\a.", then \O sends "\\", because cut strings aren't interpreted.
- \+, \-, \*, \/, \% take two integers and perform arthmetic opertions on them (respectively addition, substraction, multiplication, integer division and modulo division). The result is a string in the integer-dot format without leading zeros (yawn). Note that \- returns "." (ie. 0) when the first parameter isn't greater the the second, and that \/, \% return an empty string when the second parameter is 0 (ie. "." or "0." etc.). Every expression with an incorrect integer parameter also returns an empty string. Moreover, every incorrect expression should return an empty string, instead of barfing an error message.
Program execution
Program executes in turns. In each turn value of each expression (which isn't a parameter to any other expression) is computed and their values are concatenated in the same order as they appear in the source. Then, the string made of those values is interpreted the same way and the operation is iterated. Program execution stops when there are no \O operators left (the program can no longer output, so there's no point in its further execution).
Minimalism
Leszek isn't (and doesn't try to be) minimalistic. You can use "\E1" instead of "\A", "\E\N" instead of "\D", "\G2." in place of "\T", and even "\N" can be replaced by "\G.". However, short operators are comfortable when you need to write then 5 times in a row, and multum of dots is not desired in programs that use dots as delimiters.
In simple programs, operators \G nd \L aren't often necessary, but they are frequently useful in more complex ones.
Possible future changes
There could be added a swapping operator \W, which takes two expressions and concatenates their values in reverse order, but this doesn't seem to be useful.
Examples
The following code writes "Hello World!" to the output in one turn, then terminates:
\O\C\.1.Hello World!
The next also writes "Hello World!", but one character a turn, then terminates:
\E\=%\C\|1.\N\T\C\|.\C\%3.\E\=%\C\|1.\N\O\D|Hello World!%|
These are quines:
\O\C\|.
\O\T\C\..\T\Da.\T\C\.1.\C\a1.
ab\O\T\C\b.\C\a1.
This program outputs the "99 bottles of beer" song lyrics (newlines are necessary):
\E\=\TNo\C\.24.\N\T\C\|.\C\$4.\O\E\=\T99\C\.24.\D \N\G5.\C\.24.\C\$2.\E\=1\C\.24.\Ns\C\$3.\C\$5.\O\D \E\=\TNo\C\.24.\N\G4.\C\.24.\T\T\C\$2.\E\=1\C\.24.\D \Ns\C\$3.\T\T\C\.24.\C\$2.\E\=1\C\.24.\Ns\C\$6.\D \E\=1\C\.24.\TNo\-\A\G\+1.\L\.24.\D\D|.99.$1.\E\=1\D \C\.24..\N\T\C\^1.\C\$1.$ bottle$ of beer on the wall $|.$ $ of beer Take one down and pass it around $^$
External resources
- Leszek files (from the Wayback Machine; retrieved on 21 March 2016) contain an interpreter in C and some sources of Leszek programs.