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
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 =

View file

@ -28,9 +28,16 @@ struct Cell {
size_t cdr = 0;
};
struct Env {
std::unordered_set<std::string> builtin;
std::unordered_map<std::string, size_t> userdef;
// struct Env {
// std::unordered_set<std::string> builtin;
// 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 {
@ -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,7 +106,8 @@ struct Registers {
locs RP;
size_t R = 0;
Env E;
size_t E = 0;
special_indef_eval screen = special_indef_eval::NONE;
@ -138,17 +147,52 @@ struct Machine {
Registers reg;
std::unordered_set<std::string> 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<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() {
while (true) {
switch (reg.RP) {
@ -173,7 +217,7 @@ struct Machine {
// return h;
} else if (Symbol *h = dynamic_cast<Symbol *>(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<Fork *>(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<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_current = 0;
@ -290,7 +398,7 @@ struct Machine {
reg.C = reg.op;
Data *d = mem[reg.C].d;
if (Symbol *fname = dynamic_cast<Symbol *>(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<EnvFrame*>( 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<EnvFrame*> (mem[reg.E].d)->bindings[static_cast<Symbol*>(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<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;
}
@ -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<std::reference_wrapper<size_t>>& queue, Env& env) {
for (auto& def : env.userdef) {
queue.push_back(std::ref(def.second));
}
}
// void addEnvToGCQueue(std::vector<std::reference_wrapper<size_t>>& 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<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
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<Fork*>(mem_empty[scan].d)) {
GCMoveElem(std::ref(f->data));
} else if (Lambda * l = dynamic_cast<Lambda*>(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<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].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<Registers>();
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;