SuperPar

SuperPar is based on ObjectPar but better:

Everything is a object, including numbers (only integers) are objects. Words are just names for new object in one file (names can include uppercase, lowercase, numbers (but not first), underscore, plus sign, apostrofe, and the TAB character). Names are private to the file they are in. Operators have no precedence, if it is ambiguous it does it left to right, randomly, or makes error, depending on compiler option. Everything is by reference.

Statements:
 * l=r; Sets value of l to r. You can set the value of a name, but only once. Otherwise, all names have unique blank values. (Variables can be set multiple times.)
 * a*b; Returns from function if a and b refer to same object. Otherwise, it will loop when it reaches the end of the function code
 * a$b; Returns from function if a and b do not refer to same object.

Operators:
 * l.r Value of variable called r on object called l
 * l:r Get object represented by both l and r together (order is important). Code of this object is executing code of l and then when l is finished the code of r is executed, but they are executed on (l:r) instead of only l and r individually
 * {c} Creates a new object with program code c
 * @v Creates a copy of object v and executes its code. Returns object created
 * # Self
 * (v) Parentheses for grouping values
 * ~ Object which is always the value of any variables which are not set (null object)

Axioms:
 * a.b = the value of a minus b if a and b are both numbers
 * a:b = the value of a plus b if a and b are both numbers
 * @a = if a is number then executes { #.~=@(#.~); } however many times is the number, and then stops
 * ~:a = a
 * a:~ = a
 * (a:b).c = (a.c):(b.c) if the variable c is ~ or undefined in (a:b)
 * ~.a = a if the variable a is ~ or undefined in ~
 * ~.a = a if the variable a is ~ or undefined in ~

Built-ins:
 * You can use ![l]=a,b,c,... at top of program (not inside any functions) to include standard built-in function. L= library name, a,b,c = names to copy to program. To change name imported you can use a=b where a = old name, b = new name
 * !!a{b} defines word a to replaced with b whenever it occur in the code (only at top of program, not inside any functions). If you put a[b,c] inprogram code, b is !1 in b, c is !2 in b, etc.


 * STDIO/V: Variable for storing I/O values
 * STDIO/IN: Input value into variable V of new object
 * STDIO/OUT: Output value of variable V of this object to stdout

Example (output "ABAB" and exit): ![STDIO]=V,IN,OUT !!out{OUT.V=!1;do*@OUT;} { out[65]; out[66]; out[65]; out[66]; ~*~; }

Example (strings): ![STDIO]=V,IN,OUT { str={ #.val=0; #.next=~; #.input={ #.input={ #.parent.val=(@IN).V;    #.parent.next=~; #.parent.val*13; #.parent.next=@str; #.parent=#.parent.next; };   #.input.parent=#.parent; do$@(#.input); };  #.output.parent=#; #.output={ #.output={ OUT.V=#.parent.val; #.parent.next*~; do*@OUT; #.parent=#.parent.next; };   #.output.parent=#.parent; do$@(#.output); };  #.output.parent=#; ~*~; };  ~*~; }

Truth machine: ![STDIO]=V,IN,OUT !!out{OUT.V=!1;do*@OUT;} !!in{!1=@IN.V;} { machine={ out[#.input]; #.input*48; }; in[machine.input]; do$@machine; }

Multiplication (untested): { mult={ #.t1=0.~; #.t2=#.in1.~; 0.~=#;  #.out=0; #.in1.~={ 0.~.out=0.~.out:(0.~.in2); ~*~;  };   do$@(#.in1); 0.~=#.t1; #.in1.~=#.t2; ~*~; };  ~*~; }