From 82d320137464359ab704e129a755ac5210379493 Mon Sep 17 00:00:00 2001 From: Elias Bennour Date: Thu, 18 Jan 2024 18:53:46 +0100 Subject: [PATCH] add bigint to execute --- Makefile | 48 +++++--------------------- consts.c | 2 +- njvm.c | 102 +++++++++++++++++++++++++++++++++---------------------- njvm.o | Bin 46360 -> 46408 bytes 4 files changed, 71 insertions(+), 81 deletions(-) diff --git a/Makefile b/Makefile index 452f957..71dc1c1 100644 --- a/Makefile +++ b/Makefile @@ -1,43 +1,11 @@ # Makefile for a simple C program +build: + gcc -g -Wall -Ibigint/build/include -o support.o -c support.c + gcc -g -Wall -Ibigint/build/include -o njvm.o -c njvm.c + gcc -g -Wall -Lbigint/build/lib -o njvm njvm.o support.o -lbigint -# Compiler -CC = gcc +run: build + ./njvm programs/prog1.bin -# program to Run -F = programs/prog1.bin - -# Compiler flags -CFLAGS = -g -Wall -Ibigint/build/include - -LDFLAGS = -g -Wall -Lbigint/build/lib - -# Source file -SRC = njvm.c - -# Executable name -TARGET = njvm - -njvm.o: - $(CC) $(CFLAGS) -o njvm.o -c njvm.c - -support.o: - $(CC) $(CFLAGS) -o support.o -c support.c - -# Default target -all: njvm.o support.o - $(CC) $(LDFLAGS) -o $(TARGET) njvm.o support.o -lbigint -# Clean up -clean: - rm -f $(OBJ) $(TARGET) - -debug: all - ./$(TARGET) --debug $(F) - -run: all - ./$(TARGET) $(F) - -nja: ./nja/nja$(V) - ./nja/nja$(V) $(IN) $(OUT) - -njc: ./njc/njc$(V) - ./njc/njc$(V) $(IN) $(OUT) +debug: build + ./njvm --debug prog.bin \ No newline at end of file diff --git a/consts.c b/consts.c index f9e447a..efb7fc7 100644 --- a/consts.c +++ b/consts.c @@ -1,6 +1,6 @@ #ifndef CONSTS #define CONSTS -#define VERSION 5 +#define VERSION 2 #endif /* ifndef CONSTS #define CONSTS diff --git a/njvm.c b/njvm.c index ecf1c1b..93fd6ce 100644 --- a/njvm.c +++ b/njvm.c @@ -44,7 +44,6 @@ void help(void) { void execute(struct program program) { int i; - int intInput; unsigned int temp; char charInput; StackSlot tempSlot; @@ -57,44 +56,54 @@ void execute(struct program program) { goto end; case PUSHC: if (debug == 1) printf("pushc: %i\n", IMMEDIATE(program.program[i])); - push(stack, stackSlotWithObjRef(getIntObj(SIGN_EXTEND(IMMEDIATE(program.program[i]))))); + bigFromInt(SIGN_EXTEND(IMMEDIATE(program.program[i]))); + push(stack, stackSlotWithObjRef(bip.res)); break; case ADD: if (debug == 1) printf("add: %i + %i\n", peek(stack, 2), peek(stack, 1)); - bip.op1 = pop(stack).u.objRef; bip.op2 = pop(stack).u.objRef; + bip.op1 = pop(stack).u.objRef; bigAdd(); push(stack, stackSlotWithObjRef(bip.res)); break; case SUB: if (debug == 1) printf("sub: %i - %i\n", peek(stack, 2), peek(stack, 1)); - temp = getIntValfromStackSlot(pop(stack)); - push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) - temp))); + bip.op2 = pop(stack).u.objRef; + bip.op1 = pop(stack).u.objRef; + bigSub(); + push(stack, stackSlotWithObjRef(bip.res)); break; case MUL: if (debug == 1) printf("mul: %i * %i\n", peek(stack, 2), peek(stack, 1)); - push(stack, stackSlotWithObjRef( - getIntObj(getIntValfromStackSlot(pop(stack)) * getIntValfromStackSlot(pop(stack))))); + bip.op2 = pop(stack).u.objRef; + bip.op1 = pop(stack).u.objRef; + bigMul(); + push(stack, stackSlotWithObjRef(bip.res)); break; case DIV: if (debug == 1) printf("div: %i / %i\n", peek(stack, 2), peek(stack, 1)); - temp = getIntValfromStackSlot(pop(stack)); - push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack)) / temp))); + bip.op2 = pop(stack).u.objRef; + bip.op1 = pop(stack).u.objRef; + bigDiv(); + push(stack, stackSlotWithObjRef(bip.res)); break; case MOD: if (debug == 1) printf("mod: %i %% %i\n", peek(stack, 2), peek(stack, 1)); - temp = getIntValfromStackSlot(pop(stack)); - push(stack, stackSlotWithObjRef(getIntObj(getIntValfromStackSlot(pop(stack))))); + bip.op2 = pop(stack).u.objRef; + bip.op1 = pop(stack).u.objRef; + bigDiv(); + push(stack, stackSlotWithObjRef(bip.rem)); break; case RDINT: if (debug == 1) printf("rdint\n"); - scanf("%i", &intInput); - push(stack, stackSlotWithObjRef(getIntObj(intInput))); - if (debug == 1) printf("pushed %i\n", intInput); + bigRead(stdin); + push(stack, stackSlotWithObjRef(bip.res)); + if (debug == 1) printf("pushed %i\n", peek(stack, 1)); break; case WRINT: if (debug == 1) printf("wrint: %i\n", peek(stack, 1)); - printf("%i", getIntValfromStackSlot(pop(stack))); + bip.op1 = pop(stack).u.objRef; + bigPrint(stdout); break; case RDCHR: if (debug == 1) printf("rdchr\n"); @@ -104,7 +113,8 @@ void execute(struct program program) { break; case WRCHR: if (debug == 1) printf("wrchr: %c\n", peek(stack, 1)); - printf("%c", getIntValfromStackSlot(pop(stack))); + bip.op1 = pop(stack).u.objRef; + printf("%c", bigToInt()); break; case PUSHG: if (debug == 1) printf("pushg: %i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); @@ -137,58 +147,70 @@ void execute(struct program program) { break; case NE: if (debug == 1) printf("ne: %i != %i\n", peek(stack, 2), peek(stack, 1)); - if (getIntValfromStackSlot(pop(stack)) != getIntValfromStackSlot(pop(stack))) push(stack, - stackSlotWithObjRef( - getIntObj( - 1))); - else push(stack, stackSlotWithObjRef(getIntObj(0))); + bip.op2 = pop(stack).u.objRef; + bip.op1 = pop(stack).u.objRef; + if (bigCmp() != 0) push(stack, stackSlotWithObjRef(getIntObj(true))); + else push(stack, stackSlotWithObjRef(getIntObj(false))); break; case EQ: if (debug == 1) printf("eq: %i == %i\n", peek(stack, 2), peek(stack, 1)); - if (getIntValfromStackSlot(pop(stack)) == getIntValfromStackSlot(pop(stack))) push(stack, - stackSlotWithObjRef( - getIntObj( - 1))); - else push(stack, stackSlotWithObjRef(getIntObj(0))); + bip.op2 = pop(stack).u.objRef; + bip.op1 = pop(stack).u.objRef; + if (bigCmp() == 0) push(stack, stackSlotWithObjRef(getIntObj(true))); + else push(stack, stackSlotWithObjRef(getIntObj(false))); break; case LT: if (debug == 1) printf("lt: %i < %i\n", peek(stack, 2), peek(stack, 1)); - temp = getIntValfromStackSlot(pop(stack)); - if (getIntValfromStackSlot(pop(stack)) < temp) push(stack, stackSlotWithObjRef(getIntObj(1))); - else push(stack, stackSlotWithObjRef(getIntObj(0))); + bip.op2 = pop(stack).u.objRef; + bip.op1 = pop(stack).u.objRef; + if (bigCmp() < 0) push(stack, stackSlotWithObjRef(getIntObj(true))); + else push(stack, stackSlotWithObjRef(getIntObj(false))); break; case LE: if (debug == 1) printf("le: %i <= %i\n", peek(stack, 2), peek(stack, 1)); - temp = getIntValfromStackSlot(pop(stack)); - if (getIntValfromStackSlot(pop(stack)) <= temp) push(stack, stackSlotWithObjRef(getIntObj(1))); - else push(stack, stackSlotWithObjRef(getIntObj(0))); + bip.op2 = pop(stack).u.objRef; + bip.op1 = pop(stack).u.objRef; + if (bigCmp() <= 0) push(stack, stackSlotWithObjRef(getIntObj(true))); + else push(stack, stackSlotWithObjRef(getIntObj(false))); break; case GT: if (debug == 1) printf("gt: %i > %i\n", peek(stack, 2), peek(stack, 1)); - temp = getIntValfromStackSlot(pop(stack)); - if (getIntValfromStackSlot(pop(stack)) > temp) push(stack, stackSlotWithObjRef(getIntObj(1))); - else push(stack, stackSlotWithObjRef(getIntObj(0))); + bip.op2 = pop(stack).u.objRef; + bip.op1 = pop(stack).u.objRef; + if (bigCmp() > 0) push(stack, stackSlotWithObjRef(getIntObj(true))); + else push(stack, stackSlotWithObjRef(getIntObj(false))); break; case GE: if (debug == 1) printf("ge: %i >= %i\n", peek(stack, 2), peek(stack, 1)); - temp = getIntValfromStackSlot(pop(stack)); - if (getIntValfromStackSlot(pop(stack)) >= temp) push(stack, stackSlotWithObjRef(getIntObj(1))); - else push(stack, stackSlotWithObjRef(getIntObj(0))); + bip.op2 = pop(stack).u.objRef; + bip.op1 = pop(stack).u.objRef; + if (bigCmp() >= 0) push(stack, stackSlotWithObjRef(getIntObj(true))); + else push(stack, stackSlotWithObjRef(getIntObj(false))); 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 (getIntValfromStackSlot(pop(stack)) == 0) { + bip.op1 = pop(stack).u.objRef; + int b = bigToInt(); + if (b == false) { i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1; if (debug == 1) printf("new i: %i\n", i); + } else if (b != true) { + printf("Error: brf: %i\n", b); + exit(EXIT_FAILURE); } 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 (getIntValfromStackSlot(pop(stack)) == 1) { + bip.op1 = pop(stack).u.objRef; + b = bigToInt(); + if (b == true) { i = SIGN_EXTEND(IMMEDIATE(program.program[i])) - 1; if (debug == 1) printf("new i: %i\n", i); + } else if (b != false) { + printf("Error: brt: %i\n", b); + exit(EXIT_FAILURE); } break; case JMP: diff --git a/njvm.o b/njvm.o index d790adbd311699fe2488f46c48f7b33d4655ad9f..293f4ac25964fbc283796193815182c37eb28c19 100644 GIT binary patch delta 17753 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 C0h1*F delta 17822 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 f*v&8g!?WPlva&_DH@v=QoXb5RyWz)|CW-$C