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