pretty up handles finally

This commit is contained in:
2023-12-27 21:53:28 +01:00
parent e986daf6a6
commit b3b1bbbaeb
6 changed files with 81 additions and 75 deletions

View File

@@ -14,6 +14,8 @@ public:
friend MemoryContext; friend MemoryContext;
Handle(Cell *target); Handle(Cell *target);
Handle(int64_t val);
Handle(std::string strval);
~Handle(); ~Handle();
Handle(Handle const &other); Handle(Handle const &other);
@@ -23,16 +25,17 @@ public:
return _target == rhs._target; return _target == rhs._target;
} }
static Handle cons(const Handle &car, const Handle &cdr);
Handle car() { return dynamic_cast<ConsCell &>(*_target)._car.load(); } Handle car() { return dynamic_cast<ConsCell &>(*_target)._car.load(); }
Handle cdr() { return dynamic_cast<ConsCell &>(*_target)._cdr.load(); } Handle cdr() { return dynamic_cast<ConsCell &>(*_target)._cdr.load(); }
CellValType val() { return dynamic_cast<NumAtomCell &>(*_target)._val; } CellValType val() { return dynamic_cast<NumAtomCell &>(*_target)._val; }
std::string_view strval() { return dynamic_cast<StrAtomCell &>(*_target)._val; } std::string_view strval() { return dynamic_cast<StrAtomCell &>(*_target)._val; }
Handle pop();
void push(const Handle &what);
void append(const Handle &what);
static Handle cons(const Handle &car, const Handle &cdr);
static Handle pop(Handle &from);
static void push(Handle &to, const Handle &what);
static void append(Handle to, const Handle &what);
static Handle makeNumCell(int64_t val); static Handle makeNumCell(int64_t val);
static Handle makeStrCell(std::string val); static Handle makeStrCell(std::string val);
void setcar(const Handle &car); void setcar(const Handle &car);

View File

@@ -31,24 +31,25 @@ Handle Handle::cons(const Handle &car, const Handle &cdr) {
return ret; return ret;
} }
Handle Handle::pop(Handle &from) { Handle Handle::pop() {
auto ret = from.car(); auto ret = car();
from = from.cdr(); *this = cdr();
return ret; return ret;
} }
void Handle::push(Handle &to, const Handle &what) { void Handle::push(const Handle &what) {
to = cons(what, to); *this = cons(what, *this);
} }
void Handle::append(Handle to, const Handle &what) { void Handle::append(const Handle &what) {
assert(to.get() != nullptr); Handle cur = *this;
if (to.car().get() == nullptr) { assert(cur.get() != nullptr);
to.setcar(what); if (cur.car().get() == nullptr) {
cur.setcar(what);
return; return;
} }
while (to.cdr().get() != nullptr) to = to.cdr(); while (cur.cdr().get() != nullptr) cur = cur.cdr();
to.setcdr(cons(what, nullptr)); cur.setcdr(cons(what, nullptr));
} }
Handle Handle::makeNumCell(int64_t val) { Handle Handle::makeNumCell(int64_t val) {
@@ -72,3 +73,9 @@ void Handle::setcdr(const Handle &cdr) {
dynamic_cast<ConsCell &>(*_target)._cdr = cdr.get(); dynamic_cast<ConsCell &>(*_target)._cdr = cdr.get();
}); });
} }
Handle::Handle(int64_t val) {
*this = Handle::makeNumCell(val);
}
Handle::Handle(std::string strval) {
*this = Handle::makeStrCell(std::move(strval));
}

View File

@@ -32,7 +32,7 @@ Handle Parser::parseExpr() {
return out; return out;
} }
Handle::append(out, parseExpr()); out.append(parseExpr());
token = _tokenizer.peek(); token = _tokenizer.peek();
} }
_tokenizer.getNext(); _tokenizer.getNext();

View File

