diff --git a/src/vm/includes/Cell.h b/src/vm/includes/Cell.h index 04065f4..f7d2427 100644 --- a/src/vm/includes/Cell.h +++ b/src/vm/includes/Cell.h @@ -9,11 +9,12 @@ #include enum class CellType { - NIL, INT, CONS }; +using CellValType = int64_t; + struct Cell { explicit Cell(CellType type) : _type(type) {} virtual ~Cell() = 0; @@ -24,9 +25,9 @@ struct Cell { struct ValueCell : public Cell { ValueCell() = delete; - explicit ValueCell(int64_t val) : Cell(CellType::INT), _val(val) {} + explicit ValueCell(CellValType val) : Cell(CellType::INT), _val(val) {} - int64_t _val; + CellValType _val; }; struct ConsCell : public Cell { diff --git a/src/vm/includes/ConsUtils.h b/src/vm/includes/ConsUtils.h index cb3e5c5..7f767ba 100644 --- a/src/vm/includes/ConsUtils.h +++ b/src/vm/includes/ConsUtils.h @@ -11,11 +11,13 @@ namespace ConsUtils { static inline MCHandle car(const MCHandle &cell) { return dynamic_cast(*cell)._car; } static inline MCHandle cdr(const MCHandle &cell) { return dynamic_cast(*cell)._cdr; } + static inline CellValType val(const MCHandle &cell) { return dynamic_cast(*cell)._val; } MCHandle cons(const MCHandle &car, const MCHandle &cdr); MCHandle pop(MCHandle &from); MCHandle push(MCHandle &to, const MCHandle &what); void append(MCHandle to, const MCHandle &what); MCHandle makeIntCell(int64_t val); + void setcar(const MCHandle &to, const MCHandle &car); };// namespace ConsUtils diff --git a/src/vm/includes/MemoryContext.h b/src/vm/includes/MemoryContext.h index 517e137..296560b 100644 --- a/src/vm/includes/MemoryContext.h +++ b/src/vm/includes/MemoryContext.h @@ -26,7 +26,7 @@ public: class Handle { public: - Handle(Cell *target) : _target(target), _type(target ? target->_type : CellType::NIL) {} + Handle(Cell *target) : _target(target) {} Cell *operator->() const { return _target; } Cell &operator*() const { return *_target; } @@ -34,7 +34,6 @@ public: private: Cell *_target = nullptr; - CellType _type; }; private: diff --git a/src/vm/includes/VM.h b/src/vm/includes/VM.h index 4c7d9b6..d862ba0 100644 --- a/src/vm/includes/VM.h +++ b/src/vm/includes/VM.h @@ -11,6 +11,7 @@ #include #include "Cell.h" +#include "ConsUtils.h" #include "MemoryContext.h" class VM { @@ -24,10 +25,10 @@ public: void step(); private: - MCHandle _s = nullptr; - MCHandle _e = nullptr; - MCHandle _c = nullptr; - MCHandle _d = nullptr; + MCHandle _s = ConsUtils::cons(nullptr, nullptr); + MCHandle _e = ConsUtils::cons(nullptr, nullptr); + MCHandle _c = ConsUtils::cons(nullptr, nullptr); + MCHandle _d = ConsUtils::cons(nullptr, nullptr); bool _stop = false; std::istream &_instream; diff --git a/src/vm/src/ConsUtils.cpp b/src/vm/src/ConsUtils.cpp index 286ca8e..f37749e 100644 --- a/src/vm/src/ConsUtils.cpp +++ b/src/vm/src/ConsUtils.cpp @@ -34,4 +34,8 @@ void ConsUtils::append(MCHandle to, const MCHandle &what) { MCHandle ConsUtils::makeIntCell(int64_t val) { return CURRENT_MC.load()->create_cell(val); -} \ No newline at end of file +} + +void ConsUtils::setcar(const MCHandle &to, const MCHandle &car) { + dynamic_cast(*to)._car = car.get(); +} diff --git a/src/vm/src/VM.cpp b/src/vm/src/VM.cpp index 8e1f2c0..fa01b86 100644 --- a/src/vm/src/VM.cpp +++ b/src/vm/src/VM.cpp @@ -10,6 +10,8 @@ #include "ConsUtils.h" #include "VM.h" +using namespace ConsUtils; + VM::VM(std::istream &instream, std::ostream &outstream) : _instream(instream), _outstream(outstream) {} void VM::run() { @@ -17,56 +19,49 @@ void VM::run() { } void VM::step() { - MCHandle poppedH = ConsUtils::pop(_c); - ValueCell &popped = dynamic_cast(*poppedH); + MCHandle poppedH = pop(_c); - switch (Command::int_to_cmd(popped._val)) { + switch (Command::int_to_cmd(val(poppedH))) { case Command::CommandNum::NIL: { - ConsUtils::push(_s, nullptr); + push(_s, nullptr); break; } case Command::CommandNum::LDC: { - ConsUtils::push(_s, ConsUtils::pop(_c)); + push(_s, pop(_c)); break; } case Command::CommandNum::LD: { - MCHandle poppedH2 = ConsUtils::pop(_c); - ConsCell &popped2 = dynamic_cast(*poppedH2); + MCHandle poppedH2 = pop(_c); - int64_t frame = dynamic_cast(*popped2._car)._val; - int64_t arg = dynamic_cast(*popped2._cdr)._val; + int64_t frame = val(car(poppedH2)); + int64_t arg = val(cdr(poppedH2)); assert(frame > 0); assert(arg > 0); - ConsCell *curFrame = dynamic_cast(_e.get()); - assert(curFrame); + MCHandle curFrame = _e; for (int i = 1; i < frame; i++) { - curFrame = dynamic_cast(curFrame->_cdr); - assert(curFrame); + curFrame = cdr(curFrame); } - ConsCell *curArg = dynamic_cast(curFrame->_car); - assert(curArg); + MCHandle curArg = car(curFrame); for (int i = 1; i < arg; i++) { - curArg = dynamic_cast(curArg->_cdr); - assert(curArg); + curArg = cdr(curArg); } - ConsUtils::push(_s, curArg->_car); + push(_s, car(curArg)); break; } case Command::CommandNum::SEL: { - MCHandle popped2H = ConsUtils::pop(_s); - ValueCell &popped2 = dynamic_cast(*popped2H); + MCHandle popped2H = pop(_s); - MCHandle ct = ConsUtils::pop(_c); - MCHandle cf = ConsUtils::pop(_c); + MCHandle ct = pop(_c); + MCHandle cf = pop(_c); - ConsUtils::push(_d, _c); - if (popped2._val > 0) { + push(_d, _c); + if (val(popped2H) > 0) { _c = ct; } else { _c = cf; @@ -75,65 +70,66 @@ void VM::step() { break; } case Command::CommandNum::JOIN: { - _c = ConsUtils::pop(_d); + _c = pop(_d); break; } case Command::CommandNum::LDF: { - ConsUtils::push(_s, ConsUtils::cons(ConsUtils::pop(_c), _e)); + push(_s, cons(pop(_c), _e)); break; } case Command::CommandNum::AP: { - MCHandle closureH = ConsUtils::pop(_s); - MCHandle argsH = ConsUtils::pop(_s); + MCHandle closureH = pop(_s); + MCHandle argsH = pop(_s); - ConsUtils::push(_d, _s); - ConsUtils::push(_d, _e); - ConsUtils::push(_d, _c); + push(_d, _s); + push(_d, _e); + push(_d, _c); - _s = ConsUtils::cons(nullptr, nullptr); - _c = ConsUtils::car(closureH); - _e = ConsUtils::cdr(closureH); - ConsUtils::push(_e, argsH); + _s = cons(nullptr, nullptr); + _c = car(closureH); + _e = cdr(closureH); + push(_e, argsH); break; } case Command::CommandNum::RET: { - MCHandle c = ConsUtils::pop(_d); - MCHandle e = ConsUtils::pop(_d); - MCHandle s = ConsUtils::pop(_d); + MCHandle c = pop(_d); + MCHandle e = pop(_d); + MCHandle s = pop(_d); - MCHandle ret = ConsUtils::pop(_s); + MCHandle ret = pop(_s); _c = c; _e = e; _s = s; - ConsUtils::push(_s, ret); + push(_s, ret); // gc(); break; } case Command::CommandNum::DUM: { - ConsUtils::push(_e, nullptr); + push(_e, nullptr); break; } case Command::CommandNum::RAP: { - MCHandle closureH = ConsUtils::pop(_s); - MCHandle argsH = ConsUtils::pop(_s); + MCHandle closureH = pop(_s); + MCHandle argsH = pop(_s); - MCHandle origE = ConsUtils::cdr(_e); + MCHandle origE = cdr(_e); - ConsUtils::push(_d, _s); - ConsUtils::push(_d, origE); - ConsUtils::push(_d, _c); + push(_d, _s); + push(_d, origE); + push(_d, _c); - _s = ConsUtils::cons(nullptr, nullptr); - _c = ConsUtils::car(closureH); - _e = ConsUtils::cdr(closureH); + _s = cons(nullptr, nullptr); + _c = car(closureH); + _e = cdr(closureH); - MCHandle fnEnv = ConsUtils::cdr(closureH); + MCHandle fnEnv = cdr(closureH); assert(_e.get() == fnEnv.get()); - ConsUtils::push(_e, argsH); - dynamic_cast(*fnEnv)._car = argsH.get(); + + push(_e, argsH); + setcar(fnEnv, argsH); break; } case Command::CommandNum::STOP: { @@ -142,32 +138,32 @@ void VM::step() { break; } case Command::CommandNum::ADD: { - int64_t ret = dynamic_cast(*ConsUtils::pop(_s))._val + dynamic_cast(*ConsUtils::pop(_s))._val; - ConsUtils::push(_s, CURRENT_MC.load()->create_cell(ret)); + int64_t ret = val(pop(_s)) + val(pop(_s)); + push(_s, makeIntCell(ret)); break; } case Command::CommandNum::SUB: { break; } case Command::CommandNum::CONS: { - MCHandle h1 = ConsUtils::pop(_s); - MCHandle h2 = ConsUtils::pop(_s); + MCHandle h1 = pop(_s); + MCHandle h2 = pop(_s); - ConsUtils::push(_s, ConsUtils::cons(h1, h2)); + push(_s, cons(h1, h2)); break; } case Command::CommandNum::READCHAR: { char c; _instream >> c; - ConsUtils::push(_s, CURRENT_MC.load()->create_cell(c)); + push(_s, makeIntCell(c)); break; } case Command::CommandNum::PUTCHAR: { - _outstream << (char) dynamic_cast(*ConsUtils::pop(_s))._val; + _outstream << (char) val(pop(_s)); break; } case Command::CommandNum::PUTNUM: { - _outstream << dynamic_cast(*ConsUtils::pop(_s))._val; + _outstream << val(pop(_s)); break; } case Command::CommandNum::END: {