buggy
This commit is contained in:
parent
fb3477d5ba
commit
cf8315ef2b
1 changed files with 140 additions and 32 deletions
172
src/main.cpp
172
src/main.cpp
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue