#include #include #include #ifndef instruktion #include "instruktion.c" #endif /* ifndef instruktion */ #ifndef code #include "code.c" #endif /* ifndef code */ //Comment to disable debug #define DEBUG unsigned int* programmSpeicher; void copyToProgramm(unsigned int codeToCopy[]){ programmSpeicher = codeToCopy; } // Stack #define maxValues 1000 unsigned int stack[maxValues]; unsigned int current = 0; void stackPush(unsigned int value) { if (current > (maxValues-1)) { fprintf(stderr, "stack overflow\n"); exit(EXIT_FAILURE); } stack[current] = value; current++; } unsigned int stackPop(void) { if (current < 1) { fprintf(stderr, "stack underflow\n"); exit(EXIT_FAILURE); } return stack[--current]; } void version(void) { printf("Ninja Virtual Machine version %i (compiled %s, %s)\n", 0, __DATE__, __TIME__); } void help(void) { printf("usage: ./njvm [option] [option] ...\n\t--version\tshow version and exit\n\t--help\t\tshow this help and exit\n"); } void useption(int argc, char *argv[]) { if (argc > 1) { if (strcmp(argv[1], "--version") == 0) { version(); } else if (strcmp(argv[1], "--help") == 0) { help(); } else { printf("unknown command line argument '%s', try './njvm --help'", argv[1]); } } } void printProgramm(){ int i = 0; char c[10]; while (programmSpeicher[i] != 0) { switch (programmSpeicher[i] >> 24) { case PUSHC: strcpy(c,"pushc"); break; case ADD: strcpy(c,"add"); break; case SUB: strcpy(c,"sub"); break; case MUL: strcpy(c,"mul"); break; case DIV: strcpy(c,"div"); break; case MOD: strcpy(c,"mod"); break; case RDINT: strcpy(c,"rdint"); break; case WRINT: strcpy(c,"wrint"); break; case RDCHR: strcpy(c,"rdchr"); break; case WRCHR: strcpy(c,"wrchr"); break; default: strcpy(c,"halt"); break; } IMMEDIATE(programmSpeicher[i])? printf("%03i:\t%s\t%i\n",i,c,IMMEDIATE(programmSpeicher[i])) : printf("%03i:\t%s\n",i,c); i++; } printf("%03i:\thalt\n",i); } void execute(void) { int i = 0; int intInput; int temp; char charInput; while (1) { switch (programmSpeicher[i] >> 24) { case HALT: goto end; break; case PUSHC: stackPush(IMMEDIATE(programmSpeicher[i])); break; case ADD: stackPush(stackPop()+stackPop()); break; case SUB: temp = stackPop(); stackPush(stackPop() - temp); break; case MUL: stackPush(stackPop()*stackPop()); break; case DIV: temp = stackPop(); stackPush(stackPop()/temp); break; case MOD: temp = stackPop(); stackPush(stackPop()%temp); break; case RDINT: scanf("%i",&intInput); stackPush(intInput); break; case WRINT: printf("%i",stackPop()); break; case RDCHR: scanf("%c",&charInput); stackPush(charInput); break; case WRCHR: printf("%c",stackPop()); break; } i++; } end: return; } #ifdef DEBUG void printStack(void){ if(current >= 0) return; printf("----\n"); for (int i = 0; i < current; i++) { printf("|%i| \n",stack[i]); } printf("----\n"); } void tests(void){ printf("Runnig debug mode\n"); copyToProgramm(code1); printProgramm(); execute(); } #endif /* ifdef DEBUG */ int main(int argc, char *argv[]) { #ifdef DEBUG tests(); #endif /* ifdef DEBUG */ if (argc > 1) useption(argc, argv); else { // Started printf("Ninja Virtual Machine started\n"); // Stopped printf("Ninja Virtual Machine stopped\n"); return 0; } }