This commit is contained in:
IXtreme 2026-07-27 00:46:25 -04:00
parent fb3477d5ba
commit cf8315ef2b

View file

@ -1,8 +1,11 @@
#include <cassert> #include <cassert>
#include <functional>
#include <iostream> #include <iostream>
#include <istream> #include <istream>
#include <memory> #include <memory>
#include <queue>
#include <string> #include <string>
#include <type_traits>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <variant> #include <variant>
@ -21,7 +24,7 @@ struct Applyable : Data {
}; };
struct Cell { struct Cell {
Data *d; Data *d = nullptr;
size_t cdr = 0; size_t cdr = 0;
}; };
@ -57,7 +60,7 @@ struct Nil : SelfEval {
struct Fork : Data { struct Fork : Data {
size_t data; size_t data = 0;
size_t Get() { size_t Get() {
return data; return data;
} }
@ -65,34 +68,36 @@ struct Fork : Data {
struct Lambda : Data { struct Lambda : Data {
Env env; Env env;
size_t args; size_t args = 0;
size_t f; size_t f = 0;
}; };
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};
struct Registers { struct Registers {
size_t Exp; size_t Exp = 0;
size_t args_front; size_t args_front = 0;
size_t args_current; size_t args_current = 0;
size_t args_left; size_t args_left = 0;
// general registers // general registers
size_t A; size_t A = 0;
size_t B; size_t B = 0;
size_t C; size_t C = 0;
size_t D; size_t D = 0;
bool argflag = false; bool argflag = false;
size_t op; size_t op = 0;
locs RP; locs RP;
size_t R; size_t R = 0;
Env E; Env E;
special_indef_eval screen = special_indef_eval::NONE; special_indef_eval screen = special_indef_eval::NONE;
@ -104,19 +109,19 @@ struct Machine {
size_t mempty_pos = 1; size_t mempty_pos = 1;
int activebank = 0; // int activebank = 0;
std::vector<Cell> bank0; // std::vector<Cell> bank0;
std::vector<Cell> bank1; // std::vector<Cell> bank1;
std::vector<Cell>& mem; std::vector<Cell> mem;
std::vector<Cell>& mem_empty; std::vector<Cell> mem_empty;
std::vector<Registers> stack; std::vector<Registers> stack;
Registers reg; Registers reg;
Machine(size_t max) : bank0(max) , bank1(max), mem(bank0), mem_empty(bank1) { Machine(size_t max) : mem(max), mem_empty(max) {
maxCells = max; maxCells = max;
reg.E.builtin.insert("+"); reg.E.builtin.insert("+");
reg.E.builtin.insert("-"); reg.E.builtin.insert("-");
@ -408,7 +413,9 @@ struct Machine {
size_t newCell() { size_t newCell() {
if (freepos >= maxCells) { if (freepos >= maxCells) {
throw "OOM"; GC();
return newCell();
//throw "OOM";
} }
auto nc = freepos; auto nc = freepos;
freepos += 1; freepos += 1;
@ -426,19 +433,119 @@ struct Machine {
} }
void GCMoveElem(std::reference_wrapper<size_t> from) {
size_t& v = from.get();
// no need to move if the pointer is null
if (v == 0) {
return;
}
// size_t MoveThingAtAddr(size_t loc) { if (mem[v].cdr < maxCells) {
// auto nc = newCellInEmpty(); auto nloc = newCellInEmpty();
// mem_empty[nc] = mem[loc]; // copy
// mem[loc].cdr = maxCells + nc; mem_empty[nloc] = mem[v];
// return nc;
// } // leave heart
mem[v].cdr = nloc + maxCells;
// update orignal
v = nloc;
} else { // if already moved
std::cout << "v: " << v << std::endl;
v = mem[v].cdr - maxCells;
}
}
// stop and copy gc
void addRegsToGCQueue(std::vector<std::reference_wrapper<size_t>>& queue, Registers& regs) {
queue.push_back(std::ref(regs.Exp));
queue.push_back(std::ref(regs.args_front));
queue.push_back(std::ref(regs.args_current));
queue.push_back(std::ref(regs.args_left));
queue.push_back(std::ref(regs.A));
queue.push_back(std::ref(regs.B));
queue.push_back(std::ref(regs.C));
queue.push_back(std::ref(regs.D));
queue.push_back(std::ref(regs.op));
queue.push_back(std::ref(regs.R));
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 GC() {
std::cout << "GCING" << std::endl;
std::vector<std::reference_wrapper<size_t>> queue;
// add all known to queue
addRegsToGCQueue(queue, reg);
for (auto& e : stack) {
addRegsToGCQueue(queue, e);
}
// cheney's alg
// copy all root nodes over to to-space
for (size_t i = 0; i < queue.size(); i++) {
GCMoveElem(queue[i]);
}
size_t scan = 1;
std::unordered_set<Data*> handled;
while (scan != mempty_pos) { // scan not at blank cell
// move the cdr
GCMoveElem(mem_empty[scan].cdr);
if (handled.contains(mem_empty[scan].d)) {}
else {
handled.insert(mem_empty[scan].d);
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->args));
GCMoveElem(std::ref(l->f));
}
}
scan++;
}
handled.clear();
// // stop and copy gc
// void GC() {
// std::vector<
// } for (size_t i = 1; i < mempty_pos; i++) {
handled.insert(mem_empty[i].d);
}
for (size_t i = 1; i < mem.size(); i++) {
if (mem[i].cdr < maxCells && !handled.contains(mem[i].d)) {
handled.insert(mem[i].d);
delete mem[i].d;
}
mem[i].d = nullptr;
mem[i].cdr = 0;
}
mem.swap(mem_empty);
freepos = mempty_pos;
mempty_pos = 1;
}
size_t newCell(Data *d) { size_t newCell(Data *d) {
auto t = newCell(); auto t = newCell();
@ -561,7 +668,7 @@ struct Machine {
}; };
int main() { int main() {
auto m = Machine(1000); auto m = Machine(20);
Cell c; Cell c;
@ -593,6 +700,7 @@ int main() {
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;
c.d = m.mem[m.reg.R].d; c.d = m.mem[m.reg.R].d;
m.ListPrint(c); m.ListPrint(c);