#include #include #include #include #include #include using namespace std; typedef uint32_t value; #define INSTR_CONDITIONAL_MOVE 0 #define INSTR_ARRAY_INDEX 1 #define INSTR_ARRAY_AMENDMEND 2 #define INSTR_ADDITION 3 #define INSTR_MULTIPLICATION 4 #define INSTR_DIVISION 5 #define INSTR_NOT_AND 6 #define INSTR_HALT 7 #define INSTR_ALLOCATION 8 #define INSTR_ABANDONMENT 9 #define INSTR_OUTPUT 10 #define INSTR_INPUT 11 #define INSTR_LOAD 12 #define INSTR_ORTHOGRAPHY 13 vector load_module(char *filename) { FILE * fd; unsigned char buf[4096]; size_t len; vector code; fd = fopen(filename, "rb"); while ((len = fread(buf, sizeof(unsigned char), 4096, fd)) > 0) { for (size_t i = 0; i < (len / 4); i++) { value ins = ( ((value)buf[4*i] << 24) | ((value)buf[4*i + 1] << 16) | ((value)buf[4*i + 2] << 8) | (value)buf[4*i + 3]); code.push_back(ins); } } fclose(fd); return code; } #define A (regs[a]) #define B (regs[b]) #define C (regs[c]) void interpret(vector code) { value regs[8] = {0, 0, 0, 0, 0, 0, 0, 0}; vector > array_environment; array_environment.reserve(10000); array_environment.push_back(code); list free_list; value pc = 0; while (true) { value ins = code[pc++]; value op = ins >> 28; value c = ins & 7; value b = (ins >> 3) & 7; value a = (ins >> 6) & 7; //printf("pc: %d\tpat: %d\t op: %d \ta: %d\tb: %d\tc: %d\n", // pc - code - 1, pc[-1], op, a, b, c); switch (op) { case INSTR_CONDITIONAL_MOVE: if (C != 0) A = B; break; case INSTR_ARRAY_INDEX: if (B == 0) { A = code[C]; } else { A = array_environment[B][C]; } break; case INSTR_ARRAY_AMENDMEND: if (A == 0) { code[B] = C; } else { array_environment[A][B] = C; } break; case INSTR_ADDITION: A = B + C; break; case INSTR_MULTIPLICATION: A = B * C; break; case INSTR_DIVISION: A = B / C; break; case INSTR_NOT_AND: A = ~(B & C); break; case INSTR_HALT: exit(0); case INSTR_ALLOCATION: { if (free_list.empty()) { vector empty(C, 0); array_environment.push_back(empty); B = array_environment.size() - 1; } else { value loc = free_list.front(); free_list.pop_front(); array_environment[loc].resize(C, 0); B = loc; } } break; case INSTR_ABANDONMENT: { // No other way to empty it and remove storage // Not required { vector & temp = array_environment[C]; if (temp.size() > 20) { vector().swap(temp); } else { temp.clear(); } free_list.push_front(C); } } break; case INSTR_OUTPUT: putchar(C); break; case INSTR_INPUT: C = getchar(); break; case INSTR_LOAD: if (B != 0) { code = array_environment[B]; } pc = C; break; case INSTR_ORTHOGRAPHY: a = (ins >> 25) & 7; A = ins & ((1 << 25) - 1); break; default: printf("Unimplemented instruction %d\n", op); exit(0); } } } int main(int argc, char ** argv) { vector code = load_module(argv[1]); interpret(code); return 0; }