mirror of
https://github.com/usatiuk/psil.git
synced 2025-10-29 03:07:49 +01:00
pretty up handles finally
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user