def sexp(self, elements): if len(elements) > 1 and elements[-2] == PtObject.intern('.'): assert len(elements) > 2 final = elements[-1] elements = elements[:-2] else: final = PtObject.nil return PtObject.list(elements, final)
def test_let(): check_result('(let ())', PtObject.nil) check_result('(let () 1)', PtObject(1)) check_result('(let (a) a)', PtObject.nil) check_result('(let ((a)) a)', PtObject.nil) check_result('(let ((a nil)) a)', PtObject.nil) check_result('(let ((a 3)) a)', PtObject(3)) check_result('(let ((a 1)) (let ((b a)) b))', PtObject(1))
def _codegen_cons(node, bld, mod, lib, ns): if not bool(node): return _obj_ptr(bld, PtObject.nil) head, tail = node.car, node.cdr if head == PtObject.intern('quote'): return codegen_copy(tail.car, bld, mod, lib, ns) if head == PtObject.intern('begin'): nodes = list(tail) or [PtObject.nil] for node in nodes: retval = codegen(node, bld, mod, lib, ns) return retval if head == PtObject.intern('if'): return _codegen_if(tail, bld, mod, lib, ns) if head == PtObject.intern('let'): return _codegen_let(tail, bld, mod, lib, ns) return _codegen_funcall(node, bld, mod, lib, ns)
def test_literals(): check_result('0', PtObject(0)) check_result('-1', PtObject(-1)) check_result('0xf', PtObject(15)) check_result('2.1', PtObject(2.1)) check_result('-0.0', PtObject(0.0)) check_result('""', PtObject('')) check_result('"alpha"', PtObject('alpha'))
def test_symbol(): obj = PtObject.symbol('abc') assert str(obj) == 'abc' assert obj != PtObject.symbol('abc') obj = PtObject.intern('abc') assert obj != PtObject.symbol('abc') assert obj == PtObject.intern('abc') assert obj is PtObject.intern('abc') ns = { PtSymbol('a', 0): 'a', PtSymbol('b', 1): 'b', } assert ns[PtSymbol('a', 0)] == 'a' assert ns[PtSymbol('a', 1)] == 'b' assert ns[PtSymbol('b', 0)] == 'a'
def bquot(self, value): return PtObject.list([PtObject.intern('backquote'), value])
def double(self, value): return PtObject(float(value))
def test_parsing(): parser = PaltryParser(semantics=PaltrySemantics()) parse = lambda s: parser.parse(s, 'exp') assert parse('quux') == PtObject.intern('quux') assert parse('"alpha"') == PtObject('alpha') assert parse('""') == PtObject('') assert parse('120') == PtObject(120) assert parse('-2') == PtObject(-2) assert parse('120.0e1') == PtObject(1200.0) assert parse('-3.14') == PtObject(-3.14) assert parse('0xf') == PtObject(15) assert parse('-0xf') == PtObject(-15) assert parse('0o7') == PtObject(7) assert parse('-0o7') == PtObject(-7) assert parse('0b1') == PtObject(1) assert parse('-0b1') == PtObject(-1) assert parse('(a b c d "e")') == PtObject.list([ PtObject.intern('a'), PtObject.intern('b'), PtObject.intern('c'), PtObject.intern('d'), PtObject('e'), ]) assert parse("'quoted") == PtObject.list( [PtObject.intern('quote'), PtObject.intern('quoted')]) assert parse("'(a list goes here)") == PtObject.list([ PtObject.intern('quote'), PtObject.list([ PtObject.intern('a'), PtObject.intern('list'), PtObject.intern('goes'), PtObject.intern('here'), ]), ]) assert parse('`(a list goes here)') == PtObject.list([ PtObject.intern('backquote'), PtObject.list([ PtObject.intern('a'), PtObject.intern('list'), PtObject.intern('goes'), PtObject.intern('here'), ]), ]) assert parse(',sym') == PtObject.list([ PtObject.intern('unquote'), PtObject.intern('sym'), ]) assert parse(',(a b)') == PtObject.list([ PtObject.intern('unquote'), PtObject.list([ PtObject.intern('a'), PtObject.intern('b'), ]) ]) assert parse(',@sym') == PtObject.list([ PtObject.intern('unquote-splice'), PtObject.intern('sym'), ]) assert parse(',@(a b)') == PtObject.list([ PtObject.intern('unquote-splice'), PtObject.list([ PtObject.intern('a'), PtObject.intern('b'), ]) ])
def test_cons(): assert str(PtObject.nil) == 'nil' assert PtObject.nil == PtObject.nil obj = PtObject.cons(PtObject.intern('def'), PtObject.intern('ghi')) assert str(obj) == '(def . ghi)' assert obj == PtObject.cons(PtObject.intern('def'), PtObject.intern('ghi')) assert obj != PtObject.cons(PtObject.symbol('def'), PtObject.intern('ghi')) assert obj != PtObject.cons(PtObject.intern('def'), PtObject.symbol('ghi')) obj = PtObject.cons( PtObject.intern('a'), PtObject.cons( PtObject.intern('b'), PtObject.cons( PtObject.intern('c'), PtObject.intern('d')))) assert str(obj) == '(a b c . d)' assert obj == PtObject.cons( PtObject.intern('a'), PtObject.cons( PtObject.intern('b'), PtObject.cons( PtObject.intern('c'), PtObject.intern('d')))) obj = PtObject.cons( PtObject.intern('a'), PtObject.cons( PtObject.intern('b'), PtObject.cons( PtObject.intern('c'), PtObject.nil))) assert str(obj) == '(a b c)' assert obj == PtObject.cons( PtObject.intern('a'), PtObject.cons( PtObject.intern('b'), PtObject.cons( PtObject.intern('c'), PtObject.nil))) obj = PtObject.list([ PtObject.intern('a'), PtObject.intern('b'), PtObject.intern('c'), PtObject.intern('d'), PtObject.intern('e'), ]) assert str(obj) == '(a b c d e)' assert obj == PtObject.list([ PtObject.intern('a'), PtObject.intern('b'), PtObject.intern('c'), PtObject.intern('d'), PtObject.intern('e'), ])
def test_string(): obj = PtObject('abc') assert str(obj) == '"abc"' assert obj == PtObject('abc') assert obj != PtObject('abcc')
def symbol(self, name): return PtObject.intern(name)
def test_if(): check_result('(if t 1)', PtObject(1)) check_result('(if nil 1)', PtObject.nil) check_result('(if nil 1 2)', PtObject(2)) check_result('(if nil 1 2 3)', PtObject(3))
def test_begin(): check_result('(begin)', PtObject.nil) check_result('(begin 1)', PtObject(1)) check_result('(begin 1 2 3)', PtObject(3))
def test_quote(): check_result("'symbol", PtObject.intern('symbol')) check_result( "''symbol", PtObject.list([PtObject.intern('quote'), PtObject.intern('symbol')])) check_result("'(a b c)", PtObject.list([PtObject.intern(s) for s in ['a', 'b', 'c']])) check_result("'(a . b)", PtObject.cons(PtObject.intern('a'), PtObject.intern('b'))) check_result( "'(a b . c)", PtObject.cons( PtObject.intern('a'), PtObject.cons(PtObject.intern('b'), PtObject.intern('c'))))
def unquot(self, value): return PtObject.list([PtObject.intern('unquote'), value])
def unquot_splice(self, value): return PtObject.list([PtObject.intern('unquote-splice'), value])
def test_runtime(): check_result('(intern "alpha")', PtObject.intern('alpha'))
def test_float(): obj = PtObject(3.0) assert str(obj) == '3.0' assert obj == PtObject(3.0) assert obj != PtObject(-3.0)
def string(self, value): value = codecs.escape_decode(bytes(value[1:-1], 'utf-8'))[0].decode('utf-8') return PtObject(value)
def hex_integer(self, value): sign = '' if value[0] in '+-': sign, value = value[0], value[1:] return PtObject(int(sign + value[2:], 16))
def dec_integer(self, value): return PtObject(int(value))
def test_integer(): obj = PtObject(3) assert str(obj) == '3' assert obj == PtObject(3) assert obj != PtObject(4)
def intern(name): return PtObject.intern(name.string)