tail call block and rename to progn

This commit is contained in:
IXtreme 2026-06-20 00:06:22 -04:00
parent 31b14705ba
commit cb43ce6a53

View file

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