Eval: Allow multiple s-expr in fn*
This commit is contained in:
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
(defmacro! defmacro
|
(defmacro! defmacro
|
||||||
(fn* [name args & body]
|
(fn* [name args & body]
|
||||||
`(defmacro! ~name (fn* ~args (do ~@body)))))
|
`(defmacro! ~name (fn* ~args ~@body))))
|
||||||
|
|
||||||
(defmacro defn [name args & body]
|
(defmacro defn [name args & body]
|
||||||
`(def! ~name (fn* ~args (do ~@body))))
|
`(def! ~name (fn* ~args ~@body)))
|
||||||
|
|
||||||
(defmacro def [name & body]
|
(defmacro def [name & body]
|
||||||
`(def! ~name ~@body))
|
`(def! ~name ~@body))
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iterator> // std::next, std::prev
|
#include <iterator> // std::distance, std::next, std::prev
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <span>
|
#include <span>
|
||||||
@@ -70,7 +70,7 @@ ValuePtr Eval::evalDefMacro(const ValueVector& nodes, EnvironmentPtr env)
|
|||||||
// (fn* (x) x)
|
// (fn* (x) x)
|
||||||
ValuePtr Eval::evalFn(const ValueVector& nodes, EnvironmentPtr env)
|
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
|
// First element needs to be a List or Vector
|
||||||
VALUE_CAST(collection, Collection, nodes.front());
|
VALUE_CAST(collection, Collection, nodes.front());
|
||||||
@@ -84,8 +84,18 @@ ValuePtr Eval::evalFn(const ValueVector& nodes, EnvironmentPtr env)
|
|||||||
bindings.push_back(symbol->symbol());
|
bindings.push_back(symbol->symbol());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove limitation of 3 arguments
|
// If more than one s-exp in lambda body, wrap in list
|
||||||
// Wrap all other nodes in list and add that as lambda body
|
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<Symbol>("do");
|
||||||
|
std::copy(first, nodes.end(), body_nodes.begin() + 1);
|
||||||
|
auto body = makePtr<List>(body_nodes);
|
||||||
|
|
||||||
|
return makePtr<Lambda>(bindings, body, env);
|
||||||
|
}
|
||||||
|
|
||||||
return makePtr<Lambda>(bindings, *std::next(nodes.begin()), env);
|
return makePtr<Lambda>(bindings, *std::next(nodes.begin()), env);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,9 +365,9 @@ static bool isSymbol(ValuePtr value, const std::string& symbol)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto valueSymbol = std::static_pointer_cast<Symbol>(value)->symbol();
|
auto value_symbol = std::static_pointer_cast<Symbol>(value)->symbol();
|
||||||
|
|
||||||
if (valueSymbol != symbol) {
|
if (value_symbol != symbol) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iterator> // sd::advance, std::next, std::prev
|
#include <iterator> // std::advance, std::next, std::prev
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory> // std::static_pointer_cast
|
#include <memory> // std::static_pointer_cast
|
||||||
#include <span> // std::span
|
#include <span> // std::span
|
||||||
|
|||||||
Reference in New Issue
Block a user