work work
This commit is contained in:
parent
cf8315ef2b
commit
058405e5eb
1 changed files with 73 additions and 24 deletions
97
src/main.cpp
97
src/main.cpp
|
|
@ -101,6 +101,23 @@ struct Registers {
|
||||||
Env E;
|
Env E;
|
||||||
|
|
||||||
special_indef_eval screen = special_indef_eval::NONE;
|
special_indef_eval screen = special_indef_eval::NONE;
|
||||||
|
|
||||||
|
void ResetAllButEnv() {
|
||||||
|
Exp = 0;
|
||||||
|
args_front = 0;
|
||||||
|
args_current = 0;
|
||||||
|
args_left = 0;
|
||||||
|
A = 0;
|
||||||
|
B = 0;
|
||||||
|
C = 0;
|
||||||
|
D = 0;
|
||||||
|
|
||||||
|
argflag = false;
|
||||||
|
op = 0;
|
||||||
|
|
||||||
|
R = 0;
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Machine {
|
struct Machine {
|
||||||
|
|
@ -121,6 +138,8 @@ struct Machine {
|
||||||
|
|
||||||
Registers reg;
|
Registers reg;
|
||||||
|
|
||||||
|
bool invalidgc = false;
|
||||||
|
|
||||||
Machine(size_t max) : mem(max), mem_empty(max) {
|
Machine(size_t max) : mem(max), mem_empty(max) {
|
||||||
maxCells = max;
|
maxCells = max;
|
||||||
reg.E.builtin.insert("+");
|
reg.E.builtin.insert("+");
|
||||||
|
|
@ -134,27 +153,34 @@ struct Machine {
|
||||||
while (true) {
|
while (true) {
|
||||||
switch (reg.RP) {
|
switch (reg.RP) {
|
||||||
case locs::EVAL_START: { // Expects data* in D;
|
case locs::EVAL_START: { // Expects data* in D;
|
||||||
size_t loc = reg.D;
|
reg.C = reg.D;
|
||||||
|
|
||||||
Data * d = mem[loc].d;
|
Data * d = mem[reg.C].d;
|
||||||
|
|
||||||
//Data *d = std::get<Data *>(reg.D);
|
//Data *d = std::get<Data *>(reg.D);
|
||||||
if (SelfEval *h = dynamic_cast<SelfEval *>(d)) {
|
if (SelfEval *h = dynamic_cast<SelfEval *>(d)) {
|
||||||
if(stack.empty()) {
|
if(stack.empty()) {
|
||||||
reg.R = loc; //return addressof
|
reg.R = reg.C; //return addressof
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// safe to use loc because no allocs here
|
||||||
|
size_t loc = reg.C;
|
||||||
reg = stack.back();
|
reg = stack.back();
|
||||||
stack.pop_back();
|
stack.pop_back();
|
||||||
reg.R = loc; //return addressof
|
reg.R = loc; //return addressof
|
||||||
|
//
|
||||||
|
|
||||||
// return h;
|
// return h;
|
||||||
} else if (Symbol *h = dynamic_cast<Symbol *>(d)) {
|
} else if (Symbol *h = dynamic_cast<Symbol *>(d)) {
|
||||||
if (reg.E.builtin.contains(h->data)) {
|
if (reg.E.builtin.contains(h->data)) {
|
||||||
if(stack.empty()) {
|
if(stack.empty()) {
|
||||||
reg.R = loc; //return addressof
|
reg.R = reg.C; //return addressof
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// safe to use loc because no allocs here
|
||||||
|
size_t loc = reg.C;
|
||||||
reg = stack.back();
|
reg = stack.back();
|
||||||
stack.pop_back();
|
stack.pop_back();
|
||||||
reg.R = loc; //return addressof
|
reg.R = loc; //return addressof
|
||||||
|
|
@ -163,12 +189,13 @@ struct Machine {
|
||||||
reg.R = reg.E.userdef[h->data];
|
reg.R = reg.E.userdef[h->data];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = stack.back();
|
reg = stack.back();
|
||||||
stack.pop_back();
|
stack.pop_back();
|
||||||
reg.R = reg.E.userdef[h->data];
|
reg.R = reg.E.userdef[h->data];
|
||||||
}
|
}
|
||||||
} else if (Fork *h = dynamic_cast<Fork *>(d)) {
|
} else if (Fork *h = dynamic_cast<Fork *>(d)) {
|
||||||
reg.Exp = loc; //set exp to addressof
|
reg.Exp = reg.C; //set exp to addressof
|
||||||
reg.D = h->data; // pass car into eval
|
reg.D = h->data; // pass car into eval
|
||||||
reg.RP = locs::EVAL_OP_FIN;
|
reg.RP = locs::EVAL_OP_FIN;
|
||||||
reg.argflag = false;
|
reg.argflag = false;
|
||||||
|
|
@ -260,11 +287,12 @@ struct Machine {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case locs::APPLY: {
|
case locs::APPLY: {
|
||||||
size_t loc = reg.op;
|
reg.C = reg.op;
|
||||||
Data *d = mem[loc].d;
|
Data *d = mem[reg.C].d;
|
||||||
if (Symbol *fname = dynamic_cast<Symbol *>(d)) {
|
if (Symbol *fname = dynamic_cast<Symbol *>(d)) {
|
||||||
if (reg.E.builtin.contains(fname->data)) {
|
if (reg.E.builtin.contains(fname->data)) {
|
||||||
auto temp = ApplyBuiltin(fname->data, reg.args_front);
|
auto nloc = newCell();
|
||||||
|
auto temp = ApplyBuiltin(fname->data, reg.args_front, nloc);
|
||||||
if(stack.empty()) {
|
if(stack.empty()) {
|
||||||
reg.R = temp; //special case for term;
|
reg.R = temp; //special case for term;
|
||||||
return;
|
return;
|
||||||
|
|
@ -312,7 +340,7 @@ struct Machine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ApplyBuiltin(std::string fname, size_t cdr) {
|
size_t ApplyBuiltin(std::string fname, size_t cdr, size_t newlocation) {
|
||||||
if (fname == "+") {
|
if (fname == "+") {
|
||||||
int base = 0;
|
int base = 0;
|
||||||
while (cdr != 0) {
|
while (cdr != 0) {
|
||||||
|
|
@ -323,7 +351,8 @@ struct Machine {
|
||||||
}
|
}
|
||||||
Number *n = new Number;
|
Number *n = new Number;
|
||||||
n->data = base;
|
n->data = base;
|
||||||
return newCell(n);
|
mem[newlocation].d = n;
|
||||||
|
return newlocation;
|
||||||
|
|
||||||
} else if (fname == "*") {
|
} else if (fname == "*") {
|
||||||
int base = 1;
|
int base = 1;
|
||||||
|
|
@ -335,7 +364,8 @@ struct Machine {
|
||||||
}
|
}
|
||||||
Number *n = new Number;
|
Number *n = new Number;
|
||||||
n->data = base;
|
n->data = base;
|
||||||
return newCell(n);
|
mem[newlocation].d = n;
|
||||||
|
return newlocation;
|
||||||
} else if (fname == "-") {
|
} else if (fname == "-") {
|
||||||
Number *s = dynamic_cast<Number *>(mem[cdr].d);
|
Number *s = dynamic_cast<Number *>(mem[cdr].d);
|
||||||
if (!s) throw "Non Number applied to -";
|
if (!s) throw "Non Number applied to -";
|
||||||
|
|
@ -345,7 +375,8 @@ struct Machine {
|
||||||
if (cdr == 0) {
|
if (cdr == 0) {
|
||||||
Number *n = new Number;
|
Number *n = new Number;
|
||||||
n->data = -base;
|
n->data = -base;
|
||||||
return newCell(n);
|
mem[newlocation].d = n;
|
||||||
|
return newlocation;
|
||||||
} else {
|
} else {
|
||||||
while (cdr != 0) {
|
while (cdr != 0) {
|
||||||
Number *a = dynamic_cast<Number *>(mem[cdr].d);
|
Number *a = dynamic_cast<Number *>(mem[cdr].d);
|
||||||
|
|
@ -355,9 +386,11 @@ struct Machine {
|
||||||
}
|
}
|
||||||
Number *n = new Number;
|
Number *n = new Number;
|
||||||
n->data = base;
|
n->data = base;
|
||||||
return newCell(n);
|
mem[newlocation].d = n;
|
||||||
|
return newlocation;
|
||||||
}
|
}
|
||||||
} else if (fname == "lambda") {
|
} else if (fname == "lambda") {
|
||||||
|
//auto loc = newCell();
|
||||||
Fork *args = dynamic_cast<Fork *>(mem[cdr].d);
|
Fork *args = dynamic_cast<Fork *>(mem[cdr].d);
|
||||||
Fork *f = dynamic_cast<Fork *>(mem[mem[cdr].cdr].d);
|
Fork *f = dynamic_cast<Fork *>(mem[mem[cdr].cdr].d);
|
||||||
|
|
||||||
|
|
@ -365,8 +398,11 @@ struct Machine {
|
||||||
l->env = reg.E;
|
l->env = reg.E;
|
||||||
l->args = cdr; // mem[args->data];
|
l->args = cdr; // mem[args->data];
|
||||||
l->f = mem[cdr].cdr; // mem[f->data];
|
l->f = mem[cdr].cdr; // mem[f->data];
|
||||||
|
|
||||||
|
mem[newlocation].d = l;
|
||||||
|
|
||||||
// std::cout <<"got lambd" << std::endl;
|
// std::cout <<"got lambd" << std::endl;
|
||||||
return newCell(l);
|
return newlocation;
|
||||||
} else if (fname == "progn") {
|
} else if (fname == "progn") {
|
||||||
Data * out = NULL;
|
Data * out = NULL;
|
||||||
while (cdr != 0) {
|
while (cdr != 0) {
|
||||||
|
|
@ -376,7 +412,8 @@ struct Machine {
|
||||||
if (out == NULL) {
|
if (out == NULL) {
|
||||||
throw "progn with one arg";
|
throw "progn with one arg";
|
||||||
}
|
}
|
||||||
return newCell(out);
|
mem[newlocation].d = out;
|
||||||
|
return newlocation;
|
||||||
|
|
||||||
} else if (fname == "print") {
|
} else if (fname == "print") {
|
||||||
if (Number * n = dynamic_cast<Number*>(mem[cdr].d)) {
|
if (Number * n = dynamic_cast<Number*>(mem[cdr].d)) {
|
||||||
|
|
@ -400,10 +437,12 @@ struct Machine {
|
||||||
if (f->Get() < l->Get()) {
|
if (f->Get() < l->Get()) {
|
||||||
Number *n = new Number;
|
Number *n = new Number;
|
||||||
n->data = 1;
|
n->data = 1;
|
||||||
return newCell(n);
|
mem[newlocation].d = n;
|
||||||
|
return newlocation;
|
||||||
} else {
|
} else {
|
||||||
Nil * n = new Nil;
|
Nil * n = new Nil;
|
||||||
return newCell(n);
|
mem[newlocation].d = n;
|
||||||
|
return newlocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -413,8 +452,13 @@ struct Machine {
|
||||||
|
|
||||||
size_t newCell() {
|
size_t newCell() {
|
||||||
if (freepos >= maxCells) {
|
if (freepos >= maxCells) {
|
||||||
|
if (invalidgc) throw "GC called in invalid location, OOM";
|
||||||
|
invalidgc = true;
|
||||||
GC();
|
GC();
|
||||||
return newCell();
|
auto out = newCell();
|
||||||
|
invalidgc = false;
|
||||||
|
return out;
|
||||||
|
//return newCell();
|
||||||
//throw "OOM";
|
//throw "OOM";
|
||||||
}
|
}
|
||||||
auto nc = freepos;
|
auto nc = freepos;
|
||||||
|
|
@ -541,7 +585,7 @@ struct Machine {
|
||||||
mem[i].d = nullptr;
|
mem[i].d = nullptr;
|
||||||
mem[i].cdr = 0;
|
mem[i].cdr = 0;
|
||||||
}
|
}
|
||||||
|
std::cout << "GC DONE, OLDSIZE: " << freepos << " newsize: " << mempty_pos << std::endl;
|
||||||
mem.swap(mem_empty);
|
mem.swap(mem_empty);
|
||||||
freepos = mempty_pos;
|
freepos = mempty_pos;
|
||||||
mempty_pos = 1;
|
mempty_pos = 1;
|
||||||
|
|
@ -662,26 +706,31 @@ struct Machine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return front;
|
return front;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
auto m = Machine(20);
|
auto m = Machine(27);
|
||||||
|
|
||||||
|
|
||||||
Cell c;
|
Cell c;
|
||||||
// c.d = m.Eval(m.mem[exp].d);
|
// c.d = m.Eval(m.mem[exp].d);
|
||||||
Registers r;
|
Registers r;
|
||||||
|
|
||||||
|
m.reg=r;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
m.stack = std::vector<Registers>();
|
m.stack = std::vector<Registers>();
|
||||||
|
m.reg.ResetAllButEnv();
|
||||||
|
m.GC();
|
||||||
|
m.invalidgc = true;
|
||||||
auto exp = m.read_expr(std::cin);
|
auto exp = m.read_expr(std::cin);
|
||||||
r.D = exp;
|
m.invalidgc = false;
|
||||||
m.reg = r;
|
std::cout << "done reading" << std::endl;
|
||||||
|
//r.D = exp;
|
||||||
|
//m.reg = r;
|
||||||
|
m.reg.D = exp;
|
||||||
m.reg.RP = locs::EVAL_START;
|
m.reg.RP = locs::EVAL_START;
|
||||||
m.reg.E.builtin.insert("+");
|
m.reg.E.builtin.insert("+");
|
||||||
m.reg.E.builtin.insert("*");
|
m.reg.E.builtin.insert("*");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue