diff --git a/src/main.cpp b/src/main.cpp index b27a5dc..c66e2ff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -65,6 +65,9 @@ struct Lambda : Data { enum class locs { EVAL_START, EVAL_OP_FIN, EVAL_TOP_ARG, APPLY }; +enum class special_indef_eval {NONE, PROGN}; + + struct Registers { std::variant Exp; size_t args_front; @@ -85,6 +88,8 @@ struct Registers { std::variant R; Env E; + + special_indef_eval screen = special_indef_eval::NONE; }; struct Machine { @@ -101,7 +106,7 @@ struct Machine { reg.E.builtin.insert("+"); reg.E.builtin.insert("-"); reg.E.builtin.insert("lambda"); - reg.E.builtin.insert("block"); + reg.E.builtin.insert("progn"); reg.E.builtin.insert("print"); } @@ -153,6 +158,7 @@ struct Machine { } case locs::EVAL_OP_FIN: { reg.op = reg.R; // save op + reg.screen = special_indef_eval::NONE; if (Symbol * c = dynamic_cast(std::get(reg.op))) { if(c->data == "lambda") { reg.args_left = 0; @@ -163,6 +169,9 @@ struct Machine { break; } + if(c->data == "progn") { + reg.screen = special_indef_eval::PROGN; + } } reg.args_left = mem[((Fork *)std::get(reg.Exp))->data].cdr; reg.args_current = 0; @@ -183,12 +192,22 @@ struct Machine { } mem[reg.args_current].d = std::get(reg.R); } - if (reg.args_left != 0) { + if (reg.args_left != 0) { //args left + auto onlyoneleft = mem[reg.args_left].cdr == 0; reg.argflag = true; - stack.push_back(reg); + + bool newframe = false; + if (reg.screen == special_indef_eval::NONE + || (reg.screen == special_indef_eval::PROGN && !onlyoneleft)) { + stack.push_back(reg); + newframe = true; + + } reg.D = mem[reg.args_left].d; reg.args_left = mem[reg.args_left].cdr; - stack.back().args_left = reg.args_left; + if (newframe) { + stack.back().args_left = reg.args_left; + } reg.RP = locs::EVAL_START; } else { reg.RP = locs::APPLY; // all args ready @@ -293,12 +312,15 @@ struct Machine { l->f = mem[mem[cdr].cdr]; // mem[f->data]; // std::cout <<"got lambd" << std::endl; return newCell(l); - } else if (fname == "block") { + } else if (fname == "progn") { Data * out = NULL; while (cdr != 0) { out = (mem[cdr].d); cdr = mem[cdr].cdr; } + if (out == NULL) { + throw "progn with one arg"; + } return newCell(out); } else if (fname == "print") { @@ -463,7 +485,7 @@ int main() { m.reg.E.builtin.insert("*"); m.reg.E.builtin.insert("-"); m.reg.E.builtin.insert("lambda"); - m.reg.E.builtin.insert("block"); + m.reg.E.builtin.insert("progn"); m.reg.E.builtin.insert("print"); //m.ListPrint(m.mem[exp]);