support for (doc)

This commit is contained in:
Pekka Laiho 2020-06-01 20:19:26 +07:00
parent 9e113faf78
commit 9e4dffef2b
3 changed files with 20 additions and 4 deletions

View File

@ -6,17 +6,16 @@ use Closure;
class CoreFunc extends Func class CoreFunc extends Func
{ {
protected string $name; protected string $name;
protected string $doc;
protected int $minArgs; protected int $minArgs;
protected int $maxArgs; protected int $maxArgs;
public function __construct(string $name, string $doc, int $minArgs, int $maxArgs, Closure $closure) public function __construct(string $name, string $doc, int $minArgs, int $maxArgs, Closure $closure)
{ {
parent::__construct($closure, $doc);
$this->name = $name; $this->name = $name;
$this->doc = $doc;
$this->minArgs = $minArgs; $this->minArgs = $minArgs;
$this->maxArgs = $maxArgs; $this->maxArgs = $maxArgs;
$this->closure = $closure;
} }
public function call(array $args) public function call(array $args)

View File

@ -6,10 +6,12 @@ use Closure;
abstract class Func abstract class Func
{ {
protected Closure $closure; protected Closure $closure;
protected ?string $doc;
public function __construct(Closure $closure) public function __construct(Closure $closure, ?string $doc = null)
{ {
$this->closure = $closure; $this->closure = $closure;
$this->doc = $doc;
} }
public function getClosure(): Closure public function getClosure(): Closure
@ -17,6 +19,11 @@ abstract class Func
return $this->closure; return $this->closure;
} }
public function getDoc(): ?string
{
return $this->doc;
}
public function call(array $args) public function call(array $args)
{ {
return ($this->closure)(...$args); return ($this->closure)(...$args);

View File

@ -29,6 +29,16 @@ class Lisp
public function register(Env $env): void 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('eval', new CoreFunc('eval', 'Evaluate arguments.', 1, -1, $env->set('eval', new CoreFunc('eval', 'Evaluate arguments.', 1, -1,
function (...$args) use ($env) { function (...$args) use ($env) {
$results = $this->eval->eval($args, $env); $results = $this->eval->eval($args, $env);