Skip to content

Commit

Permalink
Merge pull request #96 from algosup/dev
Browse files Browse the repository at this point in the history
Add conditional goto
MaximeAlgosup authored Feb 23, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents f81d314 + 399cb81 commit a13270c
Showing 15 changed files with 84 additions and 118 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ set(CMAKE_C_COMPILER "gcc")

project(
Interpreter-AT2
VERSION 1.0.0
VERSION 1.1.0
LANGUAGES CXX C
)

@@ -27,6 +27,8 @@ add_executable(tests
src/debug.c
src/error.c
src/binExporter.c
src/vProc.c
src/vTerminal.c
test/test.cc
src/ast.c
googletest/googletest/src/gtest-all.cc
4 changes: 2 additions & 2 deletions src/2at2.c
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
#include "error.h"
#include "binExporter.h"

#define VERSION "1.0.0"
#define VERSION "1.1.0"
#define BIN_NAME "bin.2at2"

int main(int argc, char *argv[]) {
@@ -99,7 +99,7 @@ int main(int argc, char *argv[]) {
// ---------- Assemble ----------

// run exporter
exportToBin(instList, BIN_NAME, varList, errData);
exportToBin(instList, BIN_NAME, errData);

// Stop if there are errors
if(errData->errors > 0){
10 changes: 0 additions & 10 deletions src/ast.c
Original file line number Diff line number Diff line change
@@ -20,12 +20,6 @@ char *getIntCode(enum interruptKind kind, asm_error_t *errData){
return "1";
case INT_OB1:
return "2";
case INT_OR:
return "3";
case INT_AND:
return "4";
case INT_XOR:
return "5";
case INT_LT:
return "6";
case INT_LTE:
@@ -44,10 +38,6 @@ char *getIntCode(enum interruptKind kind, asm_error_t *errData){
return "13";
case INT_MOV_F_REG:
return "14";
case INT_ELSE:
return "15";
case INT_END:
return "16";
default:
errorIntCodeNotSupported(kind, errData);
return NULL;
5 changes: 0 additions & 5 deletions src/ast.h
Original file line number Diff line number Diff line change
@@ -46,9 +46,6 @@ enum interruptKind{
INT_EXIT,
INT_DRAW,
INT_OB1,
INT_OR,
INT_AND,
INT_XOR,
INT_LT,
INT_LTE,
INT_GT,
@@ -58,8 +55,6 @@ enum interruptKind{
INT_PUSHA,
INT_POPA,
INT_MOV_F_REG,
INT_ELSE,
INT_END,
};

// Register names
12 changes: 1 addition & 11 deletions src/binExporter.c
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
#include "error.h"
#include "debug.h"

void exportToBin(instList_t *nodeList, char *filename, varList_t *varList, asm_error_t *errData){
void exportToBin(instList_t *nodeList, char *filename, asm_error_t *errData){
// Open the file
FILE *file = fopen(filename, "wb");

@@ -158,12 +158,6 @@ char *interToBinCode(enum interruptKind inter){
return "00000001";
case INT_OB1:
return "00000010";
case INT_OR:
return "00000011";
case INT_AND:
return "00000100";
case INT_XOR:
return "00000101";
case INT_LT:
return "00000110";
case INT_LTE:
@@ -182,10 +176,6 @@ char *interToBinCode(enum interruptKind inter){
return "00001101";
case INT_MOV_F_REG:
return "00001110";
case INT_ELSE:
return "00001111";
case INT_END:
return "00010000";
default:
return NULL;
}
3 changes: 1 addition & 2 deletions src/binExporter.h
Original file line number Diff line number Diff line change
@@ -11,10 +11,9 @@ extern "C" {
params:
nodeList: pointer to the instruction list
filename: name of the file
varList: pointer to the variable list
errData: pointer to the error struct
*/
void exportToBin(instList_t *nodeList, char *filename, varList_t *varList, asm_error_t *errData);
void exportToBin(instList_t *nodeList, char *filename, asm_error_t *errData);

/*
Convert an operation to its binary code
17 changes: 16 additions & 1 deletion src/builder.c
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ void buildNode(instNode_t *node, varList_t *varList, labelList_t *labeList, asm_
buildCall(node, labeList, errData);
break;
case OP_INT:
node->isBuilt = true;
node->isBuilt = buildIntOpe(node, errData);
break;
case OP_B_XOR: case OP_DIV: case OP_ADD: case OP_SUB: case OP_MUL: case OP_R_SHIFT: case OP_L_SHIFT: case OP_B_AND: case OP_B_OR: case OP_B_NOT: case OP_MOD:
buildOperation(node, varList, errData);
@@ -474,4 +474,19 @@ int getVarDatasize(char *str){
else{
return (int)strlen(str);
}
}

bool buildIntOpe(instNode_t *node, asm_error_t *errData){
switch (node->inter)
{
case INT_LT: case INT_GT: case INT_LTE: case INT_GTE: case INT_EQ: case INT_NEQ:
// check if next node is a goto
if(node->next == NULL || node->next->op != OP_GOTO){
errorIfInt(node->lineNb, errData);
return false;
}
return true;
default:
return true;
}
}
10 changes: 10 additions & 0 deletions src/builder.h
Original file line number Diff line number Diff line change
@@ -99,6 +99,16 @@ enum regKind getRegKind(char *str, long lineNb, asm_error_t *errData);
*/
int getVarDatasize(char *str);

/*
build interrupt operation
params:
node: pointer to the instruction node
errData: pointer to the error struct
returns:
bool: true if the operation was built
*/
bool buildIntOpe(instNode_t *node, asm_error_t *errData);

#ifdef __cplusplus
}
#endif
10 changes: 0 additions & 10 deletions src/debug.c
Original file line number Diff line number Diff line change
@@ -113,12 +113,6 @@ char *getInterName(enum interruptKind kind){
return "DRAW";
case INT_OB1:
return "OB1";
case INT_OR:
return "OR";
case INT_AND:
return "AND";
case INT_XOR:
return "XOR";
case INT_LT:
return "LT";
case INT_LTE:
@@ -137,10 +131,6 @@ char *getInterName(enum interruptKind kind){
return "POPA";
case INT_MOV_F_REG:
return "MOV_F_REG";
case INT_ELSE:
return "ELSE";
case INT_END:
return "END";
default:
return "UNKNOWN";
}
9 changes: 9 additions & 0 deletions src/error.c
Original file line number Diff line number Diff line change
@@ -475,4 +475,13 @@ void errorOverflow(asm_error_t *errData){
char *errType = "Overflow";
char *errDetails = "The value is too large";
displayError(errType, errDetails, NULL, errorFile, errData);
}

void errorIfInt(long lineNb, asm_error_t *errData){
char *errType = "Interrupt Error";
char errDetails[64];
char errLocation[64];
sprintf(errDetails, "If interrupt must be followed by goto instruction");
sprintf(errLocation, "File %s, line %ld", errData->inputFile, lineNb);
displayError(errType, errDetails, errLocation, errorFile, errData);
}
10 changes: 9 additions & 1 deletion src/error.h
Original file line number Diff line number Diff line change
@@ -381,6 +381,14 @@ void errorReadOnly(asm_error_t *errData);
*/
void errorOverflow(asm_error_t *errData);

/*
Display error messages for invalid if statement
params:
lineNb: Line number
errData: Error history
*/
void errorIfInt(long lineNb, asm_error_t *errData);

#ifdef __cplusplus
}
#endif
#endif
25 changes: 0 additions & 25 deletions src/parser.c
Original file line number Diff line number Diff line change
@@ -282,21 +282,6 @@ bool isOp(char *inst, instNode_t *newNode, varList_t *varList, labelList_t *labe
newNode->isInter = true;
newNode->inter = INT_OB1;
}
else if(strcmp(inst, "if_or") == 0){
newNode->op = OP_INT;
newNode->isInter = true;
newNode->inter = INT_OR;
}
else if(strcmp(inst, "if_and") == 0){
newNode->op = OP_INT;
newNode->isInter = true;
newNode->inter = INT_AND;
}
else if(strcmp(inst, "if_xor") == 0){
newNode->op = OP_INT;
newNode->isInter = true;
newNode->inter = INT_XOR;
}
else if(strcmp(inst, "if_lt") == 0){
newNode->op = OP_INT;
newNode->isInter = true;
@@ -337,16 +322,6 @@ bool isOp(char *inst, instNode_t *newNode, varList_t *varList, labelList_t *labe
newNode->isInter = true;
newNode->inter = INT_POPA;
}
else if(strcmp(inst, "else") == 0){
newNode->op = OP_INT;
newNode->isInter = true;
newNode->inter = INT_ELSE;
}
else if(strcmp(inst, "end") == 0){
newNode->op = OP_INT;
newNode->isInter = true;
newNode->inter = INT_END;
}
else{
errorInstruction(inst, newNode->lineNb, errData);
return false;
40 changes: 30 additions & 10 deletions src/vProc.c
Original file line number Diff line number Diff line change
@@ -21,6 +21,8 @@ int lastVarIdx = 0;
fpos_t cursorPos[MAX_CALL_STACK];
int callStackSize = 0;

bool allowGoto = true;

// registers
vRegister_t rg0 = {true, 0};
vRegister_t rg1 = {true, 0};
@@ -106,6 +108,10 @@ bool run(instruction_t inst, carry_t *carry, FILE *file, char *filename, asm_err
reg->value = inst.arg;
return true;
case 1: //goto
if(!allowGoto){
allowGoto = true;
return true;
}
pos = searchLabel(inst.arg, filename, errData);
// goto label
fsetpos(file, &pos);
@@ -283,23 +289,41 @@ bool runInt(instruction_t inst, carry_t *carry){
return true;
case 2: // ob1
return true;
case 3: // cmp or
return true;
case 4: // cmp and
return true;
case 5: // cmp xor
return true;
case 6: // cmp less than
if(!(rg0.value < rg1.value))
{
allowGoto = false;
}
return true;
case 7: // cmp less than or equal
if(!(rg0.value <= rg1.value))
{
allowGoto = false;
}
return true;
case 8: // cmp greater than
if(!(rg0.value > rg1.value))
{
allowGoto = false;
}
return true;
case 9: // cmp greater than or equal
if(!(rg0.value >= rg1.value))
{
allowGoto = false;
}
return true;
case 10: // cmp equal
if(!(rg0.value == rg1.value))
{
allowGoto = false;
}
return true;
case 11: // cmp not equal
if(!(rg0.value != rg1.value))
{
allowGoto = false;
}
return true;
case 12: // pusha
return true;
@@ -310,10 +334,6 @@ bool runInt(instruction_t inst, carry_t *carry){
carry->nextArg = getRegister(inst.reg)->value;
carry->isUsed = true;
return true;
case 15: // else
return true;
case 16: // end
return true;
default:
exit(EXIT_FAILURE);
}
2 changes: 1 addition & 1 deletion src/vTerminal.c
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@

#include "vTerminal.h"

#define VERSION "1.0.0"
#define VERSION "1.1.0"

void runVTerminal(asm_error_t *errData){
char *command = (char *)malloc(100 * sizeof(char));
41 changes: 2 additions & 39 deletions test/test.cc
Original file line number Diff line number Diff line change
@@ -464,43 +464,6 @@ TEST(isOp, ob1) {
ASSERT_TRUE(newNode->op == OP_INT);
}

TEST(isOp, IntOR) {
asm_error_t *errData = initErrorFile(fileName);
char *inst = const_cast<char *>("if_or");

varList_t *varList = createEmptyVarList();
instNode_t *newNode = createEmptyInstNode(errData);
labelList_t *labelList = createEmptyLabelList();
bool isThatKind = isOp(inst, newNode, varList, labelList, errData);

ASSERT_TRUE(isThatKind);
ASSERT_TRUE(newNode->op == OP_INT);
}

TEST(isOp, IntIF_AND) {
asm_error_t *errData = initErrorFile(fileName);
char *inst = const_cast<char *>("if_and");

varList_t *varList = createEmptyVarList();
instNode_t *newNode = createEmptyInstNode(errData);
labelList_t *labelList = createEmptyLabelList();
bool isThatKind = isOp(inst, newNode, varList, labelList, errData);

ASSERT_TRUE(isThatKind);
ASSERT_TRUE(newNode->op == OP_INT);
}
TEST(isOp, IntIF_XOR) {
asm_error_t *errData = initErrorFile(fileName);
char *inst = const_cast<char *>("if_xor");

varList_t *varList = createEmptyVarList();
instNode_t *newNode = createEmptyInstNode(errData);
labelList_t *labelList = createEmptyLabelList();
bool isThatKind = isOp(inst, newNode, varList, labelList, errData);

ASSERT_TRUE(isThatKind);
ASSERT_TRUE(newNode->op == OP_INT);
}
TEST(isOp, IntIF_LT) {
asm_error_t *errData = initErrorFile(fileName);
char *inst = const_cast<char *>("if_lt");
@@ -644,9 +607,9 @@ TEST(buildProgram, ParsingAndBuilding) {
varList_t *varList = createEmptyVarList();
instList_t *nodeList = createEmptyInstList();
labelList_t *labelList = createEmptyLabelList();
char *fileName = const_cast<char *>("../test/test.aop");
char *fileName = const_cast<char *>("../test/aop/test.aop");
bool parsing = false;
parseFile(nodeList, fileName, varList, errData);
parseFile(nodeList, fileName, varList, labelList, errData);
if (nodeList->head != NULL) {
parsing = true;
}

0 comments on commit a13270c

Please sign in to comment.