mirror of
https://github.com/usatiuk/psil.git
synced 2025-10-28 18:57:48 +01:00
pretty up handles finally
This commit is contained in:
@@ -14,6 +14,8 @@ public:
|
||||
friend MemoryContext;
|
||||
|
||||
Handle(Cell *target);
|
||||
Handle(int64_t val);
|
||||
Handle(std::string strval);
|
||||
~Handle();
|
||||
|
||||
Handle(Handle const &other);
|
||||
@@ -23,16 +25,17 @@ public:
|
||||
return _target == rhs._target;
|
||||
}
|
||||
|
||||
static Handle cons(const Handle &car, const Handle &cdr);
|
||||
|
||||
Handle car() { return dynamic_cast<ConsCell &>(*_target)._car.load(); }
|
||||
Handle cdr() { return dynamic_cast<ConsCell &>(*_target)._cdr.load(); }
|
||||
CellValType val() { return dynamic_cast<NumAtomCell &>(*_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 makeStrCell(std::string val);
|
||||
void setcar(const Handle &car);
|
||||
|
||||
@@ -31,24 +31,25 @@ Handle Handle::cons(const Handle &car, const Handle &cdr) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
Handle Handle::pop(Handle &from) {
|
||||
auto ret = from.car();
|
||||
from = from.cdr();
|
||||
Handle Handle::pop() {
|
||||
auto ret = car();
|
||||
*this = cdr();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Handle::push(Handle &to, const Handle &what) {
|
||||
to = cons(what, to);
|
||||
void Handle::push(const Handle &what) {
|
||||
*this = cons(what, *this);
|
||||
}
|
||||
|
||||
void Handle::append(Handle to, const Handle &what) {
|
||||
assert(to.get() != nullptr);
|
||||
if (to.car().get() == nullptr) {
|
||||
to.setcar(what);
|
||||
void Handle::append(const Handle &what) {
|
||||
Handle cur = *this;
|
||||
assert(cur.get() != nullptr);
|
||||
if (cur.car().get() == nullptr) {
|
||||
cur.setcar(what);
|
||||
return;
|
||||
}
|
||||
while (to.cdr().get() != nullptr) to = to.cdr();
|
||||
to.setcdr(cons(what, nullptr));
|
||||
while (cur.cdr().get() != nullptr) cur = cur.cdr();
|
||||
cur.setcdr(cons(what, nullptr));
|
||||
}
|
||||
|
||||
Handle Handle::makeNumCell(int64_t val) {
|
||||
@@ -72,3 +73,9 @@ void Handle::setcdr(const Handle &cdr) {
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ Handle Parser::parseExpr() {
|
||||
|
||||
return out;
|
||||
}
|
||||
Handle::append(out, parseExpr());
|
||||
out.append(parseExpr());
|
||||
token = _tokenizer.peek();
|
||||
}
|
||||
_tokenizer.getNext();
|
||||
|
||||
@@ -16,13 +16,13 @@ void VM::run() {
|
||||
}
|
||||
|
||||
void VM::step() {
|
||||
Handle poppedH = Handle::pop(_c);
|
||||
Handle poppedH = _c.pop();
|
||||
if (poppedH == NIL) {
|
||||
Handle::push(_s, nullptr);
|
||||
_s.push(nullptr);
|
||||
} else if (poppedH == LDC) {
|
||||
Handle::push(_s, Handle::pop(_c));
|
||||
_s.push(_c.pop());
|
||||
} else if (poppedH == LD) {
|
||||
Handle poppedH2 = Handle::pop(_c);
|
||||
Handle poppedH2 = _c.pop();
|
||||
|
||||
int64_t frame = poppedH2.car().val();
|
||||
int64_t arg = poppedH2.cdr().val();
|
||||
@@ -42,92 +42,87 @@ void VM::step() {
|
||||
curArg = curArg.cdr();
|
||||
}
|
||||
|
||||
Handle::push(_s, curArg.car());
|
||||
_s.push(curArg.car());
|
||||
} 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);
|
||||
Handle cf = Handle::pop(_c);
|
||||
|
||||
Handle::push(_d, _c);
|
||||
_d.push(_c);
|
||||
if (popped2H.val() > 0) {
|
||||
_c = ct;
|
||||
} else {
|
||||
_c = cf;
|
||||
}
|
||||
} else if (poppedH == JOIN) {
|
||||
_c = Handle::pop(_d);
|
||||
_c = _d.pop();
|
||||
} else if (poppedH == LDF) {
|
||||
Handle::push(_s, Handle::cons(Handle::pop(_c), _e));
|
||||
_s.push(Handle::cons(_c.pop(), _e));
|
||||
} else if (poppedH == AP) {
|
||||
Handle closureH = Handle::pop(_s);
|
||||
Handle argsH = Handle::pop(_s);
|
||||
Handle closureH = _s.pop();
|
||||
Handle argsH = _s.pop();
|
||||
|
||||
Handle::push(_d, _s);
|
||||
Handle::push(_d, _e);
|
||||
Handle::push(_d, _c);
|
||||
_d.push(_s);
|
||||
_d.push(_e);
|
||||
_d.push(_c);
|
||||
|
||||
_s = Handle::cons(nullptr, nullptr);
|
||||
_c = closureH.car();
|
||||
_e = closureH.cdr();
|
||||
Handle::push(_e, argsH);
|
||||
_e.push(argsH);
|
||||
} else if (poppedH == RET) {
|
||||
Handle c = Handle::pop(_d);
|
||||
Handle e = Handle::pop(_d);
|
||||
Handle s = Handle::pop(_d);
|
||||
Handle c = _d.pop();
|
||||
Handle e = _d.pop();
|
||||
Handle s = _d.pop();
|
||||
|
||||
Handle ret = Handle::pop(_s);
|
||||
Handle ret = _s.pop();
|
||||
|
||||
_c = c;
|
||||
_e = e;
|
||||
_s = s;
|
||||
|
||||
Handle::push(_s, ret);
|
||||
_s.push(ret);
|
||||
} else if (poppedH == DUM) {
|
||||
Handle::push(_e, nullptr);
|
||||
_e.push(nullptr);
|
||||
} else if (poppedH == RAP) {
|
||||
Handle closureH = Handle::pop(_s);
|
||||
Handle argsH = Handle::pop(_s);
|
||||
|
||||
Handle closureH = _s.pop();
|
||||
Handle argsH = _s.pop();
|
||||
|
||||
Handle origE = _e.cdr();
|
||||
|
||||
Handle::push(_d, _s);
|
||||
Handle::push(_d, origE);
|
||||
Handle::push(_d, _c);
|
||||
_d.push(_s);
|
||||
_d.push(origE);
|
||||
_d.push(_c);
|
||||
|
||||
_s = Handle::cons(nullptr, nullptr);
|
||||
_c = closureH.car();
|
||||
_e = closureH.cdr();
|
||||
|
||||
Handle fnEnv = closureH.cdr();
|
||||
// assert(_e.get() == fnEnv.get());
|
||||
assert(_e == fnEnv);
|
||||
|
||||
Handle::push(_e, argsH);
|
||||
_e.push(argsH);
|
||||
fnEnv.setcar(argsH);
|
||||
} else if (poppedH == STOP) {
|
||||
_stop = true;
|
||||
} else if (poppedH == ADD) {
|
||||
int64_t ret = Handle::pop(_s).val() + Handle::pop(_s).val();
|
||||
Handle::push(_s, Handle::makeNumCell(ret));
|
||||
_s.push(_s.pop().val() + _s.pop().val());
|
||||
} else if (poppedH == SUB) {
|
||||
assert(false);
|
||||
int64_t ret = Handle::pop(_s).val() + Handle::pop(_s).val();
|
||||
Handle::push(_s, Handle::makeNumCell(ret));
|
||||
} else if (poppedH == CONS) {
|
||||
Handle h1 = Handle::pop(_s);
|
||||
Handle h2 = Handle::pop(_s);
|
||||
Handle h1 = _s.pop();
|
||||
Handle h2 = _s.pop();
|
||||
|
||||
Handle::push(_s, Handle::cons(h1, h2));
|
||||
_s.push(Handle::cons(h1, h2));
|
||||
} else if (poppedH == READCHAR) {
|
||||
char c;
|
||||
_instream >> c;
|
||||
Handle::push(_s, Handle::makeNumCell(c));
|
||||
_s.push(Handle::makeNumCell(c));
|
||||
} else if (poppedH == PUTCHAR) {
|
||||
_outstream << (char) Handle::pop(_s).val();
|
||||
_outstream << (char) _s.pop().val();
|
||||
} else if (poppedH == PUTNUM) {
|
||||
_outstream << Handle::pop(_s).val();
|
||||
_outstream << _s.pop().val();
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ TEST(GCTest, GCTest) {
|
||||
{
|
||||
Handle c = Handle::cons(nullptr, nullptr);
|
||||
mc.request_gc_and_wait();
|
||||
Handle::append(c, Handle::makeNumCell(1));
|
||||
Handle::append(c, Handle::makeNumCell(2));
|
||||
c.append(Handle::makeNumCell(1));
|
||||
c.append(Handle::makeNumCell(2));
|
||||
mc.request_gc_and_wait();
|
||||
EXPECT_EQ(c.car().val(), 1);
|
||||
EXPECT_EQ(c.cdr().car().val(), 2);
|
||||
@@ -23,8 +23,8 @@ TEST(GCTest, GCTest) {
|
||||
{
|
||||
Handle c = Handle::cons(nullptr, nullptr);
|
||||
mc.request_gc_and_wait();
|
||||
Handle::push(c, Handle::makeNumCell(1));
|
||||
Handle::push(c, Handle::makeNumCell(2));
|
||||
c.push(Handle::makeNumCell(1));
|
||||
c.push(Handle::makeNumCell(2));
|
||||
mc.request_gc_and_wait();
|
||||
EXPECT_EQ(c.car().val(), 2);
|
||||
EXPECT_EQ(c.cdr().car().val(), 1);
|
||||
@@ -39,7 +39,7 @@ TEST(GCTest, GCTestAppend) {
|
||||
for (int i = 0; i < 25000; i++) {
|
||||
Handle c = Handle::cons(nullptr, nullptr);
|
||||
mc.request_gc();
|
||||
Handle::append(c, Handle::makeNumCell(1));
|
||||
c.append(Handle::makeNumCell(1));
|
||||
mc.request_gc();
|
||||
EXPECT_EQ(c.car().val(), 1);
|
||||
}
|
||||
@@ -54,11 +54,11 @@ TEST(GCTest, GCTestPop) {
|
||||
static constexpr int test_size = 20000;
|
||||
for (int i = 0; i < test_size; i++) {
|
||||
mc.request_gc();
|
||||
Handle::push(c, Handle::makeNumCell(i));
|
||||
c.push(Handle::makeNumCell(i));
|
||||
}
|
||||
for (int i = test_size - 1; i >= 0; i--) {
|
||||
mc.request_gc();
|
||||
EXPECT_EQ(i, Handle::pop(c).val());
|
||||
EXPECT_EQ(i, c.pop().val());
|
||||
}
|
||||
}
|
||||
mc.request_gc_and_wait();
|
||||
@@ -72,11 +72,11 @@ TEST(GCTest, GCTestAppend2) {
|
||||
static constexpr int test_size = 2000;
|
||||
for (int i = 0; i < test_size; i++) {
|
||||
mc.request_gc();
|
||||
Handle::append(c, Handle::makeNumCell(i));
|
||||
c.append(Handle::makeNumCell(i));
|
||||
}
|
||||
for (int i = 0; i < test_size; i++) {
|
||||
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();
|
||||
@@ -85,10 +85,10 @@ TEST(GCTest, GCTestAppend2) {
|
||||
|
||||
TEST(GCTest, GCTestAppend3) {
|
||||
MemoryContext mc;
|
||||
for (int i = 0; i < 250000; i++) {
|
||||
for (int i = 0; i < 25000; i++) {
|
||||
Handle c = Handle::cons(nullptr, nullptr);
|
||||
Handle::append(c, Handle::makeNumCell(1));
|
||||
Handle::append(c, Handle::makeNumCell(2));
|
||||
c.append(Handle::makeNumCell(1));
|
||||
c.append(Handle::makeNumCell(2));
|
||||
mc.request_gc();
|
||||
Handle n = c.cdr();
|
||||
c.setcdr(nullptr);
|
||||
|
||||
@@ -9,11 +9,11 @@ TEST(VMTest, BasicHello) {
|
||||
MemoryContext mc;
|
||||
VM vm(ssin, ssout);
|
||||
Handle newc(Handle::cons(nullptr, nullptr));
|
||||
Handle::append(newc, Handle::makeStrCell("NIL"));
|
||||
Handle::append(newc, Handle::makeStrCell("LDC"));
|
||||
Handle::append(newc, Handle::makeNumCell('h'));
|
||||
Handle::append(newc, Handle::makeStrCell("PUTCHAR"));
|
||||
Handle::append(newc, Handle::makeStrCell("STOP"));
|
||||
newc.append(Handle::makeStrCell("NIL"));
|
||||
newc.append(Handle::makeStrCell("LDC"));
|
||||
newc.append(Handle::makeNumCell('h'));
|
||||
newc.append(Handle::makeStrCell("PUTCHAR"));
|
||||
newc.append(Handle::makeStrCell("STOP"));
|
||||
vm.loadControl(newc);
|
||||
vm.run();
|
||||
}
|
||||
@@ -21,6 +21,7 @@ TEST(VMTest, BasicHello) {
|
||||
EXPECT_EQ(ssout.str(), "h");
|
||||
}
|
||||
|
||||
//TODO: maybe rewrite it all...
|
||||
//TEST(VMTest, SelTest) {
|
||||
// std::stringstream ssin;
|
||||
// std::stringstream ssout;
|
||||
|
||||
Reference in New Issue
Block a user