mirror of
https://github.com/peklaiho/madlisp.git
synced 2024-11-26 15:14:12 +00:00
104 lines
3.4 KiB
PHP
104 lines
3.4 KiB
PHP
<?php
|
|
namespace MadLisp;
|
|
|
|
class LispFactory
|
|
{
|
|
public function make(array $coreLibs = [], array $userLibs = []): 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('loop', new CoreFunc('loop', 'Call the given function repeatedly in a loop until it returns false.', 1, -1,
|
|
function (Func $f, ...$args) {
|
|
do {
|
|
$result = $f->call($args);
|
|
} while ($result);
|
|
return $result;
|
|
}
|
|
));
|
|
|
|
$env->set('meta', new CoreFunc('meta', 'Read meta information of an entity.', 2, 2,
|
|
function ($obj, $attribute) {
|
|
if ($obj instanceof Env) {
|
|
if ($attribute == 'name') {
|
|
return $obj->getFullName();
|
|
} elseif ($attribute == 'parent') {
|
|
return $obj->getParent();
|
|
} else {
|
|
throw new MadLispException('unknown attribute for meta');
|
|
}
|
|
} else {
|
|
throw new MadLispException('unknown entity for meta');
|
|
}
|
|
}
|
|
));
|
|
|
|
$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);
|
|
}
|
|
));
|
|
|
|
$env->set('exit', new CoreFunc('exit', 'Terminate the script with given exit code.', 0, 1,
|
|
function ($status = 0) {
|
|
exit($status);
|
|
}
|
|
));
|
|
|
|
// Register core libraries
|
|
(new Lib\Collections())->register($env);
|
|
(new Lib\Compare())->register($env);
|
|
(new Lib\Database())->register($env);
|
|
(new Lib\Http())->register($env);
|
|
(new Lib\IO())->register($env);
|
|
(new Lib\Json())->register($env);
|
|
(new Lib\Math())->register($env);
|
|
(new Lib\Regex())->register($env);
|
|
(new Lib\Strings())->register($env);
|
|
(new Lib\Time())->register($env);
|
|
(new Lib\Types())->register($env);
|
|
|
|
// Register additional libs for root env
|
|
foreach ($coreLibs as $lib) {
|
|
$lib->register($env);
|
|
}
|
|
|
|
// User environment
|
|
$env = new Env('user', $env);
|
|
|
|
// Register additional libs for user env
|
|
foreach ($userLibs as $lib) {
|
|
$lib->register($env);
|
|
}
|
|
|
|
return new Lisp($tokenizer, $reader, $eval, $printer, $env);
|
|
}
|
|
}
|