diff --git a/classes.php b/classes.php new file mode 100644 index 0000000..d99e032 --- /dev/null +++ b/classes.php @@ -0,0 +1,35 @@ +parent = $parent; + } + + public function has(string $key) + { + return array_key_exists($key, $this->data); + } + + public function get(string $key) + { + if ($this->has($key)) { + return $this->data[$key]; + } elseif ($this->parent) { + return $this->parent->get($key); + } + + throw new MadLispException("symbol $key not defined"); + } + + public function set(string $key, $value): void + { + $this->data[$key] = $value; + } +} diff --git a/lib.php b/lib.php new file mode 100644 index 0000000..3eda6dd --- /dev/null +++ b/lib.php @@ -0,0 +1,17 @@ +set('+', fn (...$args) => array_sum($args)); + $env->set('-', fn ($a, $b) => $a - $b); + $env->set('*', fn ($a, $b) => $a * $b); + $env->set('/', fn ($a, $b) => $a / $b); + $env->set('%', fn ($a, $b) => $a % $b); + + return $env; +} diff --git a/lisp.php b/lisp.php index 51433c6..bdcb558 100644 --- a/lisp.php +++ b/lisp.php @@ -1,13 +1,17 @@ ml_eval($a, $env), $expr); + + // If the first item is a function, call it + $fn = $expr[0] ?? null; + if ($fn && $fn instanceof Closure) { + $args = array_slice($expr, 1); + return $fn(...$args); + } + } elseif (ml_is_symbol($expr)) { + return $env->get(ml_strip_symbol($expr)); + } + + return $expr; } -function ml_print($a) +function ml_print($a): string { - // print(implode('*', $a)); - print_r($a); + if ($a instanceof Closure) { + return ''; + } elseif (is_array($a)) { + return '(' . implode(' ', array_map('ml_print', $a)) . ')'; + } elseif ($a === true) { + return 'true'; + } elseif ($a === false) { + return 'false'; + } elseif ($a === null) { + return 'null'; + } elseif (ml_is_symbol($a)) { + return ml_strip_symbol($a); + } elseif (is_string($a)) { + return '"' . $a . '"'; + } else { + return $a; + } } -function ml_rep($a) +function ml_rep(string $input, Env $env): string { - ml_print(ml_eval(ml_read($a))); + $expressions = ml_read($input); + + $results = array_map(fn ($expr) => ml_eval($expr, $env), $expressions); + + return implode(" ", array_map('ml_print', $results)); } diff --git a/repl.php b/repl.php index ec5860b..3d9cfd4 100644 --- a/repl.php +++ b/repl.php @@ -1,14 +1,15 @@ '); - print('% '); - try { - ml_rep($input); + print(ml_rep($input, $env)); } catch (MadLispException $ex) { print('error: ' . $ex->getMessage()); }