add: c style register casting
This commit is contained in:
@@ -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).<br>
|
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).<br>
|
||||||
All the operands are case-sensitive, meaning that `ADD` will be an invalid operand.<br>
|
All the operands are case-sensitive, meaning that `ADD` will be an invalid operand.<br>
|
||||||
Please note that additional operands will be added in the future.<br>
|
Please note that additional operands will be added in the future.<br>
|
||||||
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`<br>
|
||||||
|
You can also cast registers to `int` or `char` using the C style syntax: `cmp a1, (char)*a2`.<br>
|
||||||
|
|
||||||
## Arrays
|
## Arrays
|
||||||
You can define an array using the keyword `set` like so :
|
You can define an array using the keyword `set` like so :
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "api.h"
|
#include "api.h"
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -14,12 +15,25 @@ bool is_array(char* arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool is_reg(char* arg) {
|
bool is_reg(char* arg) {
|
||||||
if (arg[0] == '&' || arg[0] == '*')
|
char *arg2 = strdup_(arg);
|
||||||
++arg;
|
char *s = arg2;
|
||||||
if (is_array(arg))
|
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 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) {
|
bool is_num(char* arg) {
|
||||||
@@ -45,15 +59,47 @@ bool check_args(s_arguments *args, int num_in_first, int num_args) {
|
|||||||
return true;
|
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] == '*';
|
int deref = reg_char[0] == '*';
|
||||||
|
|
||||||
if (reg_char[0] == '&' || reg_char[0] == '*')
|
if (reg_char[0] == '&' || reg_char[0] == '*')
|
||||||
++reg_char;
|
++reg_char;
|
||||||
for (int i = 0; i < state->num_arrays; i++)
|
for (int i = 0; i < state->num_arrays; i++) {
|
||||||
if (strcmp__(state->ARRAYS_NAME[i], reg_char) == 0)
|
if (strcmp__(state->ARRAYS_NAME[i], reg_char) == 0) {
|
||||||
|
free_(s);
|
||||||
return (long long *)&state->ARRAYS_VALUES[i];
|
return (long long *)&state->ARRAYS_VALUES[i];
|
||||||
switch (reg_char[1]) {
|
}
|
||||||
|
}
|
||||||
|
char c = reg_char[1];
|
||||||
|
free_(s);
|
||||||
|
switch (c) {
|
||||||
case '1' :
|
case '1' :
|
||||||
return deref ? (long long*)state->registers->a1 : &state->registers->a1;
|
return deref ? (long long*)state->registers->a1 : &state->registers->a1;
|
||||||
case '2' :
|
case '2' :
|
||||||
@@ -84,10 +130,10 @@ long long get_value(char* arg) {
|
|||||||
|
|
||||||
if (is_reg(arg)) {
|
if (is_reg(arg)) {
|
||||||
if (arg[0] == '&') {
|
if (arg[0] == '&') {
|
||||||
ret = (long long)get_reg(arg);
|
return (long long)get_reg(arg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = *get_reg(arg);
|
return *get_reg(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -119,6 +165,7 @@ void cmp() {
|
|||||||
|
|
||||||
long long a1_ = get_value(state->args->arg1);
|
long long a1_ = get_value(state->args->arg1);
|
||||||
long long a2_ = get_value(state->args->arg2);
|
long long a2_ = get_value(state->args->arg2);
|
||||||
|
a2_ = apply_cast(a2_, state->args->arg2);
|
||||||
|
|
||||||
if (a1_ == a2_) state->last_cmp_code = CMP_EQUAL;
|
if (a1_ == a2_) state->last_cmp_code = CMP_EQUAL;
|
||||||
else if (a1_ > a2_) state->last_cmp_code = CMP_ABOVE;
|
else if (a1_ > a2_) state->last_cmp_code = CMP_ABOVE;
|
||||||
@@ -304,7 +351,6 @@ void mov() {
|
|||||||
if (!check_args(state->args, 0, 2)) {
|
if (!check_args(state->args, 0, 2)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*get_reg(state->args->arg1) = get_value(state->args->arg2);
|
*get_reg(state->args->arg1) = get_value(state->args->arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ void free__state() {
|
|||||||
free_(state->labels_values);
|
free_(state->labels_values);
|
||||||
|
|
||||||
for (int j = 0; j < state->num_arrays; j++) {
|
for (int j = 0; j < state->num_arrays; j++) {
|
||||||
if (state->ARRAYS_NAME[j])
|
if (state->ARRAYS_NAME[j])
|
||||||
free_(state->ARRAYS_NAME[j]);
|
free_(state->ARRAYS_NAME[j]);
|
||||||
if (state->ARRAYS_VALUES[j])
|
if (state->ARRAYS_VALUES[j])
|
||||||
free_(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++;
|
arr_char[i++] = (long long)* ptr++;
|
||||||
}
|
}
|
||||||
state->ARRAYS_VALUES[state->num_arrays++] = (long long *)arr_char;
|
state->ARRAYS_VALUES[state->num_arrays++] = (long long *)arr_char;
|
||||||
|
free_(line_copy);
|
||||||
return ARRAY_OK;
|
return ARRAY_OK;
|
||||||
}
|
}
|
||||||
ptr = strtok_(ptr, ",");
|
ptr = strtok_(ptr, ",");
|
||||||
@@ -268,6 +269,16 @@ void sanitize_arguments() { //removes trailing spaces
|
|||||||
state->args->arg2[i] = '\0';
|
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) {
|
int parse_arguments(char *line) {
|
||||||
strcpy__(state->args->arg1, "");
|
strcpy__(state->args->arg1, "");
|
||||||
strcpy__(state->args->arg2, "");
|
strcpy__(state->args->arg2, "");
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ void free__state();
|
|||||||
void set_exit_state(int exit_state);
|
void set_exit_state(int exit_state);
|
||||||
int get_exit_state();
|
int get_exit_state();
|
||||||
int get_exit_code();
|
int get_exit_code();
|
||||||
|
int parse_argument_cast(char *arg);
|
||||||
LABEL_ERR add_label(char *label, int line);
|
LABEL_ERR add_label(char *label, int line);
|
||||||
ARRAY_ERR add_array(char *line);
|
ARRAY_ERR add_array(char *line);
|
||||||
void sanitize_arguments();
|
void sanitize_arguments();
|
||||||
|
|||||||
Reference in New Issue
Block a user