now using function ptr instead of switch case

also changed get_instruction to parser
This commit is contained in:
2023-05-12 12:40:36 +02:00
parent 091500239e
commit 6a8edc6f47
9 changed files with 149 additions and 144 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
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 CMP_EQUAL; //never hit but it makes the compiler happy
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() {
@@ -139,3 +153,23 @@ void mov() {
*get_reg(args->arg1) = get_value(args->arg2);
}
void ret() {
}
void call() {
}
void push() {
}
void pop() {
}
void and() {
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include "get_instruction.h"
#include "parser.h"
#include <stdio.h>
#include <stdbool.h>
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}
};

View File

@@ -2,7 +2,7 @@
#include <string.h>
#include <stdlib.h>
#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, ' ');

View File

@@ -1,52 +1,45 @@
#include "get_instruction.h"
#include "parser.h"
#include "main.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
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) {

5
src/parser.h Normal file
View File

@@ -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);

View File

@@ -149,15 +149,14 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="api.c" />
<ClCompile Include="get_instruction.c" />
<ClCompile Include="parser.c" />
<ClCompile Include="instructions.c" />
<ClCompile Include="main.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="api.h" />
<ClInclude Include="get_instruction.h" />
<ClInclude Include="parser.h" />
<ClInclude Include="instructions.h" />
<ClInclude Include="instruction_set.h" />
<ClInclude Include="main.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -17,7 +17,7 @@
<ClCompile Include="main.c">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="get_instruction.c">
<ClCompile Include="parser.c">
<Filter>Fichiers sources</Filter>
</ClCompile>
<ClCompile Include="instructions.c">
@@ -28,13 +28,10 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="instruction_set.h">
<Filter>Fichiers d%27en-tête</Filter>
</ClInclude>
<ClInclude Include="main.h">
<Filter>Fichiers sources</Filter>
</ClInclude>
<ClInclude Include="get_instruction.h">
<ClInclude Include="parser.h">
<Filter>Fichiers sources</Filter>
</ClInclude>
<ClInclude Include="instructions.h">