diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 0bb661b..2096376 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -3,8 +3,8 @@ { "name": "Linux", "compilerPath": "/usr/bin/clang", - "cStandard": "c17", - "cppStandard": "c++17", + "cStandard": "c99", + "cppStandard": "c++99", "intelliSenseMode": "linux-clang-x64", "includePath": [ "${workspaceFolder}/**" diff --git a/src/dynamic_array/darray.c b/src/dynamic_array/darray.c index 6185147..fda755e 100644 --- a/src/dynamic_array/darray.c +++ b/src/dynamic_array/darray.c @@ -1,77 +1,109 @@ +#include "darray.h" #include #include #include -#include "darray.h" void darray_init(DArray *arr, size_t element_size) { - arr->element_size = element_size; - arr->size = 0; - arr->capacity = CHUNK_SIZE; - arr->data = malloc(CHUNK_SIZE * element_size); - if (!arr->data) { - fprintf(stderr, "darray_init: allocation failed\n"); - exit(EXIT_FAILURE); - } + arr->element_size = element_size; + arr->size = 0; + arr->capacity = CHUNK_SIZE; + arr->data = malloc(CHUNK_SIZE * element_size); + arr->resizable = true; + if (!arr->data) { + fprintf(stderr, "darray_init: allocation failed\n"); + exit(EXIT_FAILURE); + } } void darray_resize(DArray *arr, size_t new_size) { - size_t new_capacity = ((new_size + CHUNK_SIZE) / CHUNK_SIZE) * CHUNK_SIZE; - if (new_capacity != arr->capacity) { - void *new_data = realloc(arr->data, new_capacity * arr->element_size); - if (!new_data) { - fprintf(stderr, "darray_resize: reallocation failed\n"); - exit(EXIT_FAILURE); - } - arr->data = new_data; - arr->capacity = new_capacity; + if (!arr->resizable) { + fprintf(stderr, "darray_resize: unresizable darray\n"); + exit(EXIT_FAILURE); + } + size_t new_capacity = ((new_size + CHUNK_SIZE) / CHUNK_SIZE) * CHUNK_SIZE; + if (new_capacity != arr->capacity) { + void *new_data = realloc(arr->data, new_capacity * arr->element_size); + if (!new_data) { + fprintf(stderr, "darray_resize: reallocation failed\n"); + exit(EXIT_FAILURE); } + arr->data = new_data; + arr->capacity = new_capacity; + } - arr->size = new_size; + arr->size = new_size; } void darray_push(DArray *arr, void *element) { - if (arr->size >= arr->capacity) { - darray_resize(arr, arr->size + 1); - } else { - arr->size++; - } + if (!arr->resizable) { + fprintf(stderr, "darray_resize: unresizable darray\n"); + exit(EXIT_FAILURE); + } + if (arr->size >= arr->capacity) { + darray_resize(arr, arr->size + 1); + } else { + arr->size++; + } - void *target = (void *)arr->data + (arr->size - 1) * arr->element_size; - memcpy(target, element, arr->element_size); + void *target = (char *)arr->data + (arr->size - 1) * arr->element_size; + memcpy(target, element, arr->element_size); } void darray_pop(DArray *arr, void (*free_data)(void *)) { - if (arr->size == 0) - return; + if (!arr->resizable) { + fprintf(stderr, "darray_resize: unresizable darray\n"); + exit(EXIT_FAILURE); + } + if (arr->size == 0) + return; - arr->size--; + if (free_data) { + void *target = (char *)arr->data + (arr->size-1) * arr->element_size; + free_data(target); + } - if (free_data) { - void *target = (void *)arr->data + arr->size * arr->element_size; - free_data(target); - } - - darray_resize(arr, arr->size); + darray_resize(arr, arr->size); } void *darray_get(DArray *arr, size_t index) { - if (index >= arr->size) { - fprintf(stderr, "darray_get: index out of bounds\n"); - exit(EXIT_FAILURE); - } - return (void *)arr->data + index * arr->element_size; + if (index >= arr->size) { + fprintf(stderr, "darray_get: index out of bounds\n"); + exit(EXIT_FAILURE); + } + return (char *)arr->data + index * arr->element_size; +} + +DArray darray_slice(DArray *arr, size_t start, size_t end) { + if (start > end || end > arr->size) { + fprintf(stderr, "darray_slice: invalid slice range\n"); + exit(EXIT_FAILURE); + } + + DArray slice; + + slice.data = (char *)arr->data + start * arr->element_size; + slice.size = (end - start); + slice.element_size = arr->element_size; + slice.capacity = ((slice.size + CHUNK_SIZE) / CHUNK_SIZE) * CHUNK_SIZE; + slice.resizable = false; + + return slice; } void darray_free(DArray *arr, void (*free_data)(void *)) { - if (free_data) { - for (size_t i = 0; i < arr->size; ++i) { - void *element = (void *)arr->data + i * arr->element_size; - free_data(element); - } + if (!arr->resizable) { + // It's a view/slice — don't free + return; + } + if (free_data) { + for (size_t i = 0; i < arr->size; ++i) { + void *element = (char *)arr->data + i * arr->element_size; + free_data(element); } - free(arr->data); - arr->data = NULL; - arr->size = 0; - arr->capacity = 0; - arr->element_size = 0; + } + free(arr->data); + arr->data = NULL; + arr->size = 0; + arr->capacity = 0; + arr->element_size = 0; } \ No newline at end of file diff --git a/src/dynamic_array/darray.h b/src/dynamic_array/darray.h index 533d007..a5554aa 100644 --- a/src/dynamic_array/darray.h +++ b/src/dynamic_array/darray.h @@ -1,15 +1,17 @@ #ifndef DARRAY_H #define DARRAY_H -#include // for size_t +#include +#include // for size_t #define CHUNK_SIZE 16 typedef struct { - void *data; - size_t element_size; - size_t size; - size_t capacity; + void *data; + size_t element_size; + size_t size; + size_t capacity; + bool resizable; } DArray; // Initializes the dynamic_array @@ -30,4 +32,6 @@ void darray_free(DArray *arr, void (*free_data)(void *)); // Resizes the array to a new size (internal use, but exposed) void darray_resize(DArray *arr, size_t new_size); +DArray darray_slice(DArray *arr, size_t start, size_t end); + #endif // DARRAY_H diff --git a/src/parser/assign/assign.c b/src/parser/assign/assign.c index b00bef7..079cccb 100644 --- a/src/parser/assign/assign.c +++ b/src/parser/assign/assign.c @@ -8,26 +8,20 @@ ParsedValue *parse_assign(char *file, DArray *parsed, DArray *tokens, ParsedValue *assign_to, size_t *index) { Token *token = darray_get(tokens, *index); + switch (assign_to->type) { + case AST_IDENTIFIER: + case AST_ASSIGN: + break; + default: + fprintf(stderr, "%s:%u:%u error: can't assign to %s\n", file, token->line, + token->column, ValueTypeNames[assign_to->type]); + exit(EXIT_FAILURE); + } ParsedAssign *assign = malloc(sizeof(ParsedAssign)); assign->to = assign_to; assign->type = token->type; (*index)++; token = darray_get(tokens, *index); - switch (token->type) { - case TOKEN_ASSIGN: - case TOKEN_ASSIGN_CARET: - case TOKEN_ASSIGN_FLOORDIV: - case TOKEN_ASSIGN_MINUS: - case TOKEN_ASSIGN_MODULO: - case TOKEN_ASSIGN_PLUS: - case TOKEN_ASSIGN_SLASH: - case TOKEN_ASSIGN_STAR: - fprintf(stderr, "%s:%u:%u error: invalid syntax\n", file, token->line, - token->column); - exit(EXIT_FAILURE); - default: - break; - } assign->from = parse_token(file, parsed, tokens, index, true); ParsedValue *parsedValue = malloc(sizeof(ParsedValue)); parsedValue->type = AST_ASSIGN; diff --git a/src/parser/parser.c b/src/parser/parser.c index fbc9059..5b0ab8f 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -10,6 +10,8 @@ #include #include +const char *ValueTypeNames[] = {"string", "assign", "identifier"}; + ParsedValue *parse_token(char *file, DArray *parsed, DArray *tokens, size_t *index, bool inline_flag) { Token *token = darray_get(tokens, *index); @@ -34,6 +36,26 @@ ParsedValue *parse_token(char *file, DArray *parsed, DArray *tokens, fprintf(stderr, "%s:%u:%u error: invalid indentation\n", file, token->line, token->column); exit(EXIT_FAILURE); + case TOKEN_IDENTIFIER:; + ParsedValue *assign_to = parse_identifier(token); + (*index)++; + if (*index >= tokens->size) + return assign_to; + token = darray_get(tokens, *index); + switch (token->type) { + case TOKEN_ASSIGN: + case TOKEN_ASSIGN_CARET: + case TOKEN_ASSIGN_FLOORDIV: + case TOKEN_ASSIGN_MINUS: + case TOKEN_ASSIGN_MODULO: + case TOKEN_ASSIGN_PLUS: + case TOKEN_ASSIGN_SLASH: + case TOKEN_ASSIGN_STAR:; + DArray slice = darray_slice(parsed, parsed->size, parsed->size); + return parse_assign(file, &slice, tokens, assign_to, index); + default: + return assign_to; + } case TOKEN_ASSIGN: case TOKEN_ASSIGN_CARET: case TOKEN_ASSIGN_FLOORDIV: @@ -42,19 +64,9 @@ ParsedValue *parse_token(char *file, DArray *parsed, DArray *tokens, case TOKEN_ASSIGN_PLUS: case TOKEN_ASSIGN_SLASH: case TOKEN_ASSIGN_STAR: - if (parsed->size == 0) { - fprintf(stderr, "%s:%u:%u error: syntax error\n", file, token->line, - token->column); - exit(EXIT_FAILURE); - } - ParsedValue *assign_to = malloc(sizeof(ParsedValue)); - memcpy(assign_to, darray_get(parsed, parsed->size - 1), - sizeof(ParsedValue)); - darray_resize(parsed, parsed->size - 1); - return parse_assign(file, parsed, tokens, assign_to, index); - case TOKEN_IDENTIFIER: - (*index)++; - return parse_identifier(token); + fprintf(stderr, "%s:%u:%u error: syntax error\n", file, token->line, + token->column); + exit(EXIT_FAILURE); default: fprintf(stderr, "Panic: unreachable\n"); exit(EXIT_FAILURE); diff --git a/src/parser/parser.h b/src/parser/parser.h index bb56971..80916b0 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -10,9 +10,11 @@ typedef struct LinkedList LinkedList; typedef enum { AST_STRING, AST_ASSIGN, - AST_IDENTIFIER, + AST_IDENTIFIER } ValueType; +extern const char* ValueTypeNames[]; + typedef struct { ValueType type; void *data; diff --git a/test.ar b/test.ar index 6d65f3b..70e857d 100644 --- a/test.ar +++ b/test.ar @@ -1,483 +1 @@ -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -x="hello world" -"hello world" - - +"hello world"=10 \ No newline at end of file