From a7d7ded80389d31daeb822876b16272634bfd89e Mon Sep 17 00:00:00 2001 From: William Bell <62452284+Ugric@users.noreply.github.com> Date: Sat, 2 Aug 2025 20:17:24 +0100 Subject: [PATCH] start working on runtime oop --- app.py | 1 - gentest.py | 7 +- src/arobject.h | 11 ++- src/dynamic_array/darray.c | 21 +++--- src/dynamic_array/darray.h | 2 +- src/err.c | 2 +- src/memory.c | 2 + src/memory.h | 1 + src/runtime/call/call.c | 0 src/runtime/call/call.h | 0 src/runtime/declaration/declaration.c | 3 +- src/runtime/declaration/declaration.h | 1 + .../dynamic_array_armem/darray_armem.c | 34 +++++++--- .../dynamic_array_armem/darray_armem.h | 2 +- src/runtime/objects/object.c | 5 +- src/runtime/runtime.c | 68 +++++++++++++------ src/runtime/runtime.h | 25 +++++-- test.py | 9 ++- testing.ar | 19 ++++-- 19 files changed, 142 insertions(+), 71 deletions(-) delete mode 100644 app.py create mode 100644 src/runtime/call/call.c create mode 100644 src/runtime/call/call.h diff --git a/app.py b/app.py deleted file mode 100644 index 838d20b..0000000 --- a/app.py +++ /dev/null @@ -1 +0,0 @@ -return "hello world" \ No newline at end of file diff --git a/gentest.py b/gentest.py index a05b12f..69a8498 100644 --- a/gentest.py +++ b/gentest.py @@ -5,7 +5,6 @@ import random import sys -for i in range(10000): - sys.stdout.write("\"") - sys.stdout.write(str(random.random())) - sys.stdout.write("\"\n") +for i in range(10000000): + sys.stdout.write("\"hello world\"\n") + diff --git a/src/arobject.h b/src/arobject.h index 748716f..4e2a397 100644 --- a/src/arobject.h +++ b/src/arobject.h @@ -7,11 +7,11 @@ #ifndef AROBJECT_H #define AROBJECT_H -#include #include "runtime/internals/dynamic_array_armem/darray_armem.h" #include "runtime/internals/hashmap/hashmap.h" +#include -typedef struct ArgonObject ArgonObject; // forward declaration +typedef struct ArgonObject ArgonObject; // forward declaration typedef enum ArgonType { TYPE_NULL, @@ -40,13 +40,12 @@ struct argon_function_struct { char **parameters; }; + + // full definition of ArgonObject (no typedef again!) struct ArgonObject { ArgonType type; - char *name; - ArgonObject *self; - ArgonObject *baseObject; - struct hashmap_GC *fields; + struct hashmap_GC *dict; union { mpq_t as_number; bool as_bool; diff --git a/src/dynamic_array/darray.c b/src/dynamic_array/darray.c index 2d13036..fcd1174 100644 --- a/src/dynamic_array/darray.c +++ b/src/dynamic_array/darray.c @@ -8,17 +8,14 @@ #include #include #include +#include "../memory.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); + arr->capacity = CHUNK_SIZE / element_size; + arr->data = checked_malloc(CHUNK_SIZE); // fixed byte allocation 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) { @@ -26,9 +23,17 @@ void darray_resize(DArray *arr, size_t new_size) { fprintf(stderr, "darray_resize: unresizable darray\n"); exit(EXIT_FAILURE); } - size_t new_capacity = ((new_size + CHUNK_SIZE) / CHUNK_SIZE) * CHUNK_SIZE; + + // Determine number of full chunks needed to store new_size elements + size_t required_bytes = new_size * arr->element_size; + size_t new_capacity_bytes = ((required_bytes + CHUNK_SIZE - 1) / CHUNK_SIZE) * CHUNK_SIZE; + size_t new_capacity = new_capacity_bytes / arr->element_size; + if (!new_capacity) { + return; + } + if (new_capacity != arr->capacity) { - void *new_data = realloc(arr->data, new_capacity * arr->element_size); + void *new_data = realloc(arr->data, new_capacity_bytes); if (!new_data) { fprintf(stderr, "darray_resize: reallocation failed\n"); exit(EXIT_FAILURE); diff --git a/src/dynamic_array/darray.h b/src/dynamic_array/darray.h index b08bf58..d314b87 100644 --- a/src/dynamic_array/darray.h +++ b/src/dynamic_array/darray.h @@ -10,7 +10,7 @@ #include #include // for size_t -#define CHUNK_SIZE 1048576 +#define CHUNK_SIZE 4096 typedef struct { void *data; diff --git a/src/err.c b/src/err.c index c6ae73e..45a060c 100644 --- a/src/err.c +++ b/src/err.c @@ -140,7 +140,7 @@ void output_err(ArErr err) { fprintf(stderr, " "); } fprintf(stderr, "|\n"); - for (size_t i = 0;isource_locations, source_location_index); return create_err(source_location->line, source_location->column, source_location->length, state->path, "Runtime Error", "Identifier '%.*s' has already been declared in the current scope", length, arena_get(&translated->constants, offset)); } - hashmap_insert_GC(stack->scope, hash, arena_get(&translated->constants, offset), state->registers[from_register], 0); + ArgonObject * key = init_string_object(arena_get(&translated->constants, offset), length); + hashmap_insert_GC(stack->scope, hash, key, state->registers[from_register], 0); return no_err; } \ No newline at end of file diff --git a/src/runtime/declaration/declaration.h b/src/runtime/declaration/declaration.h index afb1314..f90a4cb 100644 --- a/src/runtime/declaration/declaration.h +++ b/src/runtime/declaration/declaration.h @@ -7,6 +7,7 @@ #ifndef runtime_declaration_H #define runtime_declaration_H #include "../runtime.h" +#include "../objects/string/string.h" ArErr runtime_declaration(Translated *translated, RuntimeState *state, struct Stack *stack); diff --git a/src/runtime/internals/dynamic_array_armem/darray_armem.c b/src/runtime/internals/dynamic_array_armem/darray_armem.c index 5cccdad..2ce8aa8 100644 --- a/src/runtime/internals/dynamic_array_armem/darray_armem.c +++ b/src/runtime/internals/dynamic_array_armem/darray_armem.c @@ -12,11 +12,17 @@ #include void darray_armem_init(darray_armem *arr, size_t element_size) { + if (element_size > CHUNK_SIZE) { + fprintf(stderr, "darray_armem_init: element size larger than chunk size\n"); + exit(EXIT_FAILURE); + } + arr->element_size = element_size; arr->size = 0; - arr->capacity = CHUNK_SIZE; - arr->data = ar_alloc(CHUNK_SIZE * element_size); + arr->capacity = CHUNK_SIZE / element_size; + arr->data = ar_alloc(CHUNK_SIZE); // fixed-size byte allocation arr->resizable = true; + if (!arr->data) { fprintf(stderr, "darray_armem_init: allocation failed\n"); exit(EXIT_FAILURE); @@ -28,15 +34,23 @@ void darray_armem_resize(darray_armem *arr, size_t new_size) { fprintf(stderr, "darray_armem_resize: unresizable darray_armem\n"); exit(EXIT_FAILURE); } - size_t new_capacity = ((new_size + CHUNK_SIZE) / CHUNK_SIZE) * CHUNK_SIZE; + + size_t required_bytes = new_size * arr->element_size; + size_t new_capacity_bytes = + ((required_bytes + CHUNK_SIZE - 1) / CHUNK_SIZE) * CHUNK_SIZE; + size_t new_capacity = new_capacity_bytes / arr->element_size; + + if (!new_capacity) { + return; + } + if (new_capacity != arr->capacity) { - void *new_data = ar_alloc(new_capacity * arr->element_size); - memccpy(new_data,arr->data, arr->element_size, arr->capacity); - if (!new_data) { + printf("%zu\n", new_capacity_bytes); + arr->data = ar_realloc(arr->data, new_capacity_bytes); + if (!arr->data) { fprintf(stderr, "darray_armem_resize: reallocation failed\n"); exit(EXIT_FAILURE); } - arr->data = new_data; arr->capacity = new_capacity; } @@ -67,11 +81,11 @@ void darray_armem_pop(darray_armem *arr, void (*free_data)(void *)) { return; if (free_data) { - void *target = (char *)arr->data + (arr->size-1) * arr->element_size; + void *target = (char *)arr->data + (arr->size - 1) * arr->element_size; free_data(target); } - - darray_armem_resize(arr, arr->size-1); + + darray_armem_resize(arr, arr->size - 1); } void *darray_armem_get(darray_armem *arr, size_t index) { diff --git a/src/runtime/internals/dynamic_array_armem/darray_armem.h b/src/runtime/internals/dynamic_array_armem/darray_armem.h index 8d9474c..cf54640 100644 --- a/src/runtime/internals/dynamic_array_armem/darray_armem.h +++ b/src/runtime/internals/dynamic_array_armem/darray_armem.h @@ -10,7 +10,7 @@ #include #include // for size_t -#define CHUNK_SIZE 1048576 +#define CHUNK_SIZE 4096 typedef struct { void *data; diff --git a/src/runtime/objects/object.c b/src/runtime/objects/object.c index 9ecd863..355377a 100644 --- a/src/runtime/objects/object.c +++ b/src/runtime/objects/object.c @@ -29,8 +29,9 @@ ArgonObject *init_argon_class(char *name) { ArgonObject *object = ar_alloc(sizeof(ArgonObject)); object->name = name; object->type = TYPE_OBJECT; - object->self = NULL; - object->baseObject = ARGON_TYPE; + object->self = object; + object->classObject = ; + object->baseObject = BASE_CLASS; object->fields = createHashmap_GC(); memset(&object->value, 0, sizeof(object->value)); return object; diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index f5673ba..6c10590 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -23,14 +23,6 @@ #include #include -uint64_t bytes_to_uint64(const uint8_t bytes[8]) { - uint64_t value = 0; - for (int i = 0; i < 8; i++) { - value |= ((uint64_t)bytes[i]) << (i * 8); - } - return value; -} - void init_types() { BASE_CLASS = init_argon_class("BASE_CLASS"); @@ -40,6 +32,13 @@ void init_types() { init_string_type(); init_base_field(); + BASE_CLASS->baseObject = ARGON_NULL; +} + +int compare_by_order(const void *a, const void *b) { + const struct node_GC *itemA = (const struct node_GC *)a; + const struct node_GC *itemB = (const struct node_GC *)b; + return itemA->order - itemB->order; } uint8_t pop_byte(Translated *translated, RuntimeState *state) { @@ -47,11 +46,11 @@ uint8_t pop_byte(Translated *translated, RuntimeState *state) { } uint64_t pop_bytecode(Translated *translated, RuntimeState *state) { - uint8_t bytes[8]; - for (size_t i = 0; i < sizeof(bytes); i++) { - bytes[i] = *((uint8_t *)darray_get(&translated->bytecode, state->head++)); + uint64_t value = 0; + for (int i = 0; i < 8; i++) { + value |= ((uint64_t)pop_byte(translated, state)) << (i * 8); } - return bytes_to_uint64(bytes); + return value; } void load_const(Translated *translated, RuntimeState *state) { @@ -147,7 +146,28 @@ ArErr run_instruction(Translated *translated, RuntimeState *state, case OP_NEW_SCOPE: *stack = create_scope(*stack); break; - case OP_POP_SCOPE: + case OP_POP_SCOPE:; + // struct node_GC *array = + // checked_malloc(sizeof(struct node_GC) * (*stack)->scope->count); + // size_t j = 0; + // for (size_t i = 0; i < (*stack)->scope->size; i++) { + // struct node_GC *temp = (*stack)->scope->list[i]; + // while (temp) { + // array[j++] = *temp; + // temp = temp->next; + // } + // } + // qsort(array, (*stack)->scope->count, sizeof(struct node_GC), + // compare_by_order); + // for (size_t i = 0; i < (*stack)->scope->count; i++) { + // struct node_GC temp = array[i]; + // printf("%.*s = %.*s\n", + // (int)((ArgonObject *)temp.key)->value.as_str.length, + // ((ArgonObject *)temp.key)->value.as_str.data, + // (int)((ArgonObject *)temp.val)->value.as_str.length, + // ((ArgonObject *)temp.val)->value.as_str.data); + // } + // free(array); *stack = (*stack)->prev; break; default: @@ -160,7 +180,7 @@ ArErr run_instruction(Translated *translated, RuntimeState *state, RuntimeState init_runtime_state(Translated translated, char *path) { return (RuntimeState){ checked_malloc(translated.registerCount * sizeof(ArgonObject *)), 0, path, - ARGON_NULL}; + ARGON_NULL, NULL, NULL}; } Stack *create_scope(Stack *prev) { @@ -172,11 +192,21 @@ Stack *create_scope(Stack *prev) { ArErr runtime(Translated translated, RuntimeState state, Stack *stack) { state.head = 0; - while (state.head < translated.bytecode.size) { - ArErr err = run_instruction(&translated, &state, &stack); - if (err.exists) { - return err; + StackFrame *currentStackFrame = checked_malloc(sizeof(StackFrame)); + *currentStackFrame = (StackFrame){translated, state, stack, NULL}; + state.currentStackFramePointer = ¤tStackFrame; + ArErr err = no_err; + while (currentStackFrame) { + while (currentStackFrame->state.head < + currentStackFrame->translated.bytecode.size && + !err.exists) { + err = + run_instruction(¤tStackFrame->translated, + ¤tStackFrame->state, ¤tStackFrame->stack); } + StackFrame *tempStackFrame = currentStackFrame; + currentStackFrame = currentStackFrame->previousStackFrame; + free(tempStackFrame); } - return no_err; + return err; } \ No newline at end of file diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 63fc55b..2a066f5 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -6,20 +6,35 @@ #ifndef RUNTIME_H #define RUNTIME_H +#include "../returnTypes.h" #include "../translator/translator.h" #include "internals/hashmap/hashmap.h" -#include "../returnTypes.h" -typedef struct { +typedef struct StackFrame StackFrame; +typedef struct RuntimeState RuntimeState; + +typedef ArErr (*error_result)(ArErr, Translated *translated, + RuntimeState *state, struct Stack **stack); + +typedef struct RuntimeState { ArgonObject **registers; size_t head; - char*path; - ArgonObject * return_value; + char *path; + ArgonObject *return_value; + StackFrame **currentStackFramePointer; + error_result result; } RuntimeState; +typedef struct StackFrame { + Translated translated; + RuntimeState state; + Stack *stack; + StackFrame *previousStackFrame; +} StackFrame; + void init_types(); -extern struct hashmap * runtime_hash_table; +extern struct hashmap *runtime_hash_table; uint64_t runtime_hash(const void *data, size_t len, uint64_t prehash); diff --git a/test.py b/test.py index 482d559..b81251c 100644 --- a/test.py +++ b/test.py @@ -10,7 +10,7 @@ def generate_names(max_width, skip_keywords=None): if skip_keywords is None: skip_keywords = {"if", "else", "while", "forever", "for", "break", "continue", "return", "let", "import", "from", "do", "true", "false", "null", - "delete", "not", "try", "catch", "in"} + "delete", "not", "try", "catch", "in", "or", "and", "elif"} else: skip_keywords = set(skip_keywords) @@ -25,15 +25,14 @@ def generate_names(max_width, skip_keywords=None): name = ''.join(p) if name in skip_keywords: continue - if not first: - write('\n') + write('let ') write(name) + write(' = null\n') first = False if i>10000000: break i+=1 # Example usage: -max_width = 15 -# sys.stdout.write("let ") +max_width = 5 generate_names(max_width) diff --git a/testing.ar b/testing.ar index 387e769..5301fb8 100644 --- a/testing.ar +++ b/testing.ar @@ -1,11 +1,16 @@ # SPDX-FileCopyrightText: 2025 William Bell # SPDX-License-Identifier: GPL-3.0-or-later - -let y = 1 - -let x = do +do + let x = "hello world" + let i = "hell" do - return y - x -let z = x \ No newline at end of file + let x = "hello world" + let i = "hell" + let z = "hello world" + let a = "hello world" + let b = "hello world" + x + let z = "hello world" + let a = "hello world" + let b = "hello world" \ No newline at end of file