From 72ba208f49df2dab5c469846bf5445f5c41f53ed Mon Sep 17 00:00:00 2001 From: Maxime CARON <145995231+MaximeAlgosup@users.noreply.github.com> Date: Fri, 23 Feb 2024 00:28:18 +0100 Subject: [PATCH 1/7] Add goto action to vproc Add goto action to vproc when read goto instruction in binary --- src/vProc.c | 70 +++++++++++++++++++++++++++++++++++++++++++++---- src/vProc.h | 27 ++++++++++++++++++- src/vTerminal.c | 25 +----------------- 3 files changed, 92 insertions(+), 30 deletions(-) diff --git a/src/vProc.c b/src/vProc.c index 4b5b96b..f1c6095 100644 --- a/src/vProc.c +++ b/src/vProc.c @@ -2,7 +2,6 @@ This file is part of VAT2. This file contains the implementation of the virtual processor. */ -#include #include #include #include @@ -28,6 +27,33 @@ vRegister_t rg5 = {true, 0}; vRegister_t rg6 = {true, 0}; vRegister_t rg7 = {true, 0}; +bool readFile(char *filename, asm_error_t *errData){ + //Check if the file is present + FILE *file = fopen(filename, "rb"); + if(file == NULL){ + errorfnf(filename, errData); + } + // Run program + char line[LINE_MAX_BITS]; + + // Set as carry for action on next instruction + carry_t carry = {0, false}; + + int time = 0; + int lastTime = 0; + int latentTicks = 0; + while(fgets(line, LINE_MAX_BITS + 1, file)) { + setClock(time, lastTime, latentTicks); + instruction_t inst = charBinToInst(line); + if(!run(inst, &carry, file, filename, errData)){ + fclose(file); + return false; + } + } + fclose(file); + return true; +} + void setClock(int time, int lastTime, int latentTicks){ sleep(CLOCK_TICKS); ++latentTicks; @@ -47,9 +73,9 @@ instruction_t charBinToInst(char *bin){ instruction_t instruction = {0, 0, 0}; // Define masks for each field - unsigned int instMask = 0b11111; - unsigned int regMask = 0b111; - unsigned int argMask = 0b0000000011111111; + unsigned int instMask = 31; // 0b11111 + unsigned int regMask = 7; // 0b111 + unsigned int argMask = 255; // 0b0000000011111111 // Extract each field using bitwise AND and shift operations instruction.inst = (inst >> 11) & instMask; @@ -59,7 +85,7 @@ instruction_t charBinToInst(char *bin){ return instruction; } -bool run(instruction_t inst, carry_t *carry, asm_error_t *errData){ +bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_error_t *errData){ vRegister_t *reg; // check if there is a carry if(carry->isUsed && inst.inst != 24){ @@ -75,6 +101,11 @@ bool run(instruction_t inst, carry_t *carry, asm_error_t *errData){ reg->value = inst.arg; return true; case 1: //goto + fpos_t pos = searchLabel(inst.arg, filename, errData); + if(pos == -1){ + return false; + } + fsetpos(file, &pos); return true; case 2: //call return true; @@ -292,6 +323,35 @@ vRegister_t *getRegister(int reg){ } } +fpos_t searchLabel(int labId, char *filename, asm_error_t *errData){ + FILE *file = fopen(filename, "rb"); + if(file == NULL){ + errorfnf(filename, errData); + return 0; + } + char line[LINE_MAX_BITS]; + fpos_t pos; + while(fgets(line, LINE_MAX_BITS + 1, file)) { + if(line[0] == '1'){ + int inst = (int)strtoul(line, NULL, 2); + unsigned int instMask = 31; // 0b11111 + unsigned int argMask = 255; // 0b0000000011111111 + + int instId = (inst >> 11) & instMask; + int arg = inst & argMask; + + if(instId == 18 && arg == labId){ + fgetpos(file, &pos); + fclose(file); + return pos; + } + } + } + fclose(file); + return -1; +} + + bool opAdd(vRegister_t *reg, unsigned int arg, asm_error_t *errData){ if(reg->writable){ reg->value += arg; diff --git a/src/vProc.h b/src/vProc.h index 231a733..606160d 100644 --- a/src/vProc.h +++ b/src/vProc.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -35,6 +36,17 @@ typedef struct { } vProcVar_t; +/* + Read a file + params: + char *filename: the file to read + asm_error_t *errData: Error history + returns: + bool: if the file have been read +*/ +bool readFile(char *filename, asm_error_t *errData); + + /* Set the speed of the clock based on ticks params: @@ -59,11 +71,13 @@ instruction_t charBinToInst(char *bin); params: instruction_t inst: the instruction to redirect to carry_t *carry: Carry for action on next instruction + FILE *file: File to write the output + char *filename: the filename of the file asm_error_t *errData: Error history returns: bool: if the instructions have been run */ -bool run(instruction_t inst, carry_t *carry, asm_error_t *errData); +bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_error_t *errData); /* Run interrupt operation @@ -85,6 +99,17 @@ bool runInt(instruction_t inst, carry_t *carry, asm_error_t *errData); */ vRegister_t *getRegister(int reg); +/* + Search label position in a file + params: + int labId: the label to search + char *filename: the filename of the file + asm_error_t *errData: Error history + returns: + fpos_t: the position of the label +*/ +fpos_t searchLabel(int labId, char *filename, asm_error_t *errData); + /* Add a value to a register params: diff --git a/src/vTerminal.c b/src/vTerminal.c index 3016a86..c4add97 100644 --- a/src/vTerminal.c +++ b/src/vTerminal.c @@ -45,30 +45,7 @@ bool runCmd(char *command, asm_error_t *errData){ system("clear"); } else{ - //Check if the file is present - FILE *file = fopen(command, "rb"); - if(file == NULL){ - errorfnf(command, errData); - } - // Run program - char line[LINE_MAX_BITS]; - - // Set as carry for action on next instruction - carry_t carry = {0, false}; - - int time = 0; - int lastTime = 0; - int latentTicks = 0; - while(fgets(line, sizeof(line) + 1, file)) { - setClock(time, lastTime, latentTicks); - - instruction_t inst = charBinToInst(line); - if(!run(inst, &carry, errData)){ - fclose(file); - return false; - } - } - fclose(file); + readFile(command, errData); } return true; } From fd6f0b096df97ec54c7125447b31e47aba8ffe1d Mon Sep 17 00:00:00 2001 From: Maxime CARON <145995231+MaximeAlgosup@users.noreply.github.com> Date: Fri, 23 Feb 2024 01:22:25 +0100 Subject: [PATCH 2/7] Add call and ret actions to vproc - Add stack to store call position - Store call position before goto --- src/vProc.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/vProc.h | 16 ++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/src/vProc.c b/src/vProc.c index f1c6095..eced860 100644 --- a/src/vProc.c +++ b/src/vProc.c @@ -10,6 +10,7 @@ #define LINE_MAX_BITS 16 #define VAR_LIST_SIZE 256 +#define MAX_CALL_STACK 256 #define CLOCK_TICKS 1/20 // variables @@ -17,6 +18,9 @@ vProcVar_t vProcVars[VAR_LIST_SIZE]; int lastVarIdx = 0; +fpos_t cursorPos[MAX_CALL_STACK]; +int callStackSize = 0; + // registers vRegister_t rg0 = {true, 0}; vRegister_t rg1 = {true, 0}; @@ -105,9 +109,23 @@ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_err if(pos == -1){ return false; } + // goto label fsetpos(file, &pos); return true; case 2: //call + // get call position + fpos_t callPos; + fgetpos(file, &callPos); + if(!addCallPos(callPos)){ + return false; + } + // search label + fpos_t labelPos = searchLabel(inst.arg, filename, errData); + if(pos == -1){ + return false; + } + // goto label + fsetpos(file, &labelPos); return true; case 3: //int return runInt(inst, carry, errData); @@ -197,6 +215,13 @@ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_err } return opMod(reg, inst.arg, errData); case 22: //ret + // get call next position + fpos_t callNextPos = cursorPos[0]; + if(!removeCallPos()){ + return false; + } + // go to new position + fsetpos(file, &callNextPos); return true; case 23: //mov from var // set carry to var data @@ -473,6 +498,35 @@ bool opShr(vRegister_t *reg, unsigned int arg, asm_error_t *errData){ } } +bool addCallPos(fpos_t pos) { + if (callStackSize >= MAX_CALL_STACK) { + fprintf(stderr, "Call stack overflow\n"); + return false; + } + + for (int i = callStackSize; i > 0; i--) { + cursorPos[i] = cursorPos[i - 1]; + } + + cursorPos[0] = pos; + ++callStackSize; + return true; +} + +bool removeCallPos() { + if (callStackSize == 0) { + fprintf(stderr, "Call stack is empty\n"); + return false; + } + + for (int i = 0; i < callStackSize - 1; i++) { + cursorPos[i] = cursorPos[i + 1]; + } + + --callStackSize; + return true; +} + void printVar(int idx){ printf("Var %d: ", idx); for(int i = 0; i < vProcVars[idx].size; i++){ diff --git a/src/vProc.h b/src/vProc.h index 606160d..5ab621a 100644 --- a/src/vProc.h +++ b/src/vProc.h @@ -230,6 +230,22 @@ bool opShl(vRegister_t *reg, unsigned int arg, asm_error_t *errData); */ bool opShr(vRegister_t *reg, unsigned int arg, asm_error_t *errData); +/* + Add call position to the call stack + params: + fpos_t pos: the position to add + returns: + bool: if the position have been added +*/ +bool addCallPos(fpos_t pos); + +/* + Remove first element from the call stack + returns: + bool: if the position have been removed +*/ +bool removeCallPos(); + /* print a variable data params: From 311547e6b27151a6d130fb9216e75ec49792668f Mon Sep 17 00:00:00 2001 From: Maxime CARON <145995231+MaximeAlgosup@users.noreply.github.com> Date: Fri, 23 Feb 2024 01:45:43 +0100 Subject: [PATCH 3/7] Update version --- CMakeLists.txt | 2 +- src/2at2.c | 2 +- src/vTerminal.c | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec64131..4912807 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ set(CMAKE_C_COMPILER "gcc") project( Interpreter-AT2 - VERSION 0.5.0 + VERSION 1.0.0 LANGUAGES CXX C ) diff --git a/src/2at2.c b/src/2at2.c index e72e534..90f90d0 100644 --- a/src/2at2.c +++ b/src/2at2.c @@ -13,7 +13,7 @@ #include "error.h" #include "binExporter.h" -#define VERSION "0.5.0" +#define VERSION "1.0.0" #define BIN_NAME "bin.2at2" int main(int argc, char *argv[]) { diff --git a/src/vTerminal.c b/src/vTerminal.c index c4add97..6cdcf0b 100644 --- a/src/vTerminal.c +++ b/src/vTerminal.c @@ -8,7 +8,7 @@ #include "vTerminal.h" -#define LINE_MAX_BITS 16 +#define VERSION "1.0.0" void runVTerminal(asm_error_t *errData){ char *command = (char *)malloc(100 * sizeof(char)); @@ -39,11 +39,15 @@ bool runCmd(char *command, asm_error_t *errData){ printf("Commands:\n"); printf("exit - to exit the terminal\n"); printf("clear - to clear the terminal\n"); + printf("version - to display the version\n"); printf("help - to display the help\n"); } else if(strcmp(command, "clear") == 0){ system("clear"); } + else if(strcmp(command, "version") == 0){ + printf("Version: %s\n", VERSION); + } else{ readFile(command, errData); } From a6bdfde9d662be995ebdd1654b38ad5c3162f1ea Mon Sep 17 00:00:00 2001 From: Maxime CARON <145995231+MaximeAlgosup@users.noreply.github.com> Date: Fri, 23 Feb 2024 13:31:54 +0100 Subject: [PATCH 4/7] Update error.c Correct overflow on sprintf --- src/error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/error.c b/src/error.c index 9c93d51..d6f8b72 100644 --- a/src/error.c +++ b/src/error.c @@ -322,7 +322,7 @@ void errorFileIssues(const char *filename, asm_error_t *errData){ char *errType = "File Issues Error"; char errDetails[64]; - sprintf(errDetails, "Error: the targeted file '%s' contains errors and couldn't be converted properly", filename); + sprintf(errDetails, "Error: the targeted file '%s' contains errors", filename); displayError(errType, errDetails, NULL, errorFile, errData); } From f9af8ab13a0a28d8519c3efcf035abd67761f536 Mon Sep 17 00:00:00 2001 From: Maxime CARON <145995231+MaximeAlgosup@users.noreply.github.com> Date: Fri, 23 Feb 2024 13:50:04 +0100 Subject: [PATCH 5/7] Update vProc.c Remove variable declaration in switch statement in run function of virtual processor --- src/vProc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vProc.c b/src/vProc.c index eced860..f34b899 100644 --- a/src/vProc.c +++ b/src/vProc.c @@ -91,6 +91,7 @@ instruction_t charBinToInst(char *bin){ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_error_t *errData){ vRegister_t *reg; + fpos_t pos; // check if there is a carry if(carry->isUsed && inst.inst != 24){ inst.arg = carry->nextArg; @@ -105,7 +106,7 @@ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_err reg->value = inst.arg; return true; case 1: //goto - fpos_t pos = searchLabel(inst.arg, filename, errData); + pos = searchLabel(inst.arg, filename, errData); if(pos == -1){ return false; } @@ -114,18 +115,17 @@ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_err return true; case 2: //call // get call position - fpos_t callPos; - fgetpos(file, &callPos); - if(!addCallPos(callPos)){ + fgetpos(file, &pos); + if(!addCallPos(pos)){ return false; } // search label - fpos_t labelPos = searchLabel(inst.arg, filename, errData); + pos = searchLabel(inst.arg, filename, errData); if(pos == -1){ return false; } // goto label - fsetpos(file, &labelPos); + fsetpos(file, &pos); return true; case 3: //int return runInt(inst, carry, errData); @@ -216,12 +216,12 @@ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_err return opMod(reg, inst.arg, errData); case 22: //ret // get call next position - fpos_t callNextPos = cursorPos[0]; + pos = cursorPos[0]; if(!removeCallPos()){ return false; } // go to new position - fsetpos(file, &callNextPos); + fsetpos(file, &pos); return true; case 23: //mov from var // set carry to var data From bcd1fa699f1080b090f38c176636fbfeebe78ea7 Mon Sep 17 00:00:00 2001 From: Maxime CARON <145995231+MaximeAlgosup@users.noreply.github.com> Date: Fri, 23 Feb 2024 13:57:48 +0100 Subject: [PATCH 6/7] Convert searchLabel default output type --- src/vProc.c | 6 +++--- src/vProc.h | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vProc.c b/src/vProc.c index f34b899..f37062f 100644 --- a/src/vProc.c +++ b/src/vProc.c @@ -128,7 +128,7 @@ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_err fsetpos(file, &pos); return true; case 3: //int - return runInt(inst, carry, errData); + return runInt(inst, carry); case 4: //push return true; case 5: //xor @@ -279,7 +279,7 @@ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_err } } -bool runInt(instruction_t inst, carry_t *carry, asm_error_t *errData){ +bool runInt(instruction_t inst, carry_t *carry){ switch(inst.arg){ case 0: //nigeru return false; @@ -373,7 +373,7 @@ fpos_t searchLabel(int labId, char *filename, asm_error_t *errData){ } } fclose(file); - return -1; + return (fpos_t)-1; } diff --git a/src/vProc.h b/src/vProc.h index 5ab621a..125fe0b 100644 --- a/src/vProc.h +++ b/src/vProc.h @@ -84,11 +84,10 @@ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_err params: instruction_t inst: the instruction to redirect to carry_t *carry: Carry for action on next instruction - asm_error_t *errData: Error history returns: bool: if the instructions have been run */ -bool runInt(instruction_t inst, carry_t *carry, asm_error_t *errData); +bool runInt(instruction_t inst, carry_t *carry); /* Get a register From 5f7bb2d7acca9b4b4f2b950b72f94284f657a556 Mon Sep 17 00:00:00 2001 From: Maxime CARON <145995231+MaximeAlgosup@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:06:28 +0100 Subject: [PATCH 7/7] Update vProc.c Final fpos type correction --- src/vProc.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/vProc.c b/src/vProc.c index f37062f..63445de 100644 --- a/src/vProc.c +++ b/src/vProc.c @@ -107,9 +107,6 @@ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_err return true; case 1: //goto pos = searchLabel(inst.arg, filename, errData); - if(pos == -1){ - return false; - } // goto label fsetpos(file, &pos); return true; @@ -121,9 +118,6 @@ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_err } // search label pos = searchLabel(inst.arg, filename, errData); - if(pos == -1){ - return false; - } // goto label fsetpos(file, &pos); return true; @@ -352,7 +346,7 @@ fpos_t searchLabel(int labId, char *filename, asm_error_t *errData){ FILE *file = fopen(filename, "rb"); if(file == NULL){ errorfnf(filename, errData); - return 0; + exit(EXIT_FAILURE); } char line[LINE_MAX_BITS]; fpos_t pos; @@ -373,7 +367,7 @@ fpos_t searchLabel(int labId, char *filename, asm_error_t *errData){ } } fclose(file); - return (fpos_t)-1; + exit(EXIT_FAILURE); }