diff --git a/bootstrap.php b/bootstrap.php index a6a61f2..b0869df 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -25,5 +25,8 @@ function ml_get_lisp(): array (new MadLisp\Lib\Time())->register($env); (new MadLisp\Lib\Types())->register($env); + // Functions defined in lisp itself + $lisp->re('(def loadf (fn (f) (if (file? f) (eval (read (str "(do " (fread f) ")"))) (error (str "file " f " does not exist")))))', $env); + return [$lisp, $env]; } diff --git a/src/Evaller.php b/src/Evaller.php index 459f166..d40acb7 100644 --- a/src/Evaller.php +++ b/src/Evaller.php @@ -62,8 +62,8 @@ class Evaller $value = $this->eval($ast->get(2), $env); return $env->set($ast->get(1)->getName(), $value); } elseif ($ast->get(0)->getName() == 'do') { - if ($ast->count() < 2) { - throw new MadLispException("do requires at least 1 argument"); + if ($ast->count() == 1) { + return null; } for ($i = 1; $i < $ast->count() - 1; $i++) { diff --git a/src/Lisp.php b/src/Lisp.php index 0dd9063..bae56a4 100644 --- a/src/Lisp.php +++ b/src/Lisp.php @@ -16,13 +16,18 @@ class Lisp $this->printer = $printer; } - public function rep(string $input, Env $env): void + public function re(string $input, Env $env) { $tokens = $this->tokenizer->tokenize($input); $expr = $this->reader->read($tokens); - $result = $this->eval->eval($expr, $env); + return $this->eval->eval($expr, $env); + } + + public function rep(string $input, Env $env): void + { + $result = $this->re($input, $env); $this->printer->print($result); } @@ -53,5 +58,11 @@ class Lisp return null; } )); + + $env->set('error', new CoreFunc('error', 'Throw an exception using argument (string) as message.', 1, 1, + function (string $error) { + throw new MadLispException($error); + } + )); } }