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 <functional>
#include <iostream>
#include <istream>
#include <memory>
#include <queue>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <variant>
@ -21,7 +24,7 @@ struct Applyable : Data {
};
struct Cell {
Data *d;
Data *d = nullptr;
size_t cdr = 0;
};
@ -57,7 +60,7 @@ struct Nil : SelfEval {
struct Fork : Data {
size_t data;
size_t data = 0;
size_t Get() {
return data;
}
@ -65,34 +68,36 @@ struct Fork : Data {
struct Lambda : Data {
Env env;
size_t args;
size_t f;
size_t args = 0;
size_t f = 0;
};
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};
struct Registers {
size_t Exp;
size_t args_front;
size_t args_current;
size_t args_left;
size_t Exp = 0;
size_t args_front = 0;
size_t args_current = 0;
size_t args_left = 0;
// general registers
size_t A;
size_t B;
size_t C;
size_t D;
size_t A = 0;
size_t B = 0;
size_t C = 0;
size_t D = 0;
bool argflag = false;
size_t op;
size_t op = 0;
locs RP;
size_t R;
size_t R = 0;
Env E;
special_indef_eval screen = special_indef_eval::NONE;
@ -104,19 +109,19 @@ struct Machine {
size_t mempty_pos = 1;
int activebank = 0;
std::vector<Cell> bank0;
std::vector<Cell> bank1;
// int activebank = 0;
// std::vector<Cell> bank0;
// std::vector<Cell> bank1;
std::vector<Cell>& mem;
std::vector<Cell>& mem_empty;
std::vector<Cell> mem;
std::vector<Cell> mem_empty;
std::vector<Registers> stack;
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;
reg.E.builtin.insert("+");
reg.E.builtin.insert("-");
@ -408,7 +413,9 @@ struct Machine {
size_t newCell() {
if (freepos >= maxCells) {
throw "OOM";
GC();
return newCell();
//throw "OOM";
}
auto nc = freepos;
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) {
// auto nc = newCellInEmpty();
// mem_empty[nc] = mem[loc];
// mem[loc].cdr = maxCells + nc;
// return nc;
// }
if (mem[v].cdr < maxCells) {
auto nloc = newCellInEmpty();
// copy
mem_empty[nloc] = mem[v];
// 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) {
auto t = newCell();
@ -561,7 +668,7 @@ struct Machine {
};
int main() {
auto m = Machine(1000);
auto m = Machine(20);
Cell c;
@ -593,6 +700,7 @@ int main() {
std::cout << err << 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;
m.ListPrint(c);