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 _slice(arr, *xs): n = len(xs) rc = None if n == 0: rc = arr[:] elif n == 1: rc = arr[xs[0]:] elif n == 2: rc = arr[xs[0]:xs[1]] elif n == 3: rc = arr[xs[0]:xs[1]:xs[2]] else: throwE("bad slice arg") return rc
def setMacro(cmd, func): if cmd and std.isFunction(func): cmd = str(cmd) #only add namespace'd macro if "/" not in cmd: c = core.peekNS() if not c: throwE(f"setMacro: macro {cmd} has no namespace") cmd = f'{c.id}/{cmd}' #console.log(`added macro: ${cmd}`); CACHE[cmd] = func else: func = None return func
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 get(self, k): _expect(k) env = self.find(k) if not env: throwE(f"Unbound var: {k}") return env.data[k.value]
def _expect(k): if not std.isSymbol(k): throwE("expected symbol")
def meta(obj): if std.isSimple(obj): throwE(f"can't get meta from: {std.rtti(obj)}") return obj["____meta"]
def addLib(alias, lib): #console.log(`adding lib ${alias}`) if alias in _STAR_libs_STAR: throwE(f"Library alias already added: {alias}") _STAR_libs_STAR[alias] = lib
def addVar(sym, info): s = str(sym) m = _STAR_vars_STAR.get(s) if m: throwE(f"var: {s} already added") _STAR_vars_STAR[s] = info
############################################################################## def _swap(a, f, *xs): p = [a.value, *xs] a.value = f(*p) return a.value ############################################################################## _intrinsics_ = { "macroexpand*": lambda a, e=None: println(std.prn(expandMacro(a, e or genv()))), "macros*": _macros, "env*": _env, "slice*": _slice, "throw*": lambda *xs: throwE("".join(xs)), "str*": lambda *xs: "".join([str(x) for x in xs]), "obj-type*": std.rtti, "gensym*": std.gensym, "is-eq?": std.isEQ, "is-some?": lambda o: not (o is None), "is-str?": lambda a: type(a) == str, "false?": lambda a: a is False, "true?": lambda a: a is True, "is-nil?": std.isNil, "is?": lambda a, b: a is b, "is-keyword?": std.isKeyword, "is-symbol?": std.isSymbol, "keyword*": std.keyword, "symbol*": std.symbol, "println*": prnLn,
def __init__(self,token): name= "1" if token.value == "%" else token.value[1:] v = int(name) if not (v >0): std.throwE(f"invalid lambda-arg {token.value}") super().__init__(f"%{v}")