tail call block and rename to progn
This commit is contained in:
parent
31b14705ba
commit
cb43ce6a53
1 changed files with 28 additions and 6 deletions
34
src/main.cpp
34
src/main.cpp
|
|
@ -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;
|
||||||
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.D = mem[reg.args_left].d;
|
||||||
reg.args_left = mem[reg.args_left].cdr;
|
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;
|
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]);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue