From 0d5b736a82e02578736975635523bec6a0b805da Mon Sep 17 00:00:00 2001 From: ALittlePatate Date: Thu, 16 Jan 2025 11:26:39 +0100 Subject: [PATCH] add: c style register casting --- docs/documentation.md | 3 +- src/instructions.c | 72 ++++++++++++++++++++++++++++++++-------- src/interpreter_states.c | 15 +++++++-- src/interpreter_states.h | 1 + 4 files changed, 75 insertions(+), 16 deletions(-) diff --git a/docs/documentation.md b/docs/documentation.md index 9740cbc..b16dd90 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -92,7 +92,8 @@ The syntax is very close to x86 Intel Assembly. Here is a list of the operands a All the `jmp`-related operands (`je`, `jna`, ...) can have a number as argument, this way the program will jump to `x` lines (ex: `jmp 3` will jump 3 lines down).
All the operands are case-sensitive, meaning that `ADD` will be an invalid operand.
Please note that additional operands will be added in the future.
-You can use the `&` and the `*` keywords just like in C to get the address and/or dereference and address. Example : `mov a1, &eax` +You can use the `&` and the `*` keywords just like in C to get the address and/or dereference and address. Example : `mov a1, &eax`
+You can also cast registers to `int` or `char` using the C style syntax: `cmp a1, (char)*a2`.
## Arrays You can define an array using the keyword `set` like so : diff --git a/src/instructions.c b/src/instructions.c index 00edae7..4e2e493 100644 --- a/src/instructions.c +++ b/src/instructions.c @@ -3,6 +3,7 @@ #include "api.h" #include "libc.h" #include +#include #include #include @@ -14,12 +15,25 @@ bool is_array(char* arg) { } bool is_reg(char* arg) { - if (arg[0] == '&' || arg[0] == '*') - ++arg; - if (is_array(arg)) + char *arg2 = strdup_(arg); + char *s = arg2; + strtok_(arg2, ")"); + arg2 = strtok_(NULL, ")"); + if (arg2 == NULL) { + arg2 = arg; + } + + if (arg2[0] == '&' || arg2[0] == '*') + ++arg2; + if (is_array(arg2)) { + free_(s); return true; - return (strcmp__(arg, "eax") == 0) || (((arg[0] == 'a' && - ('1' <= arg[1] && arg[1] <= '9'))) && strlen__(arg) == 2); + } + int r = (strcmp__(arg2, "eax") == 0) || (((arg2[0] == 'a' && + ('1' <= arg2[1] && arg2[1] <= '9'))) && strlen__(arg2) == 2); + + free_(s); + return r; } bool is_num(char* arg) { @@ -45,15 +59,47 @@ bool check_args(s_arguments *args, int num_in_first, int num_args) { return true; } -long long* get_reg(char* reg_char) { +long long apply_cast(long long val, char *arg) { + long long v = val; + long long r = v; + int c = parse_argument_cast(arg); + + if (c == -1) return val; + switch (c) { + case 1: + r = (long long)((char)v); + break; + case 4: + r = (long long)((int)v); + break; + default: + return val; + } + return r; +} + +long long* get_reg(char* arg) { + char *reg_char = strdup_(arg); + char *s = reg_char; + strtok_(reg_char, ")"); + reg_char = strtok_(NULL, ")"); + if (reg_char == NULL) { + reg_char = arg; + } + int deref = reg_char[0] == '*'; if (reg_char[0] == '&' || reg_char[0] == '*') ++reg_char; - for (int i = 0; i < state->num_arrays; i++) - if (strcmp__(state->ARRAYS_NAME[i], reg_char) == 0) + for (int i = 0; i < state->num_arrays; i++) { + if (strcmp__(state->ARRAYS_NAME[i], reg_char) == 0) { + free_(s); return (long long *)&state->ARRAYS_VALUES[i]; - switch (reg_char[1]) { + } + } + char c = reg_char[1]; + free_(s); + switch (c) { case '1' : return deref ? (long long*)state->registers->a1 : &state->registers->a1; case '2' : @@ -84,10 +130,10 @@ long long get_value(char* arg) { if (is_reg(arg)) { if (arg[0] == '&') { - ret = (long long)get_reg(arg); + return (long long)get_reg(arg); } - else { - ret = *get_reg(arg); + else { + return *get_reg(arg); } } else { @@ -119,6 +165,7 @@ void cmp() { long long a1_ = get_value(state->args->arg1); long long a2_ = get_value(state->args->arg2); + a2_ = apply_cast(a2_, state->args->arg2); if (a1_ == a2_) state->last_cmp_code = CMP_EQUAL; else if (a1_ > a2_) state->last_cmp_code = CMP_ABOVE; @@ -304,7 +351,6 @@ void mov() { if (!check_args(state->args, 0, 2)) { return; } - *get_reg(state->args->arg1) = get_value(state->args->arg2); } diff --git a/src/interpreter_states.c b/src/interpreter_states.c index 2780e9e..6a9024c 100644 --- a/src/interpreter_states.c +++ b/src/interpreter_states.c @@ -64,8 +64,8 @@ void free__state() { free_(state->labels_values); for (int j = 0; j < state->num_arrays; j++) { - if (state->ARRAYS_NAME[j]) - free_(state->ARRAYS_NAME[j]); + if (state->ARRAYS_NAME[j]) + free_(state->ARRAYS_NAME[j]); if (state->ARRAYS_VALUES[j]) free_(state->ARRAYS_VALUES[j]); } @@ -196,6 +196,7 @@ ARRAY_ERR add_array(char* line) { arr_char[i++] = (long long)* ptr++; } state->ARRAYS_VALUES[state->num_arrays++] = (long long *)arr_char; + free_(line_copy); return ARRAY_OK; } ptr = strtok_(ptr, ","); @@ -268,6 +269,16 @@ void sanitize_arguments() { //removes trailing spaces state->args->arg2[i] = '\0'; } +int parse_argument_cast(char *arg) { + //possible casts : int, char + + if (strncmp__(arg, "(char", 5) == 0) + return 1; + if (strncmp__(arg, "(int", 4) == 0) + return 4; + return -1; +} + int parse_arguments(char *line) { strcpy__(state->args->arg1, ""); strcpy__(state->args->arg2, ""); diff --git a/src/interpreter_states.h b/src/interpreter_states.h index bcf7bb7..52dfae0 100644 --- a/src/interpreter_states.h +++ b/src/interpreter_states.h @@ -77,6 +77,7 @@ void free__state(); void set_exit_state(int exit_state); int get_exit_state(); int get_exit_code(); +int parse_argument_cast(char *arg); LABEL_ERR add_label(char *label, int line); ARRAY_ERR add_array(char *line); void sanitize_arguments();