mirror of
https://github.com/peklaiho/madlisp.git
synced 2024-11-22 21:35:03 +00:00
remove bootstrap, add LispFactory
This commit is contained in:
parent
0ecc4a7b73
commit
d32ca9a4b6
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
require('vendor/autoload.php');
|
|
||||||
|
|
||||||
function ml_get_lisp(bool $debug): array
|
|
||||||
{
|
|
||||||
$tokenizer = new MadLisp\Tokenizer();
|
|
||||||
$reader = new MadLisp\Reader();
|
|
||||||
$printer = new MadLisp\Printer();
|
|
||||||
$eval = new MadLisp\Evaller($tokenizer, $reader, $printer);
|
|
||||||
$eval->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];
|
|
||||||
}
|
|
17
run.php
17
run.php
@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
require('bootstrap.php');
|
require(__DIR__ . '/vendor/autoload.php');
|
||||||
|
|
||||||
if (php_sapi_name() != 'cli') {
|
if (php_sapi_name() != 'cli') {
|
||||||
exit('Currently only cli usage is supported.');
|
exit('Currently only cli usage is supported.');
|
||||||
}
|
}
|
||||||
|
|
||||||
function ml_repl($lisp, $env)
|
function ml_repl($lisp)
|
||||||
{
|
{
|
||||||
// Read history
|
// Read history
|
||||||
$historyFile = $_SERVER['HOME'] . '/.madlisp_history';
|
$historyFile = $_SERVER['HOME'] . '/.madlisp_history';
|
||||||
@ -17,7 +17,7 @@ function ml_repl($lisp, $env)
|
|||||||
$input = readline('> ');
|
$input = readline('> ');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$lisp->rep($input, $env, true);
|
$lisp->rep($input, true);
|
||||||
|
|
||||||
if ($input) {
|
if ($input) {
|
||||||
readline_add_history($input);
|
readline_add_history($input);
|
||||||
@ -37,17 +37,16 @@ function ml_run()
|
|||||||
{
|
{
|
||||||
$args = getopt('de:f:r');
|
$args = getopt('de:f:r');
|
||||||
|
|
||||||
$debug = array_key_exists('d', $args);
|
$factory = new MadLisp\LispFactory();
|
||||||
|
$lisp = $factory->make();
|
||||||
list($lisp, $env) = ml_get_lisp($debug);
|
|
||||||
|
|
||||||
if (array_key_exists('e', $args)) {
|
if (array_key_exists('e', $args)) {
|
||||||
$lisp->rep($args['e'], $env, false);
|
$lisp->rep($args['e'], false);
|
||||||
} elseif (array_key_exists('f', $args)) {
|
} elseif (array_key_exists('f', $args)) {
|
||||||
$input = "(load \"{$args['f']}\")";
|
$input = "(load \"{$args['f']}\")";
|
||||||
$lisp->rep($input, $env, false);
|
$lisp->rep($input, false);
|
||||||
} elseif (array_key_exists('r', $args)) {
|
} elseif (array_key_exists('r', $args)) {
|
||||||
ml_repl($lisp, $env);
|
ml_repl($lisp);
|
||||||
} else {
|
} else {
|
||||||
print("Usage:" . PHP_EOL);
|
print("Usage:" . PHP_EOL);
|
||||||
print("-d :: Debug mode" . PHP_EOL);
|
print("-d :: Debug mode" . PHP_EOL);
|
||||||
|
38
src/Lisp.php
38
src/Lisp.php
@ -7,53 +7,25 @@ class Lisp
|
|||||||
protected Reader $reader;
|
protected Reader $reader;
|
||||||
protected Evaller $eval;
|
protected Evaller $eval;
|
||||||
protected Printer $printer;
|
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->tokenizer = $tokenizer;
|
||||||
$this->reader = $reader;
|
$this->reader = $reader;
|
||||||
$this->eval = $eval;
|
$this->eval = $eval;
|
||||||
$this->printer = $printer;
|
$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);
|
$tokens = $this->tokenizer->tokenize($input);
|
||||||
|
|
||||||
$expr = $this->reader->read($tokens);
|
$expr = $this->reader->read($tokens);
|
||||||
|
|
||||||
$result = $this->eval->eval($expr, $env);
|
$result = $this->eval->eval($expr, $this->env);
|
||||||
|
|
||||||
$this->printer->print($result, $printReadable);
|
$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);
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
63
src/LispFactory.php
Normal file
63
src/LispFactory.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
namespace MadLisp;
|
||||||
|
|
||||||
|
class LispFactory
|
||||||
|
{
|
||||||
|
public function make(array $libraries = []): Lisp
|
||||||
|
{
|
||||||
|
$tokenizer = new Tokenizer();
|
||||||
|
$reader = new Reader();
|
||||||
|
$printer = new Printer();
|
||||||
|
$eval = new Evaller($tokenizer, $reader, $printer);
|
||||||
|
|
||||||
|
// Root environment
|
||||||
|
$env = new Env('root');
|
||||||
|
|
||||||
|
// Register core functions
|
||||||
|
$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) => $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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user