Eval: Add and/or special forms
This commit is contained in:
@@ -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())) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user