fix memory being freed too early
This commit is contained in:
27
src/main.c
27
src/main.c
@@ -44,6 +44,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include "err.h"
|
#include "err.h"
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
|
||||||
@@ -152,7 +154,8 @@ const char FILE_IDENTIFIER[5] = "ARBI";
|
|||||||
const char BYTECODE_EXTENTION[] = "arbin";
|
const char BYTECODE_EXTENTION[] = "arbin";
|
||||||
const uint32_t version_number = 0;
|
const uint32_t version_number = 0;
|
||||||
|
|
||||||
int load_cache(Translated *translated_dest, char *joined_paths, uint64_t hash, char*source_path) {
|
int load_cache(Translated *translated_dest, char *joined_paths, uint64_t hash,
|
||||||
|
char *source_path) {
|
||||||
FILE *bytecode_file = fopen(joined_paths, "rb");
|
FILE *bytecode_file = fopen(joined_paths, "rb");
|
||||||
if (!bytecode_file) {
|
if (!bytecode_file) {
|
||||||
printf("cache doesnt exist... compiling from source.\n");
|
printf("cache doesnt exist... compiling from source.\n");
|
||||||
@@ -376,6 +379,9 @@ Execution execute(char *path, Stack *stack) {
|
|||||||
printf("Translation time taken: %f seconds\n", time_spent);
|
printf("Translation time taken: %f seconds\n", time_spent);
|
||||||
|
|
||||||
darray_free(&ast, free_parsed);
|
darray_free(&ast, free_parsed);
|
||||||
|
|
||||||
|
malloc_trim(0);
|
||||||
|
|
||||||
ensure_dir_exists(cache_folder_path);
|
ensure_dir_exists(cache_folder_path);
|
||||||
|
|
||||||
file = fopen(cache_file_path, "wb");
|
file = fopen(cache_file_path, "wb");
|
||||||
@@ -417,20 +423,18 @@ Execution execute(char *path, Stack *stack) {
|
|||||||
}
|
}
|
||||||
hashmap_free(translated.constants.hashmap, NULL);
|
hashmap_free(translated.constants.hashmap, NULL);
|
||||||
Translated gc_translated = {
|
Translated gc_translated = {
|
||||||
translated.registerCount,
|
translated.registerCount, NULL, {}, {}, translated.path};
|
||||||
NULL,
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
translated.path
|
|
||||||
};
|
|
||||||
gc_translated.bytecode.data = ar_alloc(translated.bytecode.capacity);
|
gc_translated.bytecode.data = ar_alloc(translated.bytecode.capacity);
|
||||||
memcpy(gc_translated.bytecode.data, translated.bytecode.data, translated.bytecode.capacity);
|
memcpy(gc_translated.bytecode.data, translated.bytecode.data,
|
||||||
|
translated.bytecode.capacity);
|
||||||
gc_translated.bytecode.element_size = translated.bytecode.element_size;
|
gc_translated.bytecode.element_size = translated.bytecode.element_size;
|
||||||
gc_translated.bytecode.size = translated.bytecode.size;
|
gc_translated.bytecode.size = translated.bytecode.size;
|
||||||
gc_translated.bytecode.resizable = false;
|
gc_translated.bytecode.resizable = false;
|
||||||
gc_translated.bytecode.capacity = translated.bytecode.size*translated.bytecode.element_size;
|
gc_translated.bytecode.capacity =
|
||||||
|
translated.bytecode.size * translated.bytecode.element_size;
|
||||||
gc_translated.constants.data = ar_alloc(translated.constants.capacity);
|
gc_translated.constants.data = ar_alloc(translated.constants.capacity);
|
||||||
memcpy(gc_translated.constants.data, translated.constants.data, translated.constants.capacity);
|
memcpy(gc_translated.constants.data, translated.constants.data,
|
||||||
|
translated.constants.capacity);
|
||||||
gc_translated.constants.size = translated.constants.size;
|
gc_translated.constants.size = translated.constants.size;
|
||||||
gc_translated.constants.capacity = translated.constants.capacity;
|
gc_translated.constants.capacity = translated.constants.capacity;
|
||||||
darray_free(&translated.bytecode, NULL);
|
darray_free(&translated.bytecode, NULL);
|
||||||
@@ -440,7 +444,6 @@ Execution execute(char *path, Stack *stack) {
|
|||||||
RuntimeState state = init_runtime_state(gc_translated, path);
|
RuntimeState state = init_runtime_state(gc_translated, path);
|
||||||
Stack *main_scope = create_scope(stack);
|
Stack *main_scope = create_scope(stack);
|
||||||
ArErr err = runtime(gc_translated, state, main_scope);
|
ArErr err = runtime(gc_translated, state, main_scope);
|
||||||
free_runtime_state(state);
|
|
||||||
end = clock();
|
end = clock();
|
||||||
time_spent = (double)(end - start) / CLOCKS_PER_SEC;
|
time_spent = (double)(end - start) / CLOCKS_PER_SEC;
|
||||||
total_time_spent += time_spent;
|
total_time_spent += time_spent;
|
||||||
@@ -453,6 +456,7 @@ Execution execute(char *path, Stack *stack) {
|
|||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
ar_memory_init();
|
ar_memory_init();
|
||||||
|
|
||||||
generate_siphash_key(siphash_key);
|
generate_siphash_key(siphash_key);
|
||||||
bootstrap_types();
|
bootstrap_types();
|
||||||
bootstrap_globals();
|
bootstrap_globals();
|
||||||
@@ -470,5 +474,6 @@ int main(int argc, char *argv[]) {
|
|||||||
output_err(resp.err);
|
output_err(resp.err);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
// Your main thread code
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include <gc/gc.h>
|
#include <gc.h>
|
||||||
#include <gmp.h>
|
#include <gmp.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h> // for malloc/free (temp arena fallback)
|
#include <stdlib.h> // for malloc/free (temp arena fallback)
|
||||||
@@ -42,7 +42,8 @@ void *ar_realloc(void * old,size_t size) { return GC_REALLOC(old, size); }
|
|||||||
|
|
||||||
void ar_finalizer(void *obj, GC_finalization_proc fn, void *client_data,
|
void ar_finalizer(void *obj, GC_finalization_proc fn, void *client_data,
|
||||||
GC_finalization_proc *old_fn, void **old_client_data) {
|
GC_finalization_proc *old_fn, void **old_client_data) {
|
||||||
return GC_register_finalizer_no_order(obj, fn, client_data, old_fn, old_client_data);
|
return GC_register_finalizer_no_order(obj, fn, client_data, old_fn,
|
||||||
|
old_client_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ar_alloc_atomic(size_t size) { return GC_MALLOC_ATOMIC(size); }
|
void *ar_alloc_atomic(size_t size) { return GC_MALLOC_ATOMIC(size); }
|
||||||
|
|||||||
@@ -88,19 +88,17 @@ ArErr run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
|||||||
object = call_method;
|
object = call_method;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool to_free_args = false;
|
|
||||||
if (object->type == TYPE_METHOD) {
|
if (object->type == TYPE_METHOD) {
|
||||||
ArgonObject *binding_object =
|
ArgonObject *binding_object =
|
||||||
get_field(object, "__binding__", false, false);
|
get_field(object, "__binding__", false, false);
|
||||||
if (binding_object) {
|
if (binding_object) {
|
||||||
ArgonObject **new_call_args = malloc(sizeof(ArgonObject *) * (argc + 1));
|
ArgonObject **new_call_args = ar_alloc(sizeof(ArgonObject *) * (argc + 1));
|
||||||
new_call_args[0] = binding_object;
|
new_call_args[0] = binding_object;
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
memcpy(new_call_args + 1, argv, argc * sizeof(ArgonObject *));
|
memcpy(new_call_args + 1, argv, argc * sizeof(ArgonObject *));
|
||||||
}
|
}
|
||||||
argv = new_call_args;
|
argv = new_call_args;
|
||||||
argc++;
|
argc++;
|
||||||
to_free_args = true;
|
|
||||||
}
|
}
|
||||||
ArgonObject *function_object =
|
ArgonObject *function_object =
|
||||||
get_field(object, "__function__", false, false);
|
get_field(object, "__function__", false, false);
|
||||||
@@ -131,8 +129,6 @@ ArErr run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
|||||||
hashmap_insert_GC(scope->scope, hash,
|
hashmap_insert_GC(scope->scope, hash,
|
||||||
new_string_object(key.data, key.length), value, 0);
|
new_string_object(key.data, key.length), value, 0);
|
||||||
}
|
}
|
||||||
if (to_free_args)
|
|
||||||
free(argv);
|
|
||||||
StackFrame new_stackFrame = {
|
StackFrame new_stackFrame = {
|
||||||
{object->value.argon_fn.translated.registerCount,
|
{object->value.argon_fn.translated.registerCount,
|
||||||
NULL,
|
NULL,
|
||||||
@@ -157,7 +153,7 @@ ArErr run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
|||||||
if (((*state->currentStackFramePointer)->depth + 1) % STACKFRAME_CHUNKS ==
|
if (((*state->currentStackFramePointer)->depth + 1) % STACKFRAME_CHUNKS ==
|
||||||
0) {
|
0) {
|
||||||
*state->currentStackFramePointer =
|
*state->currentStackFramePointer =
|
||||||
checked_malloc(sizeof(StackFrame) * STACKFRAME_CHUNKS);
|
ar_alloc(sizeof(StackFrame) * STACKFRAME_CHUNKS);
|
||||||
} else {
|
} else {
|
||||||
*state->currentStackFramePointer = *state->currentStackFramePointer + 1;
|
*state->currentStackFramePointer = *state->currentStackFramePointer + 1;
|
||||||
}
|
}
|
||||||
@@ -185,8 +181,6 @@ ArErr run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
|||||||
} else if (object->type == TYPE_NATIVE_FUNCTION) {
|
} else if (object->type == TYPE_NATIVE_FUNCTION) {
|
||||||
ArErr err = no_err;
|
ArErr err = no_err;
|
||||||
state->registers[0] = object->value.native_fn(argc, argv, &err, state);
|
state->registers[0] = object->value.native_fn(argc, argv, &err, state);
|
||||||
if (to_free_args)
|
|
||||||
free(argv);
|
|
||||||
if (err.exists && strlen(err.path) == 0) {
|
if (err.exists && strlen(err.path) == 0) {
|
||||||
err.line = state->source_location.line;
|
err.line = state->source_location.line;
|
||||||
err.column = state->source_location.column;
|
err.column = state->source_location.column;
|
||||||
@@ -195,8 +189,6 @@ ArErr run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
|||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if (to_free_args)
|
|
||||||
free(argv);
|
|
||||||
ArgonObject *type_object_name =
|
ArgonObject *type_object_name =
|
||||||
get_field_for_class(get_field(original_object, "__class__", false, false),
|
get_field_for_class(get_field(original_object, "__class__", false, false),
|
||||||
"__name__", original_object);
|
"__name__", original_object);
|
||||||
|
|||||||
@@ -123,7 +123,6 @@ void darray_armem_free(darray_armem *arr, void (*free_data)(void *)) {
|
|||||||
free_data(element);
|
free_data(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(arr->data);
|
|
||||||
arr->data = NULL;
|
arr->data = NULL;
|
||||||
arr->size = 0;
|
arr->size = 0;
|
||||||
arr->capacity = 0;
|
arr->capacity = 0;
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
|
|
||||||
struct hashmap_GC *createHashmap_GC() {
|
struct hashmap_GC *createHashmap_GC() {
|
||||||
size_t size = 8;
|
size_t size = 8;
|
||||||
struct hashmap_GC *t = (struct hashmap_GC *)ar_alloc(sizeof(struct hashmap_GC));
|
struct hashmap_GC *t =
|
||||||
|
(struct hashmap_GC *)ar_alloc(sizeof(struct hashmap_GC));
|
||||||
t->size = size;
|
t->size = size;
|
||||||
t->order = 1;
|
t->order = 1;
|
||||||
t->list = (struct node_GC **)ar_alloc(sizeof(struct node_GC *) * size);
|
t->list = (struct node_GC **)ar_alloc(sizeof(struct node_GC *) * size);
|
||||||
@@ -47,7 +48,9 @@ void resize_hashmap_GC(struct hashmap_GC *t) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int hashCode_GC(struct hashmap_GC *t, uint64_t hash) { return hash & (t->size - 1); }
|
int hashCode_GC(struct hashmap_GC *t, uint64_t hash) {
|
||||||
|
return hash & (t->size - 1);
|
||||||
|
}
|
||||||
|
|
||||||
int hashmap_remove_GC(struct hashmap_GC *t, uint64_t hash) {
|
int hashmap_remove_GC(struct hashmap_GC *t, uint64_t hash) {
|
||||||
int pos = hashCode_GC(t, hash);
|
int pos = hashCode_GC(t, hash);
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ ArgonObject *get_field_for_class_l(ArgonObject *target, char *name,
|
|||||||
|
|
||||||
ArgonObject *get_field_l(ArgonObject *target, char *name, size_t length,
|
ArgonObject *get_field_l(ArgonObject *target, char *name, size_t length,
|
||||||
bool recursive, bool disable_method_wrapper) {
|
bool recursive, bool disable_method_wrapper) {
|
||||||
|
if(!target|| !target->dict) return NULL;
|
||||||
char *field = "__class__";
|
char *field = "__class__";
|
||||||
size_t field_size = strlen(field);
|
size_t field_size = strlen(field);
|
||||||
ArgonObject *object = hashmap_lookup_GC(
|
ArgonObject *object = hashmap_lookup_GC(
|
||||||
|
|||||||
28
src/runtime/objects/term/term.c
Normal file
28
src/runtime/objects/term/term.c
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 William Bell
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
#include "term.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "../../call/call.h"
|
||||||
|
|
||||||
|
ArgonObject *term_log(size_t argc, ArgonObject **argv, ArErr *err,
|
||||||
|
RuntimeState *state) {
|
||||||
|
for (size_t i = 0; i < argc; i++) {
|
||||||
|
if (i != 0)
|
||||||
|
printf(" ");
|
||||||
|
ArgonObject *string_convert_method = get_field_for_class(
|
||||||
|
get_field(argv[i], "__class__", false, false), "__string__", argv[i]);
|
||||||
|
|
||||||
|
if (string_convert_method) {
|
||||||
|
ArgonObject *string_object =
|
||||||
|
argon_call(string_convert_method, 0, NULL, err, state);
|
||||||
|
fwrite(string_object->value.as_str.data, sizeof(char),
|
||||||
|
string_object->value.as_str.length, stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
return ARGON_NULL;
|
||||||
|
}
|
||||||
16
src/runtime/objects/term/term.h
Normal file
16
src/runtime/objects/term/term.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 William Bell
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef runtime_term_H
|
||||||
|
#define runtime_term_H
|
||||||
|
#include "../../objects/literals/literals.h"
|
||||||
|
#include "../../objects/object.h"
|
||||||
|
#include "../../runtime.h"
|
||||||
|
|
||||||
|
ArgonObject *term_log(size_t argc, ArgonObject **argv, ArErr *err,
|
||||||
|
RuntimeState *state);
|
||||||
|
|
||||||
|
#endif // runtime_term_H
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "../err.h"
|
#include "../err.h"
|
||||||
#include "../hash_data/hash_data.h"
|
#include "../hash_data/hash_data.h"
|
||||||
#include "../translator/translator.h"
|
#include "../translator/translator.h"
|
||||||
|
#include "access/access.h"
|
||||||
#include "call/call.h"
|
#include "call/call.h"
|
||||||
#include "declaration/declaration.h"
|
#include "declaration/declaration.h"
|
||||||
#include "internals/hashmap/hashmap.h"
|
#include "internals/hashmap/hashmap.h"
|
||||||
@@ -15,8 +16,8 @@
|
|||||||
#include "objects/literals/literals.h"
|
#include "objects/literals/literals.h"
|
||||||
#include "objects/object.h"
|
#include "objects/object.h"
|
||||||
#include "objects/string/string.h"
|
#include "objects/string/string.h"
|
||||||
|
#include "objects/term/term.h"
|
||||||
#include "objects/type/type.h"
|
#include "objects/type/type.h"
|
||||||
#include "access/access.h"
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <gc/gc.h>
|
#include <gc/gc.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
@@ -108,6 +109,23 @@ ArgonObject *BASE_CLASS___init__(size_t argc, ArgonObject **argv, ArErr *err,
|
|||||||
return ARGON_NULL;
|
return ARGON_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArgonObject *BASE_CLASS___string__(size_t argc, ArgonObject **argv, ArErr *err,
|
||||||
|
RuntimeState *state) {
|
||||||
|
(void)state;
|
||||||
|
if (argc != 1) {
|
||||||
|
*err = create_err(0, 0, 0, "", "Runtime Error",
|
||||||
|
"__string__ expects 1 arguments, got %" PRIu64, argc);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArgonObject *object_name = get_field_for_class(argv[0], "__name__", NULL);
|
||||||
|
ArgonObject *class_name = get_field_for_class(
|
||||||
|
get_field(argv[0], "__class__", false, false), "__name__", NULL);
|
||||||
|
|
||||||
|
char buffer[100];
|
||||||
|
snprintf(buffer, sizeof(buffer), "<%.*s %.*s at %p>", (int)class_name->value.as_str.length, class_name->value.as_str.data, (int)object_name->value.as_str.length, object_name->value.as_str.data,argv[0]);
|
||||||
|
return new_string_object_null_terminated(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
ArgonObject *ARGON_STRING_TYPE___init__(size_t argc, ArgonObject **argv,
|
ArgonObject *ARGON_STRING_TYPE___init__(size_t argc, ArgonObject **argv,
|
||||||
ArErr *err, RuntimeState *state) {
|
ArErr *err, RuntimeState *state) {
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
@@ -128,11 +146,11 @@ ArgonObject *ARGON_STRING_TYPE___init__(size_t argc, ArgonObject **argv,
|
|||||||
argon_call(string_convert_method, 0, NULL, err, state);
|
argon_call(string_convert_method, 0, NULL, err, state);
|
||||||
if (err->exists)
|
if (err->exists)
|
||||||
return ARGON_NULL;
|
return ARGON_NULL;
|
||||||
object->value.as_str.data =
|
self->value.as_str.data =
|
||||||
ar_alloc_atomic(string_object->value.as_str.length);
|
ar_alloc_atomic(string_object->value.as_str.length);
|
||||||
memcpy(object->value.as_str.data, string_object->value.as_str.data,
|
memcpy(self->value.as_str.data, string_object->value.as_str.data,
|
||||||
string_object->value.as_str.length);
|
string_object->value.as_str.length);
|
||||||
object->value.as_str.length = string_object->value.as_str.length;
|
self->value.as_str.length = string_object->value.as_str.length;
|
||||||
}
|
}
|
||||||
return ARGON_NULL;
|
return ARGON_NULL;
|
||||||
}
|
}
|
||||||
@@ -165,7 +183,7 @@ ArgonObject *ARGON_STRING_TYPE___string__(size_t argc, ArgonObject **argv,
|
|||||||
(void)state;
|
(void)state;
|
||||||
if (argc != 1) {
|
if (argc != 1) {
|
||||||
*err = create_err(0, 0, 0, "", "Runtime Error",
|
*err = create_err(0, 0, 0, "", "Runtime Error",
|
||||||
"__init__ expects 1 arguments, got %" PRIu64, argc);
|
"__string__ expects 1 arguments, got %" PRIu64, argc);
|
||||||
}
|
}
|
||||||
return argv[0];
|
return argv[0];
|
||||||
}
|
}
|
||||||
@@ -218,6 +236,8 @@ void bootstrap_types() {
|
|||||||
create_argon_native_function("__new__", BASE_CLASS___new__));
|
create_argon_native_function("__new__", BASE_CLASS___new__));
|
||||||
add_field(BASE_CLASS, "__init__",
|
add_field(BASE_CLASS, "__init__",
|
||||||
create_argon_native_function("__init__", BASE_CLASS___new__));
|
create_argon_native_function("__init__", BASE_CLASS___new__));
|
||||||
|
add_field(BASE_CLASS, "__string__",
|
||||||
|
create_argon_native_function("__string__", BASE_CLASS___string__));
|
||||||
add_field(ARGON_TYPE_TYPE, "__call__",
|
add_field(ARGON_TYPE_TYPE, "__call__",
|
||||||
create_argon_native_function("__call__", ARGON_TYPE_TYPE___call__));
|
create_argon_native_function("__call__", ARGON_TYPE_TYPE___call__));
|
||||||
add_field(
|
add_field(
|
||||||
@@ -228,7 +248,8 @@ void bootstrap_types() {
|
|||||||
create_argon_native_function("__string__", ARGON_STRING_TYPE___string__));
|
create_argon_native_function("__string__", ARGON_STRING_TYPE___string__));
|
||||||
add_field(ARGON_BOOL_TYPE, "__new__",
|
add_field(ARGON_BOOL_TYPE, "__new__",
|
||||||
create_argon_native_function("__new__", ARGON_BOOL_TYPE___new__));
|
create_argon_native_function("__new__", ARGON_BOOL_TYPE___new__));
|
||||||
ACCESS_FUNCTION = create_argon_native_function("ACCESS_FUNCTION", ARGON_TYPE_TYPE___get_attr__);
|
ACCESS_FUNCTION = create_argon_native_function("ACCESS_FUNCTION",
|
||||||
|
ARGON_TYPE_TYPE___get_attr__);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_to_scope(Stack *stack, char *name, ArgonObject *value) {
|
void add_to_scope(Stack *stack, char *name, ArgonObject *value) {
|
||||||
@@ -243,6 +264,11 @@ void bootstrap_globals() {
|
|||||||
add_to_scope(Global_Scope, "string", ARGON_STRING_TYPE);
|
add_to_scope(Global_Scope, "string", ARGON_STRING_TYPE);
|
||||||
add_to_scope(Global_Scope, "type", ARGON_TYPE_TYPE);
|
add_to_scope(Global_Scope, "type", ARGON_TYPE_TYPE);
|
||||||
add_to_scope(Global_Scope, "boolean", ARGON_BOOL_TYPE);
|
add_to_scope(Global_Scope, "boolean", ARGON_BOOL_TYPE);
|
||||||
|
|
||||||
|
ArgonObject *argon_term = new_object();
|
||||||
|
add_field(argon_term, "__init__", ARGON_NULL);
|
||||||
|
add_field(argon_term, "log", create_argon_native_function("log", term_log));
|
||||||
|
add_to_scope(Global_Scope, "term", argon_term);
|
||||||
}
|
}
|
||||||
|
|
||||||
int compare_by_order(const void *a, const void *b) {
|
int compare_by_order(const void *a, const void *b) {
|
||||||
@@ -341,7 +367,8 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
|||||||
ArErr err = no_err;
|
ArErr err = no_err;
|
||||||
uint8_t to_register = pop_byte(translated, state);
|
uint8_t to_register = pop_byte(translated, state);
|
||||||
ArgonObject *args[] = {ARGON_BOOL_TYPE, state->registers[0]};
|
ArgonObject *args[] = {ARGON_BOOL_TYPE, state->registers[0]};
|
||||||
state->registers[to_register] = ARGON_BOOL_TYPE___new__(2, args, &err, state);
|
state->registers[to_register] =
|
||||||
|
ARGON_BOOL_TYPE___new__(2, args, &err, state);
|
||||||
return err;
|
return err;
|
||||||
case OP_JUMP_IF_FALSE:;
|
case OP_JUMP_IF_FALSE:;
|
||||||
uint8_t from_register = pop_byte(translated, state);
|
uint8_t from_register = pop_byte(translated, state);
|
||||||
@@ -384,8 +411,8 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
|||||||
size_t length = pop_bytecode(translated, state);
|
size_t length = pop_bytecode(translated, state);
|
||||||
call_instance call_instance = {
|
call_instance call_instance = {
|
||||||
state->call_instance, state->registers[0],
|
state->call_instance, state->registers[0],
|
||||||
checked_malloc(length * sizeof(ArgonObject *)), length};
|
ar_alloc(length * sizeof(ArgonObject *)), length};
|
||||||
state->call_instance = checked_malloc(sizeof(call_instance));
|
state->call_instance = ar_alloc(sizeof(call_instance));
|
||||||
*state->call_instance = call_instance;
|
*state->call_instance = call_instance;
|
||||||
break;
|
break;
|
||||||
case OP_INSERT_ARG:;
|
case OP_INSERT_ARG:;
|
||||||
@@ -396,10 +423,7 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
|||||||
err = run_call(state->call_instance->to_call,
|
err = run_call(state->call_instance->to_call,
|
||||||
state->call_instance->args_length,
|
state->call_instance->args_length,
|
||||||
state->call_instance->args, state, false);
|
state->call_instance->args, state, false);
|
||||||
free(state->call_instance->args);
|
state->call_instance = (*state->call_instance).previous;
|
||||||
call_instance = *state->call_instance;
|
|
||||||
free(state->call_instance);
|
|
||||||
state->call_instance = call_instance.previous;
|
|
||||||
return err;
|
return err;
|
||||||
// ArgonObject *object = state->registers[from_register];
|
// ArgonObject *object = state->registers[from_register];
|
||||||
// char *field = "__class__";
|
// char *field = "__class__";
|
||||||
@@ -426,7 +450,8 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
|||||||
pop_bytecode(translated, state)};
|
pop_bytecode(translated, state)};
|
||||||
break;
|
break;
|
||||||
case OP_LOAD_BOOL:
|
case OP_LOAD_BOOL:
|
||||||
state->registers[0] = pop_byte(translated, state)?ARGON_TRUE:ARGON_FALSE;
|
state->registers[0] =
|
||||||
|
pop_byte(translated, state) ? ARGON_TRUE : ARGON_FALSE;
|
||||||
break;
|
break;
|
||||||
case OP_LOAD_ACCESS_FUNCTION:
|
case OP_LOAD_ACCESS_FUNCTION:
|
||||||
state->registers[0] = ACCESS_FUNCTION;
|
state->registers[0] = ACCESS_FUNCTION;
|
||||||
@@ -440,7 +465,7 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
|||||||
|
|
||||||
RuntimeState init_runtime_state(Translated translated, char *path) {
|
RuntimeState init_runtime_state(Translated translated, char *path) {
|
||||||
RuntimeState runtime = {
|
RuntimeState runtime = {
|
||||||
checked_malloc(translated.registerCount * sizeof(ArgonObject *)),
|
ar_alloc(translated.registerCount * sizeof(ArgonObject *)),
|
||||||
0,
|
0,
|
||||||
path,
|
path,
|
||||||
NULL,
|
NULL,
|
||||||
@@ -450,10 +475,6 @@ RuntimeState init_runtime_state(Translated translated, char *path) {
|
|||||||
return runtime;
|
return runtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_runtime_state(RuntimeState runtime_state) {
|
|
||||||
free(runtime_state.registers);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack *create_scope(Stack *prev) {
|
Stack *create_scope(Stack *prev) {
|
||||||
Stack *stack = ar_alloc(sizeof(Stack));
|
Stack *stack = ar_alloc(sizeof(Stack));
|
||||||
stack->scope = createHashmap_GC();
|
stack->scope = createHashmap_GC();
|
||||||
@@ -465,7 +486,7 @@ ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
|
|||||||
state.head = 0;
|
state.head = 0;
|
||||||
|
|
||||||
StackFrame *currentStackFrame =
|
StackFrame *currentStackFrame =
|
||||||
checked_malloc(sizeof(StackFrame) * STACKFRAME_CHUNKS);
|
ar_alloc(sizeof(StackFrame) * STACKFRAME_CHUNKS);
|
||||||
*currentStackFrame = (StackFrame){translated, state, stack, NULL, 0};
|
*currentStackFrame = (StackFrame){translated, state, stack, NULL, 0};
|
||||||
currentStackFrame->state.currentStackFramePointer = ¤tStackFrame;
|
currentStackFrame->state.currentStackFramePointer = ¤tStackFrame;
|
||||||
ArErr err = no_err;
|
ArErr err = no_err;
|
||||||
@@ -477,19 +498,7 @@ ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
|
|||||||
run_instruction(¤tStackFrame->translated,
|
run_instruction(¤tStackFrame->translated,
|
||||||
¤tStackFrame->state, ¤tStackFrame->stack);
|
¤tStackFrame->state, ¤tStackFrame->stack);
|
||||||
}
|
}
|
||||||
StackFrame *tempStackFrame = currentStackFrame;
|
|
||||||
|
|
||||||
while (currentStackFrame->state.call_instance) {
|
|
||||||
free(currentStackFrame->state.call_instance->args);
|
|
||||||
call_instance call_instance = *currentStackFrame->state.call_instance;
|
|
||||||
free(currentStackFrame->state.call_instance);
|
|
||||||
currentStackFrame->state.call_instance = call_instance.previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentStackFrame = currentStackFrame->previousStackFrame;
|
currentStackFrame = currentStackFrame->previousStackFrame;
|
||||||
if (tempStackFrame->depth % STACKFRAME_CHUNKS == 0) {
|
|
||||||
free(tempStackFrame);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -73,8 +73,6 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
|||||||
|
|
||||||
RuntimeState init_runtime_state(Translated translated, char *path);
|
RuntimeState init_runtime_state(Translated translated, char *path);
|
||||||
|
|
||||||
void free_runtime_state(RuntimeState runtime_state);
|
|
||||||
|
|
||||||
Stack *create_scope(Stack *prev);
|
Stack *create_scope(Stack *prev);
|
||||||
|
|
||||||
ArErr runtime(Translated translated, RuntimeState state, Stack *stack);
|
ArErr runtime(Translated translated, RuntimeState state, Stack *stack);
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ size_t translate_parsed_call(Translated *translated, ParsedCall *call,
|
|||||||
translate_parsed(translated, call->to_call, err);
|
translate_parsed(translated, call->to_call, err);
|
||||||
size_t first = push_instruction_byte(translated, OP_INIT_CALL);
|
size_t first = push_instruction_byte(translated, OP_INIT_CALL);
|
||||||
push_instruction_code(translated, call->args.size);
|
push_instruction_code(translated, call->args.size);
|
||||||
|
|
||||||
|
push_instruction_byte(translated, OP_NEW_SCOPE);
|
||||||
for (size_t i = 0; i < call->args.size; i++) {
|
for (size_t i = 0; i < call->args.size; i++) {
|
||||||
translate_parsed(translated, darray_get(&call->args, i), err);
|
translate_parsed(translated, darray_get(&call->args, i), err);
|
||||||
if (err->exists)
|
if (err->exists)
|
||||||
@@ -27,5 +29,6 @@ size_t translate_parsed_call(Translated *translated, ParsedCall *call,
|
|||||||
push_instruction_code(translated, 1);
|
push_instruction_code(translated, 1);
|
||||||
|
|
||||||
push_instruction_byte(translated, OP_CALL);
|
push_instruction_byte(translated, OP_CALL);
|
||||||
|
push_instruction_byte(translated, OP_POP_SCOPE);
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
10
testing.ar
10
testing.ar
@@ -1,6 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 William Bell
|
let split(url) = do
|
||||||
#
|
let split = url.splitN("?", 2)
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
if (split.length != 2) return {path: split[0], query: {}}
|
||||||
|
else return {path: split[0], query: decodeURLQuery(split[1])}
|
||||||
let f()="hello world"
|
|
||||||
type(string(f()))(10)
|
|
||||||
Reference in New Issue
Block a user