@@ -16,13 +16,13 @@ void VM::run() {
} }
void VM::step() { void VM::step() {
Handle poppedH = Handle::pop(_c); Handle poppedH = _c.pop();
if (poppedH == NIL) { if (poppedH == NIL) {
Handle::push(_s, nullptr); _s.push(nullptr);
} else if (poppedH == LDC) { } else if (poppedH == LDC) {
Handle::push(_s, Handle::pop(_c)); _s.push(_c.pop());
} else if (poppedH == LD) { } else if (poppedH == LD) {
Handle poppedH2 = Handle::pop(_c); Handle poppedH2 = _c.pop();
int64_t frame = poppedH2.car().val(); int64_t frame = poppedH2.car().val();
int64_t arg = poppedH2.cdr().val(); int64_t arg = poppedH2.cdr().val();
@@ -42,92 +42,87 @@ void VM::step() {
curArg = curArg.cdr(); curArg = curArg.cdr();
} }
Handle::push(_s, curArg.car()); _s.push(curArg.car());
} else if (poppedH == SEL) { } else if (poppedH == SEL) {
Handle popped2H = _s.pop();
Handle popped2H = Handle::pop(_s); Handle ct = _c.pop();
Handle cf = _c.pop();
Handle ct = Handle::pop(_c); _d.push(_c);
Handle cf = Handle::pop(_c);
Handle::push(_d, _c);
if (popped2H.val() > 0) { if (popped2H.val() > 0) {
_c = ct; _c = ct;
} else { } else {
_c = cf; _c = cf;
} }
} else if (poppedH == JOIN) { } else if (poppedH == JOIN) {
_c = Handle::pop(_d); _c = _d.pop();
} else if (poppedH == LDF) { } else if (poppedH == LDF) {
Handle::push(_s, Handle::cons(Handle::pop(_c), _e)); _s.push(Handle::cons(_c.pop(), _e));
} else if (poppedH == AP) { } else if (poppedH == AP) {
Handle closureH = Handle::pop(_s); Handle closureH = _s.pop();
Handle argsH = Handle::pop(_s); Handle argsH = _s.pop();
Handle::push(_d, _s); _d.push(_s);
Handle::push(_d, _e); _d.push(_e);
Handle::push(_d, _c); _d.push(_c);
_s = Handle::cons(nullptr, nullptr); _s = Handle::cons(nullptr, nullptr);
_c = closureH.car(); _c = closureH.car();
_e = closureH.cdr(); _e = closureH.cdr();
Handle::push(_e, argsH); _e.push(argsH);
} else if (poppedH == RET) { } else if (poppedH == RET) {
Handle c = Handle::pop(_d); Handle c = _d.pop();
Handle e = Handle::pop(_d); Handle e = _d.pop();
Handle s = Handle::pop(_d); Handle s = _d.pop();
Handle ret = Handle::pop(_s); Handle ret = _s.pop();
_c = c; _c = c;
_e = e; _e = e;
_s = s; _s = s;
Handle::push(_s, ret); _s.push(ret);
} else if (poppedH == DUM) { } else if (poppedH == DUM) {
Handle::push(_e, nullptr); _e.push(nullptr);
} else if (poppedH == RAP) { } else if (poppedH == RAP) {
Handle closureH = Handle::pop(_s); Handle closureH = _s.pop();
Handle argsH = Handle::pop(_s); Handle argsH = _s.pop();
Handle origE = _e.cdr(); Handle origE = _e.cdr();
Handle::push(_d, _s); _d.push(_s);
Handle::push(_d, origE); _d.push(origE);
Handle::push(_d, _c); _d.push(_c);
_s = Handle::cons(nullptr, nullptr); _s = Handle::cons(nullptr, nullptr);
_c = closureH.car(); _c = closureH.car();
_e = closureH.cdr(); _e = closureH.cdr();
Handle fnEnv = closureH.cdr(); Handle fnEnv = closureH.cdr();
// assert(_e.get() == fnEnv.get()); assert(_e == fnEnv);
Handle::push(_e, argsH); _e.push(argsH);
fnEnv.setcar(argsH); fnEnv.setcar(argsH);
} else if (poppedH == STOP) { } else if (poppedH == STOP) {
_stop = true; _stop = true;
} else if (poppedH == ADD) { } else if (poppedH == ADD) {
int64_t ret = Handle::pop(_s).val() + Handle::pop(_s).val(); _s.push(_s.pop().val() + _s.pop().val());
Handle::push(_s, Handle::makeNumCell(ret));
} else if (poppedH == SUB) { } else if (poppedH == SUB) {
assert(false); assert(false);
int64_t ret = Handle::pop(_s).val() + Handle::pop(_s).val();
Handle::push(_s, Handle::makeNumCell(ret));
} else if (poppedH == CONS) { } else if (poppedH == CONS) {
Handle h1 = Handle::pop(_s); Handle h1 = _s.pop();
Handle h2 = Handle::pop(_s); Handle h2 = _s.pop();
Handle::push(_s, Handle::cons(h1, h2)); _s.push(Handle::cons(h1, h2));
} else if (poppedH == READCHAR) { } else if (poppedH == READCHAR) {
char c; char c;
_instream >> c; _instream >> c;
Handle::push(_s, Handle::makeNumCell(c)); _s.push(Handle::makeNumCell(c));
} else if (poppedH == PUTCHAR) { } else if (poppedH == PUTCHAR) {
_outstream << (char) Handle::pop(_s).val(); _outstream << (char) _s.pop().val();
} else if (poppedH == PUTNUM) { } else if (poppedH == PUTNUM) {
_outstream << Handle::pop(_s).val(); _outstream << _s.pop().val();
} else { } else {
assert(false); assert(false);
} }

View File

@@ -11,8 +11,8 @@ TEST(GCTest, GCTest) {
{ {
Handle c = Handle::cons(nullptr, nullptr); Handle c = Handle::cons(nullptr, nullptr);
mc.request_gc_and_wait(); mc.request_gc_and_wait();
Handle::append(c, Handle::makeNumCell(1)); c.append(Handle::makeNumCell(1));
Handle::append(c, Handle::makeNumCell(2)); c.append(Handle::makeNumCell(2));
mc.request_gc_and_wait(); mc.request_gc_and_wait();
EXPECT_EQ(c.car().val(), 1); EXPECT_EQ(c.car().val(), 1);
EXPECT_EQ(c.cdr().car().val(), 2); EXPECT_EQ(c.cdr().car().val(), 2);
@@ -23,8 +23,8 @@ TEST(GCTest, GCTest) {
{ {
Handle c = Handle::cons(nullptr, nullptr); Handle c = Handle::cons(nullptr, nullptr);
mc.request_gc_and_wait(); mc.request_gc_and_wait();
Handle::push(c, Handle::makeNumCell(1)); c.push(Handle::makeNumCell(1));
Handle::push(c, Handle::makeNumCell(2)); c.push(Handle::makeNumCell(2));
mc.request_gc_and_wait(); mc.request_gc_and_wait();
EXPECT_EQ(c.car().val(), 2); EXPECT_EQ(c.car().val(), 2);
EXPECT_EQ(c.cdr().car().val(), 1); EXPECT_EQ(c.cdr().car().val(), 1);
@@ -39,7 +39,7 @@ TEST(GCTest, GCTestAppend) {
for (int i = 0; i < 25000; i++) { for (int i = 0; i < 25000; i++) {
Handle c = Handle::cons(nullptr, nullptr); Handle c = Handle::cons(nullptr, nullptr);
mc.request_gc(); mc.request_gc();
Handle::append(c, Handle::makeNumCell(1)); c.append(Handle::makeNumCell(1));
mc.request_gc(); mc.request_gc();
EXPECT_EQ(c.car().val(), 1); EXPECT_EQ(c.car().val(), 1);
} }
@@ -54,11 +54,11 @@ TEST(GCTest, GCTestPop) {
static constexpr int test_size = 20000; static constexpr int test_size = 20000;
for (int i = 0; i < test_size; i++) { for (int i = 0; i < test_size; i++) {
mc.request_gc(); mc.request_gc();
Handle::push(c, Handle::makeNumCell(i)); c.push(Handle::makeNumCell(i));
} }
for (int i = test_size - 1; i >= 0; i--) { for (int i = test_size - 1; i >= 0; i--) {
mc.request_gc(); mc.request_gc();
EXPECT_EQ(i, Handle::pop(c).val()); EXPECT_EQ(i, c.pop().val());
} }
} }
mc.request_gc_and_wait(); mc.request_gc_and_wait();
@@ -72,11 +72,11 @@ TEST(GCTest, GCTestAppend2) {
static constexpr int test_size = 2000; static constexpr int test_size = 2000;
for (int i = 0; i < test_size; i++) { for (int i = 0; i < test_size; i++) {
mc.request_gc(); mc.request_gc();
Handle::append(c, Handle::makeNumCell(i)); c.append(Handle::makeNumCell(i));
} }
for (int i = 0; i < test_size; i++) { for (int i = 0; i < test_size; i++) {
mc.request_gc(); mc.request_gc();
EXPECT_EQ(i, Handle::pop(c).val()); EXPECT_EQ(i, c.pop().val());
} }
mc.request_gc_and_wait(); mc.request_gc_and_wait();
mc.request_gc_and_wait(); mc.request_gc_and_wait();
@@ -85,10 +85,10 @@ TEST(GCTest, GCTestAppend2) {
TEST(GCTest, GCTestAppend3) { TEST(GCTest, GCTestAppend3) {
MemoryContext mc; MemoryContext mc;
for (int i = 0; i < 250000; i++) { for (int i = 0; i < 25000; i++) {
Handle c = Handle::cons(nullptr, nullptr); Handle c = Handle::cons(nullptr, nullptr);
Handle::append(c, Handle::makeNumCell(1)); c.append(Handle::makeNumCell(1));
Handle::append(c, Handle::makeNumCell(2)); c.append(Handle::makeNumCell(2));
mc.request_gc(); mc.request_gc();
Handle n = c.cdr(); Handle n = c.cdr();
c.setcdr(nullptr); c.setcdr(nullptr);

View File

@@ -9,11 +9,11 @@ TEST(VMTest, BasicHello) {
MemoryContext mc; MemoryContext mc;
VM vm(ssin, ssout); VM vm(ssin, ssout);
Handle newc(Handle::cons(nullptr, nullptr)); Handle newc(Handle::cons(nullptr, nullptr));
Handle::append(newc, Handle::makeStrCell("NIL")); newc.append(Handle::makeStrCell("NIL"));
Handle::append(newc, Handle::makeStrCell("LDC")); newc.append(Handle::makeStrCell("LDC"));
Handle::append(newc, Handle::makeNumCell('h')); newc.append(Handle::makeNumCell('h'));
Handle::append(newc, Handle::makeStrCell("PUTCHAR")); newc.append(Handle::makeStrCell("PUTCHAR"));
Handle::append(newc, Handle::makeStrCell("STOP")); newc.append(Handle::makeStrCell("STOP"));
vm.loadControl(newc); vm.loadControl(newc);
vm.run(); vm.run();
} }
@@ -21,6 +21,7 @@ TEST(VMTest, BasicHello) {
EXPECT_EQ(ssout.str(), "h"); EXPECT_EQ(ssout.str(), "h");
} }
//TODO: maybe rewrite it all...
//TEST(VMTest, SelTest) { //TEST(VMTest, SelTest) {
// std::stringstream ssin; // std::stringstream ssin;
// std::stringstream ssout; // std::stringstream ssout;