diff --git a/Makefile b/Makefile index aef1076..eaa9be7 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ CC = gcc CXX = g++ -CPPFLAGS = -std=c++20 -g -Wall -Wextra -Wpedantic #-O3 -ffast-math -CFLAGS = -g -Wall -Wextra -Wpedantic #-O3 -ffast-math -LDFLAGS = -g -Wall -Wextra -Wpedantic #-O3 -ffast-math +CPPFLAGS = -std=c++20 -g -Wall -Wextra -Wpedantic -O3 -ffast-math +CFLAGS = -g -Wall -Wextra -Wpedantic -O3 -ffast-math +LDFLAGS = -g -Wall -Wextra -Wpedantic -O3 -ffast-math LDLIBS = diff --git a/src/main.cpp b/src/main.cpp index 091408c..f578965 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,9 +28,16 @@ struct Cell { size_t cdr = 0; }; -struct Env { - std::unordered_set builtin; - std::unordered_map userdef; +// struct Env { +// std::unordered_set builtin; +// std::unordered_map userdef; +// }; + + +struct EnvFrame : Data { + size_t parent = 0; + std::unordered_map bindings; + EnvFrame(size_t par) : parent(par) {} }; struct Symbol : Data { @@ -67,7 +74,8 @@ struct Fork : Data { }; struct Lambda : Data { - Env env; + //Env env; + size_t env = 0; size_t args = 0; size_t f = 0; }; @@ -76,7 +84,7 @@ struct Lambda : Data { enum class locs { EVAL_START, EVAL_OP_FIN, EVAL_TOP_ARG, APPLY }; -enum class special_indef_eval {NONE, PROGN, IF_BEGIN, FORCE_RETURN_NEXT_ARG}; +enum class special_indef_eval {NONE, PROGN, IF_BEGIN, FORCE_RETURN_NEXT_ARG, DEFINE}; struct Registers { @@ -98,8 +106,9 @@ struct Registers { locs RP; size_t R = 0; - Env E; - + + size_t E = 0; + special_indef_eval screen = special_indef_eval::NONE; void ResetAllButEnv() { @@ -138,17 +147,52 @@ struct Machine { Registers reg; + std::unordered_set builtin; + + size_t global_env = 0; + bool invalidgc = false; Machine(size_t max) : mem(max), mem_empty(max) { maxCells = max; - reg.E.builtin.insert("+"); - reg.E.builtin.insert("-"); - reg.E.builtin.insert("lambda"); - reg.E.builtin.insert("progn"); - reg.E.builtin.insert("print"); + + builtin.insert("+"); + builtin.insert("*"); + builtin.insert("-"); + builtin.insert("lambda"); + builtin.insert("progn"); + builtin.insert("print"); + builtin.insert("<"); + builtin.insert("if"); + builtin.insert("quote"); + builtin.insert("define"); + builtin.insert("defun-unq"); + builtin.insert("defun"); + + //alloc global environment node + global_env = newCell(new EnvFrame(0)); + + // reg.E.builtin.insert("+"); + // reg.E.builtin.insert("-"); + // reg.E.builtin.insert("lambda"); + // reg.E.builtin.insert("progn"); + // reg.E.builtin.insert("print"); } + + size_t EnvLookup(size_t startAddr, std::string name) { + + EnvFrame * env = static_cast(mem[startAddr].d); + while(true) { + if (env == 0) return 0; + if (env->bindings.contains(name)) { + return env->bindings[name]; + } + env = static_cast(mem[env->parent].d); + } + + } + void EvalLoop() { while (true) { switch (reg.RP) { @@ -173,7 +217,7 @@ struct Machine { // return h; } else if (Symbol *h = dynamic_cast(d)) { - if (reg.E.builtin.contains(h->data)) { + if (builtin.contains(h->data)) { if(stack.empty()) { reg.R = reg.C; //return addressof return; @@ -186,13 +230,15 @@ struct Machine { reg.R = loc; //return addressof } else { if(stack.empty()) { - reg.R = reg.E.userdef[h->data]; + //reg.R = reg.E.userdef[h->data]; + reg.R = EnvLookup(reg.E, h->data); return; } reg = stack.back(); stack.pop_back(); - reg.R = reg.E.userdef[h->data]; + //reg.R = reg.E.userdef[h->data]; + reg.R = EnvLookup(reg.E, h->data); } } else if (Fork *h = dynamic_cast(d)) { reg.Exp = reg.C; //set exp to addressof @@ -225,6 +271,68 @@ struct Machine { } else if (c->data == "if") { reg.screen = special_indef_eval::IF_BEGIN; } + // if(c->data == "define") { + // reg.screen = special_indef_eval::DEFINE; + + // } + if(c->data == "quote") { + reg.args_left = 0; + reg.args_current = 0; + reg.args_front = mem[((Fork *) mem[reg.Exp].d)->data].cdr; + reg.RP = locs::EVAL_TOP_ARG; + reg.argflag = false; + break; + + } + + if (c->data == "defun") { + reg.args_front = mem[((Fork *) mem[reg.Exp].d)->data].cdr; + reg.A = newCell(); // quote fork + reg.B = newCell(); // quote + reg.C = newCell(); // to store symbol name + reg.D = newCell(); // almsot root + + mem[reg.D].d = new Symbol; + static_cast(mem[reg.D].d)->data = "defun-unq"; + + // reg.C = newCell(); // lambda + mem[reg.B].d = new Symbol; + static_cast(mem[reg.B].d)->data = "quote"; + + mem[reg.C].d = new Symbol; + static_cast(mem[reg.C].d)->data = static_cast(mem[reg.args_front].d)->data; + + + mem[reg.B].cdr = reg.C; + mem[reg.A].d = new Fork; + static_cast(mem[reg.A].d)->data = reg.B; + + mem[reg.D].cdr = reg.A; + + + reg.A = newCell(); // lambda fork + reg.B = newCell(); // lambda symbol + + mem[mem[reg.D].cdr].cdr = reg.A; + + + mem[reg.A].d = new Fork; + static_cast(mem[reg.A].d)->data = reg.B; + + mem[reg.B].d = new Symbol; + static_cast(mem[reg.B].d)->data = "lambda"; + mem[reg.B].cdr = mem[reg.args_front].cdr; + + reg.A = newCell(); //wrapper + mem[reg.A].d = new Fork; + static_cast(mem[reg.A].d)->data = reg.D; + + reg.D = reg.A; + + reg.RP = locs::EVAL_START; + break; + } + } reg.args_left = mem[((Fork *) mem[reg.Exp].d)->data].cdr; reg.args_current = 0; @@ -290,7 +398,7 @@ struct Machine { reg.C = reg.op; Data *d = mem[reg.C].d; if (Symbol *fname = dynamic_cast(d)) { - if (reg.E.builtin.contains(fname->data)) { + if (builtin.contains(fname->data)) { auto nloc = newCell(); auto temp = ApplyBuiltin(fname->data, reg.args_front, nloc); if(stack.empty()) { @@ -314,10 +422,22 @@ struct Machine { reg.B = reg.args_front; // reg.E = f->env; - reg.E.userdef = f->env.userdef; + //reg.E.userdef = f->env.userdef; + + + //make new env with parrent set as the lambda's env + reg.C = newCell(); + mem[reg.C].d = new EnvFrame(f->env); + + + //(static_cast( mem[reg.E].d))->parent + + reg.E = reg.C; while (reg.A != 0) { - reg.E.userdef[((Symbol *)mem[reg.A].d)->data] = - reg.B; + //reg.E.userdef[((Symbol *)mem[reg.A].d)->data] = reg.B; + //EnvLookup(0, ((Symbol *) mem[reg.A].d)->data); + + static_cast (mem[reg.E].d)->bindings[static_cast(mem[reg.A].d)->data] = reg.B; reg.A = mem[reg.A].cdr; reg.B = mem[reg.B].cdr; } @@ -445,7 +565,15 @@ struct Machine { return newlocation; } - + } else if (fname == "quote") { + return cdr; + } else if (fname == "define") { + static_cast(mem[reg.E].d)->bindings[static_cast(mem[cdr].d)->data] = mem[cdr].cdr; + return cdr; + } else if (fname == "defun-unq") { + static_cast(mem[reg.E].d)->bindings[static_cast(mem[cdr].d)->data] = mem[cdr].cdr; + static_cast(mem[static_cast(mem[mem[cdr].cdr].d)->env].d)->bindings[static_cast(mem[cdr].d)->data] = mem[cdr].cdr; + return cdr; } return 0; } @@ -495,7 +623,7 @@ struct Machine { // update orignal v = nloc; } else { // if already moved - std::cout << "v: " << v << std::endl; + //std::cout << "v: " << v << std::endl; v = mem[v].cdr - maxCells; } } @@ -516,19 +644,23 @@ struct Machine { queue.push_back(std::ref(regs.op)); queue.push_back(std::ref(regs.R)); - addEnvToGCQueue(queue, regs.E); + queue.push_back(std::ref(regs.E)); + //addEnvToGCQueue(queue, regs.E); } - void addEnvToGCQueue(std::vector>& queue, Env& env) { - for (auto& def : env.userdef) { - queue.push_back(std::ref(def.second)); - } - } + // void addEnvToGCQueue(std::vector>& queue, Env& env) { + // for (auto& def : env.userdef) { + // queue.push_back(std::ref(def.second)); + // } + // } void GC() { - std::cout << "GCING" << std::endl; + //std::cout << "GCING" << std::endl; std::vector> queue; + + // add global environment to queue (probably pos 1) + queue.push_back(std::ref(global_env)); // add all known to queue addRegsToGCQueue(queue, reg); @@ -536,6 +668,7 @@ struct Machine { addRegsToGCQueue(queue, e); } + // cheney's alg // copy all root nodes over to to-space @@ -558,11 +691,14 @@ struct Machine { if (Fork * f = dynamic_cast(mem_empty[scan].d)) { GCMoveElem(std::ref(f->data)); } else if (Lambda * l = dynamic_cast(mem_empty[scan].d)) { - for (auto& def : l->env.userdef) { - GCMoveElem(std::ref(def.second)); - } + GCMoveElem(std::ref(l->env)); GCMoveElem(std::ref(l->args)); GCMoveElem(std::ref(l->f)); + } else if (EnvFrame * e = dynamic_cast(mem_empty[scan].d)) { + GCMoveElem(std::ref(e->parent)); + for (auto& pair : e->bindings) { + GCMoveElem(std::ref(pair.second)); + } } } @@ -585,7 +721,7 @@ struct Machine { mem[i].d = nullptr; mem[i].cdr = 0; } - std::cout << "GC DONE, OLDSIZE: " << freepos << " newsize: " << mempty_pos << std::endl; + //std::cout << "GC DONE, OLDSIZE: " << freepos << " newsize: " << mempty_pos << std::endl; mem.swap(mem_empty); freepos = mempty_pos; mempty_pos = 1; @@ -711,7 +847,7 @@ struct Machine { }; int main() { - auto m = Machine(27); + auto m = Machine(270000); Cell c; @@ -723,6 +859,7 @@ int main() { m.stack = std::vector(); m.reg.ResetAllButEnv(); + m.reg.E = m.global_env; m.GC(); m.invalidgc = true; auto exp = m.read_expr(std::cin); @@ -732,14 +869,6 @@ int main() { //m.reg = r; m.reg.D = exp; 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("progn"); - m.reg.E.builtin.insert("print"); - m.reg.E.builtin.insert("<"); - m.reg.E.builtin.insert("if"); //m.ListPrint(m.mem[exp]); std::cout << std::endl; @@ -748,7 +877,7 @@ int main() { } catch (const char * err) { std::cout << err << std::endl; } - std::cout << "out of loop" << std::endl; + //std::cout << "out of loop" << std::endl; std::cout << "freepos: " << m.freepos << " out of: " << m.maxCells << std::endl; c.d = m.mem[m.reg.R].d;