We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
User:I am islptng/Draft
Jump to navigation
Jump to search
Write a detailed description and give it a name!
Interpreter
def parse(code):
# Lexer
tokens = []
cur = ""
for c in code:
if c.isspace():
if cur: tokens.append(cur); cur = ""
elif c in ";<>'?!$":
if cur: tokens.append(cur); cur = ""
tokens.append(c)
else: cur += c
if cur: tokens.append(cur)
# Parser
tokens = tokens[::-1]
def consume(env):
tk = tokens.pop()
if tk in env:
arity = env[tk]
res = [tk]
for i in range(arity): res.append(consume(env))
return tuple(res)
elif tk == "!":
env = env.copy()
name = consume_name(env); env[name] = 0
args = []
while True:
try:
argname = consume_name(env)
args.append(argname)
env[name] += 1
env[argname] = 0
except SyntaxError as e: break
body = consume(env)
for i in args: del env[i]
expr = consume(env)
return ("!", name, args, body, expr)
else: raise SyntaxError("Unknown name: <%s>" % tk)
def consume_name(env):
tk = tokens.pop()
if tk in env or tk == "!":
tokens.append(tk)
raise SyntaxError("Expected name, got expression")
return tk
try: return consume({";":0,"<":1,">":1,"'":2,"?":3})
except IndexError: raise SyntaxError("Unexpected end of input")
def evalt(ast, env={}):
op = ast[0]
if op == ";": return None
elif op == "<": res = evalt(ast[1], env); return None if res is None else res[0]
elif op == ">": res = evalt(ast[1], env); return None if res is None else res[1]
elif op == "'": return (evalt(ast[1], env), evalt(ast[2], env))
elif op == "?": res = evalt(ast[1], env); return evalt(ast[2] if res is None else ast[3], env)
elif op == "!":
op, name, args, body, expr = ast
env2 = env.copy()
if args: env2[name] = (args, body)
else: env2[name] = ([], evalt(body, env))
return evalt(expr, env2)
elif op in env:
args, body = env[op]
if not args: return body
env2 = env.copy()
for name,val in zip(args,ast[1:]):
env2[name] = ([], evalt(val, env))
res = evalt(body, env2)
return res
assert False