diff --git a/SDA.c b/SDA.c index ff50bd2..2ea0509 100644 --- a/SDA.c +++ b/SDA.c @@ -4,17 +4,17 @@ #ifndef SDA #define SDA #include - +#include "stackslot.c" struct sda { int *size; - unsigned int *sda; + ObjRef *sda; }; -unsigned int getSDA(int i, struct sda s) { +ObjRef getSDA(int i, struct sda s) { return s.sda[i]; } -void setSDA(int point, int val, struct sda s) { +void setSDA(int point, ObjRef val, struct sda s) { s.sda[point] = val; } diff --git a/consts.c b/consts.c index 348d59a..f9e447a 100644 --- a/consts.c +++ b/consts.c @@ -1,6 +1,6 @@ #ifndef CONSTS #define CONSTS -#define VERSION 8 +#define VERSION 5 #endif /* ifndef CONSTS #define CONSTS diff --git a/nja/nja5 b/nja/nja5 index 1e6a1ce..67ee60f 100755 Binary files a/nja/nja5 and b/nja/nja5 differ diff --git a/njvm.c b/njvm.c index 70902b1..51b9bab 100644 --- a/njvm.c +++ b/njvm.c @@ -1,4 +1,5 @@ #include +#include #include #include "instruktion.c" #include "code.c" @@ -6,16 +7,17 @@ #include "program.c" #include "codeReader.c" #include "SDA.c" +#include "reg.c" // Debug -int debug = 0; +int debug = 1; // Stack struct stack stack; #define SIZE 1000 //Register -struct stack reg; +struct reg reg; // Program struct program program; @@ -37,73 +39,74 @@ void execute(struct program program) { int intInput; unsigned int temp; char charInput; + StackSlot tempSlot; for (i = 0; i < *program.size; ++i) { if (debug == 1) printf("=== DEBUG: Stack before instruction %i ===\n", i); if (debug == 1) printStack(stack, fp); if (debug == 1) printf("=== DEBUG: Instruction %i ===\n", 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]))); + push(stack, stackSlotWithObjRef(getIntObj(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)); + if (debug == 1) printf("add: %i + %i\n", * (int *)peek(stack, 2).u.objRef->data, * (int *)peek(stack, 1).u.objRef); + push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) + getIntValfromStackSlot(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); + temp = getIntValfromStackSlot(pop(stack)); + push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(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)); + push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) * getIntValfromStackSlot(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); + temp = getIntValfromStackSlot(pop(stack)); + push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(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); + temp = getIntValfromStackSlot(pop(stack)); + push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack))))); break; case RDINT: if (debug == 1) printf("rdint\n"); scanf("%i", &intInput); - push(stack, intInput); + push(stack, stackSlotWithObjRef(getIntObj(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)); + printf("%i", getIntValfromStackSlot(pop(stack))); break; case RDCHR: if (debug == 1) printf("rdchr\n"); scanf("%c", &charInput); - push(stack, charInput); + push(stack, stackSlotWithObjRef(getIntObj(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)); + printf("%c", getIntValfromStackSlot(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)); + push(stack, stackSlotWithObjRef(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); + setSDA(SIGN_EXTEND(IMMEDIATE(program.program[i])), pop(stack).u.objRef, sda); break; case ASF: if (debug == 1) printf("asf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); - push(stack, fp); + push(stack, stackSlotWitchNumber(fp)); fp = *stack.current; *stack.current = *stack.current + SIGN_EXTEND(IMMEDIATE(program.program[i])); break; @@ -111,7 +114,8 @@ void execute(struct program program) { if (debug == 1) printf("rsf: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); *stack.current = fp; if (debug == 1) printf("pop: %i\n", peek(stack, 1)); - fp = pop(stack); + tempSlot = pop(stack) ; + fp = getIntValfromStackSlot(tempSlot); break; case POPL: if (debug == 1) printf("popl: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); @@ -123,42 +127,42 @@ void execute(struct program program) { 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); + if (getIntValfromStackSlot(pop(stack)) != getIntValfromStackSlot(pop(stack))) push(stack, stackSlotWitchNumber(1)); + else push(stack, stackSlotWitchNumber(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); + if (getIntValfromStackSlot(pop(stack)) == getIntValfromStackSlot(pop(stack))) push(stack, stackSlotWitchNumber(1)); + else push(stack, stackSlotWitchNumber(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); + temp = getIntValfromStackSlot(pop(stack)); + if (getIntValfromStackSlot(pop(stack)) < temp) push(stack, stackSlotWitchNumber(1)); + else push(stack, stackSlotWitchNumber(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); + temp = getIntValfromStackSlot(pop(stack)); + if (getIntValfromStackSlot(pop(stack)) <= temp) push(stack, stackSlotWitchNumber(1)); + else push(stack, stackSlotWitchNumber(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); + temp = getIntValfromStackSlot(pop(stack)); + if (getIntValfromStackSlot(pop(stack)) > temp) push(stack, stackSlotWitchNumber(1)); + else push(stack, stackSlotWitchNumber(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); + temp = getIntValfromStackSlot(pop(stack)); + if (getIntValfromStackSlot(pop(stack)) >= temp) push(stack, stackSlotWitchNumber(1)); + else push(stack, stackSlotWitchNumber(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) { + if (getIntValfromStackSlot(pop(stack)) == 0) { i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1; if (debug == 1) printf("new i: %i\n", i); } @@ -166,7 +170,7 @@ void execute(struct program program) { 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) { + if (getIntValfromStackSlot(pop(stack)) == 1) { i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1; if (debug == 1) printf("new i: %i\n", i); } @@ -178,7 +182,7 @@ void execute(struct program program) { break; case CALL: if (debug == 1) printf("call: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); - push(stack, i); + push(stack, stackSlotWitchNumber(i)); if (debug == 1) printf("push: %i\n", i + 1); i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1; if (debug == 1) printf("new i: %i\n", i); @@ -186,23 +190,23 @@ void execute(struct program program) { case RET: if (debug == 1) printf("ret\n"); if (debug == 1) printf("pop: %i\n", peek(stack, 1)); - i = pop(stack); + i = getIntValfromStackSlot(pop(stack)); if (debug == 1) printf("new i: %i\n", i); break; case DROP: *stack.current = *stack.current - SIGN_EXTEND(IMMEDIATE(program.program[i])); break; case DUP: - temp = pop(stack); - push(stack, temp); - push(stack, temp); + temp = getIntValfromStackSlot(pop(stack)); + push(stack, stackSlotWitchNumber(temp)); + push(stack, stackSlotWitchNumber(temp)); break; case PUSHR: //TODO - push(reg, SIGN_EXTEND(IMMEDIATE(program.program[i]))); + pushR(reg, SIGN_EXTEND(IMMEDIATE(program.program[i]))); break; case POPR: - push(stack, pop(reg)); + push(stack, stackSlotWitchNumber(popR(reg))); break; } @@ -275,7 +279,7 @@ int main(int argc, char *argv[]) { if (run) { printf("Ninja Virtual Machine started\n"); - unsigned int s[sizeSDA]; + ObjRef s[sizeSDA]; sda.size = &sizeSDA; sda.sda = s; if (debug == 1) printProgram(program); diff --git a/programs/prog04.asm b/programs/prog04.asm new file mode 100644 index 0000000..a1fec33 --- /dev/null +++ b/programs/prog04.asm @@ -0,0 +1,32 @@ +// +// prog04.asm -- call/ret with args, and with ret value +// + + asf 3 + pushc 11 + wrint + pushc '\n' + wrchr + pushc 11 + pushc 33 + call proc + drop 2 + pushr + wrint + pushc '\n' + wrchr + pushc 33 + wrint + pushc '\n' + wrchr + rsf + halt + +proc: + asf 2 + pushl -3 + pushl -4 + sub + popr + rsf + ret diff --git a/reg.c b/reg.c new file mode 100755 index 0000000..65b3ce5 --- /dev/null +++ b/reg.c @@ -0,0 +1,49 @@ +// +// Created by Nils on 29.10.2023. +// +#ifndef REG +#define REG + +#include +#include + +struct reg { + int* size; + int* current; + unsigned int *stack; +}; + +void printStackR(struct reg stack, int fp) { + printf("Stack\nSize:\t\t%i\nCurrent:\t%i\n", *stack.size, *stack.current); + for (int i = 0; i < *stack.current; ++i) { + if(fp == i) printf("|FP|\n"); + printf("|%i|\n", stack.stack[i]); + } +} + +void pushR(struct reg s, unsigned int value) { + if (*s.current >= *s.size) { + printf("Stack Overflow\n"); + exit(EXIT_FAILURE); + } + s.stack[*s.current] = value; + *s.current=*s.current + 1; +} + +unsigned int popR(struct reg s) { + if (*s.current == 0) { + printf("Stack Underflow\n"); + exit(EXIT_FAILURE); + } + *s.current = *s.current -1; + return s.stack[*s.current]; +} + +unsigned int peekR(struct reg s, int steps) { + if (*s.current - steps < 0) { + printf("Stack Underflow\n"); + exit(EXIT_FAILURE); + } + return s.stack[*s.current - steps]; +} +#endif diff --git a/stack.c b/stack.c index 10feff0..f481085 100755 --- a/stack.c +++ b/stack.c @@ -6,11 +6,12 @@ #include #include +#include "stackslot.c" struct stack { int* size; int* current; - unsigned int *stack; + StackSlot *stack; }; void printStack(struct stack stack, int fp) { @@ -21,7 +22,7 @@ void printStack(struct stack stack, int fp) { } } -void push(struct stack s, unsigned int value) { +void push(struct stack s, StackSlot value) { if (*s.current >= *s.size) { printf("Stack Overflow\n"); exit(EXIT_FAILURE); @@ -30,7 +31,7 @@ void push(struct stack s, unsigned int value) { *s.current=*s.current + 1; } -unsigned int pop(struct stack s) { +StackSlot pop(struct stack s) { if (*s.current == 0) { printf("Stack Underflow\n"); exit(EXIT_FAILURE); @@ -39,7 +40,7 @@ unsigned int pop(struct stack s) { return s.stack[*s.current]; } -unsigned int peek(struct stack s, int steps) { +StackSlot peek(struct stack s, int steps) { if (*s.current - steps < 0) { printf("Stack Underflow\n"); exit(EXIT_FAILURE); diff --git a/stackslot.c b/stackslot.c new file mode 100644 index 0000000..5cbd04a --- /dev/null +++ b/stackslot.c @@ -0,0 +1,55 @@ +#include +#include +#include +#ifndef STACKSLOT +#define STACKSLOT +typedef int Object; +typedef struct { + unsigned int size; + unsigned char data[1]; +} *ObjRef; + +typedef struct{ + bool isObjRef; + union { + ObjRef objRef; + int number; + } u; +} StackSlot; + +ObjRef getIntObj(int val){ + ObjRef intObject; + unsigned int objSize = sizeof(unsigned int) + sizeof(int); + if ((intObject = malloc(objSize)) == NULL) { + perror("malloc"); + } + *(int *)intObject->data=val; + return intObject; +} +int getValFromIntObj(ObjRef iref){ + return *(int *)iref->data; +} +int getIntValfromStackSlot(StackSlot s){ + if(s.isObjRef){ + return *(int *)s.u.objRef->data; + } + return s.u.number; +} +void setValIntObj(ObjRef iref, int val){ + *(int *)iref->data=val; +} +StackSlot stackSlotWithObjRef(ObjRef val){ + StackSlot *stackSlot; + stackSlot=malloc(sizeof(StackSlot)); + stackSlot->isObjRef=true; + stackSlot->u.objRef=val; + return *stackSlot; +} +StackSlot stackSlotWitchNumber(int val){ + StackSlot *stackSlot; + stackSlot= malloc(sizeof(StackSlot)); + stackSlot->isObjRef=false; + stackSlot->u.number=val; + return *stackSlot; +} +#endif diff --git a/test.bin b/test.bin new file mode 100644 index 0000000..9a783d0 Binary files /dev/null and b/test.bin differ