diff --git a/bootstrap.php b/bootstrap.php deleted file mode 100644 index 0090745..0000000 --- a/bootstrap.php +++ /dev/null @@ -1,33 +0,0 @@ -setDebug($debug); - - $lisp = new MadLisp\Lisp($tokenizer, $reader, $eval, $printer); - - // Root environment - $env = new MadLisp\Env('root'); - - // Register core functions - $lisp->register($env); - - // Register libraries - (new MadLisp\Lib\Collections())->register($env); - (new MadLisp\Lib\Compare())->register($env); - (new MadLisp\Lib\IO())->register($env); - (new MadLisp\Lib\Math())->register($env); - (new MadLisp\Lib\Strings())->register($env); - (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 e2c8fe8..5639bdd 100644 --- a/run.php +++ b/run.php @@ -1,11 +1,11 @@ '); try { - $lisp->rep($input, $env, true); + $lisp->rep($input, true); if ($input) { readline_add_history($input); @@ -37,17 +37,16 @@ function ml_run() { $args = getopt('de:f:r'); - $debug = array_key_exists('d', $args); - - list($lisp, $env) = ml_get_lisp($debug); + $factory = new MadLisp\LispFactory(); + $lisp = $factory->make(); if (array_key_exists('e', $args)) { - $lisp->rep($args['e'], $env, false); + $lisp->rep($args['e'], false); } elseif (array_key_exists('f', $args)) { $input = "(load \"{$args['f']}\")"; - $lisp->rep($input, $env, false); + $lisp->rep($input, false); } elseif (array_key_exists('r', $args)) { - ml_repl($lisp, $env); + ml_repl($lisp); } else { print("Usage:" . PHP_EOL); print("-d :: Debug mode" . PHP_EOL); diff --git a/src/Lisp.php b/src/Lisp.php index 6ede8ed..2e3d559 100644 --- a/src/Lisp.php +++ b/src/Lisp.php @@ -7,53 +7,25 @@ class Lisp protected Reader $reader; protected Evaller $eval; protected Printer $printer; + protected Env $env; - public function __construct(Tokenizer $tokenizer, Reader $reader, Evaller $eval, Printer $printer) + public function __construct(Tokenizer $tokenizer, Reader $reader, Evaller $eval, Printer $printer, Env $env) { $this->tokenizer = $tokenizer; $this->reader = $reader; $this->eval = $eval; $this->printer = $printer; + $this->env = $env; } - public function rep(string $input, Env $env, bool $printReadable): void + public function rep(string $input, bool $printReadable): void { $tokens = $this->tokenizer->tokenize($input); $expr = $this->reader->read($tokens); - $result = $this->eval->eval($expr, $env); + $result = $this->eval->eval($expr, $this->env); $this->printer->print($result, $printReadable); } - - public function register(Env $env): void - { - $env->set('doc', new CoreFunc('doc', 'Get documentation for a function.', 1, 1, - function ($a) { - if ($a instanceof Func) { - return $a->getDoc(); - } - - throw new MadLispException('first argument to doc is not function'); - } - )); - - $env->set('read', new CoreFunc('read', 'Read string as code.', 1, 1, - fn (string $a) => $this->reader->read($this->tokenizer->tokenize($a)) - )); - - $env->set('print', new CoreFunc('print', 'Print argument. Give second argument as true to show strings in readable format.', 1, 2, - function ($a, bool $readable = false) { - $this->printer->print($a, $readable); - 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); - } - )); - } } diff --git a/src/LispFactory.php b/src/LispFactory.php new file mode 100644 index 0000000..ad0a2fd --- /dev/null +++ b/src/LispFactory.php @@ -0,0 +1,63 @@ +set('doc', new CoreFunc('doc', 'Get documentation for a function.', 1, 1, + function ($a) { + if ($a instanceof Func) { + return $a->getDoc(); + } + + throw new MadLispException('first argument to doc is not function'); + } + )); + + $env->set('read', new CoreFunc('read', 'Read string as code.', 1, 1, + fn (string $a) => $reader->read($tokenizer->tokenize($a)) + )); + + $env->set('print', new CoreFunc('print', 'Print argument. Give second argument as true to show strings in readable format.', 1, 2, + function ($a, bool $readable = false) use ($printer) { + $printer->print($a, $readable); + 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); + } + )); + + // Register core libraries + (new Lib\Collections())->register($env); + (new Lib\Compare())->register($env); + (new Lib\IO())->register($env); + (new Lib\Math())->register($env); + (new Lib\Strings())->register($env); + (new Lib\Time())->register($env); + (new Lib\Types())->register($env); + + // Register additional libraries + foreach ($libraries as $lib) { + $lib->register($env); + } + + // User environment + $env = new Env('user', $env); + + return new Lisp($tokenizer, $reader, $eval, $printer, $env); + } +}