diff --git a/src/get_instruction.h b/src/get_instruction.h deleted file mode 100644 index c9f4c60..0000000 --- a/src/get_instruction.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include "instruction_set.h" - -INSTRUCTION get_instruction(char* line, int* args_start_pos, int line_number); -void get_args(char* line, int args_start_pos); diff --git a/src/instruction_set.h b/src/instruction_set.h deleted file mode 100644 index 1205a90..0000000 --- a/src/instruction_set.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -typedef enum INSTRUCTIONS { - ERROR_INSTRUCTION = -2, - LABEL = -1, - ADD, - SUB, - MOV, - CMP, - JE, - JNE, - JMP, - JB, - JNB, - JA, - JNA, - RET, - POP, - PUSH, - CALL, - AND -} INSTRUCTION; diff --git a/src/instructions.c b/src/instructions.c index ce63a56..acb897e 100644 --- a/src/instructions.c +++ b/src/instructions.c @@ -64,22 +64,36 @@ int get_value(char* arg) { return ret; } -cmp_return_codes cmp() { +const command_t *find_command(char *your_var) +{ + if (your_var == NULL) + return NULL; + for (int index = 0; command_map[index].fptr != NULL; index += 1) { + if (strcmp(your_var, command_map[index].command) == 0) { + return &command_map[index]; + } + } + return NULL; +} + +void cmp() { if (!check_args(1)) { - return CMP_ERROR; + last_cmp_code = CMP_ERROR; + return; } int a1_ = get_value(args->arg1); int a2_ = get_value(args->arg2); - if (a1_ == a2_) return CMP_EQUAL; - if (a1_ > a2_) return CMP_ABOVE; - if (a2_ > a1_) return CMP_BELOW; - - return CMP_EQUAL; //never hit but it makes the compiler happy + if (a1_ == a2_) last_cmp_code = CMP_EQUAL; + else if (a1_ > a2_) last_cmp_code = CMP_ABOVE; + else if (a2_ > a1_) last_cmp_code = CMP_BELOW; + + return; } void jmp() { + return; for (int i = 0; i < MAX_LABEL; i++) { if (labels[i] == NULL) break; if (strcmp(args->arg1, labels[i]) == 0) { @@ -92,28 +106,28 @@ void jmp() { return; } -bool jna() { - return last_cmp_code != CMP_ABOVE; +void jna() { + if (last_cmp_code != CMP_ABOVE) jmp(); } -bool ja() { - return last_cmp_code == CMP_ABOVE; +void ja() { + if (last_cmp_code == CMP_ABOVE) jmp(); } -bool jnb() { - return last_cmp_code != CMP_BELOW; +void jnb() { + if (last_cmp_code != CMP_BELOW) jmp(); } -bool jb() { - return last_cmp_code == CMP_BELOW; +void jb() { + if (last_cmp_code == CMP_BELOW) jmp(); } -bool jne() { - return last_cmp_code != CMP_EQUAL; +void jne() { + if (last_cmp_code != CMP_EQUAL) jmp(); } -bool je() { - return last_cmp_code == CMP_EQUAL; +void je() { + if (last_cmp_code == CMP_EQUAL) jmp(); } void sub() { @@ -138,4 +152,24 @@ void mov() { } *get_reg(args->arg1) = get_value(args->arg2); +} + +void ret() { + +} + +void call() { + +} + +void push() { + +} + +void pop() { + +} + +void and() { + } \ No newline at end of file diff --git a/src/instructions.h b/src/instructions.h index 15cc18a..0b7be36 100644 --- a/src/instructions.h +++ b/src/instructions.h @@ -1,5 +1,6 @@ #pragma once -#include "get_instruction.h" +#include "parser.h" +#include #include typedef enum cmp_return_codes { @@ -17,20 +18,50 @@ typedef enum check_args_codes { } check_args_codes ; extern check_args_codes last_check_args_code; +//pasted from https://github.com/Sakutaroo/Templates/blob/main/C/FunctionPointer/function_pointer.h +typedef struct command_s { + char *command; + void (*fptr)(); +} command_t; + +const command_t *find_command(char *your_var); + bool check_args(int num_in_first); void add(); void sub(); void mov(); -cmp_return_codes cmp(); -bool je(); -bool jne(); -bool jb(); -bool jnb(); -bool ja(); -bool jna(); +void cmp(); +void je(); +void jne(); +void jb(); +void jnb(); +void ja(); +void jna(); void jmp(); void ret(); void pop(); void push(); void call(); +void and(); + +static const command_t command_map[] = { + {.command = "add", .fptr = add}, + {.command = "sub", .fptr = sub}, + {.command = "mov", .fptr = mov}, + {.command = "cmp", .fptr = cmp}, + {.command = "je", .fptr = je}, + {.command = "jne", .fptr = jne}, + {.command = "jb", .fptr = jb}, + {.command = "jnb", .fptr = jnb}, + {.command = "ja", .fptr = ja}, + {.command = "jna", .fptr = jna}, + {.command = "jmp", .fptr = jmp}, + {.command = "ret", .fptr = ret}, + {.command = "pop", .fptr = pop}, + {.command = "push", .fptr = push}, + {.command = "call", .fptr = call}, + {.command = "and", .fptr = and}, + + {.command = NULL, .fptr = NULL} +}; diff --git a/src/main.c b/src/main.c index 26a85f7..27aa3ab 100644 --- a/src/main.c +++ b/src/main.c @@ -2,7 +2,7 @@ #include #include #include "main.h" -#include "get_instruction.h" +#include "parser.h" #include "instructions.h" void show_help() { @@ -43,7 +43,9 @@ int main(int argc, char** argv) { char line[256]; int line_number = 1; size_t char_read = 0; + const command_t* com = NULL; while (fgets(line, sizeof(line), fptr)) { + com = NULL; char_read += strlen(line); if (line[0] == ';' || line[0] == '\n') { @@ -52,68 +54,39 @@ int main(int argc, char** argv) { } int args_pos; - INSTRUCTION ins = get_instruction(line, &args_pos, (int)char_read); - if (args_pos != -1) { + + char* ins = calloc(MAX_INS_LENGHT, 1); + + get_instruction(line, &args_pos, (int)char_read, &ins); + if (args_pos == -1) { + free(ins); + ++line_number; + continue; + } + + com = find_command(ins); + if (com != NULL) { get_args(line, args_pos); } - switch (ins) { - case SUB : - sub(); - break; - case MOV : - mov(); - break; - case ADD : - add(); - break; - case CMP : - last_cmp_code = cmp(); - break; - case JE : - if (je()) { - jmp(); - } - break; - case JNE : - if (jne()) { - jmp(); - } - break; - case JB : - if (jb()) { - jmp(); - } - break; - case JNB : - if (jnb()) { - jmp(); - } - break; - case JA : - if (ja()) { - jmp(); - } - break; - case JNA : - if (jna()) { - jmp(); - } - break; - case JMP : - jmp(); - break; - case LABEL : - break; - case ERROR_INSTRUCTION: - printf("%s ^\n |\ninvalid operand on line %d", line, line_number); - free(args->arg1); - free(args->arg2); - free(args); - fclose(fptr); - return 1; + free(ins); + + if (args == NULL || args->arg1 == NULL || args->arg2 == NULL) { + ++line_number; + continue; } - + + if (com == NULL) { + printf("%s ^\n |\ninvalid operand on line %d", line, line_number); + free(args->arg1); + free(args->arg2); + free(args); + fclose(fptr); + return 1; + } + + com->fptr(); + if (last_check_args_code != OK) { printf("%s", line); printf("%*c ^\n", args_pos, ' '); diff --git a/src/get_instruction.c b/src/parser.c similarity index 64% rename from src/get_instruction.c rename to src/parser.c index 385573f..7d5e0bd 100644 --- a/src/get_instruction.c +++ b/src/parser.c @@ -1,52 +1,45 @@ -#include "get_instruction.h" +#include "parser.h" #include "main.h" #include #include #include -const char* instructions_char[] = {"add", "sub", "mov", "cmp", "je", "jne", "jmp", "jb", "jbn", "ja", "jna", "ret", "pop", "push", "call", "and"}; +void get_instruction(char* line, int* args_start_pos, int line_number, char** ins) { + char temp[MAX_INS_LENGHT]; + memset(temp, 0, sizeof(temp)); -INSTRUCTION get_instruction(char* line, int* args_start_pos, int line_number) { - char ins[20]; //20 should be enough - memset(ins, 0, sizeof(ins)); - - for (int i = 0; i < (int)strlen(line); i++) { + for (int i = 0; i < MAX_INS_LENGHT; i++) { if (line[i] == ' ' || line[i] == '\n' || line[i] == '\0') { - ins[i] = '\0'; + temp[i] = '\0'; *args_start_pos = i + 1; break; } if (line[i] == ':') { - ins[i] = '\0'; + temp[i] = '\0'; *args_start_pos = -1; + strcpy_s(*ins, strlen(temp)+1,temp); for (int i = 0; i < MAX_LABEL; i++) { if (labels[i] == NULL) break; - if (strcmp(ins, labels[i]) == 0) { - return LABEL; + if (strcmp(temp, labels[i]) == 0) { + return; } } - labels[num_labels] = (char*)calloc(1, strlen(ins) + 1); + labels[num_labels] = (char*)calloc(1, strlen(temp) + 1); if (labels[num_labels] != NULL) { - strcpy_s(labels[num_labels], strlen(ins) + 1, ins); + strcpy_s(labels[num_labels], strlen(temp) + 1, temp); } labels_lines[num_labels] = line_number; ++num_labels; - return LABEL; + return; } - ins[i] = line[i]; + temp[i] = line[i]; } - for (int j = 0; j < sizeof(instructions_char)/sizeof(instructions_char[0]); j++) { - if (strcmp(ins, instructions_char[j]) == 0) { - return (INSTRUCTION)j; - } - } - - *args_start_pos = -1; - return ERROR_INSTRUCTION; + strcpy_s(*ins, strlen(temp)+1,temp); + return; } void get_args(char* line, int args_start_pos) { diff --git a/src/parser.h b/src/parser.h new file mode 100644 index 0000000..30c641c --- /dev/null +++ b/src/parser.h @@ -0,0 +1,5 @@ +#pragma once +#define MAX_INS_LENGHT 20 + +void get_instruction(char* line, int* args_start_pos, int line_number, char** ins); +void get_args(char* line, int args_start_pos); diff --git a/src/pasm.vcxproj b/src/pasm.vcxproj index 74a30e6..7d860bf 100644 --- a/src/pasm.vcxproj +++ b/src/pasm.vcxproj @@ -149,15 +149,14 @@ - + - + - diff --git a/src/pasm.vcxproj.filters b/src/pasm.vcxproj.filters index cbd3bda..979a4c3 100644 --- a/src/pasm.vcxproj.filters +++ b/src/pasm.vcxproj.filters @@ -17,7 +17,7 @@ Fichiers sources - + Fichiers sources @@ -28,13 +28,10 @@ - - Fichiers d%27en-tĂȘte - Fichiers sources - + Fichiers sources