add function calling

This commit is contained in:
William Bell
2025-08-04 23:31:25 +01:00
parent 6c05eff6a4
commit a8acafffe9
13 changed files with 177 additions and 2185037 deletions

4
app.py Normal file
View File

@@ -0,0 +1,4 @@
def factorial(x):
if x==1: return 1
return factorial(x-1) + x
factorial(10000)

View File

@@ -36,9 +36,12 @@ typedef struct Stack {
struct argon_function_struct { struct argon_function_struct {
uint8_t* bytecode; uint8_t* bytecode;
size_t bytecode_length; size_t bytecode_length;
Stack stack; Stack *stack;
size_t number_of_parameters; size_t number_of_parameters;
struct string_struct *parameters; struct string_struct *parameters;
char* path;
uint64_t line;
uint64_t column;
}; };

View File

@@ -16,6 +16,9 @@ ParsedValueReturn parse_call(char *file, DArray *tokens, size_t *index,
ParsedValue *to_call) { ParsedValue *to_call) {
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
ParsedCall *call = checked_malloc(sizeof(ParsedCall)); ParsedCall *call = checked_malloc(sizeof(ParsedCall));
Token *token = darray_get(tokens, *index);
call->line = token->line;
call->column = token->column;
call->to_call = to_call; call->to_call = to_call;
parsedValue->data = call; parsedValue->data = call;
parsedValue->type = AST_CALL; parsedValue->type = AST_CALL;
@@ -29,7 +32,7 @@ ParsedValueReturn parse_call(char *file, DArray *tokens, size_t *index,
free(parsedValue); free(parsedValue);
return (ParsedValueReturn){err, NULL}; return (ParsedValueReturn){err, NULL};
} }
Token *token = darray_get(tokens, *index); token = darray_get(tokens, *index);
if (token->type != TOKEN_RPAREN) { if (token->type != TOKEN_RPAREN) {
while ((*index) < tokens->size) { while ((*index) < tokens->size) {
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);

View File

@@ -12,6 +12,8 @@
typedef struct { typedef struct {
ParsedValue * to_call; ParsedValue * to_call;
DArray args; DArray args;
uint64_t line;
uint64_t column;
} ParsedCall; } ParsedCall;
// Function declaration for parsing an identifier // Function declaration for parsing an identifier

View File

@@ -0,0 +1,111 @@
/*
* SPDX-FileCopyrightText: 2025 William Bell
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "call.h"
#include "../../hash_data/hash_data.h"
#include "../objects/string/string.h"
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#if defined(_WIN32)
#include <psapi.h>
#include <windows.h>
double get_memory_usage_mb() {
PROCESS_MEMORY_COUNTERS pmc;
if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
return pmc.WorkingSetSize / (1024.0 * 1024.0); // in MB
}
return 0.0;
}
#elif defined(__APPLE__)
#include <mach/mach.h>
double get_memory_usage_mb() {
struct task_basic_info info;
mach_msg_type_number_t size = TASK_BASIC_INFO_COUNT;
if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size) ==
KERN_SUCCESS) {
return info.resident_size / (1024.0 * 1024.0); // in MB
}
return 0.0;
}
#elif defined(__linux__)
#include <stdlib.h>
#include <string.h>
double get_memory_usage_mb() {
FILE *fp = fopen("/proc/self/status", "r");
if (!fp)
return 0.0;
char line[256];
size_t memory_kb = 0;
while (fgets(line, sizeof(line), fp)) {
if (strncmp(line, "VmRSS:", 6) == 0) {
sscanf(line + 6, "%zu", &memory_kb);
break;
}
}
fclose(fp);
return memory_kb / 1024.0; // Convert KB to MB
}
#else
double get_memory_usage_mb() {
// Unsupported platform
return 0.0;
}
#endif
void run_call(Translated *translated, RuntimeState *state) {
uint8_t from_register = pop_byte(translated, state);
uint8_t source_location_index = pop_bytecode(translated, state);
ArgonObject *object = state->registers[from_register];
if (object->type == TYPE_FUNCTION) {
Stack *scope = create_scope(object->value.argon_fn.stack);
for (size_t i = 0; i < state->call_args_length; i++) {
struct string_struct key = object->value.argon_fn.parameters[i];
ArgonObject *value = state->call_args[i];
uint64_t hash = siphash64_bytes(key.data, key.length, siphash_key);
hashmap_insert_GC(scope->scope, hash,
new_string_object(key.data, key.length), value, 0);
}
DArray bytecode_darray = {object->value.argon_fn.bytecode, sizeof(uint8_t),
object->value.argon_fn.bytecode_length,
object->value.argon_fn.bytecode_length, false};
StackFrame new_stackFrame = {
(Translated){translated->registerCount, NULL, bytecode_darray,
translated->source_locations, translated->constants,
object->value.argon_fn.path},
(RuntimeState){state->registers, 0, state->path,
state->currentStackFramePointer, state->call_args,
state->call_args_length},
scope,
*state->currentStackFramePointer,
no_err,
(*state->currentStackFramePointer)->depth + 1};
if ((*state->currentStackFramePointer)->depth >= 10000) {
double logval = log10((double)(*state->currentStackFramePointer)->depth);
if (floor(logval) == logval) {
SourceLocation *source_location =
darray_get(&translated->source_locations, source_location_index);
fprintf(stderr,
"Warning: %s:%zu:%zu the call stack depth has exceeded %zu\n",
state->path, source_location->line, source_location->column,
(*state->currentStackFramePointer)->depth);
}
};
*state->currentStackFramePointer = checked_malloc(sizeof(StackFrame));
**state->currentStackFramePointer = new_stackFrame;
}
}

View File

@@ -0,0 +1,13 @@
/*
* SPDX-FileCopyrightText: 2025 William Bell
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef runtime_call_H
#define runtime_call_H
#include "../runtime.h"
void run_call(Translated *translated, RuntimeState *state);
#endif // runtime_call_H

View File

@@ -22,6 +22,7 @@ void load_argon_function(Translated *translated, RuntimeState *state,
uint64_t offset = pop_bytecode(translated, state); uint64_t offset = pop_bytecode(translated, state);
uint64_t length = pop_bytecode(translated, state); uint64_t length = pop_bytecode(translated, state);
add_field(object, "__name__", new_string_object(arena_get(&translated->constants, offset), length)); add_field(object, "__name__", new_string_object(arena_get(&translated->constants, offset), length));
object->value.argon_fn.path = translated->path;
object->value.argon_fn.number_of_parameters = pop_bytecode(translated, state); object->value.argon_fn.number_of_parameters = pop_bytecode(translated, state);
object->value.argon_fn.parameters = object->value.argon_fn.parameters =
ar_alloc(object->value.argon_fn.number_of_parameters * sizeof(struct string_struct)); ar_alloc(object->value.argon_fn.number_of_parameters * sizeof(struct string_struct));
@@ -35,6 +36,6 @@ void load_argon_function(Translated *translated, RuntimeState *state,
length = pop_bytecode(translated, state); length = pop_bytecode(translated, state);
object->value.argon_fn.bytecode = arena_get(&translated->constants, offset); object->value.argon_fn.bytecode = arena_get(&translated->constants, offset);
object->value.argon_fn.bytecode_length = length; object->value.argon_fn.bytecode_length = length;
object->value.argon_fn.stack = *stack; object->value.argon_fn.stack = stack;
state->registers[0]=object; state->registers[0]=object;
} }

View File

@@ -9,6 +9,7 @@
#include "../hash_data/hash_data.h" #include "../hash_data/hash_data.h"
#include "../translator/translator.h" #include "../translator/translator.h"
#include "declaration/declaration.h" #include "declaration/declaration.h"
#include "call/call.h"
#include "internals/hashmap/hashmap.h" #include "internals/hashmap/hashmap.h"
#include "objects/functions/functions.h" #include "objects/functions/functions.h"
#include "objects/literals/literals.h" #include "objects/literals/literals.h"
@@ -212,26 +213,27 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
state->call_args[pop_bytecode(translated, state)] = state->call_args[pop_bytecode(translated, state)] =
state->registers[to_register]; state->registers[to_register];
break; break;
case OP_RESET_ARGS:;
free(state->call_args);
state->call_args = NULL;
break;
case OP_CALL: case OP_CALL:
from_register = pop_byte(translated, state); run_call(translated, state);
ArgonObject *object = state->registers[from_register]; // ArgonObject *object = state->registers[from_register];
char *field = "__class__"; // char *field = "__class__";
uint64_t hash = siphash64_bytes(field, strlen(field), siphash_key); // uint64_t hash = siphash64_bytes(field, strlen(field), siphash_key);
ArgonObject *class = hashmap_lookup_GC(object->dict, hash); // ArgonObject *class = hashmap_lookup_GC(object->dict, hash);
field = "__name__"; // field = "__name__";
hash = siphash64_bytes(field, strlen(field), siphash_key); // hash = siphash64_bytes(field, strlen(field), siphash_key);
ArgonObject *class_name = hashmap_lookup_GC(class->dict, hash); // ArgonObject *class_name = hashmap_lookup_GC(class->dict, hash);
hash = siphash64_bytes(field, strlen(field), siphash_key); // hash = siphash64_bytes(field, strlen(field), siphash_key);
ArgonObject *object_name = hashmap_lookup_GC(object->dict, hash); // ArgonObject *object_name = hashmap_lookup_GC(object->dict, hash);
if (object_name) { // if (object_name) {
printf("call <%.*s %.*s at %p>\n", (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, object); // printf("call <%.*s %.*s at %p>\n",
} else { // (int)class_name->value.as_str.length,
printf("call <%.*s object at %p>\n", (int)class_name->value.as_str.length, class_name->value.as_str.data, object); // class_name->value.as_str.data,(int)object_name->value.as_str.length,
} // object_name->value.as_str.data, object);
// } else {
// printf("call <%.*s object at %p>\n",
// (int)class_name->value.as_str.length, class_name->value.as_str.data,
// object);
// }
break; break;
default: default:
return create_err(0, 0, 0, NULL, "Runtime Error", "Invalid Opcode %#x", return create_err(0, 0, 0, NULL, "Runtime Error", "Invalid Opcode %#x",
@@ -245,10 +247,9 @@ RuntimeState init_runtime_state(Translated translated, char *path) {
checked_malloc(translated.registerCount * sizeof(ArgonObject *)), checked_malloc(translated.registerCount * sizeof(ArgonObject *)),
0, 0,
path, path,
ARGON_NULL,
NULL, NULL,
NULL, NULL,
NULL}; 0};
return runtime; return runtime;
} }
@@ -267,9 +268,10 @@ Stack *create_scope(Stack *prev) {
ArErr runtime(Translated translated, RuntimeState state, Stack *stack) { ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
state.head = 0; state.head = 0;
StackFrame *currentStackFrame = checked_malloc(sizeof(StackFrame)); StackFrame *currentStackFrame = checked_malloc(sizeof(StackFrame));
*currentStackFrame = (StackFrame){translated, state, stack, NULL, no_err}; *currentStackFrame = (StackFrame){translated, state, stack, NULL, no_err};
state.currentStackFramePointer = &currentStackFrame; currentStackFrame->state.currentStackFramePointer = &currentStackFrame;
ArErr err = no_err; ArErr err = no_err;
while (currentStackFrame) { while (currentStackFrame) {
while (currentStackFrame->state.head < while (currentStackFrame->state.head <
@@ -282,9 +284,8 @@ ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
StackFrame *tempStackFrame = currentStackFrame; StackFrame *tempStackFrame = currentStackFrame;
err = currentStackFrame->err; err = currentStackFrame->err;
currentStackFrame = currentStackFrame->previousStackFrame; currentStackFrame = currentStackFrame->previousStackFrame;
if (currentStackFrame)
free_runtime_state(tempStackFrame->state);
free(tempStackFrame); free(tempStackFrame);
} }
return err; return err;
} }

View File

@@ -14,17 +14,13 @@
typedef struct StackFrame StackFrame; typedef struct StackFrame StackFrame;
typedef struct RuntimeState RuntimeState; typedef struct RuntimeState RuntimeState;
typedef ArErr (*error_result)(ArErr, Translated *translated,
RuntimeState *state, struct Stack **stack);
typedef struct RuntimeState { typedef struct RuntimeState {
ArgonObject **registers; ArgonObject **registers;
size_t head; size_t head;
char *path; char *path;
ArgonObject *return_value;
StackFrame **currentStackFramePointer; StackFrame **currentStackFramePointer;
error_result result;
ArgonObject** call_args; ArgonObject** call_args;
size_t call_args_length;
} RuntimeState; } RuntimeState;
typedef struct StackFrame { typedef struct StackFrame {
@@ -33,6 +29,7 @@ typedef struct StackFrame {
Stack *stack; Stack *stack;
StackFrame *previousStackFrame; StackFrame *previousStackFrame;
ArErr err; ArErr err;
uint64_t depth;
} StackFrame; } StackFrame;
void bootstrap_types(); void bootstrap_types();

View File

@@ -109,6 +109,7 @@ resets the arguments buffer to NULL
call a function with args call a function with args
1. the register containing the function to call. (*) 1. the register containing the function to call. (*)
4. the index of the source location.
## OP_SWAP_REGISTERS ## OP_SWAP_REGISTERS

View File

@@ -22,6 +22,12 @@ size_t translate_parsed_call(Translated *translated, ParsedCall* call, ArErr *er
return first; return first;
push_instruction_byte(translated, OP_CALL); push_instruction_byte(translated, OP_CALL);
push_instruction_byte(translated, 0); push_instruction_byte(translated, 0);
push_instruction_byte(translated, OP_RESET_ARGS); SourceLocation source_locations = {
call->line,
call->column,
1
};
push_instruction_code(translated, translated->source_locations.size);
darray_push(&translated->source_locations, &source_locations);
return first; return first;
} }

1092503
test.txt

File diff suppressed because it is too large Load Diff

1092503
testing.ar

File diff suppressed because it is too large Load Diff