Browse Source

Eval: Add and/or special forms

Riyyi 1 year ago
parent
commit
b727f7147e
  1. 54
      src/eval-special-form.cpp
  2. 8
      src/eval.cpp
  3. 2
      src/eval.h

54
src/eval-special-form.cpp

@ -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
src/eval.cpp

@ -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
src/eval.h

@ -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);

Loading…
Cancel
Save