2 use lib IO
::Path
.new
($?FILE
).dirname
;
11 sub eval_ast
($ast, $env) {
13 when MalSymbol
{ $env{$ast.val
} || die X
::MalNotFound
.new
(name
=> $ast.val
) }
14 when MalList
{ MalList
([$ast.map({ eval($_, $env) })]) }
15 when MalVector
{ MalVector
([$ast.map({ eval($_, $env) })]) }
16 when MalHashMap
{ MalHashMap
($ast.kv
.map({ $^a
=> eval($^b
, $env) }).Hash
) }
17 default { $ast // $NIL }
21 sub eval ($ast, $env) {
22 return eval_ast
($ast, $env) if $ast !~~ MalList
;
23 return $ast if !$ast.elems
;
25 my ($func, @args) = eval_ast
($ast, $env).val
;
26 my $arglist = MalList
(@args);
27 return $func.apply
($arglist);
31 return pr_str
($exp, True
);
37 return print(eval(read($str), $repl_env));
41 $repl_env<+> = MalCode
({ MalNumber
($^a
[0].val
+ $^a
[1].val
) });
42 $repl_env<-> = MalCode
({ MalNumber
($^a
[0].val
- $^a
[1].val
) });
43 $repl_env<*> = MalCode
({ MalNumber
($^a
[0].val
* $^a
[1].val
) });
44 $repl_env</> = MalCode({ MalNumber(($^a[0].val / $^a
[1].val
).Int
) });
46 while (my $line = prompt
'user> ').defined {
49 when X
::MalException
{ .Str
.say }