#include #include #include "instruktion.c" #include "code.c" #include "stack.c" #include "program.c" #include "codeReader.c" #include "SDA.c" // Debug int debug = 0; // Stack struct stack stack; #define SIZE 1000 // Program struct program program; // SDA struct sda sda; unsigned fp; void version(void) { printf("Ninja Virtual Machine version %i (compiled %s, %s)\n", 0, __DATE__, __TIME__); } void help(void) { printf("Usage: ./njvm [options] \n\t--debug\tstart virtual machine in debug mode\n\t--version\tshow version and exit\n\t--help\t\tshow this help and exit\n"); } void execute(struct program program) { int i; int intInput; unsigned int temp; char charInput; for (i = 0; i < *program.size; ++i) { switch (program.program[i] >> 24) { case HALT: if (debug == 1) printf("halt\n"); goto end; case PUSHC: if (debug == 1) printf("pushc: %i\n", IMMEDIATE(program.program[i])); push(stack, SIGN_EXTEND(IMMEDIATE(program.program[i]))); break; case ADD: if (debug == 1) printf("add: %i + %i\n", peek(stack, 2), peek(stack, 1)); push(stack, pop(stack) + pop(stack)); break; case SUB: if (debug == 1) printf("sub: %i - %i\n", peek(stack, 2), peek(stack, 1)); temp = pop(stack); push(stack, pop(stack) - temp); break; case MUL: if (debug == 1) printf("mul: %i * %i\n", peek(stack, 2), peek(stack, 1)); push(stack, pop(stack) * pop(stack)); break; case DIV: if (debug == 1) printf("div: %i / %i\n", peek(stack, 2), peek(stack, 1)); temp = pop(stack); push(stack, pop(stack) / temp); break; case MOD: if (debug == 1) printf("mod: %i %% %i\n", peek(stack, 2), peek(stack, 1)); temp = pop(stack); push(stack, pop(stack) % temp); break; case RDINT: if (debug == 1) printf("rdint\n"); scanf("%i", &intInput); push(stack, intInput); if (debug == 1) printf("pushed %i\n", intInput); break; case WRINT: if (debug == 1) printf("wrint: %i\n", peek(stack, 1)); printf("%i", pop(stack)); break; case RDCHR: if (debug == 1) printf("rdchr\n"); scanf("%c", &charInput); push(stack, charInput); if (debug == 1) printf("pushed %c\n", charInput); break; case WRCHR: if (debug == 1) printf("wrchr: %c\n", peek(stack, 1)); printf("%c", pop(stack)); break; case PUSHG: if (debug == 1) printf("pushg: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); push(stack, getSDA(SIGN_EXTEND(IMMEDIATE(program.program[i])), sda)); break; case POPG: if (debug == 1) printf("popg: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); setSDA(SIGN_EXTEND(IMMEDIATE(program.program[i])), pop(stack), sda); break; case ASF: if (debug == 1) printf("asf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); push(stack, *stack.current); fp = *stack.current; *stack.current = *stack.current + SIGN_EXTEND(IMMEDIATE(program.program[i])); break; case RSF: if (debug == 1) printf("rsf\n"); *stack.current = fp + 2; fp = pop(stack); case POPL: if (debug == 1) printf("popl: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); stack.stack[fp + SIGN_EXTEND(IMMEDIATE(program.program[i]))] = pop(stack); break; case PUSHL: if (debug == 1) printf("pushl: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); push(stack, stack.stack[fp + SIGN_EXTEND(IMMEDIATE(program.program[i]))]); break; case NE: if (debug == 1) printf("ne: %i != %i\n", peek(stack, 2), peek(stack, 1)); if (pop(stack) != pop(stack)) push(stack, 1); else push(stack, 0); break; case EQ: if (debug == 1) printf("eq: %i == %i\n", peek(stack, 2), peek(stack, 1)); if (pop(stack) == pop(stack)) push(stack, 1); else push(stack, 0); break; case LT: if (debug == 1) printf("lt: %i < %i\n", peek(stack, 2), peek(stack, 1)); temp = pop(stack); if (pop(stack) < temp) push(stack, 1); else push(stack, 0); break; case LE: if (debug == 1) printf("le: %i <= %i\n", peek(stack, 2), peek(stack, 1)); temp = pop(stack); if (pop(stack) <= temp) push(stack, 1); else push(stack, 0); break; case GT: if (debug == 1) printf("gt: %i > %i\n", peek(stack, 2), peek(stack, 1)); temp = pop(stack); if (pop(stack) > temp) push(stack, 1); else push(stack, 0); break; case GE: if (debug == 1) printf("ge: %i >= %i\n", peek(stack, 2), peek(stack, 1)); temp = pop(stack); if (pop(stack) >= temp) push(stack, 1); else push(stack, 0); break; case BRF: if (debug == 1) printf("brf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("pop: %i\n", peek(stack, 1)); if (pop(stack) == 0) { i = SIGN_EXTEND(IMMEDIATE(program.program[i])); if (debug == 1) printf("new i: %i\n", i); } break; case BRT: if (debug == 1) printf("brt: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); if (debug == 1) printf("pop: %i\n", peek(stack, 1)); if (pop(stack) == 1) { i = SIGN_EXTEND(IMMEDIATE(program.program[i])); if (debug == 1) printf("new i: %i\n", i); } case JMP: if (debug == 1) printf("jmp: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); i = SIGN_EXTEND(IMMEDIATE(program.program[i])); if (debug == 1) printf("new i: %i\n", i); break; } } end: return; } void tests(void) { } int main(int argc, char *argv[]) { // Initialize the Stack int size = SIZE; int current = 0; unsigned int s[SIZE]; stack.size = &size; stack.current = ¤t; stack.stack = s; // Initialize ProgrammSpeicher int psize = 1000; int saveProgram = 0; unsigned int p[1000]; program.size = &psize; program.program = p; program.saveProgram = &saveProgram; int run = 0; int sizeSDA; if (argc > 1) { for (int i = 1; i < argc; ++i) { if (strcmp(argv[i], "--debug") == 0) { debug = 1; } else if (strcmp(argv[i], "--version") == 0) { version(); return 0; } else if (strcmp(argv[i], "--help") == 0) { help(); return 0; } else { sizeSDA = fromFile(argv[i], program); run = 1; } } } if (debug) { tests(); } if (run) { unsigned int s[sizeSDA]; sda.size = &sizeSDA; sda.sda = s; if (debug == 1) printProgram(program); execute(program); } else { printf("Error: no code file specified\n"); return 1; } }