def test_quotes(self): code = """ (define his-name ''(kenjin che)) """ self.assertEqual( parse(code), ['define', 'his-name', ['quote', ['quote', ['kenjin', 'che']]]])
def test_simple(self): code = """ (define (gcd a b) (if (= b 0) a (gcd b (rem a b)))) """ self.assertEqual(parse(code), [ 'define', ['gcd', 'a', 'b'], ['if', ['=', 'b', 0], 'a', ['gcd', 'b', ['rem', 'a', 'b']]] ])
def test_string(self): code = """ (define (fib n) "Computes nth fibonacci number" (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) """ self.assertEqual(parse(code), [ 'define', ['fib', 'n'], '"Computes nth fibonacci number"', [ 'if', ['<', 'n', 2], 'n', ['+', ['fib', ['-', 'n', 1]], ['fib', ['-', 'n', 2]]] ] ])
def test_gcd(self): code = """ (test-b (test (op =) (reg b) (const 0)) (branch (label gcd-done)) (assign t (op rem) (reg a) (reg b)) (assign a (reg b)) (assign b (reg t)) (goto (label test-b)) gcd-done) """ m = Machine(["a", "b", "t"], [("rem", lambda x, y: x % y), ("=", lambda x, y: x == y)], parse(code)) m.get_register('a').value = 206 m.get_register('b').value = 40 m.start() self.assertEqual(m.get_register('a').value, 2)
def test_fib(self): code = """ (fib-start (assign continue (label fib-done)) fib-loop (test (op <) (reg n) (const 2)) (branch (label immediate-answer)) (save continue) (assign continue (label afterfib-n-1)) (save n) (assign n (op -) (reg n) (const 1)) (goto (label fib-loop)) afterfib-n-1 (restore n) (restore continue) (assign n (op -) (reg n) (const 2)) (save continue) (assign continue (label afterfib-n-2)) (save val) (goto (label fib-loop)) afterfib-n-2 (assign n (reg val)) (restore val) (restore continue) (assign val (op +) (reg val) (reg n)) (goto (reg continue)) immediate-answer (assign val (reg n)) (goto (reg continue)) fib-done) """ m = Machine(['n', 'val', 'continue'], [('<', lambda a, b: a < b), ('-', lambda a, b: a - b), ('+', lambda a, b: a + b)], parse(code)) m.get_register('n').value = 10 m.start() self.assertEqual(m.get_register('val').value, 55)
Vanilla Scheme interpreter for SICP Chapter 4 ctrl-d to exit, Happy Hacking!! """) code_to_eval = [] while True: if code_to_eval == []: print(PROMPT, end='') try: code = input() except EOFError: print('Goodbye!!') break else: code_to_eval.append(code) expr = parse(' '.join(code_to_eval)) # succeeds to parse if expr != None: try: value = vseval(expr, GLOBAL_ENV) except UnboundVar as e: print('Unbound Variable: ', e) except Exception as e: print('Error: ', e) else: print("=> ", end='') print(value) finally: code_to_eval = []
def ev(exp, env=GLOBAL_ENV): return vseval(parse(exp), env)
# (list 'set-variable-value! set-variable-value!) # (list 'define-variable! define-variable!) # (list 'primitive-procedure? primitive-procedure?) # (list 'apply-primitive-procedure apply-primitive-procedure) # (list 'prompt-for-input prompt-for-input) # (list 'announce-output announce-output) # (list 'user-print user-print) # (list 'empty-arglist empty-arglist) # (list 'adjoin-arg adjoin-arg) # (list 'last-operand? last-operand?) # (list 'no-more-exps? no-more-exps?) ;for non-tail-recursive machine # (list 'get-global-environment get-global-environment)) eval_operations = [ ("read", lambda: parse(input())), ('self-evaluating?', is_self_evaluating), ('quoted?', lambda exp: exp[0] == 'quote'), ('text-of-quotation', text_of_quotation), ] eval_code = """ (read-eval-print-loop (perform (op initialize-stack)) (perform (op prompt-for-input) (const ";;; EC-Eval input:")) (assign exp (op read))
ctrl-d to exit, Happy Hacking!! """) code_to_eval = [] while True: if code_to_eval == []: print(PROMPT, end='') try: code = input() except EOFError: print('Goodbye!!') break else: code_to_eval.append(code) expr = parse(' '.join(code_to_eval)) # succeeds to parse if expr != None: try: value = vseval(expr, GLOBAL_ENV) except UnboundVar as e: print('Unbound Variable: ', e) except Exception as e: print('Error: ', e) else: print("=> ", end='') print(value) finally: code_to_eval = []
def test_dot(self): self.assertEqual(parse("(a . b)"), ['a', ['dot', 'b']]) with self.assertRaises(ValueError): print(parse("(a . b c)"))
def test_simpler(self): self.assertEqual(parse('3'), 3) self.assertEqual(parse('-3.34'), -3.34) self.assertEqual(parse('"abc"'), '"abc"') self.assertEqual(parse("'a"), ['quote', 'a'])
# (list 'lookup-variable-value lookup-variable-value) # (list 'set-variable-value! set-variable-value!) # (list 'define-variable! define-variable!) # (list 'primitive-procedure? primitive-procedure?) # (list 'apply-primitive-procedure apply-primitive-procedure) # (list 'prompt-for-input prompt-for-input) # (list 'announce-output announce-output) # (list 'user-print user-print) # (list 'empty-arglist empty-arglist) # (list 'adjoin-arg adjoin-arg) # (list 'last-operand? last-operand?) # (list 'no-more-exps? no-more-exps?) ;for non-tail-recursive machine # (list 'get-global-environment get-global-environment)) eval_operations = [ ("read", lambda: parse(input())), ('self-evaluating?', is_self_evaluating), ('quoted?', lambda exp: exp[0] == 'quote'), ('text-of-quotation', text_of_quotation), ] eval_code = """ (read-eval-print-loop (perform (op initialize-stack)) (perform (op prompt-for-input) (const ";;; EC-Eval input:")) (assign exp (op read)) (assign env (op get-global-environment)) (assign continue (label print-result)) (goto (label eval-dispatch)) print-result