def backtick(ast): def lstQ(a): return std.isSequential(a) and std.notEmpty(a) if not lstQ(ast): rc = std.pair(std.symbol("quote"), ast) elif std.isSymbol(ast[0], "unquote"): rc = ast[1] elif lstQ(ast[0]) and std.isSymbol(ast[0][0], "splice-unquote"): rc = std.pair(std.symbol("concat*"), ast[0][1], backtick(ast.slice(1))) else: rc = std.pair(std.symbol("cons*"), backtick(ast[0]), backtick(ast[1:])) return rc
def evalEx(ast, env): rc = ast if std.isStr(ast): rc = std.unquoteStr(ast) elif std.isNil(ast): rc = None elif std.isSimple(ast): #primitive data rc = ast elif std.isKeyword(ast): #keyword data rc = str(ast) elif std.isSymbol(ast): rc = _resolveSymbol(ast, env) elif std.isVec(ast): for i, v in enumerate(ast): ast[i] = compute(v, env) elif std.isMap(ast) or std.isSet(ast): pass elif std.isPair(ast): rc = std.pair() for v in ast: rc.append(compute(v, env)) else: throwE(f"eval* failed: {std.prn(ast,1)}") return rc
def readBlock(tree, ends): ast,token= std.pair(), popToken(tree) cur,jso,expr,ok,start=None,None,None,True,token ### if ends[0]=="[": ast=std.vector() if ends[0]=="(": expr=True if token.value != ends[0]: throwE(token, "expected '", ends[0], "'") while True: cur = peekToken(tree) if not cur: throwE(start, "expected '", ends[1], "', got EOF") if ends[1] == cur.value: break addAst(ast, readAst(tree)) ##get rid of the last token popToken(tree) if jso: ast.insert(0,std.symbol("object*")) elif expr: if ast and std.isSymbol(ast[0]): cmd=str(ast[0]) if cmd== "hash-map": ast[0].value="hashmap*" elif cmd== "hash-set": ast[0].value="hashset*" elif cmd== "list": ast[0].value="list*" elif cmd== "vec" or cmd=="vector": ast[0].value="vector*" elif cmd=="js-obj" or cmd== "object": ast[0].value="object*" elif ends[0]=="#{": ast.insert(0,std.symbol("hashset*")) elif ends[0]=="{": ast.insert(0,std.symbol("hashmap*")) return copyTokenData(start, ast)
def isMacroCall(ast, env): return std.isPair(ast, 1) and std.isSymbol(ast[0]) and getMacro(str( ast[0]))
def _expect(k): if not std.isSymbol(k): throwE("expected symbol")