From c3c5934c572a274bbc27f5a4d73846fd4a66ae07 Mon Sep 17 00:00:00 2001 From: Pekka Laiho Date: Sun, 31 May 2020 16:35:03 +0700 Subject: [PATCH] fn keyword --- src/Evaller.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/Evaller.php b/src/Evaller.php index f9ab0c4..dc0b119 100644 --- a/src/Evaller.php +++ b/src/Evaller.php @@ -68,6 +68,31 @@ class Evaller } return $value; + } elseif ($ast->get(0)->getName() == 'fn') { + if ($ast->count() != 3) { + throw new MadLispException("fn requires exactly 2 arguments"); + } + + if (!($ast->get(1) instanceof MList)) { + throw new MadLispException("first argument to fn is not list"); + } + + $bindings = $ast->get(1)->getData(); + foreach ($bindings as $bind) { + if (!($bind instanceof Symbol)) { + throw new MadLispException("binding key for fn is not symbol"); + } + } + + return function (...$args) use ($bindings, $ast, $env) { + $newEnv = new Env($env); + + for ($i = 0; $i < count($bindings); $i++) { + $newEnv->set($bindings[$i]->getName(), $args[$i] ?? null); + } + + return $this->doEval($ast->get(2), $newEnv); + }; } elseif ($ast->get(0)->getName() == 'if') { if ($ast->count() < 3 || $ast->count() > 4) { throw new MadLispException("if requires 2 or 3 arguments");