add support for vectors to quasiquote

This commit is contained in:
Pekka Laiho 2020-12-05 17:15:15 +07:00
parent 25ba08a6e7
commit dae6fe455f

View File

@ -358,36 +358,49 @@ class Evaller
} }
} }
$result = new MList(); return $this->quasiquoteLoop($data);
} elseif ($ast instanceof Vector) {
for ($i = count($data) - 1; $i >= 0; $i--) { return new MList([
$elt = $data[$i]; new Symbol('ltov'),
$this->quasiquoteLoop($ast->getData())
if ($elt instanceof MList && count($elt->getData()) > 0 && $elt->get(0) instanceof Symbol && $elt->get(0)->getName() == 'splice-unquote') { ]);
if (count($elt->getData()) == 2) { } elseif ($ast instanceof Symbol || $ast instanceof Hash) {
$result = new MList([
new Symbol('concat'),
$elt->get(1),
$result
]);
} else {
throw new MadLispException("splice-unquote requires exactly 1 argument");
}
} else {
$result = new MList([
new Symbol('pull'),
$this->quasiquote($elt),
$result
]);
}
}
return $result;
} elseif ($ast instanceof Symbol || $ast instanceof Collection) {
// Quote other forms which are affected by evaluation // Quote other forms which are affected by evaluation
return new MList([new Symbol('quote'), $ast]); return new MList([
new Symbol('quote'),
$ast
]);
} else { } else {
return $ast; return $ast;
} }
} }
private function quasiquoteLoop(array $data): MList
{
$result = new MList();
for ($i = count($data) - 1; $i >= 0; $i--) {
$elt = $data[$i];
if ($elt instanceof MList && count($elt->getData()) > 0 && $elt->get(0) instanceof Symbol && $elt->get(0)->getName() == 'splice-unquote') {
if (count($elt->getData()) == 2) {
$result = new MList([
new Symbol('concat'),
$elt->get(1),
$result
]);
} else {
throw new MadLispException("splice-unquote requires exactly 1 argument");
}
} else {
$result = new MList([
new Symbol('pull'),
$this->quasiquote($elt),
$result
]);
}
}
return $result;
}
} }