put more stuff in consutils

This commit is contained in:
2023-12-26 11:45:25 +01:00
parent 58f56f158d
commit 4513ec82aa
6 changed files with 74 additions and 71 deletions

View File

@@ -9,11 +9,12 @@
#include <cstdint>
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 {

View File

@@ -11,11 +11,13 @@
namespace ConsUtils {
static inline MCHandle car(const MCHandle &cell) { return dynamic_cast<ConsCell &>(*cell)._car; }
static inline MCHandle cdr(const MCHandle &cell) { return dynamic_cast<ConsCell &>(*cell)._cdr; }
static inline CellValType val(const MCHandle &cell) { return dynamic_cast<ValueCell &>(*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

View File

@@ -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:

View File

@@ -11,6 +11,7 @@
#include <vector>
#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;

View File

@@ -35,3 +35,7 @@ void ConsUtils::append(MCHandle to, const MCHandle &what) {
MCHandle ConsUtils::makeIntCell(int64_t val) {
return CURRENT_MC.load()->create_cell<ValueCell>(val);
}
void ConsUtils::setcar(const MCHandle &to, const MCHandle &car) {
dynamic_cast<ConsCell &>(*to)._car = car.get();
}

View File

@@ -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<ValueCell &>(*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<ConsCell &>(*poppedH2);
MCHandle poppedH2 = pop(_c);
int64_t frame = dynamic_cast<ValueCell &>(*popped2._car)._val;
int64_t arg = dynamic_cast<ValueCell &>(*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<ConsCell *>(_e.get());
assert(curFrame);
MCHandle curFrame = _e;
for (int i = 1; i < frame; i++) {
curFrame = dynamic_cast<ConsCell *>(curFrame->_cdr);
assert(curFrame);
curFrame = cdr(curFrame);
}
ConsCell *curArg = dynamic_cast<ConsCell *>(curFrame->_car);
assert(curArg);
MCHandle curArg = car(curFrame);
for (int i = 1; i < arg; i++) {
curArg = dynamic_cast<ConsCell *>(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<ValueCell &>(*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<ConsCell &>(*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<ValueCell &>(*ConsUtils::pop(_s))._val + dynamic_cast<ValueCell &>(*ConsUtils::pop(_s))._val;
ConsUtils::push(_s, CURRENT_MC.load()->create_cell<ValueCell>(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<ValueCell>(c));
push(_s, makeIntCell(c));
break;
}
case Command::CommandNum::PUTCHAR: {
_outstream << (char) dynamic_cast<ValueCell &>(*ConsUtils::pop(_s))._val;
_outstream << (char) val(pop(_s));
break;
}
case Command::CommandNum::PUTNUM: {
_outstream << dynamic_cast<ValueCell &>(*ConsUtils::pop(_s))._val;
_outstream << val(pop(_s));
break;
}
case Command::CommandNum::END: {