def test_env_constructor_binds_multiple(self): env = Env( outer=None, binds=[MalSymbol("a"), MalSymbol("b")], exprs=[MalInt(44), MalInt(32)], ) self.assertEqual(44, env.get("a").native()) self.assertEqual(32, env.get("b").native())
def count(args): seq = args[0] if isinstance(seq, MalList): return MalInt(len(seq)) elif seq is nil: return MalInt(0) else: throw_str("count called on non-sequence")
def test_if_basic_false(self): env = Env(None) self.assertEqual( 1234, step4_if_fn_do.EVAL( MalList( [MalSymbol("if"), MalBoolean(False), MalInt(4321), MalInt(1234)] ), env, ).native(), )
def test_eval_1_plus_1(self): env = Env(None) env.set( "+", mal_types.MalFunctionCompiled( lambda a: MalInt(a[0].native() + a[1].native())), ) self.assertEqual( 2, step3_env.EVAL(MalList([MalSymbol("+"), MalInt(1), MalInt(1)]), env).native(), )
def read_atom(reader): if IS_RPYTHON: int_re = '-?[0-9]+$' float_re = '-?[0-9][0-9.]*$' else: int_re = re.compile('-?[0-9]+$') float_re = re.compile('-?[0-9][0-9.]*$') token = reader.next() if re.match(int_re, token): return MalInt(int(token)) ## elif re.match(float_re, token): return int(token) elif token[0] == '"': end = len(token) - 1 if end < 2: return MalStr(u"") else: s = unicode(token[1:end]) s = types._replace(u'\\"', u'"', s) s = types._replace(u'\\n', u"\n", s) s = types._replace(u'\\\\', u"\\", s) return MalStr(s) elif token[0] == ':': return _keywordu(unicode(token[1:])) elif token == "nil": return types.nil elif token == "true": return types.true elif token == "false": return types.false else: return MalSym(unicode(token))
def divide(args): a, b = args[0], args[1] if not isinstance(a, MalInt) or not isinstance(b, MalInt): throw_str("/ called on non-integer") if b.value == 0: throw_str("divide by zero") return MalInt(int(a.value/b.value))
def test_MalFunctionCompiled(self): self.assertEqual( "3", str( mal_types.MalFunctionCompiled( lambda a: MalInt(a[0].native() + a[1].native())).call( [mal_types.MalInt(1), mal_types.MalInt(2)])), )
def test_def(self): env = Env(None) self.assertEqual( 1, step3_env.EVAL( MalList([MalSymbol("def!"), MalSymbol("a"), MalInt(1)]), env).native(), ) self.assertEqual(1, env.get("a").native())
def test_if_basic_false_no_fourth_arg(self): env = Env(None) self.assertEqual( "nil", str( step4_if_fn_do.EVAL( MalList([MalSymbol("if"), MalBoolean(False), MalInt(4321)]), env ) ), )
def test_let_advanced(self): env = Env(None) env.set( "+", mal_types.MalFunctionCompiled( lambda a: MalInt(a[0].native() + a[1].native())), ) self.assertEqual( 4, step3_env.EVAL( MalList([ MalSymbol("let*"), MalList([MalSymbol("c"), MalInt(2)]), MalList([MalSymbol("+"), MalSymbol("c"), MalInt(2)]), ]), env, ).native(), )
def test_let_basic(self): env = Env(None) self.assertEqual( 2, step3_env.EVAL( MalList([ MalSymbol("let*"), MalList([MalSymbol("c"), MalInt(2)]), MalSymbol("c"), ]), env, ).native(), )
def read_atom(reader): if IS_RPYTHON: int_re = '-?[0-9]+$' float_re = '-?[0-9][0-9.]*$' str_re = '"(?:[\\\\].|[^\\\\"])*"' else: int_re = re.compile('-?[0-9]+$') float_re = re.compile('-?[0-9][0-9.]*$') str_re = re.compile('"(?:[\\\\].|[^\\\\"])*"') token = reader.next() if re.match(int_re, token): return MalInt(int(token)) ## elif re.match(float_re, token): return int(token) elif re.match(str_re, token): end = len(token) - 1 if end <= 1: return MalStr(u"") else: s = unicode(token[1:end]) s = types._replace(u'\\\\', u"\u029e", s) s = types._replace(u'\\"', u'"', s) s = types._replace(u'\\n', u"\n", s) s = types._replace(u"\u029e", u"\\", s) return MalStr(s) elif token[0] == '"': types.throw_str("expected '\"', got EOF") elif token[0] == ':': return _keywordu(unicode(token[1:])) elif token == "nil": return types.nil elif token == "true": return types.true elif token == "false": return types.false else: return MalSym(unicode(token))
def time_ms(args): return MalInt(int(time.time() * 1000))
def test_step8_is_macro(self): self.assertEqual(False, MalFunctionCompiled(lambda a: MalInt(1)).is_macro()) self.assertEqual( False, MalFunctionRaw(core.ns["+"], MalInt(1), MalList([]), Env(None)).is_macro(), )
def multiply(args): a, b = args[0], args[1] if not isinstance(a, MalInt) or not isinstance(b, MalInt): throw_str("* called on non-integer") return MalInt(a.value*b.value)
def minus(args): a, b = args[0], args[1] if not isinstance(a, MalInt) or not isinstance(b, MalInt): throw_str("- called on non-integer") return MalInt(a.value-b.value)
def test_env_get(self): env = Env(None) expression = MalInt(1) env.set("key", expression) self.assertTrue(env.get("key") is expression)
def minus(args): a, b = args[0], args[1] assert isinstance(a, MalInt) assert isinstance(b, MalInt) return MalInt(a.value - b.value)
def swap(args: List[MalExpression]) -> MalExpression: atom = args[0] assert isinstance(atom, MalAtom) func = args[1] assert isinstance(func, MalFunctionCompiled) or isinstance( func, MalFunctionRaw) atom.reset(func.call([atom.native()] + args[2:])) return atom.native() ns = { "+": MalFunctionCompiled( lambda args: MalInt(args[0].native() + args[1].native())), "-": MalFunctionCompiled( lambda args: MalInt(args[0].native() - args[1].native())), "*": MalFunctionCompiled( lambda args: MalInt(args[0].native() * args[1].native())), "/": MalFunctionCompiled( lambda args: MalInt(int(args[0].native() / args[1].native()))), "prn": MalFunctionCompiled(lambda args: prn(args)), "pr-str": MalFunctionCompiled(lambda args: pr_str(args)), "println": MalFunctionCompiled(lambda args: println(args)),
def visit_mInt(self, node, children) -> MalInt: return MalInt(int(node.value))
import readline from typing import Dict import reader from mal_types import MalExpression, MalSymbol from mal_types import MalFunctionCompiled, MalInt from mal_types import MalList, MalVector, MalHash_map from mal_types import MalUnknownSymbolException, MalSyntaxException repl_env = { "+": MalFunctionCompiled(lambda a: MalInt(a[0].native() + a[1].native())), "-": MalFunctionCompiled(lambda a: MalInt(a[0].native() - a[1].native())), "*": MalFunctionCompiled(lambda a: MalInt(a[0].native() * a[1].native())), "/": MalFunctionCompiled(lambda a: MalInt(int(a[0].native() / a[1].native()))), } def READ(x: str) -> MalExpression: return reader.read(x) def EVAL(ast: MalExpression, env: Dict[str, MalFunctionCompiled]) -> MalExpression: # print("EVAL: " + str(ast)) if isinstance(ast, MalSymbol): try: return env[str(ast)] except KeyError: raise MalUnknownSymbolException(str(ast)) if isinstance(ast, MalVector):
def test_env_find(self): e = Env(None) e.set("key", MalInt(1)) result = e.find("key") self.assertTrue(e is result)
def test_mallist_native(self): x = MalInt(1) self.assertEqual([x], MalList([x]).native())
def test_env_find_outer(self): outer = Env(None) e = Env(outer) outer.set("key", MalInt(1)) result = e.find("key") self.assertTrue(result is outer)
def test_env_constructor_binds(self): env = Env(outer=None, binds=[MalSymbol("a")], exprs=[MalInt(3)]) self.assertEqual(3, env.get("a").native())
def count(x: MalExpression) -> MalInt: if isinstance(x, MalList) or isinstance(x, MalVector): return MalInt(len(x.native())) elif isinstance(x, MalNil): return MalInt(0) raise MalInvalidArgumentException(x, "not a list")
def divide(args): a, b = args[0], args[1] assert isinstance(a, MalInt) assert isinstance(b, MalInt) return MalInt(int(a.value / b.value))
import readline from typing import Dict import reader from env import Env from mal_types import ( MalExpression, MalBoolean, MalNil, MalSymbol, MalInvalidArgumentException, MalUnknownSymbolException, MalSyntaxException, ) from mal_types import MalInt, MalList, MalFunctionCompiled, MalVector, MalHash_map repl_env = Env(None) repl_env.set("+", MalFunctionCompiled(lambda a: MalInt(a[0].native() + a[1].native()))) repl_env.set("-", MalFunctionCompiled(lambda a: MalInt(a[0].native() - a[1].native()))) repl_env.set("*", MalFunctionCompiled(lambda a: MalInt(a[0].native() * a[1].native()))) repl_env.set( "/", MalFunctionCompiled(lambda a: MalInt(int(a[0].native() / a[1].native()))) ) def READ(x: str) -> MalExpression: return reader.read(x) def EVAL(ast: MalExpression, env: Env) -> MalExpression: dbgeval = env.get("DEBUG-EVAL") if (dbgeval is not None and not isinstance(dbgeval, MalNil)
def multiply(args): a, b = args[0], args[1] assert isinstance(a, MalInt) assert isinstance(b, MalInt) return MalInt(a.value * b.value)
def test_eval_invalid(self): with self.assertRaises(MalInvalidArgumentException): step3_env.EVAL(MalList([MalInt(1), MalInt(2)]), Env(None))