end of work from old arch
This commit is contained in:
parent
9db341eac5
commit
31b14705ba
1 changed files with 220 additions and 101 deletions
321
src/main.cpp
321
src/main.cpp
|
|
@ -29,7 +29,7 @@ struct Env {
|
||||||
std::unordered_map<std::string, size_t> userdef;
|
std::unordered_map<std::string, size_t> userdef;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Symbol : Data{
|
struct Symbol : Data {
|
||||||
std::string data;
|
std::string data;
|
||||||
std::string Get() {
|
std::string Get() {
|
||||||
return data;
|
return data;
|
||||||
|
|
@ -63,10 +63,27 @@ struct Lambda : Data {
|
||||||
Cell f;
|
Cell f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class locs { EVAL_START, EVAL_OP_FIN, EVAL_TOP_ARG, APPLY };
|
||||||
|
|
||||||
struct Registers {
|
struct Registers {
|
||||||
|
std::variant<size_t, Data *, Cell> Exp;
|
||||||
|
size_t args_front;
|
||||||
|
size_t args_current;
|
||||||
|
size_t args_left;
|
||||||
|
|
||||||
|
// general registers
|
||||||
std::variant<size_t, Data *, Cell> A;
|
std::variant<size_t, Data *, Cell> A;
|
||||||
std::variant<size_t, Data *, Cell> B;
|
std::variant<size_t, Data *, Cell> B;
|
||||||
std::variant<size_t, Data *, Cell> C;
|
std::variant<size_t, Data *, Cell> C;
|
||||||
|
std::variant<size_t, Data *, Cell> D;
|
||||||
|
|
||||||
|
bool argflag = false;
|
||||||
|
|
||||||
|
std::variant<size_t, Data *, Cell> op;
|
||||||
|
|
||||||
|
locs RP;
|
||||||
|
|
||||||
|
std::variant<size_t, Data *, Cell> R;
|
||||||
Env E;
|
Env E;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -84,46 +101,149 @@ 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("set");
|
reg.E.builtin.insert("block");
|
||||||
|
reg.E.builtin.insert("print");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Apply(Data * d, size_t cdr) {
|
void EvalLoop() {
|
||||||
if (Symbol * fname = dynamic_cast<Symbol*>(d)) {
|
while (true) {
|
||||||
if (reg.E.builtin.contains(fname->data)) {
|
switch (reg.RP) {
|
||||||
return ApplyBuiltin(fname->data, cdr);
|
case locs::EVAL_START: { // Expects data* in D;
|
||||||
} else { //defined symbol.
|
Data *d = std::get<Data *>(reg.D);
|
||||||
return 0; //TODO
|
if (SelfEval *h = dynamic_cast<SelfEval *>(d)) {
|
||||||
}
|
if(stack.empty()) {
|
||||||
|
reg.R = h;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reg = stack.back();
|
||||||
|
stack.pop_back();
|
||||||
|
reg.R = h;
|
||||||
|
|
||||||
} else if (Lambda * f = dynamic_cast<Lambda*>(d)) {
|
// return h;
|
||||||
reg.A = f->args;
|
} else if (Symbol *h = dynamic_cast<Symbol *>(d)) {
|
||||||
reg.A = ((Fork *) (std::get<Cell>(reg.A)).d)->data;
|
if (reg.E.builtin.contains(h->data)) {
|
||||||
|
if(stack.empty()) {
|
||||||
|
reg.R = h;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reg = stack.back();
|
||||||
|
stack.pop_back();
|
||||||
|
reg.R = h;
|
||||||
|
} else {
|
||||||
|
if(stack.empty()) {
|
||||||
|
reg.R = mem[reg.E.userdef[h->data]].d;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reg = stack.back();
|
||||||
|
stack.pop_back();
|
||||||
|
reg.R = mem[reg.E.userdef[h->data]].d;
|
||||||
|
}
|
||||||
|
} else if (Fork *h = dynamic_cast<Fork *>(d)) {
|
||||||
|
reg.Exp = h;
|
||||||
|
reg.D = mem[h->data].d; // pass car into eval
|
||||||
|
reg.RP = locs::EVAL_OP_FIN;
|
||||||
|
reg.argflag = false;
|
||||||
|
stack.push_back(reg);
|
||||||
|
reg.RP = locs::EVAL_START; // start eval of car;
|
||||||
|
} else {
|
||||||
|
throw("err no eval type");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case locs::EVAL_OP_FIN: {
|
||||||
|
reg.op = reg.R; // save op
|
||||||
|
if (Symbol * c = dynamic_cast<Symbol*>(std::get<Data*>(reg.op))) {
|
||||||
|
if(c->data == "lambda") {
|
||||||
|
reg.args_left = 0;
|
||||||
|
reg.args_current = 0;
|
||||||
|
reg.args_front = mem[((Fork *)std::get<Data *>(reg.Exp))->data].cdr;
|
||||||
|
reg.RP = locs::EVAL_TOP_ARG;
|
||||||
|
reg.argflag=false;
|
||||||
|
break;
|
||||||
|
|
||||||
reg.B = cdr;
|
}
|
||||||
auto tmp = reg.E;
|
}
|
||||||
//reg.E = f->env;
|
reg.args_left = mem[((Fork *)std::get<Data *>(reg.Exp))->data].cdr;
|
||||||
reg.E.userdef.merge(f->env.userdef);
|
reg.args_current = 0;
|
||||||
while (std::get<size_t>(reg.A) != 0) {
|
reg.args_front = 0;
|
||||||
reg.E.userdef[ ((Symbol *) mem[std::get<size_t>(reg.A)].d )->data] = std::get<size_t>(reg.B);
|
reg.RP = locs::EVAL_TOP_ARG;
|
||||||
reg.A = mem[std::get<size_t>(reg.A)].cdr;
|
reg.argflag = false;
|
||||||
reg.B = mem[std::get<size_t>(reg.B)].cdr;
|
break;
|
||||||
}
|
}
|
||||||
|
case locs::EVAL_TOP_ARG: {
|
||||||
|
if (reg.argflag) {
|
||||||
|
if (reg.args_front == 0) {
|
||||||
|
reg.args_front = newCell();
|
||||||
|
reg.args_current = reg.args_front;
|
||||||
|
} else {
|
||||||
|
auto temp = newCell();
|
||||||
|
mem[reg.args_current].cdr = temp;
|
||||||
|
reg.args_current = temp;
|
||||||
|
}
|
||||||
|
mem[reg.args_current].d = std::get<Data*>(reg.R);
|
||||||
|
}
|
||||||
|
if (reg.args_left != 0) {
|
||||||
|
reg.argflag = true;
|
||||||
|
stack.push_back(reg);
|
||||||
|
reg.D = mem[reg.args_left].d;
|
||||||
|
reg.args_left = mem[reg.args_left].cdr;
|
||||||
|
stack.back().args_left = reg.args_left;
|
||||||
|
reg.RP = locs::EVAL_START;
|
||||||
|
} else {
|
||||||
|
reg.RP = locs::APPLY; // all args ready
|
||||||
|
}
|
||||||
|
|
||||||
auto ret = Eval(f->f.d);
|
break;
|
||||||
reg.E = tmp;
|
}
|
||||||
return newCell(ret);
|
case locs::APPLY: {
|
||||||
|
Data *d = std::get<Data *>(reg.op);
|
||||||
} else {
|
if (Symbol *fname = dynamic_cast<Symbol *>(d)) {
|
||||||
return 0;
|
if (reg.E.builtin.contains(fname->data)) {
|
||||||
}
|
auto temp = ApplyBuiltin(fname->data, reg.args_front);
|
||||||
}
|
if(stack.empty()) {
|
||||||
|
reg.R = mem[temp].d; //special case for term;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reg = stack.back();
|
||||||
|
stack.pop_back();
|
||||||
|
reg.R = mem[temp].d;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
throw "err2";
|
||||||
|
}
|
||||||
|
} else if (Lambda *f = dynamic_cast<Lambda *>(d)) {
|
||||||
|
reg.A = f->args;
|
||||||
|
reg.A = ((Fork *)(std::get<Cell>(reg.A)).d)->data;
|
||||||
|
|
||||||
|
reg.B = reg.args_front;
|
||||||
|
// reg.E = f->env;
|
||||||
|
reg.E.userdef = f->env.userdef;
|
||||||
|
while (std::get<size_t>(reg.A) != 0) {
|
||||||
|
reg.E.userdef[((Symbol *)mem[std::get<size_t>(reg.A)].d)->data] =
|
||||||
|
std::get<size_t>(reg.B);
|
||||||
|
reg.A = mem[std::get<size_t>(reg.A)].cdr;
|
||||||
|
reg.B = mem[std::get<size_t>(reg.B)].cdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg.D = f->f.d;
|
||||||
|
//reg.E.userdef.merge(f->env.userdef);
|
||||||
|
reg.RP = locs::EVAL_START;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
throw "err";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t ApplyBuiltin(std::string fname, size_t cdr) {
|
size_t ApplyBuiltin(std::string fname, size_t cdr) {
|
||||||
if (fname == "+") {
|
if (fname == "+") {
|
||||||
int base = 0;
|
int base = 0;
|
||||||
while (cdr != 0) {
|
while (cdr != 0) {
|
||||||
Number *a = dynamic_cast<Number *>(mem[cdr].d);
|
Number *a = dynamic_cast<Number *>(mem[cdr].d);
|
||||||
|
if (!a) throw "Non Number applied to +";
|
||||||
base += a->data;
|
base += a->data;
|
||||||
cdr = mem[cdr].cdr;
|
cdr = mem[cdr].cdr;
|
||||||
}
|
}
|
||||||
|
|
@ -131,8 +251,20 @@ struct Machine {
|
||||||
n->data = base;
|
n->data = base;
|
||||||
return newCell(n);
|
return newCell(n);
|
||||||
|
|
||||||
|
} else if (fname == "*") {
|
||||||
|
int base = 1;
|
||||||
|
while (cdr != 0) {
|
||||||
|
Number *a = dynamic_cast<Number *>(mem[cdr].d);
|
||||||
|
if (!a) throw "Non Number applied to +";
|
||||||
|
base *= a->data;
|
||||||
|
cdr = mem[cdr].cdr;
|
||||||
|
}
|
||||||
|
Number *n = new Number;
|
||||||
|
n->data = base;
|
||||||
|
return newCell(n);
|
||||||
} 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 -";
|
||||||
int base = s->data;
|
int base = s->data;
|
||||||
|
|
||||||
cdr = mem[cdr].cdr;
|
cdr = mem[cdr].cdr;
|
||||||
|
|
@ -143,6 +275,7 @@ struct Machine {
|
||||||
} else {
|
} else {
|
||||||
while (cdr != 0) {
|
while (cdr != 0) {
|
||||||
Number *a = dynamic_cast<Number *>(mem[cdr].d);
|
Number *a = dynamic_cast<Number *>(mem[cdr].d);
|
||||||
|
if (!a) throw "Non Number applied to -";
|
||||||
base -= a->data;
|
base -= a->data;
|
||||||
cdr = mem[cdr].cdr;
|
cdr = mem[cdr].cdr;
|
||||||
}
|
}
|
||||||
|
|
@ -151,23 +284,39 @@ struct Machine {
|
||||||
return newCell(n);
|
return newCell(n);
|
||||||
}
|
}
|
||||||
} else if (fname == "lambda") {
|
} else if (fname == "lambda") {
|
||||||
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);
|
||||||
|
|
||||||
Lambda * l = new Lambda;
|
Lambda *l = new Lambda;
|
||||||
l->env = reg.E;
|
l->env = reg.E;
|
||||||
l->args = mem[cdr]; //mem[args->data];
|
l->args = mem[cdr]; // mem[args->data];
|
||||||
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") {
|
||||||
}
|
Data * out = NULL;
|
||||||
|
while (cdr != 0) {
|
||||||
|
out = (mem[cdr].d);
|
||||||
|
cdr = mem[cdr].cdr;
|
||||||
|
}
|
||||||
|
return newCell(out);
|
||||||
|
|
||||||
|
} else if (fname == "print") {
|
||||||
|
if (Number * n = dynamic_cast<Number*>(mem[cdr].d)) {
|
||||||
|
std::cout << n->data << std::endl;
|
||||||
|
} else if (String * s = dynamic_cast<String*>(mem[cdr].d)) {
|
||||||
|
std::cout << s->data << std::endl;
|
||||||
|
} else {
|
||||||
|
throw "invalid print";
|
||||||
|
}
|
||||||
|
return cdr;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t newCell() {
|
size_t newCell() {
|
||||||
if (freepos >= maxCells) {
|
if (freepos >= maxCells) {
|
||||||
exit(1);
|
throw "OOM";
|
||||||
}
|
}
|
||||||
auto nc = freepos;
|
auto nc = freepos;
|
||||||
freepos += 1;
|
freepos += 1;
|
||||||
|
|
@ -180,58 +329,6 @@ struct Machine {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data *Eval(Data *d) {
|
|
||||||
// std::cout << "Eval top" << std::endl;
|
|
||||||
if (SelfEval *h = dynamic_cast<SelfEval *>(d)) {
|
|
||||||
return h;
|
|
||||||
} else if (Symbol *h = dynamic_cast<Symbol*>(d)) {
|
|
||||||
if (reg.E.builtin.contains(h->data)) return h;
|
|
||||||
return mem[reg.E.userdef[h->data]].d;
|
|
||||||
} else if (Fork *h = dynamic_cast<Fork *>(d)) {
|
|
||||||
// std::cout << "Eval callllled" << std::endl;
|
|
||||||
// Symbol *car = dynamic_cast<Symbol *>(mem[h->data].d);
|
|
||||||
//new car:
|
|
||||||
auto car = mem[h->data].d;
|
|
||||||
|
|
||||||
// if (!car) {
|
|
||||||
// throw(100);
|
|
||||||
// }
|
|
||||||
size_t front = 0;
|
|
||||||
size_t current = 0;
|
|
||||||
size_t firstargleft = mem[h->data].cdr;
|
|
||||||
|
|
||||||
// std::cout << "Farg " << firstargleft << std::endl;
|
|
||||||
|
|
||||||
while (firstargleft != 0) {
|
|
||||||
if (auto c = dynamic_cast<Symbol*>(car)) {
|
|
||||||
if(c->data == "lambda") {
|
|
||||||
front = mem[h->data].cdr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (front == 0) {
|
|
||||||
front = newCell();
|
|
||||||
current = front;
|
|
||||||
} else {
|
|
||||||
auto temp = newCell();
|
|
||||||
mem[current].cdr = temp;
|
|
||||||
current = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::cout << "here" << std::endl;
|
|
||||||
mem[current].d = Eval(mem[firstargleft].d);
|
|
||||||
|
|
||||||
// std::cout << "there" << std::endl;
|
|
||||||
firstargleft = mem[firstargleft].cdr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mem[Apply(Eval(car), front)].d;
|
|
||||||
} else {
|
|
||||||
throw("err");
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListPrint(Cell c) {
|
void ListPrint(Cell c) {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
@ -312,7 +409,7 @@ struct Machine {
|
||||||
size_t current = 0;
|
size_t current = 0;
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
while (in.get(ch)) {
|
while (in.get(ch) && ch != '\n') {
|
||||||
if (!std::isspace(ch)) {
|
if (!std::isspace(ch)) {
|
||||||
if (ch == '(') {
|
if (ch == '(') {
|
||||||
auto temp = newCell();
|
auto temp = newCell();
|
||||||
|
|
@ -347,19 +444,41 @@ struct Machine {
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
auto m = Machine(1000);
|
auto m = Machine(10000);
|
||||||
|
|
||||||
auto exp = m.read_expr(std::cin);
|
|
||||||
|
|
||||||
m.ListPrint(m.mem[exp]);
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
Cell c;
|
Cell c;
|
||||||
c.d = m.Eval(m.mem[exp].d);
|
// c.d = m.Eval(m.mem[exp].d);
|
||||||
|
Registers r;
|
||||||
|
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
m.stack = std::vector<Registers>();
|
||||||
|
auto exp = m.read_expr(std::cin);
|
||||||
|
r.D = m.mem[exp].d;
|
||||||
|
m.reg = r;
|
||||||
|
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("lambda");
|
||||||
|
m.reg.E.builtin.insert("block");
|
||||||
|
m.reg.E.builtin.insert("print");
|
||||||
|
|
||||||
|
//m.ListPrint(m.mem[exp]);
|
||||||
|
std::cout << std::endl;
|
||||||
|
try {
|
||||||
|
m.EvalLoop();
|
||||||
|
} catch (const char * err) {
|
||||||
|
std::cout << err << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "out of loop" << std::endl;
|
||||||
|
|
||||||
|
c.d = std::get<Data *>(m.reg.R);
|
||||||
m.ListPrint(c);
|
m.ListPrint(c);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue