From b74f3448b2253997efbdbd5c1a169bc3ce1bb75f Mon Sep 17 00:00:00 2001 From: Riyyi Date: Sun, 5 Nov 2023 14:30:24 +0100 Subject: [PATCH] Eval: Allow multiple s-expr in fn* --- lisp/init.bl | 4 ++-- src/eval-special-form.cpp | 22 ++++++++++++++++------ src/eval.cpp | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lisp/init.bl b/lisp/init.bl index 993c140..3067c64 100644 --- a/lisp/init.bl +++ b/lisp/init.bl @@ -1,10 +1,10 @@ (defmacro! defmacro (fn* [name args & body] - `(defmacro! ~name (fn* ~args (do ~@body))))) + `(defmacro! ~name (fn* ~args ~@body)))) (defmacro defn [name args & body] - `(def! ~name (fn* ~args (do ~@body)))) + `(def! ~name (fn* ~args ~@body))) (defmacro def [name & body] `(def! ~name ~@body)) diff --git a/src/eval-special-form.cpp b/src/eval-special-form.cpp index 60ee18e..98a1728 100644 --- a/src/eval-special-form.cpp +++ b/src/eval-special-form.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: MIT */ -#include // std::next, std::prev +#include // std::distance, std::next, std::prev #include #include #include @@ -70,7 +70,7 @@ ValuePtr Eval::evalDefMacro(const ValueVector& nodes, EnvironmentPtr env) // (fn* (x) x) ValuePtr Eval::evalFn(const ValueVector& nodes, EnvironmentPtr env) { - CHECK_ARG_COUNT_IS("fn*", nodes.size(), 2); + CHECK_ARG_COUNT_AT_LEAST("fn*", nodes.size(), 2); // First element needs to be a List or Vector VALUE_CAST(collection, Collection, nodes.front()); @@ -84,8 +84,18 @@ ValuePtr Eval::evalFn(const ValueVector& nodes, EnvironmentPtr env) bindings.push_back(symbol->symbol()); } - // TODO: Remove limitation of 3 arguments - // Wrap all other nodes in list and add that as lambda body + // If more than one s-exp in lambda body, wrap in list + if (nodes.size() > 2) { + auto first = std::next(nodes.begin()); + auto last = std::prev(nodes.end()); + auto body_nodes = ValueVector(std::distance(first, last) + 2); + body_nodes.at(0) = makePtr("do"); + std::copy(first, nodes.end(), body_nodes.begin() + 1); + auto body = makePtr(body_nodes); + + return makePtr(bindings, body, env); + } + return makePtr(bindings, *std::next(nodes.begin()), env); } @@ -355,9 +365,9 @@ static bool isSymbol(ValuePtr value, const std::string& symbol) return false; } - auto valueSymbol = std::static_pointer_cast(value)->symbol(); + auto value_symbol = std::static_pointer_cast(value)->symbol(); - if (valueSymbol != symbol) { + if (value_symbol != symbol) { return false; } diff --git a/src/eval.cpp b/src/eval.cpp index de014a0..40f99aa 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: MIT */ -#include // sd::advance, std::next, std::prev +#include // std::advance, std::next, std::prev #include #include // std::static_pointer_cast #include // std::span