Leonardo Santagada avatar Leonardo Santagada committed 0c1917a

more tests and a fix for lambda execution, also you can quit repl now

Comments (0)

Files changed (2)

         return self.val
 
 class W_function(W_object):
-    def __init__(self, w_exp, w_args, env):
-        self.w_exp = w_exp
+    def __init__(self, w_args, w_body, env):
+        self.w_body = w_body
         self.w_args = w_args
         self.outer = env
 
     def eval(self, exps):
-        return eval(self.w_exp, Env(self.w_args.lval, exps, self.outer))
+        return eval(self.w_body, Env(self.w_args.lval, exps, self.outer))
 
     def to_str(self):
-        return '(lambda ' + self.w_args.to_str() + self.w_exp.to_str() + ')'
+        return '(lambda ' + self.w_args.to_str() + self.w_body.to_str() + ')'
 
 class W_builtin(W_function):
     def __init__(self):
         if var in self.d:
             return self
         else:
-            self.outer.find(var)
+            return self.outer.find(var)
 
 def add_globals(env):
     "Add some Scheme standard procedures to an environment."
     elif not isa(w_x, W_list):         # constant literal
         return w_x
 
-    if isa(w_x, W_list):
-        l = w_x.lval
+    l = w_x.lval
+    if isa(l[0], W_symbol):
         if l[0].val == 'quote':          # (quote exp)
             (_, exp) = l
             return exp
         elif l[0].val == 'set!':           # (set! var exp)
             (_, var, exp) = l
             env.find(var.val).d[var.val] = eval(exp, env)
+            return exp
         elif l[0].val == 'define':         # (define var exp)
             (_, var, exp) = l
             env.d[var.val] = eval(exp, env)
+            return exp
         elif l[0].val == 'lambda':         # (lambda (var*) exp)
             (_, vars, exp) = l
-            w_f = W_function(exp, vars, env)
+            w_f = W_function(vars, exp, env)
             return w_f
         elif l[0].val == 'begin':          # (begin exp*)
             val = W_object()
             for exp in l[1:]:
                 val = eval(exp, env)
             return val
-        else:                          # (proc exp*)
-            exps = [eval(exp, env) for exp in l]
-            proc = exps.pop(0)
-            return proc.eval(exps)
+    # (proc exp*)
+    exps = [eval(exp, env) for exp in l]
+    proc = exps.pop(0)
+    return proc.eval(exps)
 
 ################ parse, read, and user interaction
 
     while True:
         os.write(2,prompt)
         r = readline()
-        if r == 'quit':
+        if r in ['\n', '']:
             return
         val = eval(parse(r), env)
         if val is not None: os.write(2, to_string(val) + '\n')
     while 1:
         s = os.read(0, 1)
         result.append(s)
-        if s == "\n":
+        if s in ['\n', '']:
             break
-        if s == '':
-            if len(result) > 1:
-                break
-            raise SystemExit
-    return "".join(result)
+
+    return ''.join(result)
 
 def main(args):
     global_env = add_globals(Env())
-    repl(env = global_env)
+    repl(env=global_env)
     return 0
 
 def target(*args):
 
 # test to_str
 
-# test eval
-
 # env
 
 # add_globals
 
-# eval
+# parse
+
+def pytest_funcarg__env(request):
+    env = lis.Env()
+    return lis.add_globals(env)
+
+@params(dict(s='(+ 1 1)', i=2),
+        dict(s='(+ (+ 1 1) 1)', i=3),
+        dict(s='(+ 1 (+ 1 1))', i=3),
+        dict(s='(begin (+ 9 9) (+ 1 1)))', i=2),
+        dict(s='((lambda (x) (+ x 1)) 1)', i=2),
+        )
+def test_(s, i, env):
+    w_x = lis.parse(s)
+    assert lis.eval(w_x, env).ival == i
+
 
 # test tokenizer
 @params(dict(s='()', tokens=['(', ')']),
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.