add hashmap to scope and identifier loading at runtime

This commit is contained in:
2025-07-12 03:33:59 +01:00
parent fe7eaa8de3
commit c0eb9e3a04
18 changed files with 141 additions and 35 deletions

View File

@@ -3,6 +3,7 @@
#include <gmp.h> #include <gmp.h>
#include "runtime/internals/dynamic_array_armem/darray_armem.h" #include "runtime/internals/dynamic_array_armem/darray_armem.h"
#include "runtime/internals/hashmap/hashmap.h"
typedef struct ArgonObject ArgonObject; // forward declaration typedef struct ArgonObject ArgonObject; // forward declaration
@@ -22,7 +23,7 @@ struct string_struct {
}; };
typedef struct Stack { typedef struct Stack {
ArgonObject *scope; struct hashmap_GC *scope;
struct Stack *prev; struct Stack *prev;
} Stack; } Stack;

View File

@@ -80,6 +80,7 @@ void output_err(ArErr err) {
while ((len = getline(&buffer, &size, file)) != -1) { while ((len = getline(&buffer, &size, file)) != -1) {
if (current_line == err.line) { if (current_line == err.line) {
printf("bruh\n");
break; break;
} }
current_line++; current_line++;
@@ -89,12 +90,13 @@ void output_err(ArErr err) {
fprintf(stderr, " "); fprintf(stderr, " ");
} }
fprintf(stderr, "|\n"); fprintf(stderr, "|\n");
getline(&buffer, &size, file);
char *line_starts = buffer; char *line_starts = buffer;
size_t skipped_chars = 0;
while (*line_starts && isspace((unsigned char)*line_starts) && line_starts-buffer < err.column-1) { while (*line_starts && isspace((unsigned char)*line_starts) && line_starts-buffer < err.column-1) {
line_starts++; line_starts++;
err.column--; err.column--;
skipped_chars++;
} }
fprintf(stderr, " %zu | ", err.line); fprintf(stderr, " %zu | ", err.line);
if (err.length) { if (err.length) {
@@ -104,7 +106,7 @@ void output_err(ArErr err) {
fprintf(stderr, "%.*s", err.length, line_starts + err.column - 1); fprintf(stderr, "%.*s", err.length, line_starts + err.column - 1);
dye_style(stderr, DYE_STYLE_RESET); dye_style(stderr, DYE_STYLE_RESET);
dyefg(stderr, DYE_RESET); dyefg(stderr, DYE_RESET);
fprintf(stderr, "%s", line_starts + (int)err.column + err.length - 1); fprintf(stderr, "%.*s", (int)len - (int)skipped_chars-(int)err.column-(int)err.length, line_starts + (int)err.column + err.length - 1);
for (int64_t i = 0; i < err.column - 1; i++) { for (int64_t i = 0; i < err.column - 1; i++) {
fprintf(stderr, " "); fprintf(stderr, " ");
} }

View File

@@ -84,6 +84,7 @@ 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) { int load_cache(Translated *translated_dest, char *joined_paths, uint64_t hash) {
bool translated_inited = false;
FILE *bytecode_file = fopen(joined_paths, "rb"); FILE *bytecode_file = fopen(joined_paths, "rb");
if (!bytecode_file) if (!bytecode_file)
return 1; return 1;
@@ -138,6 +139,16 @@ int load_cache(Translated *translated_dest, char *joined_paths, uint64_t hash) {
} }
bytecodeSize = le64toh(bytecodeSize); bytecodeSize = le64toh(bytecodeSize);
uint64_t sourceLocationSize;
if (fread(&sourceLocationSize, 1, sizeof(sourceLocationSize),
bytecode_file) != sizeof(sourceLocationSize)) {
goto FAILED;
}
sourceLocationSize = le64toh(sourceLocationSize);
*translated_dest = init_translator();
translated_inited = true;
arena_resize(&translated_dest->constants, constantsSize); arena_resize(&translated_dest->constants, constantsSize);
if (fread(translated_dest->constants.data, 1, constantsSize, bytecode_file) != if (fread(translated_dest->constants.data, 1, constantsSize, bytecode_file) !=
@@ -152,16 +163,24 @@ int load_cache(Translated *translated_dest, char *joined_paths, uint64_t hash) {
goto FAILED; goto FAILED;
} }
darray_resize(&translated_dest->source_locations, sourceLocationSize);
if (fread(translated_dest->source_locations.data, sizeof(SourceLocation), sourceLocationSize, bytecode_file) !=
sourceLocationSize) {
goto FAILED;
}
translated_dest->registerCount = register_count; translated_dest->registerCount = register_count;
fclose(bytecode_file); fclose(bytecode_file);
return 0; return 0;
FAILED: FAILED:
if (translated_inited) free_translator(translated_dest);
fclose(bytecode_file); fclose(bytecode_file);
return 1; return 1;
} }
Execution execute(char *absolute_path) { Execution execute(char *absolute_path, Stack *stack) {
clock_t start, end; clock_t start, end;
double time_spent, total_time_spent = 0; double time_spent, total_time_spent = 0;
@@ -213,10 +232,9 @@ Execution execute(char *absolute_path) {
uint64_t hash = XXH3_64bits_digest(hash_state); uint64_t hash = XXH3_64bits_digest(hash_state);
XXH3_freeState(hash_state); XXH3_freeState(hash_state);
Translated translated = init_translator(); Translated translated;
if (load_cache(&translated, cache_file_path, hash) != 0) { if (load_cache(&translated, cache_file_path, hash) != 0) {
free_translator(&translated);
translated = init_translator(); translated = init_translator();
DArray tokens; DArray tokens;
@@ -266,13 +284,15 @@ Execution execute(char *absolute_path) {
file = fopen(cache_file_path, "wb"); file = fopen(cache_file_path, "wb");
uint64_t constantsSize = (uint64_t)translated.constants.size; uint64_t constantsSize = translated.constants.size;
uint64_t bytecodeSize = (uint64_t)translated.bytecode.size; uint64_t bytecodeSize = translated.bytecode.size;
uint64_t sourceLocationSize = translated.source_locations.size;
uint32_t version_number_htole32ed = htole32(version_number); uint32_t version_number_htole32ed = htole32(version_number);
uint64_t net_hash = htole64(hash); uint64_t net_hash = htole64(hash);
constantsSize = htole64(constantsSize); constantsSize = htole64(constantsSize);
bytecodeSize = htole64(bytecodeSize); bytecodeSize = htole64(bytecodeSize);
sourceLocationSize = htole64(sourceLocationSize);
fwrite(&FILE_IDENTIFIER, sizeof(char), strlen(FILE_IDENTIFIER), file); fwrite(&FILE_IDENTIFIER, sizeof(char), strlen(FILE_IDENTIFIER), file);
fwrite(&version_number_htole32ed, sizeof(uint32_t), 1, file); fwrite(&version_number_htole32ed, sizeof(uint32_t), 1, file);
@@ -280,16 +300,20 @@ Execution execute(char *absolute_path) {
fwrite(&translated.registerCount, sizeof(uint8_t), 1, file); fwrite(&translated.registerCount, sizeof(uint8_t), 1, file);
fwrite(&constantsSize, sizeof(uint64_t), 1, file); fwrite(&constantsSize, sizeof(uint64_t), 1, file);
fwrite(&bytecodeSize, sizeof(uint64_t), 1, file); fwrite(&bytecodeSize, sizeof(uint64_t), 1, file);
fwrite(&sourceLocationSize, sizeof(uint64_t), 1, file);
fwrite(translated.constants.data, 1, translated.constants.size, file); fwrite(translated.constants.data, 1, translated.constants.size, file);
fwrite(translated.bytecode.data, translated.bytecode.element_size, fwrite(translated.bytecode.data, translated.bytecode.element_size,
translated.bytecode.size, file); translated.bytecode.size, file);
fwrite(translated.source_locations.data,
translated.source_locations.element_size,
translated.source_locations.size, file);
fclose(file); fclose(file);
} }
start = clock(); start = clock();
RuntimeState state = init_runtime_state(translated); RuntimeState state = init_runtime_state(translated, absolute_path);
Stack main_scope = create_scope(NULL); Stack main_scope = create_scope(stack);
ArErr err = runtime(translated, state, main_scope); ArErr err = runtime(translated, state, main_scope);
free(state.registers); free(state.registers);
end = clock(); end = clock();
@@ -314,7 +338,7 @@ int main(int argc, char *argv[]) {
char path[FILENAME_MAX]; char path[FILENAME_MAX];
cwk_path_get_absolute(CWD, path_non_absolute, path, sizeof(path)); cwk_path_get_absolute(CWD, path_non_absolute, path, sizeof(path));
free(CWD); free(CWD);
Execution resp = execute(path); Execution resp = execute(path, NULL);
if (resp.err.exists) { if (resp.err.exists) {
output_err(resp.err); output_err(resp.err);
return -1; return -1;

View File

@@ -50,8 +50,8 @@ ParsedValueReturn parse_access(char *file, DArray *tokens, size_t *index,
"Syntax Error", "expected value"), "Syntax Error", "expected value"),
NULL}; NULL};
} }
darray_push(&parsedAccess->access, parsedValue); darray_push(&parsedAccess->access, parsedAccessValue.value);
free(parsedValue); free(parsedAccessValue.value);
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); error_if_finished(file, tokens, index);
token = darray_get(tokens, *index); token = darray_get(tokens, *index);

View File

@@ -4,9 +4,22 @@
#include <string.h> #include <string.h>
#include "../../../memory.h" #include "../../../memory.h"
ParsedValueReturn parse_identifier(Token *token) { ParsedValueReturn parse_identifier(Token *token) {
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
ParsedIdentifier *parsedIdentifier = checked_malloc(sizeof(ParsedIdentifier));
parsedIdentifier->name = strcpy(checked_malloc(token->length + 1), token->value);
parsedIdentifier->line = token->line;
parsedIdentifier->column = token->column;
parsedValue->type = AST_IDENTIFIER; parsedValue->type = AST_IDENTIFIER;
parsedValue->data = strcpy(checked_malloc(strlen(token->value) + 1), token->value); parsedValue->data = parsedIdentifier;
return (ParsedValueReturn){no_err, parsedValue}; return (ParsedValueReturn){no_err, parsedValue};
} }
void free_identifier(void *ptr) {
ParsedValue *parsedValue = ptr;
ParsedIdentifier *parsed = parsedValue->data;
free(parsed->name);
free(parsed);
}

View File

@@ -3,7 +3,15 @@
#include "../../parser.h" #include "../../parser.h"
#include "../../../lexer/token.h" // for Token #include "../../../lexer/token.h" // for Token
typedef struct {
char * name;
size_t line;
size_t column;
} ParsedIdentifier;
// Function declaration for parsing an identifier // Function declaration for parsing an identifier
ParsedValueReturn parse_identifier(Token *token); ParsedValueReturn parse_identifier(Token *token);
void free_identifier(void *ptr);
#endif // IDENTIFIER_H #endif // IDENTIFIER_H

View File

@@ -35,13 +35,12 @@ ParsedValueReturn parse_dowrap(char *file, DArray *tokens, size_t *index) {
return (ParsedValueReturn){no_err, parsedValue}; return (ParsedValueReturn){no_err, parsedValue};
Token *token = darray_get(tokens, *index); Token *token = darray_get(tokens, *index);
if (token->type != TOKEN_NEW_LINE) { if (token->type != TOKEN_NEW_LINE) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){create_err(token->line, token->column, return (ParsedValueReturn){create_err(token->line, token->column,
token->length, file, "Syntax Error", token->length, file, "Syntax Error",
"expected body"), "expected body"),
NULL}; NULL};
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line,
token->column);
exit(EXIT_FAILURE);
} }
size_t indent_depth = 0; size_t indent_depth = 0;
bool temp_indent_depth_toggle = false; bool temp_indent_depth_toggle = false;

View File

@@ -179,6 +179,7 @@ ArErr parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) {
ParsedValueReturn parsed_code = ParsedValueReturn parsed_code =
parse_token(file, tokens, &index, inline_flag); parse_token(file, tokens, &index, inline_flag);
if (parsed_code.err.exists) { if (parsed_code.err.exists) {
printf("%zu\n", old_index);
return parsed_code.err; return parsed_code.err;
} else if (parsed_code.value) { } else if (parsed_code.value) {
if (expecting_new_line) { if (expecting_new_line) {
@@ -194,6 +195,7 @@ ArErr parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) {
expecting_new_line = false; expecting_new_line = false;
} }
} }
return no_err;
} }
void free_parsed(void *ptr) { void free_parsed(void *ptr) {
@@ -205,6 +207,8 @@ void free_parsed(void *ptr) {
ParsedValue *parsed = ptr; ParsedValue *parsed = ptr;
switch (parsed->type) { switch (parsed->type) {
case AST_IDENTIFIER: case AST_IDENTIFIER:
free_identifier(parsed);
break;
case AST_NUMBER: case AST_NUMBER:
free(parsed->data); free(parsed->data);
break; break;

View File

@@ -1,5 +1,6 @@
#include "runtime.h" #include "runtime.h"
#include "../err.h" #include "../err.h"
#include "../hash_data/hash_data.h"
#include "../translator/translator.h" #include "../translator/translator.h"
#include "objects/functions/functions.h" #include "objects/functions/functions.h"
#include "objects/null/null.h" #include "objects/null/null.h"
@@ -63,6 +64,31 @@ void load_const(Translated *translated, RuntimeState *state) {
state->registers[to_register] = object; state->registers[to_register] = object;
} }
ArErr load_variable(Translated *translated, RuntimeState *state,
struct Stack stack) {
int64_t length = pop_bytecode(translated, state);
int64_t offset = pop_bytecode(translated, state);
int64_t source_location_index = pop_bytecode(translated, state);
char *name = checked_malloc(length);
memcpy(name, arena_get(&translated->constants, offset), length);
uint64_t hash = siphash64_bytes(name, length, siphash_key);
struct Stack *current_stack = &stack;
while (current_stack) {
ArgonObject *result = hashmap_lookup_GC(current_stack->scope, hash);
if (result) {
state->registers[0] = result;
free(name);
return no_err;
}
current_stack = current_stack->prev;
}
SourceLocation *source_location = darray_get(&translated->source_locations, source_location_index);
ArErr err = create_err(source_location->line, source_location->column, length, state->path, "Name Error", "name '%.*s' is not defined",
(int)length, name);
free(name);
return err;
}
ArErr run_instruction(Translated *translated, RuntimeState *state, ArErr run_instruction(Translated *translated, RuntimeState *state,
struct Stack stack) { struct Stack stack) {
OperationType opcode = pop_byte(translated, state); OperationType opcode = pop_byte(translated, state);
@@ -76,18 +102,25 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
case OP_LOAD_FUNCTION: case OP_LOAD_FUNCTION:
load_argon_function(translated, state, stack); load_argon_function(translated, state, stack);
break; break;
case OP_IDENTIFIER:
return load_variable(translated, state, stack);
default: default:
return create_err(0, 0, 0, NULL, "Runtime Error", "Invalid Opcode %#x", opcode); return create_err(0, 0, 0, NULL, "Runtime Error", "Invalid Opcode %#x",
opcode);
} }
return no_err; return no_err;
} }
RuntimeState init_runtime_state(Translated translated) { RuntimeState init_runtime_state(Translated translated, char *path) {
return (RuntimeState){ return (RuntimeState){
checked_malloc(translated.registerCount * sizeof(ArgonObject *)), 0}; checked_malloc(translated.registerCount * sizeof(ArgonObject *)), 0,
path};
} }
Stack create_scope(Stack *prev) { return (Stack){NULL, prev}; } Stack create_scope(Stack *prev) {
struct hashmap_GC *scope = createHashmap_GC();
return (Stack){scope, prev};
}
ArErr runtime(Translated translated, RuntimeState state, Stack stack) { ArErr runtime(Translated translated, RuntimeState state, Stack stack) {
state.head = 0; state.head = 0;
@@ -97,6 +130,5 @@ ArErr runtime(Translated translated, RuntimeState state, Stack stack) {
return err; return err;
} }
} }
free(state.registers);
return no_err; return no_err;
} }

View File

@@ -7,6 +7,7 @@
typedef struct { typedef struct {
ArgonObject **registers; ArgonObject **registers;
size_t head; size_t head;
char*path;
} RuntimeState; } RuntimeState;
void init_types(); void init_types();
@@ -16,7 +17,7 @@ uint64_t pop_bytecode(Translated *translated, RuntimeState *state);
ArErr run_instruction(Translated *translated, RuntimeState *state, ArErr run_instruction(Translated *translated, RuntimeState *state,
struct Stack stack); struct Stack stack);
RuntimeState init_runtime_state(Translated translated); RuntimeState init_runtime_state(Translated translated, char *path);
Stack create_scope(Stack *prev); Stack create_scope(Stack *prev);

View File

@@ -43,3 +43,11 @@ initilises a function to a given register.
6. instruction 4 and 5 loop for each argument. 6. instruction 4 and 5 loop for each argument.
7. the offset of the bytecode of the function. 7. the offset of the bytecode of the function.
8. the length of the bytecode of the function. 8. the length of the bytecode of the function.
## OP_IDENTIFIER
initilises a function to a given register.
1. the length of the identifer.
2. the offset of the identifier.
3. the index of the source location.

View File

@@ -2,7 +2,6 @@
#define BYTECODE_DECLARATION_H #define BYTECODE_DECLARATION_H
#include "../translator.h" #include "../translator.h"
size_t translate_parsed_declaration(Translated *translated, size_t translate_parsed_declaration(Translated *translated, DArray delcarations);
DArray delcarations);
#endif #endif

View File

@@ -1,9 +1,9 @@
#ifndef BYTECODE_FUNCTION_H #ifndef BYTECODE_FUNCTION_H
#define BYTECODE_FUNCTION_H #define BYTECODE_FUNCTION_H
#include "../translator.h"
#include "../../parser/function/function.h" #include "../../parser/function/function.h"
#include "../translator.h"
size_t translate_parsed_function(Translated *translated, size_t translate_parsed_function(Translated *translated,
ParsedFunction *parsedFunction); ParsedFunction *parsedFunction);
#endif #endif

View File

@@ -4,12 +4,19 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
size_t translate_parsed_identifier(Translated *translated, char* identifier) { size_t translate_parsed_identifier(Translated *translated, ParsedIdentifier *parsedIdentifier) {
size_t length = strlen(identifier); size_t length = strlen(parsedIdentifier->name);
size_t identifier_pos = arena_push(&translated->constants, identifier, length); size_t identifier_pos = arena_push(&translated->constants, parsedIdentifier->name, length);
set_registers(translated, 1); set_registers(translated, 1);
size_t start = push_instruction_byte(translated, OP_IDENTIFIER); size_t start = push_instruction_byte(translated, OP_IDENTIFIER);
push_instruction_code(translated,length); push_instruction_code(translated,length);
push_instruction_code(translated, identifier_pos); push_instruction_code(translated, identifier_pos);
SourceLocation source_locations = {
parsedIdentifier->line,
parsedIdentifier->column,
length
};
push_instruction_code(translated, translated->source_locations.size);
darray_push(&translated->source_locations, &source_locations);
return start; return start;
} }

View File

@@ -3,6 +3,6 @@
#include "../translator.h" #include "../translator.h"
#include "../../parser/assignable/identifier/identifier.h" #include "../../parser/assignable/identifier/identifier.h"
size_t translate_parsed_identifier(Translated *translated, char* identifier); size_t translate_parsed_identifier(Translated *translated, ParsedIdentifier *parsedIdentifier);
#endif #endif

View File

@@ -80,6 +80,7 @@ Translated init_translator() {
Translated translated; Translated translated;
translated.registerCount = 0; translated.registerCount = 0;
darray_init(&translated.bytecode, sizeof(uint8_t)); darray_init(&translated.bytecode, sizeof(uint8_t));
darray_init(&translated.source_locations, sizeof(SourceLocation));
arena_init(&translated.constants); arena_init(&translated.constants);
return translated; return translated;
} }
@@ -124,7 +125,7 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) {
return translate_parsed_function(translated, return translate_parsed_function(translated,
(ParsedFunction *)parsedValue->data); (ParsedFunction *)parsedValue->data);
case AST_IDENTIFIER: case AST_IDENTIFIER:
return translate_parsed_identifier(translated, (char *)parsedValue->data); return translate_parsed_identifier(translated, (ParsedIdentifier *)parsedValue->data);
} }
return 0; return 0;
} }
@@ -138,5 +139,6 @@ void translate(Translated *translated, DArray *ast) {
void free_translator(Translated *translated) { void free_translator(Translated *translated) {
darray_free(&translated->bytecode, NULL); darray_free(&translated->bytecode, NULL);
darray_free(&translated->source_locations, NULL);
arena_free(&translated->constants); arena_free(&translated->constants);
} }

View File

@@ -21,9 +21,16 @@ typedef struct {
typedef struct { typedef struct {
uint8_t registerCount; uint8_t registerCount;
DArray bytecode; DArray bytecode;
DArray source_locations;
ConstantArena constants; ConstantArena constants;
} Translated; } Translated;
typedef struct {
uint64_t line;
uint64_t column;
uint64_t length;
} SourceLocation;
void arena_resize(ConstantArena *arena, size_t new_size); void arena_resize(ConstantArena *arena, size_t new_size);
void *arena_get(ConstantArena *arena, size_t offset); void *arena_get(ConstantArena *arena, size_t offset);
@@ -38,9 +45,9 @@ void set_registers(Translated *translator, uint8_t count);
Translated init_translator(); Translated init_translator();
size_t translate_parsed(Translated * translator, ParsedValue * parsedValue); size_t translate_parsed(Translated *translated, ParsedValue *parsedValue);
void translate(Translated *translator, DArray *ast); void translate(Translated *translated, DArray *ast);
void free_translator(Translated *translated); void free_translator(Translated *translated);

View File

@@ -1 +0,0 @@
let x = 10