renamed _stack to _values, to make a clearer distinction between value and call stacks
This commit is contained in:
parent
6fe4894c70
commit
d1c4106bba
234
interpreter.cpp
234
interpreter.cpp
@ -20,7 +20,7 @@ int to_int(const std::string& val) {
|
|||||||
|
|
||||||
void interpreter::reset() {
|
void interpreter::reset() {
|
||||||
_prog.clear();
|
_prog.clear();
|
||||||
_stack.clear();
|
_values.clear();
|
||||||
_labels.clear();
|
_labels.clear();
|
||||||
_vars.clear();
|
_vars.clear();
|
||||||
_calls.clear();
|
_calls.clear();
|
||||||
@ -52,36 +52,36 @@ std::string interpreter::eval(std::istream& in, bool& done) {
|
|||||||
|
|
||||||
// check literal int
|
// check literal int
|
||||||
if (std::isdigit(code[0])) {
|
if (std::isdigit(code[0])) {
|
||||||
_stack.push_back(code);
|
_values.push_back(code);
|
||||||
_pc++;
|
_pc++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check literal string
|
// check literal string
|
||||||
if (code[0] == '\\') {
|
if (code[0] == '\\') {
|
||||||
_stack.push_back(code.substr(1));
|
_values.push_back(code.substr(1));
|
||||||
_pc++;
|
_pc++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check label ref
|
// check label ref
|
||||||
if (code[0] == '>') {
|
if (code[0] == '>') {
|
||||||
_stack.push_back(code.substr(1));
|
_values.push_back(code.substr(1));
|
||||||
_pc++;
|
_pc++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check var assignment
|
// check var assignment
|
||||||
if (code[0] == '=') {
|
if (code[0] == '=') {
|
||||||
_vars[code.substr(1)] = _stack.back();
|
_vars[code.substr(1)] = _values.back();
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_pc++;
|
_pc++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check var ref
|
// check var ref
|
||||||
if (code[0] == '$') {
|
if (code[0] == '$') {
|
||||||
_stack.push_back(_vars[code.substr(1)]);
|
_values.push_back(_vars[code.substr(1)]);
|
||||||
_pc++;
|
_pc++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -90,8 +90,8 @@ std::string interpreter::eval(std::istream& in, bool& done) {
|
|||||||
exec_instruction(code, done);
|
exec_instruction(code, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_stack.size()) {
|
if (_values.size()) {
|
||||||
result = _stack.back();
|
result = _values.back();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -137,136 +137,136 @@ void interpreter::exec_instruction(const std::string& code, bool& done) {
|
|||||||
// integer operations -----------------------------------------------------
|
// integer operations -----------------------------------------------------
|
||||||
|
|
||||||
void interpreter::add() {
|
void interpreter::add() {
|
||||||
int val2 {to_int(_stack.back())};
|
int val2 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val1 {to_int(_stack.back())};
|
int val1 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.push_back(std::to_string(val1 + val2));
|
_values.push_back(std::to_string(val1 + val2));
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::sub() {
|
void interpreter::sub() {
|
||||||
int val2 {to_int(_stack.back())};
|
int val2 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val1 {to_int(_stack.back())};
|
int val1 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.push_back(std::to_string(val1 - val2));
|
_values.push_back(std::to_string(val1 - val2));
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::mul() {
|
void interpreter::mul() {
|
||||||
int val2 {to_int(_stack.back())};
|
int val2 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val1 {to_int(_stack.back())};
|
int val1 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.push_back(std::to_string(val1 * val2));
|
_values.push_back(std::to_string(val1 * val2));
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::div() {
|
void interpreter::div() {
|
||||||
int val2 {to_int(_stack.back())};
|
int val2 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val1 {to_int(_stack.back())};
|
int val1 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.push_back(std::to_string(val1 / val2));
|
_values.push_back(std::to_string(val1 / val2));
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::mod() {
|
void interpreter::mod() {
|
||||||
int val2 {to_int(_stack.back())};
|
int val2 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val1 {to_int(_stack.back())};
|
int val1 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.push_back(std::to_string(val1 % val2));
|
_values.push_back(std::to_string(val1 % val2));
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::abs() {
|
void interpreter::abs() {
|
||||||
int val {to_int(_stack.back())};
|
int val {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.push_back(std::to_string(val < 0 ? -val : val));
|
_values.push_back(std::to_string(val < 0 ? -val : val));
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::neg() {
|
void interpreter::neg() {
|
||||||
int val {to_int(_stack.back())};
|
int val {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.push_back(std::to_string(-val));
|
_values.push_back(std::to_string(-val));
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::inc() {
|
void interpreter::inc() {
|
||||||
int val {to_int(_stack.back()) + 1};
|
int val {to_int(_values.back()) + 1};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.push_back(std::to_string(val));
|
_values.push_back(std::to_string(val));
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::dec() {
|
void interpreter::dec() {
|
||||||
int val {to_int(_stack.back()) - 1};
|
int val {to_int(_values.back()) - 1};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.push_back(std::to_string(val));
|
_values.push_back(std::to_string(val));
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// string operations ------------------------------------------------------
|
// string operations ------------------------------------------------------
|
||||||
|
|
||||||
void interpreter::dup() {
|
void interpreter::dup() {
|
||||||
_stack.push_back(_stack.back());
|
_values.push_back(_values.back());
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::rev() {
|
void interpreter::rev() {
|
||||||
std::string val {_stack.back()};
|
std::string val {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
std::string result;
|
std::string result;
|
||||||
for (auto it = val.rbegin(); it != val.rend(); ++it) {
|
for (auto it = val.rbegin(); it != val.rend(); ++it) {
|
||||||
result += *it;
|
result += *it;
|
||||||
}
|
}
|
||||||
_stack.push_back(result);
|
_values.push_back(result);
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::slc() {
|
void interpreter::slc() {
|
||||||
int to {to_int(_stack.back())};
|
int to {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int from {to_int(_stack.back())};
|
int from {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
std::string val {_stack.back()};
|
std::string val {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.push_back(val.substr(from, to - from));
|
_values.push_back(val.substr(from, to - from));
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::idx() {
|
void interpreter::idx() {
|
||||||
int idx {to_int(_stack.back())};
|
int idx {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
std::string val {_stack.back()};
|
std::string val {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
val = val[idx];
|
val = val[idx];
|
||||||
_stack.emplace_back(val);
|
_values.emplace_back(val);
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::cat() {
|
void interpreter::cat() {
|
||||||
std::string val2 {_stack.back()};
|
std::string val2 {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
std::string val1 {_stack.back()};
|
std::string val1 {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.emplace_back(val1 + val2);
|
_values.emplace_back(val1 + val2);
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::len() {
|
void interpreter::len() {
|
||||||
std::string val {_stack.back()};
|
std::string val {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
_stack.push_back(std::to_string(val.size()));
|
_values.push_back(std::to_string(val.size()));
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::rot() {
|
void interpreter::rot() {
|
||||||
std::string val {_stack.back()};
|
std::string val {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
std::transform(val.begin(), val.end(), val.begin(), [](char ch) -> char {
|
std::transform(val.begin(), val.end(), val.begin(), [](char ch) -> char {
|
||||||
if (ch >= 'a' && ch <= 'm') {
|
if (ch >= 'a' && ch <= 'm') {
|
||||||
return ch + 13;
|
return ch + 13;
|
||||||
@ -279,32 +279,32 @@ void interpreter::rot() {
|
|||||||
}
|
}
|
||||||
return ch;
|
return ch;
|
||||||
});
|
});
|
||||||
_stack.push_back(val);
|
_values.push_back(val);
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::enl() {
|
void interpreter::enl() {
|
||||||
std::string val {_stack.back()};
|
std::string val {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
val += '\n';
|
val += '\n';
|
||||||
_stack.push_back(val);
|
_values.push_back(val);
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tests & jumps ----------------------------------------------------------
|
// tests & jumps ----------------------------------------------------------
|
||||||
|
|
||||||
void interpreter::gto() {
|
void interpreter::gto() {
|
||||||
_pc = _labels[_stack.back()];
|
_pc = _labels[_values.back()];
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::geq() {
|
void interpreter::geq() {
|
||||||
std::string label {_stack.back()};
|
std::string label {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
std::string val2 {_stack.back()};
|
std::string val2 {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
std::string val1 {_stack.back()};
|
std::string val1 {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
if (val1 == val2) {
|
if (val1 == val2) {
|
||||||
_pc = _labels[label];
|
_pc = _labels[label];
|
||||||
} else {
|
} else {
|
||||||
@ -313,12 +313,12 @@ void interpreter::geq() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::gne() {
|
void interpreter::gne() {
|
||||||
std::string label {_stack.back()};
|
std::string label {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
std::string val2 {_stack.back()};
|
std::string val2 {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
std::string val1 {_stack.back()};
|
std::string val1 {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
if (val1 != val2) {
|
if (val1 != val2) {
|
||||||
_pc = _labels[label];
|
_pc = _labels[label];
|
||||||
} else {
|
} else {
|
||||||
@ -327,12 +327,12 @@ void interpreter::gne() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::glt() {
|
void interpreter::glt() {
|
||||||
std::string label {_stack.back()};
|
std::string label {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val2 {to_int(_stack.back())};
|
int val2 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val1 {to_int(_stack.back())};
|
int val1 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
if (val1 < val2) {
|
if (val1 < val2) {
|
||||||
_pc = _labels[label];
|
_pc = _labels[label];
|
||||||
} else {
|
} else {
|
||||||
@ -341,12 +341,12 @@ void interpreter::glt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::gle() {
|
void interpreter::gle() {
|
||||||
std::string label {_stack.back()};
|
std::string label {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val2 {to_int(_stack.back())};
|
int val2 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val1 {to_int(_stack.back())};
|
int val1 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
if (val1 <= val2) {
|
if (val1 <= val2) {
|
||||||
_pc = _labels[label];
|
_pc = _labels[label];
|
||||||
} else {
|
} else {
|
||||||
@ -355,12 +355,12 @@ void interpreter::gle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::ggt() {
|
void interpreter::ggt() {
|
||||||
std::string label {_stack.back()};
|
std::string label {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val2 {to_int(_stack.back())};
|
int val2 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val1 {to_int(_stack.back())};
|
int val1 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
if (val1 > val2) {
|
if (val1 > val2) {
|
||||||
_pc = _labels[label];
|
_pc = _labels[label];
|
||||||
} else {
|
} else {
|
||||||
@ -369,12 +369,12 @@ void interpreter::ggt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::gge() {
|
void interpreter::gge() {
|
||||||
std::string label {_stack.back()};
|
std::string label {_values.back()};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val2 {to_int(_stack.back())};
|
int val2 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
int val1 {to_int(_stack.back())};
|
int val1 {to_int(_values.back())};
|
||||||
_stack.pop_back();
|
_values.pop_back();
|
||||||
if (val1 >= val2) {
|
if (val1 >= val2) {
|
||||||
_pc = _labels[label];
|
_pc = _labels[label];
|
||||||
} else {
|
} else {
|
||||||
@ -399,16 +399,16 @@ void interpreter::ret() {
|
|||||||
void interpreter::inp() {
|
void interpreter::inp() {
|
||||||
std::string val;
|
std::string val;
|
||||||
std::cin >> val;
|
std::cin >> val;
|
||||||
_stack.push_back(val);
|
_values.push_back(val);
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::out() {
|
void interpreter::out() {
|
||||||
std::cout << _stack.back() << '\n';
|
std::cout << _values.back() << '\n';
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interpreter::err() {
|
void interpreter::err() {
|
||||||
std::cerr << _stack.back() << '\n';
|
std::cerr << _values.back() << '\n';
|
||||||
_pc++;
|
_pc++;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class interpreter {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> _prog; // program lines without label defs or comments
|
std::vector<std::string> _prog; // program lines without label defs or comments
|
||||||
std::vector<std::string> _stack; // value stack
|
std::vector<std::string> _values; // value stack
|
||||||
std::map<std::string, size_t> _labels; // label name => prog line index
|
std::map<std::string, size_t> _labels; // label name => prog line index
|
||||||
std::map<std::string, std::string> _vars; // var name => string value
|
std::map<std::string, std::string> _vars; // var name => string value
|
||||||
std::vector<size_t> _calls; // call stack
|
std::vector<size_t> _calls; // call stack
|
||||||
|
Loading…
x
Reference in New Issue
Block a user