|
|
@ -1,4 +1,5 @@ |
|
|
|
#include <iostream>
|
|
|
|
#include <stack>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
@ -6,47 +7,48 @@ |
|
|
|
#include "error.hpp"
|
|
|
|
|
|
|
|
void Interpreter::run() { |
|
|
|
data_tape = std::vector<char>(30000, 0); // tape size from esolangs
|
|
|
|
jump = std::stack<int>(); |
|
|
|
|
|
|
|
// gamers, let's get this bread
|
|
|
|
for (unsigned long i = 0; i < prog.size(); i++) { |
|
|
|
this->processIndex(i); |
|
|
|
for (std::size_t i = 0; i < prog.size(); i++) { |
|
|
|
processIndex(i); |
|
|
|
|
|
|
|
if ((prog[i] == OpCode::LoopEnd) && (*ptr == '\0')) { // we might have to make a jump!
|
|
|
|
i = jumpTo[bracketStack-2]; // stack starts at 0
|
|
|
|
// also compensate for i++
|
|
|
|
if ((prog[i] == OpCode::LoopEnd) && (data_tape[ptr] == '\0')) { // we might have to make a jump!
|
|
|
|
i = jump.top(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (bracketStack != 0) { // levels of brackets don't match
|
|
|
|
if (!jump.empty()) { // levels of brackets don't match
|
|
|
|
throw ParseExcept(ErrType::BracketMismatch); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void Interpreter::processIndex(unsigned long index) { |
|
|
|
void Interpreter::processIndex(int index) { |
|
|
|
switch(prog[index]) { |
|
|
|
case OpCode::IncPtr: |
|
|
|
++ptr; |
|
|
|
break; |
|
|
|
case OpCode::DecPtr: |
|
|
|
--ptr; |
|
|
|
if (--ptr < 0) ptr = 0; // no negative indices
|
|
|
|
break; |
|
|
|
case OpCode::IncByte: |
|
|
|
++(*ptr); |
|
|
|
++data_tape[ptr]; |
|
|
|
break; |
|
|
|
case OpCode::DecByte: |
|
|
|
--(*ptr); |
|
|
|
--data_tape[ptr]; |
|
|
|
break; |
|
|
|
case OpCode::Write: |
|
|
|
std::cout << *ptr; |
|
|
|
std::cout << data_tape[ptr]; |
|
|
|
break; |
|
|
|
case OpCode::Read: |
|
|
|
std::cin >> *ptr; |
|
|
|
std::cin >> data_tape[ptr]; |
|
|
|
break; |
|
|
|
case OpCode::LoopBegin: |
|
|
|
jumpTo.push_back(index); |
|
|
|
bracketStack++; |
|
|
|
jump.push(index); |
|
|
|
break; |
|
|
|
case OpCode::LoopEnd: |
|
|
|
bracketStack--; // if we jump back, handled by above
|
|
|
|
jump.pop(); |
|
|
|
break; // handled in run()
|
|
|
|
default: |
|
|
|
break; // shouldn't be in here...
|
|
|
|