2020-05-28 04:55:58 +00:00
|
|
|
<?php
|
|
|
|
namespace MadLisp;
|
|
|
|
|
|
|
|
class Lisp
|
|
|
|
{
|
2020-05-28 10:10:00 +00:00
|
|
|
protected Tokenizer $tokenizer;
|
|
|
|
protected Reader $reader;
|
|
|
|
protected Evaller $eval;
|
|
|
|
protected Printer $printer;
|
2020-05-28 09:49:32 +00:00
|
|
|
|
2020-05-28 10:10:00 +00:00
|
|
|
public function __construct(Tokenizer $tokenizer, Reader $reader, Evaller $eval, Printer $printer)
|
2020-05-28 04:55:58 +00:00
|
|
|
{
|
2020-05-28 10:10:00 +00:00
|
|
|
$this->tokenizer = $tokenizer;
|
|
|
|
$this->reader = $reader;
|
|
|
|
$this->eval = $eval;
|
|
|
|
$this->printer = $printer;
|
2020-05-28 07:40:54 +00:00
|
|
|
}
|
|
|
|
|
2020-06-06 02:39:12 +00:00
|
|
|
public function re(string $input, Env $env)
|
2020-05-28 07:40:54 +00:00
|
|
|
{
|
2020-05-28 10:10:00 +00:00
|
|
|
$tokens = $this->tokenizer->tokenize($input);
|
2020-05-28 07:40:54 +00:00
|
|
|
|
2020-06-04 02:10:48 +00:00
|
|
|
$expr = $this->reader->read($tokens);
|
2020-05-28 07:40:54 +00:00
|
|
|
|
2020-06-06 02:39:12 +00:00
|
|
|
return $this->eval->eval($expr, $env);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function rep(string $input, Env $env): void
|
|
|
|
{
|
|
|
|
$result = $this->re($input, $env);
|
2020-05-28 04:55:58 +00:00
|
|
|
|
2020-06-04 02:10:48 +00:00
|
|
|
$this->printer->print($result);
|
2020-05-28 04:55:58 +00:00
|
|
|
}
|
2020-05-31 14:16:20 +00:00
|
|
|
|
|
|
|
public function register(Env $env): void
|
|
|
|
{
|
2020-06-01 13:19:26 +00:00
|
|
|
$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');
|
|
|
|
}
|
|
|
|
));
|
|
|
|
|
2020-06-04 02:10:48 +00:00
|
|
|
$env->set('read', new CoreFunc('read', 'Read string as code.', 1, 1,
|
|
|
|
fn (string $a) => $this->reader->read($this->tokenizer->tokenize($a))
|
2020-05-31 14:16:20 +00:00
|
|
|
));
|
|
|
|
|
2020-06-04 02:10:48 +00:00
|
|
|
$env->set('eval', new CoreFunc('eval', 'Evaluate argument.', 1, 1,
|
|
|
|
fn ($a) => $this->eval->eval($a, $env)
|
|
|
|
));
|
2020-05-31 14:16:20 +00:00
|
|
|
|
2020-06-04 02:10:48 +00:00
|
|
|
$env->set('print', new CoreFunc('print', 'Print argument.', 1, 1,
|
|
|
|
function ($a) {
|
|
|
|
$this->printer->print($a);
|
2020-05-31 14:16:20 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
));
|
2020-06-06 02:39:12 +00:00
|
|
|
|
|
|
|
$env->set('error', new CoreFunc('error', 'Throw an exception using argument (string) as message.', 1, 1,
|
|
|
|
function (string $error) {
|
|
|
|
throw new MadLispException($error);
|
|
|
|
}
|
|
|
|
));
|
2020-05-31 14:16:20 +00:00
|
|
|
}
|
2020-05-28 04:55:58 +00:00
|
|
|
}
|