}
# 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 {