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 <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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue