add hashmap to scope and identifier loading at runtime
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <gmp.h>
|
||||
#include "runtime/internals/dynamic_array_armem/darray_armem.h"
|
||||
#include "runtime/internals/hashmap/hashmap.h"
|
||||
|
||||
typedef struct ArgonObject ArgonObject; // forward declaration
|
||||
|
||||
@@ -22,7 +23,7 @@ struct string_struct {
|
||||
};
|
||||
|
||||
typedef struct Stack {
|
||||
ArgonObject *scope;
|
||||
struct hashmap_GC *scope;
|
||||
struct Stack *prev;
|
||||
} Stack;
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ void output_err(ArErr err) {
|
||||
|
||||
while ((len = getline(&buffer, &size, file)) != -1) {
|
||||
if (current_line == err.line) {
|
||||
printf("bruh\n");
|
||||
break;
|
||||
}
|
||||
current_line++;
|
||||
@@ -89,12 +90,13 @@ void output_err(ArErr err) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, "|\n");
|
||||
getline(&buffer, &size, file);
|
||||
|
||||
char *line_starts = buffer;
|
||||
size_t skipped_chars = 0;
|
||||
while (*line_starts && isspace((unsigned char)*line_starts) && line_starts-buffer < err.column-1) {
|
||||
line_starts++;
|
||||
err.column--;
|
||||
skipped_chars++;
|
||||
}
|
||||
fprintf(stderr, " %zu | ", err.line);
|
||||
if (err.length) {
|
||||
@@ -104,7 +106,7 @@ void output_err(ArErr err) {
|
||||
fprintf(stderr, "%.*s", err.length, line_starts + err.column - 1);
|
||||
dye_style(stderr, DYE_STYLE_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++) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
|
||||
40
src/main.c
40
src/main.c
@@ -84,6 +84,7 @@ const char BYTECODE_EXTENTION[] = "arbin";
|
||||
const uint32_t version_number = 0;
|
||||
|
||||
int load_cache(Translated *translated_dest, char *joined_paths, uint64_t hash) {
|
||||
bool translated_inited = false;
|
||||
FILE *bytecode_file = fopen(joined_paths, "rb");
|
||||
if (!bytecode_file)
|
||||
return 1;
|
||||
@@ -138,6 +139,16 @@ int load_cache(Translated *translated_dest, char *joined_paths, uint64_t hash) {
|
||||
}
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
fclose(bytecode_file);
|
||||
return 0;
|
||||
FAILED:
|
||||
if (translated_inited) free_translator(translated_dest);
|
||||
fclose(bytecode_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Execution execute(char *absolute_path) {
|
||||
Execution execute(char *absolute_path, Stack *stack) {
|
||||
clock_t start, end;
|
||||
double time_spent, total_time_spent = 0;
|
||||
|
||||
@@ -213,10 +232,9 @@ Execution execute(char *absolute_path) {
|
||||
uint64_t hash = XXH3_64bits_digest(hash_state);
|
||||
XXH3_freeState(hash_state);
|
||||
|
||||
Translated translated = init_translator();
|
||||
Translated translated;
|
||||
|
||||
if (load_cache(&translated, cache_file_path, hash) != 0) {
|
||||
free_translator(&translated);
|
||||
translated = init_translator();
|
||||
|
||||
DArray tokens;
|
||||
@@ -266,13 +284,15 @@ Execution execute(char *absolute_path) {
|
||||
|
||||
file = fopen(cache_file_path, "wb");
|
||||
|
||||
uint64_t constantsSize = (uint64_t)translated.constants.size;
|
||||
uint64_t bytecodeSize = (uint64_t)translated.bytecode.size;
|
||||
uint64_t constantsSize = translated.constants.size;
|
||||
uint64_t bytecodeSize = translated.bytecode.size;
|
||||
uint64_t sourceLocationSize = translated.source_locations.size;
|
||||
|
||||
uint32_t version_number_htole32ed = htole32(version_number);
|
||||
uint64_t net_hash = htole64(hash);
|
||||
constantsSize = htole64(constantsSize);
|
||||
bytecodeSize = htole64(bytecodeSize);
|
||||
sourceLocationSize = htole64(sourceLocationSize);
|
||||
|
||||
fwrite(&FILE_IDENTIFIER, sizeof(char), strlen(FILE_IDENTIFIER), 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(&constantsSize, 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.bytecode.data, translated.bytecode.element_size,
|
||||
translated.bytecode.size, file);
|
||||
fwrite(translated.source_locations.data,
|
||||
translated.source_locations.element_size,
|
||||
translated.source_locations.size, file);
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
start = clock();
|
||||
RuntimeState state = init_runtime_state(translated);
|
||||
Stack main_scope = create_scope(NULL);
|
||||
RuntimeState state = init_runtime_state(translated, absolute_path);
|
||||
Stack main_scope = create_scope(stack);
|
||||
ArErr err = runtime(translated, state, main_scope);
|
||||
free(state.registers);
|
||||
end = clock();
|
||||
@@ -314,7 +338,7 @@ int main(int argc, char *argv[]) {
|
||||
char path[FILENAME_MAX];
|
||||
cwk_path_get_absolute(CWD, path_non_absolute, path, sizeof(path));
|
||||
free(CWD);
|
||||
Execution resp = execute(path);
|
||||
Execution resp = execute(path, NULL);
|
||||
if (resp.err.exists) {
|
||||
output_err(resp.err);
|
||||
return -1;
|
||||
|
||||
@@ -50,8 +50,8 @@ ParsedValueReturn parse_access(char *file, DArray *tokens, size_t *index,
|
||||
"Syntax Error", "expected value"),
|
||||
NULL};
|
||||
}
|
||||
darray_push(&parsedAccess->access, parsedValue);
|
||||
free(parsedValue);
|
||||
darray_push(&parsedAccess->access, parsedAccessValue.value);
|
||||
free(parsedAccessValue.value);
|
||||
skip_newlines_and_indents(tokens, index);
|
||||
error_if_finished(file, tokens, index);
|
||||
token = darray_get(tokens, *index);
|
||||
|
||||
@@ -4,9 +4,22 @@
|
||||
#include <string.h>
|
||||
#include "../../../memory.h"
|
||||
|
||||
|
||||
|
||||
ParsedValueReturn parse_identifier(Token *token) {
|
||||
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->data = strcpy(checked_malloc(strlen(token->value) + 1), token->value);
|
||||
parsedValue->data = parsedIdentifier;
|
||||
return (ParsedValueReturn){no_err, parsedValue};
|
||||
}
|
||||
|
||||
void free_identifier(void *ptr) {
|
||||
ParsedValue *parsedValue = ptr;
|
||||
ParsedIdentifier *parsed = parsedValue->data;
|
||||
free(parsed->name);
|
||||
free(parsed);
|
||||
}
|
||||
@@ -3,7 +3,15 @@
|
||||
#include "../../parser.h"
|
||||
#include "../../../lexer/token.h" // for Token
|
||||
|
||||
typedef struct {
|
||||
char * name;
|
||||
size_t line;
|
||||
size_t column;
|
||||
} ParsedIdentifier;
|
||||
|
||||
// Function declaration for parsing an identifier
|
||||
ParsedValueReturn parse_identifier(Token *token);
|
||||
|
||||
void free_identifier(void *ptr);
|
||||
|
||||
#endif // IDENTIFIER_H
|
||||
@@ -35,13 +35,12 @@ ParsedValueReturn parse_dowrap(char *file, DArray *tokens, size_t *index) {
|
||||
return (ParsedValueReturn){no_err, parsedValue};
|
||||
Token *token = darray_get(tokens, *index);
|
||||
if (token->type != TOKEN_NEW_LINE) {
|
||||
free_parsed(parsedValue);
|
||||
free(parsedValue);
|
||||
return (ParsedValueReturn){create_err(token->line, token->column,
|
||||
token->length, file, "Syntax Error",
|
||||
"expected body"),
|
||||
NULL};
|
||||
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line,
|
||||
token->column);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
size_t indent_depth = 0;
|
||||
bool temp_indent_depth_toggle = false;
|
||||
|
||||
@@ -179,6 +179,7 @@ ArErr parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) {
|
||||
ParsedValueReturn parsed_code =
|
||||
parse_token(file, tokens, &index, inline_flag);
|
||||
if (parsed_code.err.exists) {
|
||||
printf("%zu\n", old_index);
|
||||
return parsed_code.err;
|
||||
} else if (parsed_code.value) {
|
||||
if (expecting_new_line) {
|
||||
@@ -194,6 +195,7 @@ ArErr parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) {
|
||||
expecting_new_line = false;
|
||||
}
|
||||
}
|
||||
return no_err;
|
||||
}
|
||||
|
||||
void free_parsed(void *ptr) {
|
||||
@@ -205,6 +207,8 @@ void free_parsed(void *ptr) {
|
||||
ParsedValue *parsed = ptr;
|
||||
switch (parsed->type) {
|
||||
case AST_IDENTIFIER:
|
||||
free_identifier(parsed);
|
||||
break;
|
||||
case AST_NUMBER:
|
||||
free(parsed->data);
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "runtime.h"
|
||||
#include "../err.h"
|
||||
#include "../hash_data/hash_data.h"
|
||||
#include "../translator/translator.h"
|
||||
#include "objects/functions/functions.h"
|
||||
#include "objects/null/null.h"
|
||||
@@ -63,6 +64,31 @@ void load_const(Translated *translated, RuntimeState *state) {
|
||||
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,
|
||||
struct Stack stack) {
|
||||
OperationType opcode = pop_byte(translated, state);
|
||||
@@ -76,18 +102,25 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
||||
case OP_LOAD_FUNCTION:
|
||||
load_argon_function(translated, state, stack);
|
||||
break;
|
||||
case OP_IDENTIFIER:
|
||||
return load_variable(translated, state, stack);
|
||||
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;
|
||||
}
|
||||
|
||||
RuntimeState init_runtime_state(Translated translated) {
|
||||
RuntimeState init_runtime_state(Translated translated, char *path) {
|
||||
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) {
|
||||
state.head = 0;
|
||||
@@ -97,6 +130,5 @@ ArErr runtime(Translated translated, RuntimeState state, Stack stack) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
free(state.registers);
|
||||
return no_err;
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
typedef struct {
|
||||
ArgonObject **registers;
|
||||
size_t head;
|
||||
char*path;
|
||||
} RuntimeState;
|
||||
|
||||
void init_types();
|
||||
@@ -16,7 +17,7 @@ uint64_t pop_bytecode(Translated *translated, RuntimeState *state);
|
||||
ArErr run_instruction(Translated *translated, RuntimeState *state,
|
||||
struct Stack stack);
|
||||
|
||||
RuntimeState init_runtime_state(Translated translated);
|
||||
RuntimeState init_runtime_state(Translated translated, char *path);
|
||||
|
||||
Stack create_scope(Stack *prev);
|
||||
|
||||
|
||||
@@ -43,3 +43,11 @@ initilises a function to a given register.
|
||||
6. instruction 4 and 5 loop for each argument.
|
||||
7. the offset 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.
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define BYTECODE_DECLARATION_H
|
||||
#include "../translator.h"
|
||||
|
||||
size_t translate_parsed_declaration(Translated *translated,
|
||||
DArray delcarations);
|
||||
size_t translate_parsed_declaration(Translated *translated, DArray delcarations);
|
||||
|
||||
#endif
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef BYTECODE_FUNCTION_H
|
||||
#define BYTECODE_FUNCTION_H
|
||||
#include "../translator.h"
|
||||
#include "../../parser/function/function.h"
|
||||
#include "../translator.h"
|
||||
|
||||
size_t translate_parsed_function(Translated *translated,
|
||||
ParsedFunction *parsedFunction);
|
||||
ParsedFunction *parsedFunction);
|
||||
|
||||
#endif
|
||||
@@ -4,12 +4,19 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
size_t translate_parsed_identifier(Translated *translated, char* identifier) {
|
||||
size_t length = strlen(identifier);
|
||||
size_t identifier_pos = arena_push(&translated->constants, identifier, length);
|
||||
size_t translate_parsed_identifier(Translated *translated, ParsedIdentifier *parsedIdentifier) {
|
||||
size_t length = strlen(parsedIdentifier->name);
|
||||
size_t identifier_pos = arena_push(&translated->constants, parsedIdentifier->name, length);
|
||||
set_registers(translated, 1);
|
||||
size_t start = push_instruction_byte(translated, OP_IDENTIFIER);
|
||||
push_instruction_code(translated,length);
|
||||
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;
|
||||
}
|
||||
@@ -3,6 +3,6 @@
|
||||
#include "../translator.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
|
||||
@@ -80,6 +80,7 @@ Translated init_translator() {
|
||||
Translated translated;
|
||||
translated.registerCount = 0;
|
||||
darray_init(&translated.bytecode, sizeof(uint8_t));
|
||||
darray_init(&translated.source_locations, sizeof(SourceLocation));
|
||||
arena_init(&translated.constants);
|
||||
return translated;
|
||||
}
|
||||
@@ -124,7 +125,7 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) {
|
||||
return translate_parsed_function(translated,
|
||||
(ParsedFunction *)parsedValue->data);
|
||||
case AST_IDENTIFIER:
|
||||
return translate_parsed_identifier(translated, (char *)parsedValue->data);
|
||||
return translate_parsed_identifier(translated, (ParsedIdentifier *)parsedValue->data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -138,5 +139,6 @@ void translate(Translated *translated, DArray *ast) {
|
||||
|
||||
void free_translator(Translated *translated) {
|
||||
darray_free(&translated->bytecode, NULL);
|
||||
darray_free(&translated->source_locations, NULL);
|
||||
arena_free(&translated->constants);
|
||||
}
|
||||
@@ -21,9 +21,16 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint8_t registerCount;
|
||||
DArray bytecode;
|
||||
DArray source_locations;
|
||||
ConstantArena constants;
|
||||
} Translated;
|
||||
|
||||
typedef struct {
|
||||
uint64_t line;
|
||||
uint64_t column;
|
||||
uint64_t length;
|
||||
} SourceLocation;
|
||||
|
||||
void arena_resize(ConstantArena *arena, size_t new_size);
|
||||
|
||||
void *arena_get(ConstantArena *arena, size_t offset);
|
||||
@@ -38,9 +45,9 @@ void set_registers(Translated *translator, uint8_t count);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
let x = 10
|
||||
Reference in New Issue
Block a user