Eval: Add and/or special forms

This commit is contained in:
Riyyi
2023-10-31 22:30:24 +01:00
parent c6c6d69e73
commit b727f7147e
3 changed files with 64 additions and 0 deletions
+54
View File
@@ -171,6 +171,30 @@ ValuePtr Eval::evalTry(const ValueVector& nodes, EnvironmentPtr env)
// -----------------------------------------
// (and 1 2 3)
void Eval::evalAnd(const ValueVector& nodes, EnvironmentPtr env)
{
ValuePtr result;
for (auto node : nodes) {
m_ast = node;
m_env = env;
result = evalImpl();
if (is<Constant>(result.get())) {
VALUE_CAST(constant, Constant, result, void());
if (constant->state() == Constant::Nil || constant->state() == Constant::False) {
m_ast = makePtr<Constant>(Constant::Nil);
m_env = env;
return; // TCO
}
}
}
m_ast = result;
m_env = env;
return; // TCO
}
// (do 1 2 3)
void Eval::evalDo(const ValueVector& nodes, EnvironmentPtr env)
{
@@ -295,6 +319,36 @@ void Eval::evalMacroExpand1(const ValueVector& nodes, EnvironmentPtr env)
// -----------------------------------------
// (or 1 2 3)
void Eval::evalOr(const ValueVector& nodes, EnvironmentPtr env)
{
ValuePtr result;
for (auto node : nodes) {
m_ast = node;
m_env = env;
result = evalImpl();
if (!is<Constant>(result.get())) {
m_ast = result;
m_env = env;
return; // TCO
}
VALUE_CAST(constant, Constant, result, void());
if (constant->state() == Constant::True) {
m_ast = result;
m_env = env;
return; // TCO
}
}
m_ast = makePtr<Constant>(Constant::Nil);
m_env = env;
return; // TCO
}
// -----------------------------------------
static bool isSymbol(ValuePtr value, const std::string& symbol)
{
if (!is<Symbol>(value.get())) {
+8
View File
@@ -93,6 +93,10 @@ ValuePtr Eval::evalImpl()
return evalTry(nodes, env);
}
// Tail call optimized functions
if (symbol == "and") {
evalAnd(nodes, env);
continue; // TCO
}
if (symbol == "do") {
evalDo(nodes, env);
continue; // TCO
@@ -109,6 +113,10 @@ ValuePtr Eval::evalImpl()
evalMacroExpand1(nodes, env);
continue; // TCO
}
if (symbol == "or") {
evalOr(nodes, env);
continue; // TCO
}
if (symbol == "quasiquote") {
evalQuasiQuote(nodes, env);
continue; // TCO
+2
View File
@@ -38,10 +38,12 @@ private:
ValuePtr evalQuote(const ValueVector& nodes);
ValuePtr evalTry(const ValueVector& nodes, EnvironmentPtr env);
void evalAnd(const ValueVector& nodes, EnvironmentPtr env);
void evalDo(const ValueVector& nodes, EnvironmentPtr env);
void evalIf(const ValueVector& nodes, EnvironmentPtr env);
void evalLet(const ValueVector& nodes, EnvironmentPtr env);
void evalMacroExpand1(const ValueVector& nodes, EnvironmentPtr env);
void evalOr(const ValueVector& nodes, EnvironmentPtr env);
void evalQuasiQuote(const ValueVector& nodes, EnvironmentPtr env);
void evalWhile(const ValueVector& nodes, EnvironmentPtr env);