def test_symbol(self): x = symbol('x') y = symbol('x') z = symbol(x) self.assertTrue(is_symbol(x)) self.assertIsInstance(x, symbol) self.assertEqual(x, x) self.assertEqual(x, y) self.assertEqual(x, z) self.assertEqual(y, x) self.assertEqual(y, y) self.assertEqual(y, z) self.assertEqual(z, x) self.assertEqual(z, y) self.assertEqual(z, z) self.assertEqual(id(x), id(y)) self.assertEqual(id(y), id(z)) self.assertTrue(x is y) self.assertTrue(y is z) w = symbol('w') self.assertNotEqual(x, w) self.assertNotEqual(w, x) self.assertFalse(x is w)
def test_list(self): src = "(testing a thing)" col = parse_source(src) exp = cons(symbol("testing"), symbol("a"), symbol("thing"), nil) self.assertEqual(col, exp) src = "[testing a thing]" col = parse_source(src) self.assertEqual(col, exp) with self.assertRaises(SyntaxError): src = "(no way]" col = parse_source(src) with self.assertRaises(SyntaxError): src = "[no way)" col = parse_source(src) with self.assertRaises(SyntaxError): src = "{no way]" col = parse_source(src) with self.assertRaises(SyntaxError): src = "[no way}" col = parse_source(src) with self.assertRaises(SyntaxError): src = "{no way)" col = parse_source(src) with self.assertRaises(SyntaxError): src = "(no way}" col = parse_source(src)
def test_symbol_2(self): w = "X" x = symbol(w) y = symbol(str(x)) z = symbol(str(y)) self.assertEqual(x, x) self.assertEqual(x, y) self.assertEqual(x, z) self.assertEqual(y, x) self.assertEqual(y, y) self.assertEqual(y, z) self.assertEqual(z, x) self.assertEqual(z, y) self.assertEqual(z, z) self.assertEqual(id(x), id(y)) self.assertEqual(id(y), id(z)) self.assertTrue(x is y) self.assertTrue(y is z) self.assertEqual(id(w), id(str(x))) self.assertEqual(id(w), id(str(y))) self.assertEqual(id(w), id(str(z)))
def test_simple(self): self.qq("`1", 1) self.qq("`,1", 1) self.qq("`tacos", symbol("tacos")) self.qq("`:tacos", keyword("tacos")) self.qq("`nil", symbol("nil")) self.qq("`()", nil) self.qq("`(1 2 3 ,4 ,5)", cons(1, 2, 3, 4, 5, nil)) self.qq("`(1 2 3 ,A ,B Z)", cons(1, 2, 3, 4, 5, symbol("Z"), nil), A=4, B=5) self.qq("`(1 2 ,(foo 3 6))", cons(1, 2, [3, 4, 5], nil), foo=lambda a, b: list(range(a,b)))
def test_eval_pair(self): data = cons(symbol("+"), 1, 2, symbol("tacos"), nil) src = """ (eval source_obj) """ stmt, env = compile_expr(src, source_obj=data, tacos=5) self.assertEqual(stmt(), 8)
def test_len(self): empty = symbol('') short = symbol('1') more = symbol('sibilant') self.assertEqual(len(empty), len('')) self.assertEqual(len(short), len('1')) self.assertEqual(len(more), len('sibilant'))
def test_implicit_begin(self): src = "{testing a thing}" col = parse_source(src) self.assertEqual( col, cons(symbol("begin"), symbol("testing"), symbol("a"), symbol("thing"), nil))
def test_quasi(self): src = """ `bar """ col = parse_source(src) self.assertEqual(col, cons(symbol("quasiquote"), symbol("bar"), nil))
def test_quote_symbol(self): src = """ 'foo """ col = parse_source(src) self.assertEqual(col, cons(symbol("quote"), symbol("foo"), nil))
def test_implicit_begin(self): src = "{testing a thing}" col = parse_source(src) self.assertEqual(col, cons(symbol("begin"), symbol("testing"), symbol("a"), symbol("thing"), nil))
def test_newline(self): src = """ ( this is a test ) """ col = parse_source(src) exp = cons(symbol("this"), symbol("is"), symbol("a"), symbol("test"), nil) self.assertEqual(col, exp)
def test_compile_pair(self): data = cons(symbol("+"), 1, 2, symbol("tacos"), nil) src = """ (compile source_obj) """ stmt, env = compile_expr(src, source_obj=data, tacos=5) res = stmt() self.assertIs(type(res), CodeType) self.assertEqual(eval(res, {"tacos": 5}), 8)
def test_comments(self): src = """ ; Let's check out the comments ( this is ; well it's something a test ) ; this ought to work """ col = parse_source(src) exp = cons(symbol("this"), symbol("is"), symbol("a"), symbol("test"), nil) self.assertEqual(col, exp)
def test_macro_let(self): src = """ (macro-let [[swap_test (a b c) (cons c b a '())]] (swap_test 'world 'hello cons)) """ stmt, env = compile_expr(src) self.assertEqual(stmt(), cons(symbol("hello"), symbol("world"))) self.assertFalse("swap_test" in env)
def test_fraction(self): src = "1/2/3" self.assertRaises(SyntaxError, parse_source, src) src = "1/2" col = parse_source(src) self.assertEqual(col, cons(symbol("fraction"), 1, 2, nil)) src = "-1/2" col = parse_source(src) self.assertEqual(col, cons(symbol("fraction"), -1, 2, nil))
def test_decimal(self): src = "1.5d" col = parse_source(src) self.assertEqual(col, cons(symbol("decimal"), (0, (1, 5), -1), nil)) src = ".5d" col = parse_source(src) self.assertEqual(col, cons(symbol("decimal"), (0, (5, ), -1), nil)) src = "1.d" col = parse_source(src) self.assertEqual(col, cons(symbol("decimal"), (0, (1, ), 0), nil))
def test_symbol(self): src = "lambda" col = parse_source(src) self.assertIs(col, symbol("lambda")) src = "Number123" col = parse_source(src) self.assertIs(col, symbol("Number123")) src = "None" col = parse_source(src) self.assertIs(col, symbol("None")) src = "True" col = parse_source(src) self.assertIs(col, symbol("True")) src = "False" col = parse_source(src) self.assertIs(col, symbol("False")) src = "nil" col = parse_source(src) self.assertIs(col, symbol("nil")) src = "..." col = parse_source(src) self.assertIs(col, symbol("...")) src = "taco:bell" col = parse_source(src) self.assertIs(col, symbol("taco:bell"))
def test_dict(self): x = symbol('x') y = symbol('y') d = dict() d[x] = "cookies" d[y] = "cake" d['x'] = "chicken" d['y'] = "tuna" self.assertEqual(d[x], "cookies") self.assertEqual(d[y], "cake") self.assertEqual(d['x'], "chicken") self.assertEqual(d['y'], "tuna")
def test_decimal(self): src = "1.5d" col = parse_source(src) self.assertEqual(col, cons(symbol("decimal"), "1.5", nil)) src = ".5d" col = parse_source(src) self.assertEqual(col, cons(symbol("decimal"), ".5", nil)) src = "1.d" col = parse_source(src) self.assertEqual(col, cons(symbol("decimal"), "1.", nil))
def test_against_str(self): x = symbol('x') self.assertFalse(x is 'x') self.assertNotEqual(x, 'x') self.assertNotEqual('x', x)
def test_against_symbol(self): xk = keyword("x") xs = symbol("x") self.assertFalse(xk is xs) self.assertNotEqual(xk, xs) self.assertNotEqual(xs, xk)
def test_eval_symbol(self): data = symbol("tacos") src = """ (eval source_sym) """ stmt, env = compile_expr(src, source_sym=data, tacos=5) self.assertEqual(stmt(), 5)
def test_quote_unquote_splice(self): src = """ `(,@foo) """ col = parse_source(src) exp = cons(symbol("quasiquote"), cons(cons(symbol("unquote-splicing"), symbol("foo"), nil), nil), nil) self.assertEqual(col, exp) src = """ `(,@(foo bar)) """ col = parse_source(src) exp = cons(symbol("quasiquote"), cons(cons(symbol("unquote-splicing"), cons(symbol("foo"), symbol("bar"), nil), nil), nil), nil) self.assertEqual(col, exp)
def test_compile_symbol(self): data = symbol("tacos") src = """ (compile source_sym) """ stmt, env = compile_expr(src, source_sym=data) res = stmt() self.assertIs(type(res), CodeType) self.assertEqual(eval(res, {"tacos": 5}), 5)
def test_defmacro(self): src = """ (defmacro swap_test (a b c) (cons c b a '())) """ stmt, env = compile_expr(src) self.assertEqual(stmt(), None) swap_test = env["swap_test"] self.assertTrue(isinstance(swap_test, Macro)) self.assertTrue(is_macro(swap_test)) self.assertEqual(swap_test.__name__, "swap_test") self.assertRaises(TypeError, swap_test, 1, 2, 3) self.assertEqual(swap_test.expand(1, 2, 3), cons(3, 2, 1, nil)) src = """ (swap_test 'world 'hello cons) """ # compiles to equivalent of (cons 'hello 'world) stmt, env = compile_expr(src, swap_test=swap_test) self.assertEqual(stmt(), cons(symbol("hello"), symbol("world")))
def translate_lambda(self, pseudop, args): """ Helper to _gen_code that handles just lambda definitions """ # as per pseudop_lambda, the args will be a triplet code, default_count, kwonly_count = args ci = self.consts.index(code) ni = self.consts.index(code.co_name) _Opcode = Opcode flags = 0x00 if default_count: flags |= 0x01 if kwonly_count: flags |= 0x02 if code.co_freevars: # code is a closure, so we'll need to find the matching # free/cell vars and provide them. for f in code.co_freevars: fsym = symbol(f) if fsym in self.cell_vars: fi = self.cell_vars.index(fsym) elif fsym in self.free_vars: fi = len(self.cell_vars) fi += self.free_vars.index(fsym) else: assert False, "missing local var %r" % fsym yield _Opcode.LOAD_CLOSURE, fi yield _Opcode.BUILD_TUPLE, len(code.co_freevars) flags |= 0x08 # not a closure, so just a pain ol' function yield _Opcode.LOAD_CONST, ci yield _Opcode.LOAD_CONST, ni yield _Opcode.MAKE_FUNCTION, flags
def test_quote_unquote_splice(self): src = """ `(,@foo) """ col = parse_source(src) exp = cons( symbol("quasiquote"), cons(cons(symbol("unquote-splicing"), symbol("foo"), nil), nil), nil) self.assertEqual(col, exp) src = """ `(,@(foo bar)) """ col = parse_source(src) exp = cons( symbol("quasiquote"), cons( cons(symbol("unquote-splicing"), cons(symbol("foo"), symbol("bar"), nil), nil), nil), nil) self.assertEqual(col, exp)
def test_quote_list(self): src = """ '(foo bar) """ col = parse_source(src) self.assertEqual( col, cons(symbol("quote"), cons(symbol("foo"), symbol("bar"), nil), nil)) src = """ \n'(foo\n bar\n) """ col = parse_source(src) self.assertEqual( col, cons(symbol("quote"), cons(symbol("foo"), symbol("bar"), nil), nil))
def test_quote_list(self): src = """ '(foo bar) """ col = parse_source(src) self.assertEqual(col, cons(symbol("quote"), cons(symbol("foo"), symbol("bar"), nil), nil)) src = """ \n'(foo\n bar\n) """ col = parse_source(src) self.assertEqual(col, cons(symbol("quote"), cons(symbol("foo"), symbol("bar"), nil), nil))
def test_quote_symbol(self): src = "'tacos" stmt, env = compile_expr(src, tacos=5) self.assertEqual(stmt(), symbol("tacos"))
"SibilantCompiler", "compiler_for_version", "Compiled", "is_compiled", "Special", "is_special", "Macro", "is_macro", "Alias", "is_alias", "Operator", "is_operator", "gather_formals", "gather_parameters", "env_find_compiled", "env_get_expander", ) _keyword_star = keyword("*") _keyword_starstar = keyword("**") _symbol_attr = symbol("attr") _symbol_nil = symbol("nil") _symbol_None = symbol("None") _symbol_True = symbol("True") _symbol_False = symbol("False") _symbol_ellipsis = symbol("...") _symbol_keyword = symbol("keyword") _symbol_tailcall = symbol("tailcall") _symbol_tailcall_full = symbol("tailcall-full") _symbol_tcr_frame = symbol("__tcr_frame_vars__") Symbol = Union[lazygensym, symbol] COMPILER_DEBUG = False # this is an amount to pad out all max_stack allocations
def test_repr_str(self): x = symbol('x') self.assertEqual(repr(x), "<symbol 'x'>") self.assertEqual(str(x), 'x')
def marshal_wrapper(code_objs, filename=None, mtime=0, source_size=0, builtins_name=None): """ Produce a collection of bytes representing the compiled form of a series of statements (as compiled code objects). """ import importlib._bootstrap_external as ibe try: pyc = ibe._code_to_bytecode except AttributeError: pyc = ibe._code_to_timestamp_pyc factory = compiler_for_version() codespace = factory(filename=filename, mode=Mode.MODULE) # we can't just have the code object in the file, because we # actually have multiple code objects -- one for each top-level # compiled expression. We also need to swap out builtins, which # isn't as easy as just putting it in globals, since python will # optimize away the builtins lookup if globals is the same between # two frame (ie. it won't check for new __builtins__ since the # globals is the same as the parent). So we cheat. We create a # stub code object which simply invokes the exec_marshal_module # function with the code objects, which are marshalled as a const # tuple. # we could have made this easier by making a custom loader for # .lspyc files -- but I'd prefer to be able to just reuse the # existing python loader for .pyc with codespace.active_context({}): # import and obtain sibilant.module.exec_marshal_module codespace.pseudop_const(0) codespace.pseudop_const("exec_marshal_module") codespace.pseudop_build_tuple(1) codespace.pseudop_import_name(symbol("sibilant.module")) codespace.pseudop_import_from(symbol("exec_marshal_module")) codespace.pseudop_rot_two() codespace.pseudop_pop() # argument 1. globals() codespace.pseudop_get_var(symbol("globals")) codespace.pseudop_call(0) # argument 2. tuple(code_objs) codespace.pseudop_const(tuple(code_objs)) # argument 3. builtins (either specified or None) if builtins_name: codespace.pseudop_const(0) codespace.pseudop_const("nil") codespace.pseudop_build_tuple(1) codespace.pseudop_import_name(builtins_name) else: codespace.pseudop_const(None) codespace.pseudop_call(3) codespace.pseudop_return() code = codespace.complete() return pyc(code, mtime, source_size)
def test_dot(self): src = "(testing . 123)" col = parse_source(src) exp = cons(symbol("testing"), 123) self.assertEqual(col, exp)
def test_nested(self): self.qq("``,(+ 1 2)", cons(symbol("quasiquote"), cons(symbol("unquote"), cons(symbol("+"), 1, 2, nil), nil), nil)) self.qq("`(1 2 `(foo ,(+ 1 2)))", cons(1, 2, cons(symbol("quasiquote"), cons(symbol("foo"), cons(symbol("unquote"), cons(symbol("+"), 1, 2, nil), nil), nil), nil), nil)) self.qq("`(1 2 `(foo ,,(+ 1 2)))", cons(1, 2, cons(symbol("quasiquote"), cons(symbol("foo"), cons(symbol("unquote"), 3, nil), nil), nil), nil)) self.qq("``,,(+ 1 2)", cons(symbol("quasiquote"), cons(symbol("unquote"), 3, nil), nil)) self.qq("`(1 `(bar ,@,foo))", cons(1, cons(symbol("quasiquote"), cons(symbol("bar"), cons(symbol("unquote-splicing"), cons(1, 2, 3, nil), nil), nil), nil), nil), foo=cons(1, 2, 3, nil))
"Macro", "is_macro", "Alias", "is_alias", "Operator", "is_operator", "gather_formals", "gather_parameters", "env_find_compiled", "env_get_expander", ) _keyword_star = keyword("*") _keyword_starstar = keyword("**") _symbol_attr = symbol("attr") _symbol_nil = symbol("nil") _symbol_None = symbol("None") _symbol_True = symbol("True") _symbol_False = symbol("False") _symbol_ellipsis = symbol("...") _symbol_keyword = symbol("keyword") _symbol_tailcall = symbol("tailcall") _symbol_tailcall_full = symbol("tailcall-full") _symbol_tcr_frame = symbol("__tcr_frame_vars__") Symbol = Union[lazygensym, symbol] COMPILER_DEBUG = False # this is an amount to pad out all max_stack allocations
""" from sibilant.lib import symbol from sibilant.pseudops import ( PseudopsCompiler, Pseudop, Opcode, translator, ) from sibilant.pseudops.stack import ( StackCounter, stacker, ) _symbol_format_value = symbol("__format_value__") _symbol_build_string = symbol("__build_string__") def direct(opcode, hasargs=True): if hasargs: def direct_translate(comp, pseudop, args): if len(args) == 1: yield opcode, args[0], 0 else: yield (opcode, *args) else: def direct_translate(comp, pseudop, args): yield (opcode, )