Univar
Univar is a Turing-complete language with only one variable. Code is interpreted as a series of statements that reassign the value of this variable to a new value constructed with various operators and function calls. Here's an example statement:
&,,
This is interpreted as "var = join(var,var)". The "var=" part is left out since all the statements assign a value to the variable, so the assignment is implicit. The join operator is written as "&" and uses prefix notation to eliminate the need for parenthesis. No separation between statements is needed either. "," represents the variable.
Operators
Symbol | Name | Operands | Syntax | Description | Example |
---|---|---|---|---|---|
& | Join | 2 | &AB | Joins A and B together in a pair. The left member can be selected with < and the right member with >. | &(>,)(<,) |
< | Disjoin (left) | 1 | <A | Returns the left member of a pair. (<,) is also used to represents the binary "true" value. | &<,<, |
> | Disjoin (right) | 1 | >A | Returns the right member of a pair. (>,) is also used to represents the binary "false" value. | >, |
, | Variable | 0 | , | Returns the variable. | &>,<, |
() | Function definition | 0 | (operations) | This returns a function that takes one parameter and returns one value. Inside the new function, the variable "," is used as a local variable; its initial value is the input parameter, and its final value is the return value. Functions are 1st class objects in Univar, so that they can be joined into pairs, stored, etc. | ($,&(>,)(<,)) |
$ | Apply function | 2 | $AB | Applies function A on value B and takes the return value. | $(&>,<,), |
! | Print 1 bit to output | 1 | !A | This will evaluate the argument A, and put a 0 bit in the output buffer if its value is (>,) or a 1 bit if its value is (<,) and then pass the argument value unchanged. Once 8 bits have been printed (from most significant bit to least significant bit), the corresponding character will be printed on screen. | &!<,>, |
? | Input 1 bit | 0 | ? | This will input a bit from the input buffer. If the input buffer is empty, it will get a new character from the keyboard or file input. Bits are input from most significant bit to least significant bit. | &?, |
A special feature is that if a junction is called, the left member of the junction will be called, with a junction of the right member of the junction and the parameter as an argument (this serves to provide closures) - in other words, "$&abc" => "$a&bc". Also, the interpreter must allow for tail call optimization, otherwise there is no way to write a loop that doesn't overflow the call stack.
Example code
Cat
(&!?,>,$,,)$,,
Cat with termination on null byte
( &&,(())&()? &&<<,$$>>,&(())()><,&&>>,<>,? &&<<,$$>>,&(())()><,&&>>,<>,? &&<<,$$>>,&(())()><,&&>>,<>,? &&<<,$$>>,&(())()><,&&>>,<>,? &&<<,$$>>,&(())()><,&&>>,<>,? &&<<,$$>>,&(())()><,&&>>,<>,? &&<<,$$>>,&(())()><,&&>>,<>,? &&<<,$$>>,&(())()><,&&>>,<>,() &<,<>, &,!<>>>>>>>>,<, &,!<>>>>>>>,<, &,!<>>>>>>,<, &,!<>>>>>,<, &,!<>>>>,<, &,!<>>>,<, &,!<>>,<, &,!<>,<, <, $$>,<,<, )$,,
Brainfuck interpreter
NB: The BF code must NOT have comments or new lines or spaces or any other non-BF character. Use "]" between program and input.
Integer terminator &($$>,&&&((>,))()&()()&&()()&()(),)() Integer &,($$>,&&& ($<<,&(<,)$><,(<<<,)) () &() () &&($<<,&&(>,)&<><,$><,(<<>,)&(<,)><,) (&&<<,&<><,$><,(><>,)>,&!<<,><,) &($<<,&&(>,)><,&(<,)&<><,$><,(<>>,)) (&&<<,&<><,$><,(>>>,)>,&?><,) ,) &&>,&(>,)<,>,&&>,&(>,)<,>,&&>,&(>,)<,>,&&>,&(>,)<,>, &&>,&(>,)<,>,&&>,&(>,)<,>,&&>,&(>,)<,>,&&>,&(>,)<,>,<, Infinite stack &,($$>,&(<,)(&>,&<,>,)<,) &($>,<,)&<,&>,&<,>, Infinite tape &($$>,&&& ($$<,(<,)(<<<,)) (&&$<,(<,)$<,(>,)>, &><,&<<,>, &<,&($>,<,)&<>,>>,) &() (&<,&$>,(<,)$>,(>,) &&<>,<,>>, &&($>,<,)&<<,><,>,) &&(&&$<,(<,)$<,(>,)>, &&&<<<,$<<,(<<>,)><,>, &&($>,<,)&<<,><,>,) (&&$<,(<,)$<,(>,)>, &&&<<<,$<<,(><>,)><,>, &&($>,<,)&<<,><,>,) &(&&$<,(<,)$<,(>,)>, &&&<<<,$<<,(<>>,)><,>, &&($>,<,)&<<,><,>,) (&&$<,(<,)$<,(>,)>, &&&<<<,$<<,(>>>,)><,>, &&($>,<,)&<<,><,>,) <,)&,, Build program from input &, ( <&,? <&,? $$?& ( &,&&&(<<<,)(><<,)&(<><,)(>><,)&&(<<>,)(><>,)&(<>>,)(>>>,) &<,$?>, <&,? <&,? &<,$?>, &<,$?>, &($<<,&<>,$>,><,)&$<,<,>, ) ( <&,? <&,? <&,? &,? <&,? $$>,& ( &$,,$,, & ( &( $$$>>,(<<<,)&($<,&<,&<>,$<>,>>,)(>>,),), &><>,$<,&<,&<<>,>>, $<,>, ), ) (())<, ), )&<,$>,>, Run $>,<,
Extra
- 40006 byte quine.
- Program that demonstrates addition with Church numerals (written by Fax).
Interpreter
This is written in the Lua programming language and will interpret Univar programs.
program="COPY PROGRAM HERE" input_data="COPY INPUT DATA HERE" genlef = function(a) return a[1] end genrig = function(a) return a[2] end gencal = function(a,b) if(type(a)=="function") then return a(b) else return gencal(genlef(a),{genrig(a),b}) end end output_var = 0 output_bits = 0 genout = function(bit) output_var = output_var * 2 + bit output_bits = output_bits + 1 if (output_bits>7) then io.write(string.char(output_var)) output_var = 0 output_bits = 0 end end genoutf = function(p) gencal(gencal (p,{function(p)genout(1)return p end,function(p)genout(0)return p end}),function (p) return p end) return p end input_index = 1 input_bit = 128 genin = function() local t = string.byte(input_data,input_index) if (t==nil) then return genrig end t = math.floor(t/input_bit) % 2 input_bit = input_bit / 2 if (input_bit<1) then input_bit = 128 input_index = input_index + 1 end if (t<1) then return genrig else return genlef end end program_index = 1 genexp = function() local instr = string.sub(program,program_index,program_index) program_index = program_index + 1 if (instr=="&") then return "{"..genexp()..","..genexp().."}" end if (instr=="<") then return "genlef("..genexp()..")" end if (instr==">") then return "genrig("..genexp()..")" end if (instr==",") then return "var " end if (instr=="(") then return "function (var)"..genfun().."return var end " end if (instr==")") then return "" end if (instr=="$") then return "gencal("..genexp()..","..genexp()..")" end if (instr=="!") then return "genoutf("..genexp()..")" end if (instr=="?") then return "genin()" end return genexp() end genfun = function() local exp = genexp() if (exp=="") then return "" else return "var ="..exp..genfun() end end program = program..")" translated_program = "compiled_function = function (var) "..genfun().."return var end " var = function (p) return p end assert(loadstring(translated_program))() assert(compiled_function(var))