ObjLang
ObjLang is an esolang invented by User:None1, its programs are marshalled Python nested lists and dictionaries.
Syntax
A program is a marshalled dictionary with string as keys and lists as values, the key is a command, the value is a list of arguments. (The dictionary must have only one key)
Types
There are three types: int
, str
and list
, they behave the same as normal Python types.
Commands
Command # Python equivalent/description {"print":[x]} # print(x) # Returns x {"input":[]} # input() {"intinput":[]} # int(input()) {"add":[x,y]} # x+y {"sub":[x,y]} # x-y {"mul":[x,y]} # x*y {"div":[x,y]} # x//y {"mod":[x,y]} # x%y {"and":[x,y]} # x&y {"or":[x,y]} # x|y {"not":[x]} # ~x {"xor":[x,y]} # x^y {"lsh":[x,y]} # x<<y {"rsh":[x,y]} # x>>y {"neg":[x]} # -x {"pow":[x,y]} # x**y {"eq":[x,y]} # int(x==y) {"neq":[x,y]} # int(x!=y) {"leq":[x,y]} # int(x<=y) {"geq":[x,y]} # int(x>=y) {"lt":[x,y]} # int(x<y) {"gt":[x,y]} # int(x>y) {"lnt":[x]} # int(not bool(x)) {"lnd":[x,y]} # int(bool(x) and bool(y)) {"lor":[x,y]} # int(bool(x) or bool(y)) {"if":[x,y,z]} # y if x else z {"for":[x,y,z]} # [x for i in range(y,z+1)] {"while":[x,y]} # while x: # y ## Note: returns 0 {"loop":[]} # Return the loop variable of the most inner for loop {"str":[x]} # chr(x) {"num":[x]} # ord(x) {"index":[x,y]} # x[y] {"comma":[x,y,z,...]} # Returns a list containing all the elements, usually used to execute more than one commands.
Functions
There is also a command func
, which defines a command and returns 0, it is like this:
{"func":[code,command_name,arg1,arg2,...]}
command_name is the name of the command, it cannot conflict with original commands. code is the command's code, arg1, arg2, ... are its argument names, they should not be the same with each other.
There is also a command: arg
:
{"arg":["name"]}
If it is not used in a function or the argument with the name doesn't exist, it errors, otherwise it returns the value of that argument.
For example:
{"func":[{"print":[{"arg":["x"]}]},"foo","x"]}
Defines a function named foo
with an argument x
that prints its argument.
You can then call it like this:
{"foo":[3]}
Which prints 3.
Examples
Programs are binary so they are represented in base64.
Hello, World!
e9oFcHJpbnRbAQAAAPoNSGVsbG8sIFdvcmxkITA=
Unmarshalled form:
{"print":["Hello, World!"]}
Cat Program
e9oFd2hpbGVbAgAAAOkBAAAAe9oFcHJpbnRbAQAAAHvaBWlucHV0WwAAAAAwMDA=
Unmarshalled form:
{'while': [1, {'print': [{'input': []}]}]}
Truth Machine
e9oCaWZbAwAAAHvaAmVxWwIAAAB72gVpbnB1dFsAAAAAMNoBMTB72gV3aGlsZVsCAAAA6QEAAAB72gVwcmludFsBAAAAcgUAAAAwMHtyBgAAAFsBAAAA6QAAAAAwMA==
Unmarshalled form:
{'if': [{'eq': [{'input': []}, '1']}, {'while': [1, {'print': [1]}]}, {'print': [0]}]}
Programs are getting more complex, so I'm using pprint.pprint
.
A+B Problem
e9oFcHJpbnRbAQAAAHvaA2FkZFsCAAAAe9oIaW50aW5wdXRbAAAAADB7cgIAAABbAAAAADAwMA==
Unmarshalled form:
{'print':[{'add': [{'intinput': []}, {'intinput': []}]}]}
Fibonacci (via recursion)
e9oFY29tbWFbAgAAAHvaBGZ1bmNbAwAAAHvaAmlmWwMAAAB72gJlcVsCAAAAe9oDYXJnWwEAAADaAXgw6QAAAAAw6QEAAAB7cgIAAABbAwAAAHtyAwAAAFsCAAAAe3IEAAAAWwEAAAByBQAAADByBwAAADByBwAAAHvaA2FkZFsCAAAAe9oDZmliWwEAAAB72gNzdWJbAgAAAHtyBAAAAFsBAAAAcgUAAAAwcgcAAAAwMHtyCQAAAFsBAAAAe3IKAAAAWwIAAAB7cgQAAABbAQAAAHIFAAAAMOkCAAAAMDAwMDByCQAAAHIFAAAAMHvaA2ZvclsDAAAAe9oFcHJpbnRbAQAAAHtyCQAAAFsBAAAAe9oEbG9vcFsAAAAAMDAwcgcAAADpZAAAADAw
Unmarshalled form:
{ "comma": [ { "func": [ { "if": [ { "eq": [{ "arg": ["x"] }, 0] }, 1, { "if": [ { "eq": [{ "arg": ["x"] }, 1] }, 1, { "add": [ { "fib": [{ "sub": [{ "arg": ["x"] }, 1] }] }, { "fib": [{ "sub": [{ "arg": ["x"] }, 2] }] } ] } ] } ] }, "fib", "x" ] }, { "for": [{ "print": [{ "fib": [{ "loop": [] }] }] }, 1, 100] } ] }
Programs are getting so complex that I have to use VSCode and Prettier.
Note: Slow! (because time doubles to compute each term) Prints the first 100 terms of fibonacci sequence.
Computational class
It is suspected but not proven that ObjLang is Turing-complete.