diff --git a/examples/array.pasm b/examples/array.pasm
new file mode 100644
index 0000000..c3ae3d9
--- /dev/null
+++ b/examples/array.pasm
@@ -0,0 +1,37 @@
+; Simple program that showcases the usage of string and number arrays
+
+set msg "hello, world !\0"
+set arr 1, 2, 3, 4, 5
+
+show_arr:
+mov a1, arr
+mov a2, 0
+
+loop2:
+cmp a2, 5
+jne 1
+end
+
+add a2, 1
+push *a1
+push 2
+call put
+add a1, 8
+jmp loop2
+
+main:
+mov a1, msg ; msg is a char *
+
+loop:
+cmp *a1, 0
+jne 1
+jmp show_arr
+
+push *a1
+push 1
+call put
+
+add a1, 8 ; little ptr theory here, as the stack is of type long long
+ ; to go to the next value you have to add sizeof(long long) to the ptr
+ ; so you need to add 8
+jmp loop
\ No newline at end of file
diff --git a/msvc/interpreter.vcxproj.user b/msvc/interpreter.vcxproj.user
index 88a5509..f621c28 100644
--- a/msvc/interpreter.vcxproj.user
+++ b/msvc/interpreter.vcxproj.user
@@ -1,4 +1,19 @@
-
+
+ ../examples/array.pasm
+ WindowsLocalDebugger
+
+
+ ../examples/array.pasm
+ WindowsLocalDebugger
+
+
+ ../examples/array.pasm
+ WindowsLocalDebugger
+
+
+ ../examples/array.pasm
+ WindowsLocalDebugger
+
\ No newline at end of file
diff --git a/src/api.c b/src/api.c
index 9e35933..c0946b3 100644
--- a/src/api.c
+++ b/src/api.c
@@ -11,8 +11,14 @@
extern int dprintf(int stream, const char *format, ...);
#endif
+void api_get_data() {
+ static const char dat[] = "Hello, World !";
+
+ state->registers->eax = (long long)dat;
+}
+
void api_put() {
- int mode = state->STACK[state->STACK_IDX--]; // 1 for char, 2 for num
+ int mode = (int)state->STACK[state->STACK_IDX--]; // 1 for char, 2 for num
if (mode != 1 && mode != 2) return;
int f = fstream;
@@ -25,7 +31,7 @@ void api_put() {
#endif
if (mode == 1) {
- char c = state->STACK[state->STACK_IDX--];
+ char c = (char)state->STACK[state->STACK_IDX--];
if (c == '\0') c = ' ';
dprintf(f, "%c", c); //using printf and not write because of the buffer
@@ -37,7 +43,7 @@ void api_put() {
void api_getasynckeystate() {
#ifdef _WIN32
- state->registers->eax = GetAsyncKeyState(state->STACK[state->STACK_IDX--]);
+ state->registers->eax = GetAsyncKeyState((int)state->STACK[state->STACK_IDX--]);
#else
state->STACK_IDX--;
state->registers->eax = 1;
diff --git a/src/api.h b/src/api.h
index 63967b8..ea7e96b 100644
--- a/src/api.h
+++ b/src/api.h
@@ -1,11 +1,13 @@
#pragma once
#include "instructions.h"
+void api_get_data();
void api_put();
void api_getasynckeystate();
static const command_t api_map[] = {
{.command = "put", .fptr = api_put},
+ {.command = "get_data", .fptr = api_get_data},
{.command = "GetAsyncKeyState", .fptr = api_getasynckeystate},
{.command = NULL, .fptr = NULL}
diff --git a/src/debug.c b/src/debug.c
index c4f6c7c..2118c2a 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -28,12 +28,23 @@ void show_stack() {
void show_labels() {
printf("\n\n-----LABELS-----\n");
- printf("format:\tlabel|line");
+ printf("format:\tlabel|line\n");
for (int i = 0; i < state->num_labels; i++)
printf("%s|%d\n", state->labels[i], state->labels_values[i]);
printf("\n\n-----LABELS-----\n");
}
+void show_arrays() {
+ printf("\n\n-----ARRAYS-----\n");
+ for (int i = 0; i < state->num_arrays; i++) {
+ printf("%s: ", state->ARRAYS_NAME[i]);
+ for (int j = 0; j < 20; j++)
+ printf("%lld ", state->ARRAYS_VALUES[i][j]);
+ printf("...\n");
+ }
+ printf("\n\n-----ARRAYS-----\n");
+}
+
void show_breakpoints(int *bp) {
printf("---Breakpoints---\n");
for (int i = 0; bp[i] != 0 && i < 255; i++) {
@@ -48,6 +59,7 @@ void show_states() {
show_registers();
show_labels();
show_stack();
+ show_arrays();
printf("\n\n--------PASM STATE--------\n");
}
diff --git a/src/instructions.c b/src/instructions.c
index 87dc5d6..a40c3c5 100644
--- a/src/instructions.c
+++ b/src/instructions.c
@@ -5,9 +5,18 @@
#include
#include
+bool is_array(char* arg) {
+ for (int i = 0; i < state->num_arrays; i++)
+ if (strcmp(state->ARRAYS_NAME[i], arg) == 0)
+ return true;
+ return false;
+}
+
bool is_reg(char* arg) {
if (arg[0] == '&' || arg[0] == '*')
++arg;
+ if (is_array(arg))
+ return true;
return (strcmp(arg, "eax") == 0) || (((arg[0] == 'a' &&
('1' <= arg[1] && arg[1] <= '9'))) && strlen(arg) == 2);
}
@@ -38,6 +47,9 @@ bool check_args(s_arguments *args, int num_in_first, int num_args) {
long long* get_reg(char* reg_char) {
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)
+ return &state->ARRAYS_VALUES[i];
switch (reg_char[1]) {
case '1' :
return &state->registers->a1;
diff --git a/src/interpreter_states.c b/src/interpreter_states.c
index af96d42..4e01bd9 100644
--- a/src/interpreter_states.c
+++ b/src/interpreter_states.c
@@ -45,6 +45,7 @@ int init_state() {
memset(state->labels_values, 0, sizeof(int) * MAX_LABELS);
memset(state->RET_STACK, -1, sizeof(int) * STACK_SIZE);
memset(state->STACK, 0, sizeof(long long) * STACK_SIZE);
+ state->num_arrays = 0;
state->RET_STACK_IDX = -1;
state->STACK_IDX = -1;
state->last_stack_code = STACK_OK;
@@ -59,6 +60,15 @@ void free_state() {
}
free(state->labels);
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_VALUES[j])
+ free(state->ARRAYS_VALUES[j]);
+ }
+ free(state->ARRAYS_NAME);
+ free(state->ARRAYS_VALUES);
free(state->registers);
free(state->args->arg1);
free(state->args->arg2);
@@ -105,6 +115,114 @@ LABEL_ERR add_label(char *label, int line) {
return LABEL_OK;
}
+ARRAY_ERR add_array(char* line) {
+#ifdef _WIN32
+ char *line_copy = _strdup(line);
+#else
+ char *line_copy = strdup(line);
+#endif
+ if (strncmp(line, "set", 3) != 0) {
+ free(line_copy);
+ return ARRAY_NOT_AN_ARRAY;
+ }
+ char *ptr = strtok(line_copy, " "); //set
+ ptr = strtok(NULL, " "); //array name
+ if (ptr == NULL || strlen(line) <= (4 + strlen(ptr))) {
+ free(line_copy);
+ return ARRAY_ERROR;
+ }
+
+ char **temp = realloc(state->ARRAYS_NAME, (state->num_arrays + 1) * sizeof(char*));
+ if (temp == NULL) {
+ dprintf(fstream, "Error allocating memory.\n");
+ return ARRAY_ERROR;
+ }
+ state->ARRAYS_NAME = temp;
+#ifdef _WIN32
+ state->ARRAYS_NAME[state->num_arrays] = _strdup(ptr);
+#else
+ state->ARRAYS_NAME[state->num_arrays] = strdup(ptr);
+#endif
+ ptr += strlen(ptr) + 1; //getting the data in the array, data is data after all
+ if (ptr == NULL || ptr[0] == ' ' || ptr[0] == '\0') {
+ free(line_copy);
+ return ARRAY_ERROR;
+ }
+
+ char* start_of_values = ptr;
+ int array_size = 0;
+ long long *arr = NULL;
+ if (ptr[0] == '"') {
+ ++ptr;
+ while (*ptr++ != '"') {
+ if (*ptr == '\0') {
+ free(line_copy);
+ return ARRAY_ERROR; //" is never closed
+ }
+ ++array_size;
+ }
+ long long *tmp = realloc(arr, array_size * sizeof(long long));
+ if (tmp == NULL || array_size == 0) {
+ dprintf(fstream, "Error allocating memory.\n");
+ return ARRAY_ERROR;
+ }
+ arr = tmp;
+ memset(arr, 0, array_size);
+ long long **temp = realloc(state->ARRAYS_VALUES, (state->num_arrays + 1) * sizeof(long long*));
+ if (temp == NULL) {
+ dprintf(fstream, "Error allocating memory.\n");
+ return ARRAY_ERROR;
+ }
+ state->ARRAYS_VALUES = temp;
+ ptr = start_of_values;
+ int i = 0;
+ ++ptr;
+ while (*ptr != '"') {
+ if (*ptr == '\0' || i >= array_size) {
+ free(line_copy);
+ return ARRAY_ERROR; //" is never closed
+ }
+ if (strncmp(ptr, "\\0", 2) == 0) {
+ arr[i++] = 0;
+ break;
+ }
+ arr[i++] = (long long)* ptr++;
+ }
+ state->ARRAYS_VALUES[state->num_arrays++] = arr;
+ return ARRAY_OK;
+ }
+ ptr = strtok(ptr, ",");
+ while (ptr != NULL) {
+ array_size++;
+ ptr = strtok(NULL, ",");
+ }
+ long long *tmp2 = realloc(arr, array_size * sizeof(long long));
+ if (tmp2 == NULL || array_size == 0) {
+ dprintf(fstream, "Error allocating memory.\n");
+ return ARRAY_ERROR;
+ }
+ arr = tmp2;
+ memset(arr, 0, array_size);
+ long long **temp2 = realloc(state->ARRAYS_VALUES, (state->num_arrays + 1) * sizeof(long long*));
+ if (temp2 == NULL) {
+ dprintf(fstream, "Error allocating memory.\n");
+ return ARRAY_ERROR;
+ }
+ state->ARRAYS_VALUES = temp2;
+ ptr = line + 4 + strlen(state->ARRAYS_NAME[state->num_arrays]) + 1; //leave me alone i'm tired
+ ptr = strtok(ptr, ",");
+ int j = 0;
+ while (ptr != NULL && j < array_size) {
+ if (ptr[0] == ' ')
+ ++ptr;
+ arr[j++] = atoi(ptr);
+ ptr = strtok(NULL, ",");
+ }
+ state->ARRAYS_VALUES[state->num_arrays++] = arr;
+ free(line_copy);
+ return ARRAY_OK;
+}
+
char *extract_arg(char *ptr, int a) {
char *arg = 0;
char *ptr2 = strstr(ptr, ";");
diff --git a/src/interpreter_states.h b/src/interpreter_states.h
index c49f018..850d6a9 100644
--- a/src/interpreter_states.h
+++ b/src/interpreter_states.h
@@ -48,6 +48,9 @@ typedef struct t_state {
int RET_STACK_IDX;
int STACK_IDX;
long long STACK[STACK_SIZE];
+ char** ARRAYS_NAME;
+ int num_arrays;
+ long long **ARRAYS_VALUES;
int last_jmp_code;
stack_codes last_stack_code;
cmp_return_codes last_cmp_code;
@@ -63,9 +66,16 @@ typedef enum E_LABEL_ERR {
LABEL_ERROR
} LABEL_ERR;
+typedef enum E_ARRAY_ERR {
+ ARRAY_OK,
+ ARRAY_ERROR,
+ ARRAY_NOT_AN_ARRAY
+} ARRAY_ERR;
+
int init_state();
void free_state();
void set_exit_state(int exit_state);
int get_exit_state();
LABEL_ERR add_label(char *label, int line);
+ARRAY_ERR add_array(char *line);
int parse_arguments(char *args);
diff --git a/src/pasm.c b/src/pasm.c
index 4e689c6..f653b8f 100644
--- a/src/pasm.c
+++ b/src/pasm.c
@@ -105,12 +105,22 @@ int pasm_run_script(const char *filename, char **file, size_t lines, int _fstrea
#else
char *line = strdup(file[state->curr_line]);
#endif
- if (line[0] == ';' || line[0] == '\0') {
+ if (line[0] == ';' || line[0] == '\0' || line[0] == '\t') {
free(line);
continue;
}
const command_t *com = find_command(command_map, strtok(line, " "));
if (com == NULL || com->fptr == NULL) {
+ ARRAY_ERR err = add_array(file[state->curr_line]);
+ if (err == ARRAY_OK)
+ continue;
+ if (err == ARRAY_ERROR) {
+ show_error(state->curr_line, file[state->curr_line]);
+ dprintf(fstream, "%s\n", "bad syntax in array definition");
+ set_exit_state(-1);
+ free(line);
+ break;
+ }
if (file[state->curr_line][strlen(line) - 1] != ':') {
show_error(state->curr_line, file[state->curr_line]);
dprintf(fstream, "%s \"%s\"\n", "unknown expression", strtok(file[state->curr_line], " "));