/* Universal machine in C++ */ #include #include #include #include #include #include #include #include using namespace std; typedef unsigned int platter; typedef vector array; vector free_ids; array regs(8); vector arrays; unsigned int finger = 0; void interpret() { unsigned long v1, v2; int freeid; char ch; while (true) { const platter p = arrays[0][finger++]; // cout << "platter: " << p << endl; unsigned int instr = (p >> 28); unsigned int a = (p >> 6) & 7; unsigned int b = (p >> 3) & 7; unsigned int c = (p & 7); switch (instr) { case 0: if (regs[c]) regs[a] = regs[b]; break; case 1: regs[a] = (arrays[regs[b]])[regs[c]]; break; case 2: (arrays[regs[a]])[regs[b]] = regs[c]; break; case 3: regs[a] = (unsigned int) (regs[b] + regs[c]); break; case 4: regs[a] = (regs[b] * regs[c]); break; case 5: regs[a] = (unsigned int) floor(regs[b] / regs[c]); break; case 6: regs[a] = ~ (regs[b] & regs[c]); break; case 7: cout << "halting..." << endl; return; case 8: if (!free_ids.empty()) { freeid = free_ids.back(); free_ids.pop_back(); } else { freeid = arrays.size(); arrays.push_back(array()); } arrays[freeid] = array(regs[c]); regs[b] = freeid; break; case 9: free_ids.push_back(regs[c]); arrays[regs[c]].clear(); break; case 10: cout << (char) regs[c] << flush; break; case 11: ch = getchar(); //cout << "got: " << ch << endl; regs[c] = (unsigned int) ch; break; case 12: if (regs[b]) arrays[0] = arrays[regs[b]]; finger = regs[c]; break; case 13: a = (unsigned int) (p >> 25) & 7; regs[a] = (p & ((1 << 25) - 1)); break; } } } bool get_uint(ifstream &s, unsigned int &ui) { char c1,c2,c3,c4; s.get(c1); if (s.eof()) return false; s.get(c2); s.get(c3); s.get(c4); unsigned char uc1 = c1, uc2 = c2, uc3 = c3, uc4 = c4; ui = ((unsigned int) uc1 << 24) + ((unsigned int) uc2 << 16) + ((unsigned int) uc3 << 8) + (unsigned int) uc4; // cout << "read uint "<< ui << endl; return true; } void load(ifstream &from) { array array0; arrays.push_back(array0); platter p; while (get_uint(from, p)) array0.push_back(p); arrays[0] = array0; } int main(int argc, char **argv) { if (argc == 1) { ifstream from("codex.umz"); load(from); from.close(); } else if (argc > 1 && (strcmp(argv[1],"--") != 0)) { ifstream from(argv[1]); load(from); from.close(); } cerr << "Loaded" << endl; struct termios tc; tcgetattr(fileno(stdin),&tc); tc.c_lflag &= ~ICANON; // tc.c_lflag &= ~ECHO; tc.c_cc[VMIN] = 1; tc.c_cc[VTIME] = 0; tcsetattr(fileno(stdin),0,&tc); interpret(); return 0; }