From 2c64b5b23119c024cc89f4ff9f3e9230397da2a7 Mon Sep 17 00:00:00 2001 From: IXtreme Date: Wed, 8 Jul 2026 23:54:55 -0400 Subject: [PATCH] if --- src/main.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c66e2ff..43b2dbe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,11 @@ struct Number : SelfEval { } }; +struct Nil : SelfEval { + void Get() {} +}; + + struct Fork : Data { size_t data; size_t Get() { @@ -65,7 +71,7 @@ struct Lambda : Data { enum class locs { EVAL_START, EVAL_OP_FIN, EVAL_TOP_ARG, APPLY }; -enum class special_indef_eval {NONE, PROGN}; +enum class special_indef_eval {NONE, PROGN, IF_BEGIN, FORCE_RETURN_NEXT_ARG}; struct Registers { @@ -171,6 +177,8 @@ struct Machine { } if(c->data == "progn") { reg.screen = special_indef_eval::PROGN; + } else if (c->data == "if") { + reg.screen = special_indef_eval::IF_BEGIN; } } reg.args_left = mem[((Fork *)std::get(reg.Exp))->data].cdr; @@ -191,6 +199,23 @@ struct Machine { reg.args_current = temp; } mem[reg.args_current].d = std::get(reg.R); + + // is in an 'if' statement but got first arg back + if (reg.screen == special_indef_eval::IF_BEGIN) { + Nil * v = dynamic_cast(mem[reg.args_current].d); + if(v != nullptr) { + // if conditional returned false + // skip first argument + + reg.args_left = mem[reg.args_left].cdr; + reg.screen = special_indef_eval::FORCE_RETURN_NEXT_ARG; + } else { + // if conditional returned true + reg.screen = special_indef_eval::FORCE_RETURN_NEXT_ARG; + + } + } + } if (reg.args_left != 0) { //args left auto onlyoneleft = mem[reg.args_left].cdr == 0; @@ -198,7 +223,8 @@ struct Machine { bool newframe = false; if (reg.screen == special_indef_eval::NONE - || (reg.screen == special_indef_eval::PROGN && !onlyoneleft)) { + || (reg.screen == special_indef_eval::PROGN && !onlyoneleft) + || (reg.screen == special_indef_eval::IF_BEGIN)) { stack.push_back(reg); newframe = true; @@ -253,6 +279,8 @@ struct Machine { throw "err"; } } + + } } } @@ -328,10 +356,30 @@ struct Machine { std::cout << n->data << std::endl; } else if (String * s = dynamic_cast(mem[cdr].d)) { std::cout << s->data << std::endl; + } else if(Nil * n = dynamic_cast(mem[cdr].d)) { + std::cout << "!nil!" << std::endl; } else { throw "invalid print"; } return cdr; + } else if (fname == "<") { + Number * f = dynamic_cast(mem[cdr].d); + if (!f) throw "Non Number applied to <"; + cdr = mem[cdr].cdr; + Number * l = dynamic_cast(mem[cdr].d); + if (!l) throw "Non Number applied to <"; + + + if (f->Get() < l->Get()) { + Number *n = new Number; + n->data = 1; + return newCell(n); + } else { + Nil * n = new Nil; + return newCell(n); + } + + } return 0; } @@ -466,7 +514,7 @@ struct Machine { }; int main() { - auto m = Machine(10000); + auto m = Machine(1000); Cell c; @@ -487,6 +535,8 @@ int main() { m.reg.E.builtin.insert("lambda"); m.reg.E.builtin.insert("progn"); m.reg.E.builtin.insert("print"); + m.reg.E.builtin.insert("<"); + m.reg.E.builtin.insert("if"); //m.ListPrint(m.mem[exp]); std::cout << std::endl;