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

From Esolang
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