switch for commands

This commit is contained in:
2024-01-04 11:31:07 +01:00
parent 04aa0d24b6
commit 9a7745c9e2
5 changed files with 269 additions and 210 deletions

View File

@@ -38,7 +38,7 @@ Handle Compiler::compile(const Handle &src, Handle fake_env, const Handle &suffi
return out;
};
std::function<Handle(Handle, Handle)> compileArgsList = [&](Handle args, Handle env) {
std::function<Handle(Handle, Handle)> compileArgsList = [&](Handle args, const Handle &env) {
Handle out;
out.append(make_cmd(NIL));
std::stack<Handle> rev;

View File

@@ -23,10 +23,8 @@ void VM::run() {
void VM::step() {
Handle poppedH = _c.pop();
// as to not complicate parser for tests...
CellValType poppedCmd = poppedH.type() == CellType::STRATOM ? str_to_cmd.at(poppedH.strval()) : poppedH.val();
Logger::log(
"VM",
[&](std::ostream &out) {
@@ -38,15 +36,24 @@ void VM::step() {
},
Logger::TRACE);
if (poppedCmd == NIL) {
switch (poppedCmd) {
case NIL: {
_s.push(nullptr);
} else if (poppedCmd == LDC) {
break;
}
case LDC: {
_s.push(_c.pop());
} else if (poppedCmd == ATOM) {
break;
}
case ATOM: {
_s.push(_s.pop().atom() ? 1 : 0);
} else if (poppedCmd == NILC) {
break;
}
case NILC: {
_s.push(_s.pop().null() ? 1 : 0);
} else if (poppedCmd == LD) {
break;
}
case LD: {
Handle poppedH2 = _c.pop();
int64_t frame = poppedH2.car().val();
@@ -64,7 +71,9 @@ void VM::step() {
for (int i = 1; i < arg; i++) { curArg = curArg.cdr(); }
_s.push(curArg.car());
} else if (poppedCmd == SEL) {
break;
}
case SEL: {
Handle popped2H = _s.pop();
Handle ct = _c.pop();
@@ -76,11 +85,17 @@ void VM::step() {
} else {
_c = cf;
}
} else if (poppedCmd == JOIN) {
break;
}
case JOIN: {
_c = _d.pop();
} else if (poppedCmd == LDF) {
break;
}
case LDF: {
_s.push(Handle::cons(_c.pop(), _e));
} else if (poppedCmd == AP) {
break;
}
case AP: {
Handle closureH = _s.pop();
Handle argsH = _s.pop();
@@ -91,7 +106,8 @@ void VM::step() {
std::optional<std::string> name;
if (Logger::en_level("VM", Logger::DEBUG)) {
name = "unknown";
if (_globals_names_map.find(closureH) != _globals_names_map.end()) name = _globals_names_map.at(closureH);
if (_globals_names_map.find(closureH) != _globals_names_map.end())
name = _globals_names_map.at(closureH);
_d.push(Handle(*name));
}
@@ -111,7 +127,9 @@ void VM::step() {
_cur_call_level++;
_e.push(argsH);
} else if (poppedCmd == RET) {
break;
}
case RET: {
_cur_call_level--;
Handle n;
@@ -141,9 +159,13 @@ void VM::step() {
Logger::DEBUG);
_s.push(ret);
} else if (poppedCmd == DUM) {
break;
}
case DUM: {
_e.push(nullptr);
} else if (poppedCmd == RAP) {
break;
}
case RAP: {
Handle closureH = _s.pop();
Handle argsH = _s.pop();
@@ -166,48 +188,78 @@ void VM::step() {
_e.push(argsH);
fnEnv.setcar(argsH);
} else if (poppedCmd == STOP) {
break;
}
case STOP: {
_stop = true;
} else if (poppedCmd == ADD) {
break;
}
case ADD: {
_s.push(_s.pop().val() + _s.pop().val());
} else if (poppedCmd == MULT) {
break;
}
case MULT: {
_s.push(_s.pop().val() * _s.pop().val());
} else if (poppedCmd == SUB) {
break;
}
case SUB: {
CellValType a1 = _s.pop().val();
CellValType a2 = _s.pop().val();
_s.push(a1 - a2);
} else if (poppedCmd == DIV) {
break;
}
case DIV: {
CellValType a1 = _s.pop().val();
CellValType a2 = _s.pop().val();
_s.push(a1 / a2);
} else if (poppedCmd == EQ) {
break;
}
case EQ: {
_s.push(_s.pop() == _s.pop() ? 1 : 0);
} else if (poppedCmd == LT) {
break;
}
case LT: {
CellValType a1 = _s.pop().val();
CellValType a2 = _s.pop().val();
_s.push(a1 < a2 ? 1 : 0);
} else if (poppedCmd == GT) {
break;
}
case GT: {
CellValType a1 = _s.pop().val();
CellValType a2 = _s.pop().val();
_s.push(a1 > a2 ? 1 : 0);
} else if (poppedCmd == CAR) {
break;
}
case CAR: {
_s.push(_s.pop().car());
} else if (poppedCmd == CDR) {
break;
}
case CDR: {
_s.push(_s.pop().cdr());
} else if (poppedCmd == CONS) {
break;
}
case CONS: {
Handle h1 = _s.pop();
Handle h2 = _s.pop();
_s.push(Handle::cons(h1, h2));
} else if (poppedCmd == READCHAR) {
break;
}
case READCHAR: {
char c;
_instream >> c;
_s.push(Handle::makeNumCell(c));
} else if (poppedCmd == PUTCHAR) {
break;
}
case PUTCHAR: {
_outstream << (char) _s.pop().val();
} else if (poppedCmd == PUTNUM) {
break;
}
case PUTNUM: {
_outstream << _s.pop().val();
} else if (poppedCmd == EVAL) {
break;
}
case EVAL: {
Handle code = _s.pop();
Handle newc = Compiler::compile(code, _globals_names);
Logger::log(
@@ -220,7 +272,9 @@ void VM::step() {
Logger::DEBUG);
newc.splice(_c);
_c = newc;
} else if (poppedCmd == LDG) {
break;
}
case LDG: {
Handle newclosure = Handle::cons(_c.pop(), _e);
Handle curName = _globals_names.car();
@@ -229,7 +283,9 @@ void VM::step() {
_cur_global++;
_globals_vals.append(newclosure);
} else if (poppedCmd == PRINT) {
break;
}
case PRINT: {
if (!_s.null()) {
Handle val = _s.pop();
bool cons = !val.atom();
@@ -238,14 +294,16 @@ void VM::step() {
if (cons) _outstream << ")";
_outstream << std::endl;
}
} else if (poppedCmd == READ) {
break;
}
case READ: {
std::string read;
std::getline(_instream, read);
_s.push(Parser::parse_str(read));
} else {
throw std::invalid_argument("Unexpected end of program");
}
default:
throw std::invalid_argument("Unknown command: " + std::to_string(poppedCmd));
}
Logger::log(
"VM",

View File

@@ -13,6 +13,7 @@ public:
~Environment() override {}
void SetUp() override {
Options::set<size_t>("cell_limit", 50000);
Options::set<bool>("command_strs", true);
Logger::set_level("VM", Logger::DEBUG);
Logger::set_level("Compiler", Logger::DEBUG);

View File

@@ -7,7 +7,7 @@ public:
~Environment() override {}
void SetUp() override {
Options::set<size_t>("cell_limit", 1000);
Options::set<size_t>("cell_limit", 5000);
Logger::set_level("Compiler", Logger::DEBUG);
}

View File

@@ -8,7 +8,7 @@ public:
~Environment() override {}
void SetUp() override {
Options::set<size_t>("cell_limit", 2000);
Options::set<size_t>("cell_limit", 5000);
Logger::set_level("Compiler", Logger::DEBUG);
}