def compile_expr(self, expr): if (base.numberp(expr) or base.stringp(expr) or base.booleanp(expr)): return self.compile_const(expr) elif base.symbolp(expr): return self.compile_variable(expr) elif base.pairp(expr): return self.compile_call(expr) else: msg = "Bad expr for compilation: {}".format(expr) raise CompileError(msg)
def compile_define(self, lvalue, *rest): if base.symbolp(lvalue): if len(rest) < 1: raise CompileError( "define: missing value for identifier") if len(rest) > 1: raise CompileError( "define: multiple values for identifier") return self.compile_define_var(lvalue, rest[0]) elif base.pairp(lvalue): return self.compile_define_proc(lvalue.car, lvalue.cdr, *rest) else: raise CompileError("define: invalid syntax")
def compile_lambda(self, formals, *body): formals = interop.from_scheme_list(formals) formals_rest = None formals_iter = iter(formals) positional = [] for f in formals_iter: if base.keywordp(f) and f.name == ":rest": f = next(formals_iter, None) if not base.symbolp(f): raise CompileError("lambda: expected rest argument name after :rest keyword") formals_rest = f elif base.symbolp(f): positional.append(f) else: raise CompileError(f"syntax error in lambda arguments list: {f}") body = self.compile_block(body) return core.Lambda(name=False, args=positional, rest_args=formals_rest, kwargs=None, rest_kwargs=None, body=body)
def display_pair_to(pair, port): if (base.symbolp(pair.car) and pair.car.name == "quote" and base.pairp(pair.cdr) and base.nullp(pair.cdr.cdr)): port.write("'") display_to(pair.cdr.car, port) else: port.write("(") display_to(pair.car, port) cur = pair.cdr while base.pairp(cur): port.write(" ") display_to(cur.car, port) cur = cur.cdr port.write(")")
def compile_define_proc(self, var, signature, *body): if not base.symbolp(var): raise CompileError("define: non-symbol in procedure definition") lambda_ = self.compile_lambda(signature, *body) return core.DefineVariable(variable=var, value=lambda_)
def compile_define_var(self, var, value): if not base.symbolp(var): raise CompileError("define: non-symbol in variable definition") value = self.compile_expr(value) return core.DefineVariable(variable=var, value=value)
def compile_set_var(self, var, value): if not base.symbolp(var): raise CompileError("set!: non-symbol in variable assignment") value = self.compile_expr(value) return core.SetVariable(variable=var, value=value)
def test_symbol_semicolon(self): stream = io.StringIO("abc;") result = self.reader(stream).read(stream) self.assertTrue(base.symbolp(result)) self.assertEqual(result.name, "abc")
def test_symbol_double_quote(self): stream = io.StringIO('abc"') result = self.reader(stream).read(stream) self.assertTrue(base.symbolp(result)) self.assertEqual(result.name, "abc")
def test_symbol_right_bracket(self): stream = io.StringIO("abc)") result = self.reader(stream).read(stream) self.assertTrue(base.symbolp(result)) self.assertEqual(result.name, "abc")
def test_minus(self): stream = io.StringIO("-") result = self.reader(stream).read(stream) self.assertTrue(base.symbolp(result)) self.assertEqual(result.name, "-")
def test_symbol_with_digits(self): stream = io.StringIO("123abc") result = self.reader(stream).read(stream) self.assertTrue(base.symbolp(result)) self.assertEqual(result.name, "123abc")