add: arrays

This commit is contained in:
2024-01-22 22:24:40 +01:00
parent 827937e4dc
commit 4bcb50865c
9 changed files with 228 additions and 6 deletions

37
examples/array.pasm Normal file
View File

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

View File

@@ -1,4 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommandArguments>../examples/array.pasm</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerCommandArguments>../examples/array.pasm</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>../examples/array.pasm</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>../examples/array.pasm</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

View File

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

View File

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

View File

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

View File

@@ -5,9 +5,18 @@
#include <string.h>
#include <stdlib.h>
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;

View File

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

View File

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

View File

@@ -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], " "));