Merge pull request #494 from alimpfard/master
[jackhill/mal.git] / perl / step4_if_fn_do.pl
index a2b1565..be0611b 100644 (file)
@@ -44,38 +44,41 @@ sub EVAL {
     }
 
     # apply list
-    my ($a0, $a1, $a2, $a3) = @$ast;
-    if (!$a0) { return $ast; }
+    unless (@$ast) { return $ast; }
+    my ($a0) = @$ast;
     given ($a0->isa('Mal::Symbol') ? $$a0 : $a0) {
         when ('def!') {
-            my $res = EVAL($a2, $env);
-            return $env->set($a1, $res);
+           my (undef, $sym, $val) = @$ast;
+            return $env->set($sym, EVAL($val, $env));
         }
         when ('let*') {
+           my (undef, $bindings, $body) = @$ast;
             my $let_env = Mal::Env->new($env);
-           foreach my $pair (pairs @$a1) {
+           foreach my $pair (pairs @$bindings) {
                my ($k, $v) = @$pair;
                 $let_env->set($k, EVAL($v, $let_env));
             }
-            return EVAL($a2, $let_env);
+            return EVAL($body, $let_env);
         }
         when ('do') {
-            my $el = eval_ast($ast->rest(), $env);
-            return $el->[$#$el];
+           my (undef, @todo) = @$ast;
+            my $el = eval_ast(Mal::List->new(\@todo), $env);
+            return pop @$el;
         }
         when ('if') {
-            my $cond = EVAL($a1, $env);
+           my (undef, $if, $then, $else) = @$ast;
+            my $cond = EVAL($if, $env);
             if ($cond eq $nil || $cond eq $false) {
-                return $a3 ? EVAL($a3, $env) : $nil;
+                return $else ? EVAL($else, $env) : $nil;
             } else {
-                return EVAL($a2, $env);
+                return EVAL($then, $env);
             }
         }
         when ('fn*') {
+           my (undef, $params, $body) = @$ast;
             return Mal::Function->new(sub {
                 #print "running fn*\n";
-                my $args = \@_;
-                return EVAL($a2, Mal::Env->new($env, $a1, $args));
+                return EVAL($body, Mal::Env->new($env, $params, \@_));
             });
         }
         default {