Merge pull request #49 from keith-rollin/swift
[jackhill/mal.git] / php / step3_env.php
CommitLineData
31690700
JM
1<?php
2
3require_once 'readline.php';
4require_once 'types.php';
5require_once 'reader.php';
ea81a808
JM
6require_once 'printer.php';
7require_once 'env.php';
31690700
JM
8
9// read
10function READ($str) {
11 return read_str($str);
12}
13
14// eval
15function eval_ast($ast, $env) {
ea81a808 16 if (_symbol_Q($ast)) {
b8ee29b2 17 return $env->get($ast);
ea81a808
JM
18 } elseif (_sequential_Q($ast)) {
19 if (_list_Q($ast)) {
20 $el = _list();
31690700 21 } else {
ea81a808 22 $el = _vector();
31690700
JM
23 }
24 foreach ($ast as $a) { $el[] = MAL_EVAL($a, $env); }
25 return $el;
ea81a808
JM
26 } elseif (_hash_map_Q($ast)) {
27 $new_hm = _hash_map();
31690700
JM
28 foreach (array_keys($ast->getArrayCopy()) as $key) {
29 $new_hm[$key] = MAL_EVAL($ast[$key], $env);
30 }
31 return $new_hm;
32 } else {
33 return $ast;
34 }
35}
36
37function MAL_EVAL($ast, $env) {
ea81a808
JM
38 #echo "MAL_EVAL: " . _pr_str($ast) . "\n";
39 if (!_list_Q($ast)) {
31690700
JM
40 return eval_ast($ast, $env);
41 }
42
43 // apply list
44 $a0 = $ast[0];
ea81a808 45 $a0v = (_symbol_Q($a0) ? $a0->value : $a0);
31690700
JM
46 switch ($a0v) {
47 case "def!":
48 $res = MAL_EVAL($ast[2], $env);
b8ee29b2 49 return $env->set($ast[1], $res);
31690700
JM
50 case "let*":
51 $a1 = $ast[1];
52 $let_env = new Env($env);
53 for ($i=0; $i < count($a1); $i+=2) {
b8ee29b2 54 $let_env->set($a1[$i], MAL_EVAL($a1[$i+1], $let_env));
31690700
JM
55 }
56 return MAL_EVAL($ast[2], $let_env);
57 default:
58 $el = eval_ast($ast, $env);
59 $f = $el[0];
60 return call_user_func_array($f, array_slice($el->getArrayCopy(), 1));
61 }
62}
63
64// print
65function MAL_PRINT($exp) {
10b07148 66 return _pr_str($exp, True);
31690700
JM
67}
68
69// repl
70$repl_env = new Env(NULL);
71function rep($str) {
72 global $repl_env;
73 return MAL_PRINT(MAL_EVAL(READ($str), $repl_env));
74}
31690700 75
b8ee29b2
JM
76$repl_env->set(_symbol('+'), function ($a, $b) { return intval($a + $b,10); });
77$repl_env->set(_symbol('-'), function ($a, $b) { return intval($a - $b,10); });
78$repl_env->set(_symbol('*'), function ($a, $b) { return intval($a * $b,10); });
79$repl_env->set(_symbol('/'), function ($a, $b) { return intval($a / $b,10); });
31690700 80
86b689f3 81// repl loop
31690700
JM
82do {
83 try {
84 $line = mal_readline("user> ");
85 if ($line === NULL) { break; }
86 if ($line !== "") {
10b07148 87 print(rep($line) . "\n");
31690700
JM
88 }
89 } catch (BlankException $e) {
90 continue;
91 } catch (Exception $e) {
92 echo "Error: " . $e->getMessage() . "\n";
93 echo $e->getTraceAsString() . "\n";
94 }
95} while (true);
96
86b689f3 97?>