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 _f_(ast): nonlocal env if not std.isPair(ast): res = std.atom(evalEx(ast, env)) elif 0 == len(ast): res = std.atom(std.pair()) else: cmd = str(ast[0]) cmd = _spec_forms_.get(cmd) if std.isFunction(cmd): res = cmd(ast, env) else: #a general form res = [compute(a, env) for a in ast] cmd = res[0] res = std.atom(res if not std.isFunction(cmd) else cmd( *res[1:])) ### if std.isPair(res): env = res[1] res = recur(expandMacro(res[0], env)) return res
def clone(obj): rc = None if std.isVec(obj): rc = std.into(std.vector(), obj) elif std.isMap(obj): rc = obj.copy() elif std.isSet(obj): rc = obj.copy() elif std.isPair(obj): rc = std.into(std.pair(), obj) elif std.isStr(obj) or type(obj) == list: rc = obj[:] elif std.isFunction(obj): rc = None #TODO elif std.isObject(obj): rc = copy.copy(obj) else: throwE(f"clone of non-collection: {obj}") return rc
def lspec(tree): z,c,base=0,0,std.gensym().value + "__" tree=readAst(tree) def scan(ast): nonlocal z,c for i,a in enumerate(ast): if isinstance(a,list): scan(a) elif isinstance(a, LambdaArg): z=int(a.value[1:]) if z>c: c=z #replace it with symbol ast[i]=std.symbol(f"{base}{z}") ### if not std.isPair(tree): throwE(tree, "expected pair") scan(tree) args= std.vector() i=1 while i<=c: args.append(std.symbol(f"{base}{i}")) i+=1 return std.pair(std.symbol("lambda*"), args, tree)
def isMacroCall(ast, env): return std.isPair(ast, 1) and std.isSymbol(ast[0]) and getMacro(str( ast[0]))