2016-04-04 03:14:35 -07:00
|
|
|
#include "thread.hpp"
|
|
|
|
|
2017-05-26 08:55:22 -07:00
|
|
|
Thread::Thread(std::shared_ptr<Canvas> c)
|
2016-04-04 03:14:35 -07:00
|
|
|
{
|
|
|
|
std::cerr << "Created new thread!" << std::endl;
|
|
|
|
cursor = new Cursor();
|
|
|
|
cursor->canvas = c;
|
|
|
|
}
|
|
|
|
|
2016-04-04 03:39:38 -07:00
|
|
|
Thread::~Thread()
|
|
|
|
{
|
|
|
|
std::cerr << "Deconstructing thread!" << std::endl;
|
|
|
|
|
|
|
|
state = ETS_DEAD;
|
|
|
|
if (cursor) {
|
|
|
|
delete cursor;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (!link.empty()) {
|
|
|
|
Cursor *c = link.top();
|
|
|
|
delete c;
|
|
|
|
link.pop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-04 03:14:35 -07:00
|
|
|
bool Thread::popCursor() {
|
|
|
|
delete cursor;
|
|
|
|
cursor = NULL;
|
|
|
|
|
|
|
|
if (link.empty()) {
|
|
|
|
std::cerr << "Popped cursor, end-of-LS" << std::endl;
|
|
|
|
state = ETS_DEAD;
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
cursor = link.top();
|
|
|
|
link.pop();
|
|
|
|
std::cerr << "Popped cursor, " << link.size()
|
|
|
|
<< " remaining in LS" << std::endl;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Thread::pushCursor(Cursor *nc) {
|
|
|
|
if (cursor) {
|
|
|
|
link.push(cursor);
|
|
|
|
}
|
|
|
|
cursor = nc;
|
|
|
|
state = ETS_READY;
|
|
|
|
std::cerr << "Pushed cursor!" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
char Thread::pop() {
|
|
|
|
if (stack.empty()) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
char retval = 0;
|
|
|
|
retval = stack.top();
|
|
|
|
stack.pop();
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
}
|
2016-04-04 03:08:54 -07:00
|
|
|
|
|
|
|
void Thread::step(VM *vm, std::map<int, Subroutine*> &srman)
|
|
|
|
{
|
|
|
|
assert(cursor);
|
|
|
|
assert(cursor->canvas);
|
|
|
|
char ch = getChar();
|
|
|
|
|
|
|
|
switch (state) {
|
|
|
|
case ETS_DEAD:
|
|
|
|
std::cerr << "Skipping stepping of dead thread." << std::endl;
|
|
|
|
break;
|
|
|
|
case ETS_READY: {
|
|
|
|
if (ch == '\"') {
|
|
|
|
std::cerr << "Enter string mode!" << std::endl;
|
|
|
|
state = ETS_STRING;
|
|
|
|
move();
|
|
|
|
} else if (ch == '`') {
|
|
|
|
std::cerr << "Enter numeric mode!" << std::endl;
|
|
|
|
state = ETS_NUMBER;
|
|
|
|
move();
|
|
|
|
} else {
|
|
|
|
int id = cursor->getOperator(ch);
|
|
|
|
if (id >= 0) {
|
|
|
|
// TODO: run operator
|
|
|
|
std::cerr << "Running " << ch << " which is subroutine " << id << std::endl;
|
|
|
|
auto it = srman.find(id);
|
|
|
|
if (it != srman.end()) {
|
|
|
|
it->second->run(vm, this);
|
|
|
|
} else {
|
|
|
|
state = ETS_DEAD;
|
|
|
|
std::cerr << "ERROR: Unable to find operator in memory: " << ch << std::endl;
|
|
|
|
}
|
|
|
|
} else if (ch == ' ') {
|
|
|
|
//std::cerr << "Move" << std::endl;
|
|
|
|
move();
|
|
|
|
} else {
|
|
|
|
state = ETS_DEAD;
|
|
|
|
std::cerr << "ERROR: Undefined operator: " << ch << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ETS_STRING: {
|
|
|
|
if (ch == '\"') {
|
|
|
|
std::cerr << "Exit string mode!" << std::endl;
|
|
|
|
state = ETS_READY;
|
|
|
|
} else {
|
|
|
|
std::cerr << "Push " << ch << std::endl;
|
|
|
|
stack.push(ch);
|
|
|
|
}
|
|
|
|
move();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
state = ETS_DEAD;
|
|
|
|
std::cerr << "ERROR: Cursor has invalid state." << std::endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|