mirror of
https://github.com/peklaiho/madlisp.git
synced 2024-11-26 15:14:12 +00:00
add support for userfuncs to meta
This commit is contained in:
parent
5bb2b458b3
commit
1ece3649bc
@ -159,7 +159,7 @@ class Evaller
|
|||||||
return $this->eval($astData[2], $newEnv);
|
return $this->eval($astData[2], $newEnv);
|
||||||
};
|
};
|
||||||
|
|
||||||
return new UserFunc($closure, $astData[2], $env, $bindings);
|
return new UserFunc($closure, $astData[2], $env, $astData[1]);
|
||||||
} elseif ($symbolName == 'if') {
|
} elseif ($symbolName == 'if') {
|
||||||
if ($astLength < 3 || $astLength > 4) {
|
if ($astLength < 3 || $astLength > 4) {
|
||||||
throw new MadLispException("if requires 2 or 3 arguments");
|
throw new MadLispException("if requires 2 or 3 arguments");
|
||||||
|
@ -47,6 +47,16 @@ class LispFactory
|
|||||||
} else {
|
} else {
|
||||||
throw new MadLispException('unknown attribute for meta');
|
throw new MadLispException('unknown attribute for meta');
|
||||||
}
|
}
|
||||||
|
} elseif ($obj instanceof UserFunc) {
|
||||||
|
if ($attribute == 'args') {
|
||||||
|
return $obj->getBindings();
|
||||||
|
} elseif ($attribute == 'body') {
|
||||||
|
return $obj->getAst();
|
||||||
|
} elseif ($attribute == 'code') {
|
||||||
|
return new MList([new Symbol('fn'), $obj->getBindings(), $obj->getAst()]);
|
||||||
|
} else {
|
||||||
|
throw new MadLispException('unknown attribute for meta');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new MadLispException('unknown entity for meta');
|
throw new MadLispException('unknown entity for meta');
|
||||||
}
|
}
|
||||||
@ -71,7 +81,7 @@ class LispFactory
|
|||||||
));
|
));
|
||||||
|
|
||||||
$env->set('exit', new CoreFunc('exit', 'Terminate the script with given exit code.', 0, 1,
|
$env->set('exit', new CoreFunc('exit', 'Terminate the script with given exit code.', 0, 1,
|
||||||
function ($status = 0) {
|
function (int $status = 0) {
|
||||||
exit($status);
|
exit($status);
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
@ -7,9 +7,9 @@ class UserFunc extends Func
|
|||||||
{
|
{
|
||||||
protected $ast;
|
protected $ast;
|
||||||
protected Env $tempEnv;
|
protected Env $tempEnv;
|
||||||
protected array $bindings;
|
protected Seq $bindings;
|
||||||
|
|
||||||
public function __construct(Closure $closure, $ast, Env $tempEnv, array $bindings)
|
public function __construct(Closure $closure, $ast, Env $tempEnv, Seq $bindings)
|
||||||
{
|
{
|
||||||
parent::__construct($closure, null);
|
parent::__construct($closure, null);
|
||||||
|
|
||||||
@ -23,12 +23,18 @@ class UserFunc extends Func
|
|||||||
return $this->ast;
|
return $this->ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getBindings(): Seq
|
||||||
|
{
|
||||||
|
return $this->bindings;
|
||||||
|
}
|
||||||
|
|
||||||
public function getEnv(array $args)
|
public function getEnv(array $args)
|
||||||
{
|
{
|
||||||
$newEnv = new Env('apply', $this->tempEnv);
|
$newEnv = new Env('apply', $this->tempEnv);
|
||||||
|
|
||||||
for ($i = 0; $i < count($this->bindings); $i++) {
|
$bindings = $this->bindings->getData();
|
||||||
$newEnv->set($this->bindings[$i]->getName(), $args[$i] ?? null);
|
for ($i = 0; $i < count($bindings); $i++) {
|
||||||
|
$newEnv->set($bindings[$i]->getName(), $args[$i] ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $newEnv;
|
return $newEnv;
|
||||||
|
Loading…
Reference in New Issue
Block a user