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)
|
// (do 1 2 3)
|
||||||
void Eval::evalDo(const ValueVector& nodes, EnvironmentPtr env)
|
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)
|
static bool isSymbol(ValuePtr value, const std::string& symbol)
|
||||||
{
|
{
|
||||||
if (!is<Symbol>(value.get())) {
|
if (!is<Symbol>(value.get())) {
|
||||||
|
|||||||
@@ -93,6 +93,10 @@ ValuePtr Eval::evalImpl()
|
|||||||
return evalTry(nodes, env);
|
return evalTry(nodes, env);
|
||||||
}
|
}
|
||||||
// Tail call optimized functions
|
// Tail call optimized functions
|
||||||
|
if (symbol == "and") {
|
||||||
|
evalAnd(nodes, env);
|
||||||
|
continue; // TCO
|
||||||
|
}
|
||||||
if (symbol == "do") {
|
if (symbol == "do") {
|
||||||
evalDo(nodes, env);
|
evalDo(nodes, env);
|
||||||
continue; // TCO
|
continue; // TCO
|
||||||
@@ -109,6 +113,10 @@ ValuePtr Eval::evalImpl()
|
|||||||
evalMacroExpand1(nodes, env);
|
evalMacroExpand1(nodes, env);
|
||||||
continue; // TCO
|
continue; // TCO
|
||||||
}
|
}
|
||||||
|
if (symbol == "or") {
|
||||||
|
evalOr(nodes, env);
|
||||||
|
continue; // TCO
|
||||||
|
}
|
||||||
if (symbol == "quasiquote") {
|
if (symbol == "quasiquote") {
|
||||||
evalQuasiQuote(nodes, env);
|
evalQuasiQuote(nodes, env);
|
||||||
continue; // TCO
|
continue; // TCO
|
||||||
|
|||||||
@@ -38,10 +38,12 @@ private:
|
|||||||
ValuePtr evalQuote(const ValueVector& nodes);
|
ValuePtr evalQuote(const ValueVector& nodes);
|
||||||
ValuePtr evalTry(const ValueVector& nodes, EnvironmentPtr env);
|
ValuePtr evalTry(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
|
|
||||||
|
void evalAnd(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
void evalDo(const ValueVector& nodes, EnvironmentPtr env);
|
void evalDo(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
void evalIf(const ValueVector& nodes, EnvironmentPtr env);
|
void evalIf(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
void evalLet(const ValueVector& nodes, EnvironmentPtr env);
|
void evalLet(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
void evalMacroExpand1(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 evalQuasiQuote(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
void evalWhile(const ValueVector& nodes, EnvironmentPtr env);
|
void evalWhile(const ValueVector& nodes, EnvironmentPtr env);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user