def _if(env, *args): """Evaluate and return true_case or false_case depending on cond.""" if len(args) != 3: raise SException("if takes 3 parameters ({} given).".format(len(args))) cond, true_case, false_case = args if seval_tree(cond, env).value: return seval_tree(true_case, env) else: return seval_tree(false_case, env)
def _quasiquote(env, elt): """Return the quoted expression, unquoting unquotes.""" if elt.type != 'list': return elt if (len(elt.value) > 0 and elt.value[0].type == 'id' and elt.value[0].value == 'unquote'): return seval_tree(elt.value[1], env) result = [] for e in elt.value: if (e.type != 'list' or not e.value or e.value[0].value != 'unquote-splice'): result.append(_quasiquote(env, e)) else: result.extend(seval_tree(e.value[1], env).value) return SNode('list', tuple(result))
def impl(dummy_env, *args): if not restargs and len(params.value) != len(args): raise SException("Expected {} args, got {}.".format(len(params.value), len(args))) NON_SYMBOL_ERROR = "Trying to use a non-symbol as a parameter name!" inner_env = SEnvironment(env) for p, a in zip(nameargs.value, args): if p.type != 'id': raise SException(NON_SYMBOL_ERROR) inner_env.define(p.value, a) if restargs: if params.value[1].type != 'id': raise SException(NON_SYMBOL_ERROR) rest = SNode('list', args[len(nameargs.value):]) inner_env.define(params.value[1].value, rest) for c in code[:-1]: seval_tree(c, inner_env) return seval_tree(code[-1], inner_env)
def _define(env, *args): """Add the given name to the environment.""" if len(args) != 2: raise SException("define takes 2 parameters ({} given).".format(len(args))) name, value = args if name.type != 'id': raise SException("Trying to define a non-identifier!") env.define(name.value, seval_tree(value, env)) return SNode('none', None)
def do_fuzz(program, env): try: sprint(program) seval_tree(program, env) except SException: pass
def _eval(real_env, expr, env): if env.type != 'env': raise SException("Passed in value is not an environment.") return seval_tree(expr, env.value)