CRTL
CRTL, short for "Constantly Rewriting Term Language", is a silly, uncompilable, self-modifying esolang by User:ehird.
Syntax
Whitespace is ignored outside of string_contents.
expression = '"' string_contents '"' | '(' expression ')' | name | quoted | expression '->' expression | expression '~' expression quoted = "'" name | "'" quoted
name is a sequence of one or more alphanumeric characters.
string_contents can contain any character apart from ". If a " is desired, it must be escaped with a backslash: \". If you want a \, you have to escape that too: \\.
A program is a sequence of expressions, seperated by ;. Excess ;s are just ignored.
Evaluation
We evaluate the rewrite rules of the form A -> B
, in any order. After doing each substitution, we check for the lone literals and print them out (more details below). Then, we replace according to another rule, check again, replace again, etc., until we have a run where nothing is substituted, at which case the program ends.
Rules
in: "literal";
Displayed, without quotes and unescaped, to standard output (without any newline or space following it).
in: A -> B;
In all statements apart from this one, A is found - whether A is a literal, another expression, or anything -- and is replaced with B. (Strings are searched in for A and only the substring is replaced by B)
in: A with free names -> B;
In all statements apart from this one, A is found, where a free name means "anything". What is there instead of a free name is bound to that name in B (thus becoming non-free), and all occurences of it in B are replaced with that value. If B contains free names that neither A or B define, it is an error. So this program is invalid:
(a->(b->c))->(a->d); "blah"->(d->d)
in: A ~ B
A and B must resolve to strings (they can be literals or free names, see above). They are concatentated together, and that is the result of this expression (NOT statement)
in: 'A
Matches the free name A if A is a name, or the quoted expression A if A is a quoted expression.
Examples
Hello, world!
"Hello, world!";
For something a little less boring:
"QWERTY"->"Hello, "; "UIOP"->"world!"; "QWERTYUIOP"
Even less boring:
("say hello"->x)->("Hello, "~x~"!"); "thingy"->"wor"; "mabob"->"ld"; "say hello"->"thingymabob"
Silly thing demonstrating ~
Prints "barbar".
("foo"~xs)->(xs~"bar"); "foobar"
Fibonacci numbers
Written by oklopol. Outputs in the form "previous|current" in unary.
(("fib"->a)->b)->b~"|"~a~b; a~"|"~b->(("fib"->a)->b); ("fib"->"1")->"1"