diff --git a/src/vm/includes/Handle.h b/src/vm/includes/Handle.h index ca1ea05..27eee3b 100644 --- a/src/vm/includes/Handle.h +++ b/src/vm/includes/Handle.h @@ -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(*_target)._car.load(); } Handle cdr() { return dynamic_cast(*_target)._cdr.load(); } CellValType val() { return dynamic_cast(*_target)._val; } std::string_view strval() { return dynamic_cast(*_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); diff --git a/src/vm/src/Handle.cpp b/src/vm/src/Handle.cpp index 71efa03..71b03be 100644 --- a/src/vm/src/Handle.cpp +++ b/src/vm/src/Handle.cpp @@ -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(*_target)._cdr = cdr.get(); }); } +Handle::Handle(int64_t val) { + *this = Handle::makeNumCell(val); +} +Handle::Handle(std::string strval) { + *this = Handle::makeStrCell(std::move(strval)); +} diff --git a/src/vm/src/Parser.cpp b/src/vm/src/Parser.cpp index 71ea998..fb6bbb9 100644 --- a/src/vm/src/Parser.cpp +++ b/src/vm/src/Parser.cpp @@ -32,7 +32,7 @@ Handle Parser::parseExpr() { return out; } - Handle::append(out, parseExpr()); + out.append(parseExpr()); token = _tokenizer.peek(); } _tokenizer.getNext(); diff --git a/src/vm/src/VM.cpp b/src/vm/src/VM.cpp index c47b94e..25aadc8 100644 --- a/src/vm/src/VM.cpp +++ b/src/vm/src/VM.cpp @@ -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); } diff --git a/test/vm/GCTest.cpp b/test/vm/GCTest.cpp index 1524f98..5280bde 100644 --- a/test/vm/GCTest.cpp +++ b/test/vm/GCTest.cpp @@ -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); diff --git a/test/vm/VMTest.cpp b/test/vm/VMTest.cpp index de49595..505415f 100644 --- a/test/vm/VMTest.cpp +++ b/test/vm/VMTest.cpp @@ -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;