diff --git a/bootstrap.php b/bootstrap.php index 33cb8d4..0090745 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,16 +1,17 @@ setDebug($debug); $lisp = new MadLisp\Lisp($tokenizer, $reader, $eval, $printer); - // Environment + // Root environment $env = new MadLisp\Env('root'); // Register core functions @@ -25,5 +26,8 @@ function ml_get_lisp(): array (new MadLisp\Lib\Time())->register($env); (new MadLisp\Lib\Types())->register($env); + // User environment + $env = new MadLisp\Env('user', $env); + return [$lisp, $env]; } diff --git a/run.php b/run.php index 7d7655f..1b27934 100644 --- a/run.php +++ b/run.php @@ -1,32 +1,60 @@ '); - - try { - $lisp->rep($input, $userEnv); - - if ($input) { - readline_add_history($input); - readline_write_history($historyFile); - } - } catch (MadLisp\MadLispException $ex) { - print('error: ' . $ex->getMessage()); - } catch (TypeError $ex) { - print('error: invalid argument type: ' . $ex->getMessage()); +function ml_repl($lisp, $env) +{ + // Read history + $historyFile = $_SERVER['HOME'] . '/.madlisp_history'; + if (is_readable($historyFile)) { + readline_read_history($historyFile); } - print(PHP_EOL); + while (true) { + $input = readline('> '); + + try { + $lisp->rep($input, $env); + + if ($input) { + readline_add_history($input); + readline_write_history($historyFile); + } + } catch (MadLisp\MadLispException $ex) { + print('error: ' . $ex->getMessage()); + } catch (TypeError $ex) { + print('error: invalid argument type: ' . $ex->getMessage()); + } + + print(PHP_EOL); + } } + +function ml_run() +{ + $args = getopt('de:f:r'); + + $debug = array_key_exists('d', $args); + + list($lisp, $env) = ml_get_lisp($debug); + + if (array_key_exists('e', $args)) { + $lisp->rep($args['e'], $env); + } elseif (array_key_exists('f', $args)) { + $input = "(load \"{$args['f']}\")"; + $lisp->rep($input, $env); + } elseif (array_key_exists('r', $args)) { + ml_repl($lisp, $env); + } else { + print("Usage:" . PHP_EOL); + print("-d :: Debug mode" . PHP_EOL); + print("-e :: Evaluate code" . PHP_EOL); + print("-f :: Evaluate file" . PHP_EOL); + print("-r :: Run the interactive repl" . PHP_EOL); + } +} + +ml_run(); diff --git a/src/Evaller.php b/src/Evaller.php index 8bd130f..bc10bfe 100644 --- a/src/Evaller.php +++ b/src/Evaller.php @@ -7,7 +7,7 @@ class Evaller protected Reader $reader; protected Printer $printer; - private const DEBUG = true; + protected bool $debug = false; public function __construct(Tokenizer $tokenizer, Reader $reader, Printer $printer) { @@ -18,7 +18,7 @@ class Evaller public function eval($ast, Env $env) { - if (self::DEBUG) { + if ($this->debug) { print("eval: "); $this->printer->print($ast); print("\n"); @@ -27,7 +27,7 @@ class Evaller while (true) { - if (self::DEBUG) { + if ($this->debug) { if ($loops++ > 0) { print("eval loop: "); $this->printer->print($ast); @@ -257,6 +257,11 @@ class Evaller } } + public function setDebug(bool $val): void + { + $this->debug = $val; + } + private function evalAst($ast, Env $env) { if ($ast instanceof Symbol) {