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