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