def test_if_non_tail(self): symbol_table = types.symbol_table() env = types.Environment(bindings={ symbol_table["if"]: Builtins.IF, symbol_table["+"]: base.plus, }) expr = interop.read_str("(+ (if #t 3 4) 5)", symbol_table=symbol_table) result = compile(expr, env=env) self.assertEqual( result.code, bytes([ OpCode.READ_VAR_1.value, 0, OpCode.CONST_1.value, 0, OpCode.JUMP_IF_NOT_3.value, 0, 0, 14, OpCode.CONST_1.value, 1, OpCode.JUMP_3.value, 0, 0, 16, OpCode.CONST_1.value, 2, OpCode.CONST_1.value, 3, OpCode.TAIL_CALL_1.value, 2, ])) self.assertEqual(result.variables, [symbol_table["+"]]) self.assertEqual(result.constants, [True, 3, 4, 5])
def test_quote(self): symbol_table = types.symbol_table() env = types.Environment( bindings={symbol_table["quote"]: Builtins.QUOTE}) expr = interop.read_str("'abc", symbol_table=symbol_table) result = eval.eval(expr, env=env) self.assertEqual(result, symbol_table["abc"])
def test_lambda(self): symbol_table = types.symbol_table() env = types.Environment( bindings={symbol_table["lambda"]: Builtins.LAMBDA}) expr = interop.read_str("((lambda () 1))", symbol_table=symbol_table) result = eval.eval(expr, env=env) self.assertEqual(result, 1)
def test_recursive(self): n = 100 string = "(+ 1 " * n + ")" * n symbol_table = types.symbol_table() env = types.Environment(bindings={symbol_table["+"]: base.plus}) expr = interop.read_str(string, symbol_table=symbol_table) result = eval.eval(expr, env=env) self.assertEqual(result, n)
def test_set_error(self): symbol_table = types.symbol_table() env = types.Environment(bindings={ symbol_table["set!"]: Builtins.SET, }) expr = interop.read_str("(set! x 8)", symbol_table=symbol_table) with self.assertRaises(exceptions.IdentifierNotBoundError): result = eval.eval(expr, env=env)
def read_str(str_, *, symbol_table=None, keyword_table=None): if symbol_table is None: symbol_table = types.symbol_table() if keyword_table is None: keyword_table = types.keyword_table() in_stream = io.StringIO(str_) reader_ = reader.Reader(io.StringIO(str_), symbol_table=symbol_table, keyword_table=keyword_table) return reader_.read(in_stream)
def test_define(self): symbol_table = types.symbol_table() x = symbol_table['x'] env = types.Environment(bindings={ symbol_table["define"]: Builtins.DEFINE, }) expr = interop.read_str("(define x 5)", symbol_table=symbol_table) result = eval.eval(expr, env=env) self.assertEqual(result, False) self.assertEqual(env[x], 5)
def test_quote(self): symbol_table = types.symbol_table() env = types.Environment( bindings={symbol_table["quote"]: Builtins.QUOTE}) expr = interop.read_str("'a", symbol_table=symbol_table) result = compile(expr, env=env) self.assertEqual(result.code, bytes([OpCode.CONST_1.value, 0, OpCode.RET.value])) self.assertEqual(result.variables, []) self.assertEqual(result.constants, [symbol_table["a"]])
def __init__(self): self.symbol_table = types.symbol_table() self.keyword_table = types.keyword_table() self.global_env = interop.str_bindings_to_env( self._default_builtins_dict, symbol_table=self.symbol_table) self.load_paths = [pathlib.Path.cwd()] self.stdout = ports.TextStreamPort.from_stream(sys.stdout) self.stdin = ports.TextStreamPort.from_stream(sys.stdin) self.stderr = ports.TextStreamPort.from_stream(sys.stderr) self.hooks = {"eval": {"call": None}}
def test_define_set(self): symbol_table = types.symbol_table() x = symbol_table['x'] env = types.Environment(bindings={ symbol_table["set!"]: Builtins.SET, x: 3, }) expr = interop.read_str("(set! x 8)", symbol_table=symbol_table) result = eval.eval(expr, env=env) self.assertEqual(result, False) self.assertEqual(env[x], 8)
def test_lambda_rest(self): symbol_table = types.symbol_table() env = types.Environment( bindings={ symbol_table["lambda"]: Builtins.LAMBDA, symbol_table["quote"]: Builtins.QUOTE, }) expr = interop.read_str("((lambda (x :rest y) y) 1 2 3)", symbol_table=symbol_table) result = eval.eval(expr, env=env) result_list = interop.from_scheme_list(result) self.assertEqual(result_list, [2, 3])
def test_set(self): symbol_table = types.symbol_table() env = types.Environment(bindings={symbol_table["set!"]: Builtins.SET}) x = symbol_table["x"] expr = interop.read_str("(set! x 3)", symbol_table=symbol_table) result = compile(expr, env=env) self.assertEqual( result.code, bytes([ OpCode.CONST_1.value, 0, OpCode.SET_VAR_1.value, 0, OpCode.PUSH_FALSE.value, OpCode.RET.value ])) self.assertEqual(result.variables, [x]) self.assertEqual(result.constants, [3])
def eval_str(str_, str_bindings): symbol_table = types.symbol_table() keyword_table = types.keyword_table() env = str_bindings_to_env(str_bindings, symbol_table=symbol_table) reader_ = reader.Reader(io.StringIO(str_), symbol_table=symbol_table, keyword_table=keyword_table) in_stream = io.StringIO(str_) result = False while True: expr = reader_.read(in_stream) if base.eofp(expr): return result result = eval.eval(expr, env=env)
def test_lexical_scope(self): symbol_table = types.symbol_table() lexical = symbol_table['lexical'] dynamic = symbol_table['dynamic'] env = types.Environment( bindings={ symbol_table["lambda"]: Builtins.LAMBDA, symbol_table["quote"]: Builtins.QUOTE, }) expr = interop.read_str(""" ((lambda (x) (((lambda (x) (lambda () x)) 'lexical))) 'dynamic) """, symbol_table=symbol_table) result = eval.eval(expr, env=env) self.assertEqual(result, lexical)
def test_set_local(self): symbol_table = types.symbol_table() x = symbol_table['x'] env = types.Environment( bindings={ symbol_table["lambda"]: Builtins.LAMBDA, symbol_table["set!"]: Builtins.SET, x: 3, }) expr = interop.read_str(""" ((lambda () (set! x 8) x)) """, symbol_table=symbol_table) result = eval.eval(expr, env=env) self.assertEqual(result, 8) self.assertEqual(env[x], 8)
def test_call(self): symbol_table = types.symbol_table() env = types.Environment(bindings={symbol_table["+"]: None}) expr = interop.read_str("(+ 10 20)", symbol_table=symbol_table) result = compile(expr, env=env) self.assertEqual( result.code, bytes([ OpCode.READ_VAR_1.value, 0, OpCode.CONST_1.value, 0, OpCode.CONST_1.value, 1, OpCode.TAIL_CALL_1.value, 2, ])) self.assertEqual(result.variables, [symbol_table["+"]]) self.assertEqual(result.constants, [10, 20])
def test_lambda_arg(self): symbol_table = types.symbol_table() env = types.Environment( bindings={symbol_table["lambda"]: Builtins.LAMBDA}) x = symbol_table["x"] expr = interop.read_str("(lambda (x) x)", symbol_table=symbol_table) result = compile(expr, env=env) self.assertEqual( result.code, bytes([ OpCode.CONST_1.value, 0, OpCode.MAKE_CLOSURE.value, OpCode.RET.value ])) self.assertEqual(result.variables, []) self.assertIsInstance(result.constants[0], Bytecode) self.assertEqual(result.constants[0].code, bytes([OpCode.READ_VAR_1.value, 0, OpCode.RET.value])) self.assertEqual(result.constants[0].constants, []) self.assertEqual(result.constants[0].variables, [x]) self.assertEqual(result.constants[0].formals, [x])
def test_if_tail(self): symbol_table = types.symbol_table() env = types.Environment(bindings={symbol_table["if"]: Builtins.IF}) expr = interop.read_str("(if #t 3 4)", symbol_table=symbol_table) result = compile(expr, env=env) self.assertEqual( result.code, bytes([ OpCode.CONST_1.value, 0, OpCode.JUMP_IF_NOT_3.value, 0, 0, 9, OpCode.CONST_1.value, 1, OpCode.RET.value, OpCode.CONST_1.value, 2, OpCode.RET.value, ])) self.assertEqual(result.variables, []) self.assertEqual(result.constants, [True, 3, 4])
def reader(self, stream): return reader.Reader( stream, symbol_table=types.symbol_table(), keyword_table=types.keyword_table())
def test_if_false(self): symbol_table = types.symbol_table() env = types.Environment(bindings={symbol_table["if"]: Builtins.IF}) expr = interop.read_str("(if #f 2 3)", symbol_table=symbol_table) result = eval.eval(expr, env=env) self.assertEqual(result, 3)
def test_fun_call_order(self): symbol_table = types.symbol_table() env = types.Environment(bindings={symbol_table["-"]: base.minus}) expr = interop.read_str("(- 1 2 3)", symbol_table=symbol_table) result = eval.eval(expr, env=env) self.assertEqual(result, -4)
def test_fun_call(self): symbol_table = types.symbol_table() env = types.Environment(bindings={symbol_table["+"]: base.plus}) expr = interop.read_str("(+ 1 2)", symbol_table=symbol_table) result = eval.eval(expr, env=env) self.assertEqual(result, 3)
def test_variable(self): symbol_table = types.symbol_table() env = types.Environment(bindings={symbol_table["a"]: 5}) expr = interop.read_str("a", symbol_table=symbol_table) result = eval.eval(expr, env=env) self.assertEqual(result, 5)
def test_symbol_unique(self): store = types.symbol_table() a = store['qwe'] b = store['qwe'] self.assertEqual(a, b)