it lives !!

This commit is contained in:
IXtreme 2026-08-02 16:09:54 -04:00
parent 058405e5eb
commit f4fccc86d2
2 changed files with 174 additions and 45 deletions

View file

@ -1,9 +1,9 @@
CC = gcc CC = gcc
CXX = g++ CXX = g++
CPPFLAGS = -std=c++20 -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 CFLAGS = -g -Wall -Wextra -Wpedantic -O3 -ffast-math
LDFLAGS = -g -Wall -Wextra -Wpedantic #-O3 -ffast-math LDFLAGS = -g -Wall -Wextra -Wpedantic -O3 -ffast-math
LDLIBS = LDLIBS =

View file

@ -28,9 +28,16 @@ struct Cell {
size_t cdr = 0; size_t cdr = 0;
}; };
struct Env { // struct Env {
std::unordered_set<std::string> builtin; // std::unordered_set<std::string> builtin;
std::unordered_map<std::string, size_t> userdef; // std::unordered_map<std::string, size_t> userdef;
// };
struct EnvFrame : Data {
size_t parent = 0;
std::unordered_map<std::string, size_t> bindings;
EnvFrame(size_t par) : parent(par) {}
}; };
struct Symbol : Data { struct Symbol : Data {
@ -67,7 +74,8 @@ struct Fork : Data {
}; };
struct Lambda : Data { struct Lambda : Data {
Env env; //Env env;
size_t env = 0;
size_t args = 0; size_t args = 0;
size_t f = 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 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 { struct Registers {
@ -98,7 +106,8 @@ struct Registers {
locs RP; locs RP;
size_t R = 0; size_t R = 0;
Env E;
size_t E = 0;
special_indef_eval screen = special_indef_eval::NONE; special_indef_eval screen = special_indef_eval::NONE;
@ -138,17 +147,52 @@ struct Machine {
Registers reg; Registers reg;
std::unordered_set<std::string> builtin;
size_t global_env = 0;
bool invalidgc = false; 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("-"); builtin.insert("+");
reg.E.builtin.insert("lambda"); builtin.insert("*");
reg.E.builtin.insert("progn"); builtin.insert("-");
reg.E.builtin.insert("print"); 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<EnvFrame*>(mem[startAddr].d);
while(true) {
if (env == 0) return 0;
if (env->bindings.contains(name)) {
return env->bindings[name];
}
env = static_cast<EnvFrame*>(mem[env->parent].d);
}
}
void EvalLoop() { void EvalLoop() {
while (true) { while (true) {
switch (reg.RP) { switch (reg.RP) {
@ -173,7 +217,7 @@ struct Machine {
// 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 (builtin.contains(h->data)) {
if(stack.empty()) { if(stack.empty()) {
reg.R = reg.C; //return addressof reg.R = reg.C; //return addressof
return; return;
@ -186,13 +230,15 @@ struct Machine {
reg.R = loc; //return addressof reg.R = loc; //return addressof
} else { } else {
if(stack.empty()) { 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; 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];
reg.R = EnvLookup(reg.E, h->data);
} }
} else if (Fork *h = dynamic_cast<Fork *>(d)) { } else if (Fork *h = dynamic_cast<Fork *>(d)) {
reg.Exp = reg.C; //set exp to addressof reg.Exp = reg.C; //set exp to addressof
@ -225,6 +271,68 @@ struct Machine {
} else if (c->data == "if") { } else if (c->data == "if") {
reg.screen = special_indef_eval::IF_BEGIN; 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<Symbol*>(mem[reg.D].d)->data = "defun-unq";
// reg.C = newCell(); // lambda
mem[reg.B].d = new Symbol;
static_cast<Symbol*>(mem[reg.B].d)->data = "quote";
mem[reg.C].d = new Symbol;
static_cast<Symbol*>(mem[reg.C].d)->data = static_cast<Symbol*>(mem[reg.args_front].d)->data;
mem[reg.B].cdr = reg.C;
mem[reg.A].d = new Fork;
static_cast<Fork*>(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<Fork*>(mem[reg.A].d)->data = reg.B;
mem[reg.B].d = new Symbol;
static_cast<Symbol*>(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<Fork*>(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_left = mem[((Fork *) mem[reg.Exp].d)->data].cdr;
reg.args_current = 0; reg.args_current = 0;
@ -290,7 +398,7 @@ struct Machine {
reg.C = reg.op; reg.C = reg.op;
Data *d = mem[reg.C].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 (builtin.contains(fname->data)) {
auto nloc = newCell(); auto nloc = newCell();
auto temp = ApplyBuiltin(fname->data, reg.args_front, nloc); auto temp = ApplyBuiltin(fname->data, reg.args_front, nloc);
if(stack.empty()) { if(stack.empty()) {
@ -314,10 +422,22 @@ struct Machine {
reg.B = reg.args_front; reg.B = reg.args_front;
// reg.E = f->env; // 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<EnvFrame*>( mem[reg.E].d))->parent
reg.E = reg.C;
while (reg.A != 0) { while (reg.A != 0) {
reg.E.userdef[((Symbol *)mem[reg.A].d)->data] = //reg.E.userdef[((Symbol *)mem[reg.A].d)->data] = reg.B;
reg.B; //EnvLookup(0, ((Symbol *) mem[reg.A].d)->data);
static_cast<EnvFrame*> (mem[reg.E].d)->bindings[static_cast<Symbol*>(mem[reg.A].d)->data] = reg.B;
reg.A = mem[reg.A].cdr; reg.A = mem[reg.A].cdr;
reg.B = mem[reg.B].cdr; reg.B = mem[reg.B].cdr;
} }
@ -445,7 +565,15 @@ struct Machine {
return newlocation; return newlocation;
} }
} else if (fname == "quote") {
return cdr;
} else if (fname == "define") {
static_cast<EnvFrame*>(mem[reg.E].d)->bindings[static_cast<Symbol*>(mem[cdr].d)->data] = mem[cdr].cdr;
return cdr;
} else if (fname == "defun-unq") {
static_cast<EnvFrame*>(mem[reg.E].d)->bindings[static_cast<Symbol*>(mem[cdr].d)->data] = mem[cdr].cdr;
static_cast<EnvFrame*>(mem[static_cast<Lambda*>(mem[mem[cdr].cdr].d)->env].d)->bindings[static_cast<Symbol*>(mem[cdr].d)->data] = mem[cdr].cdr;
return cdr;
} }
return 0; return 0;
} }
@ -495,7 +623,7 @@ struct Machine {
// update orignal // update orignal
v = nloc; v = nloc;
} else { // if already moved } else { // if already moved
std::cout << "v: " << v << std::endl; //std::cout << "v: " << v << std::endl;
v = mem[v].cdr - maxCells; v = mem[v].cdr - maxCells;
} }
} }
@ -516,19 +644,23 @@ struct Machine {
queue.push_back(std::ref(regs.op)); queue.push_back(std::ref(regs.op));
queue.push_back(std::ref(regs.R)); 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<std::reference_wrapper<size_t>>& queue, Env& env) { // void addEnvToGCQueue(std::vector<std::reference_wrapper<size_t>>& queue, Env& env) {
for (auto& def : env.userdef) { // for (auto& def : env.userdef) {
queue.push_back(std::ref(def.second)); // queue.push_back(std::ref(def.second));
} // }
} // }
void GC() { void GC() {
std::cout << "GCING" << std::endl; //std::cout << "GCING" << std::endl;
std::vector<std::reference_wrapper<size_t>> queue; std::vector<std::reference_wrapper<size_t>> queue;
// add global environment to queue (probably pos 1)
queue.push_back(std::ref(global_env));
// add all known to queue // add all known to queue
addRegsToGCQueue(queue, reg); addRegsToGCQueue(queue, reg);
@ -536,6 +668,7 @@ struct Machine {
addRegsToGCQueue(queue, e); addRegsToGCQueue(queue, e);
} }
// cheney's alg // cheney's alg
// copy all root nodes over to to-space // copy all root nodes over to to-space
@ -558,11 +691,14 @@ struct Machine {
if (Fork * f = dynamic_cast<Fork*>(mem_empty[scan].d)) { if (Fork * f = dynamic_cast<Fork*>(mem_empty[scan].d)) {
GCMoveElem(std::ref(f->data)); GCMoveElem(std::ref(f->data));
} else if (Lambda * l = dynamic_cast<Lambda*>(mem_empty[scan].d)) { } else if (Lambda * l = dynamic_cast<Lambda*>(mem_empty[scan].d)) {
for (auto& def : l->env.userdef) { GCMoveElem(std::ref(l->env));
GCMoveElem(std::ref(def.second));
}
GCMoveElem(std::ref(l->args)); GCMoveElem(std::ref(l->args));
GCMoveElem(std::ref(l->f)); GCMoveElem(std::ref(l->f));
} else if (EnvFrame * e = dynamic_cast<EnvFrame*>(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].d = nullptr;
mem[i].cdr = 0; 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); mem.swap(mem_empty);
freepos = mempty_pos; freepos = mempty_pos;
mempty_pos = 1; mempty_pos = 1;
@ -711,7 +847,7 @@ struct Machine {
}; };
int main() { int main() {
auto m = Machine(27); auto m = Machine(270000);
Cell c; Cell c;
@ -723,6 +859,7 @@ int main() {
m.stack = std::vector<Registers>(); m.stack = std::vector<Registers>();
m.reg.ResetAllButEnv(); m.reg.ResetAllButEnv();
m.reg.E = m.global_env;
m.GC(); m.GC();
m.invalidgc = true; m.invalidgc = true;
auto exp = m.read_expr(std::cin); auto exp = m.read_expr(std::cin);
@ -732,14 +869,6 @@ int main() {
//m.reg = r; //m.reg = r;
m.reg.D = exp; 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("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]); //m.ListPrint(m.mem[exp]);
std::cout << std::endl; std::cout << std::endl;
@ -748,7 +877,7 @@ int main() {
} catch (const char * err) { } catch (const char * err) {
std::cout << err << std::endl; 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; std::cout << "freepos: " << m.freepos << " out of: " << m.maxCells << std::endl;
c.d = m.mem[m.reg.R].d; c.d = m.mem[m.reg.R].d;