Env: Add more core functions
This commit is contained in:
+113
-1
@@ -410,7 +410,6 @@ ADD_FUNCTION(
|
|||||||
return makePtr<String>(file.data());
|
return makePtr<String>(file.data());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
ADD_FUNCTION(
|
ADD_FUNCTION(
|
||||||
"eval",
|
"eval",
|
||||||
{
|
{
|
||||||
@@ -422,6 +421,119 @@ ADD_FUNCTION(
|
|||||||
return eval(nodes.front(), nullptr);
|
return eval(nodes.front(), nullptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// (atom 1)
|
||||||
|
ADD_FUNCTION(
|
||||||
|
"atom",
|
||||||
|
{
|
||||||
|
if (nodes.size() != 1) {
|
||||||
|
Error::the().add(format("wrong number of arguments: atom, {}", nodes.size()));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return makePtr<Atom>(nodes.front());
|
||||||
|
});
|
||||||
|
|
||||||
|
// (atom? myatom 2 "foo")
|
||||||
|
ADD_FUNCTION(
|
||||||
|
"atom?",
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
if (nodes.size() == 0) {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto node : nodes) {
|
||||||
|
if (!is<Atom>(node.get())) {
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return makePtr<Value>((result) ? Value::True : Value::False);
|
||||||
|
});
|
||||||
|
|
||||||
|
// (deref myatom)
|
||||||
|
ADD_FUNCTION(
|
||||||
|
"deref",
|
||||||
|
{
|
||||||
|
if (nodes.size() != 1) {
|
||||||
|
Error::the().add(format("wrong number of arguments: deref, {}", nodes.size()));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is<Atom>(nodes.front().get())) {
|
||||||
|
Error::the().add(format("wrong argument type: atom, '{}'", nodes.front()));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::static_pointer_cast<Atom>(nodes.front())->deref();
|
||||||
|
});
|
||||||
|
|
||||||
|
// (reset! myatom 2)
|
||||||
|
ADD_FUNCTION(
|
||||||
|
"reset!",
|
||||||
|
{
|
||||||
|
if (nodes.size() != 2) {
|
||||||
|
Error::the().add(format("wrong number of arguments: reset!, {}", nodes.size()));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is<Atom>(nodes.front().get())) {
|
||||||
|
Error::the().add(format("wrong argument type: atom, '{}'", nodes.front()));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto atom = std::static_pointer_cast<Atom>(*nodes.begin());
|
||||||
|
auto value = *std::next(nodes.begin());
|
||||||
|
|
||||||
|
atom->reset(value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// (swap! myatom (fn* [x] (+ 1 x)))
|
||||||
|
ADD_FUNCTION(
|
||||||
|
"swap!",
|
||||||
|
{
|
||||||
|
if (nodes.size() < 2) {
|
||||||
|
Error::the().add(format("wrong number of arguments: reset!, {}", nodes.size()));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto first_argument = *nodes.begin();
|
||||||
|
auto second_argument = *std::next(nodes.begin());
|
||||||
|
|
||||||
|
if (!is<Atom>(first_argument.get())) {
|
||||||
|
Error::the().add(format("wrong argument type: atom, '{}'", first_argument));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is<Callable>(second_argument.get())) {
|
||||||
|
Error::the().add(format("wrong argument type: function, '{}'", second_argument));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto atom = std::static_pointer_cast<Atom>(first_argument);
|
||||||
|
|
||||||
|
// Remove atom and function from the argument list, add atom value
|
||||||
|
nodes.pop_front();
|
||||||
|
nodes.pop_front();
|
||||||
|
nodes.push_front(atom->deref());
|
||||||
|
|
||||||
|
ASTNodePtr value = nullptr;
|
||||||
|
if (is<Function>(second_argument.get())) {
|
||||||
|
auto function = std::static_pointer_cast<Function>(second_argument)->function();
|
||||||
|
value = function(nodes);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto lambda = std::static_pointer_cast<Lambda>(second_argument);
|
||||||
|
value = eval(lambda->body(), Environment::create(lambda, nodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return atom->reset(value);
|
||||||
|
});
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
void installFunctions(EnvironmentPtr env)
|
void installFunctions(EnvironmentPtr env)
|
||||||
|
|||||||
Reference in New Issue
Block a user