add if statement and declaration

This commit is contained in:
2025-07-13 03:34:31 +01:00
parent 744e3c281d
commit f7ff3393f0
36 changed files with 587 additions and 165 deletions

View File

@@ -3,7 +3,7 @@ LEXER_C = src/lexer/lex.yy.c
LEXER_H = src/lexer/lex.yy.h LEXER_H = src/lexer/lex.yy.h
CFILES = external/xxhash/xxhash.c external/cwalk/src/cwalk.c external/libdye/src/dye.c $(shell find src -name '*.c') CFILES = external/xxhash/xxhash.c external/cwalk/src/cwalk.c external/libdye/src/dye.c $(shell find src -name '*.c')
CFLAGS = $(ARCHFLAGS) -lm -lgc -lgmp -Wall -Wextra -Wno-unused-function -Iexternal/cwalk/include -Iexternal/libdye/include CFLAGS = $(ARCHFLAGS) -lm -lgc -lgmp -Wall -Wextra -Wno-unused-function -Werror=unused-result -Iexternal/cwalk/include -Iexternal/libdye/include
BINARY = bin/argon BINARY = bin/argon
all: $(BINARY) all: $(BINARY)

View File

@@ -1,10 +1,12 @@
#include <fcntl.h> #include <fcntl.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include "siphash/siphash.h" #include "siphash/siphash.h"
#include "hash_data.h" #include "hash_data.h"
uint8_t siphash_key[16]; uint8_t siphash_key[16];
const uint8_t siphash_key_fixed_for_translator[16] = {218, 19, 245, 136, 128, 160, 122, 81, 249, 147, 111, 230, 174, 145, 125 ,218};
uint8_t empty_siphash_key[16]; uint8_t empty_siphash_key[16];
void generate_siphash_key(uint8_t hash_key[16]) { void generate_siphash_key(uint8_t hash_key[16]) {
@@ -15,7 +17,7 @@ void generate_siphash_key(uint8_t hash_key[16]) {
close(fd); close(fd);
} }
uint64_t siphash64_bytes(const void *data, size_t len,uint8_t hash_key[16]) { uint64_t siphash64_bytes(const void *data, size_t len,const uint8_t hash_key[16]) {
uint8_t out[8]; uint8_t out[8];
if (siphash(data, len, hash_key, out, sizeof(out)) != 0) if (siphash(data, len, hash_key, out, sizeof(out)) != 0)
return 0; return 0;

View File

@@ -4,8 +4,9 @@
#include <stdint.h> #include <stdint.h>
extern uint8_t siphash_key[16]; extern uint8_t siphash_key[16];
extern const uint8_t siphash_key_fixed_for_translator[16];
extern uint8_t empty_siphash_key[16]; extern uint8_t empty_siphash_key[16];
void generate_siphash_key(uint8_t siphash_key[16]); void generate_siphash_key(uint8_t siphash_key[16]);
uint64_t siphash64_bytes(const void *data, size_t len,uint8_t siphash_key[16]); uint64_t siphash64_bytes(const void *data, size_t len,const uint8_t hash_key[16]);
#endif //HASH_DATA_H #endif //HASH_DATA_H

View File

@@ -8,9 +8,7 @@ ArErr lexer(LexerState state) {
int ch; int ch;
while ((ch = fgetc(state.file)) != EOF) { while ((ch = fgetc(state.file)) != EOF) {
if (ch == 0 || (ch < 0x20 && ch != '\n' && ch != '\r' && ch != '\t')) { if (ch == 0 || (ch < 0x20 && ch != '\n' && ch != '\r' && ch != '\t')) {
fprintf(stderr, "%s:%zu:%zu error: disallowed character\n", state.path, return create_err(line, column, 1, state.path, "Syntax Error", "disallowed character");
line, column);
exit(1);
} }
if (ch == '\n') { if (ch == '\n') {

View File

@@ -86,8 +86,10 @@ 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; bool translated_inited = false;
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");
return 1; return 1;
}
char file_identifier_from_cache[sizeof(FILE_IDENTIFIER)] = {0}; char file_identifier_from_cache[sizeof(FILE_IDENTIFIER)] = {0};
if (fread(&file_identifier_from_cache, 1, if (fread(&file_identifier_from_cache, 1,
sizeof(file_identifier_from_cache) - 1, sizeof(file_identifier_from_cache) - 1,
@@ -165,42 +167,45 @@ int load_cache(Translated *translated_dest, char *joined_paths, uint64_t hash) {
darray_resize(&translated_dest->source_locations, sourceLocationSize); darray_resize(&translated_dest->source_locations, sourceLocationSize);
if (fread(translated_dest->source_locations.data, sizeof(SourceLocation), sourceLocationSize, bytecode_file) != if (fread(translated_dest->source_locations.data, sizeof(SourceLocation),
sourceLocationSize) { sourceLocationSize, bytecode_file) != sourceLocationSize) {
goto FAILED; goto FAILED;
} }
translated_dest->registerCount = register_count; translated_dest->registerCount = register_count;
printf("cache exists and is valid, so will be used.\n");
fclose(bytecode_file); fclose(bytecode_file);
return 0; return 0;
FAILED: FAILED:
if (translated_inited) free_translator(translated_dest); printf("cache is invalid... compiling from source.\n");
if (translated_inited)
free_translator(translated_dest);
fclose(bytecode_file); fclose(bytecode_file);
return 1; return 1;
} }
Execution execute(char *absolute_path, Stack *stack) { Execution execute(char *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;
const char *basename_ptr; const char *basename_ptr;
size_t basename_length; size_t basename_length;
cwk_path_get_basename(absolute_path, &basename_ptr, &basename_length); cwk_path_get_basename(path, &basename_ptr, &basename_length);
if (!basename_ptr) if (!basename_ptr)
return (Execution){create_err(0, 0, 0, NULL, "Path Error", return (Execution){create_err(0, 0, 0, NULL, "Path Error",
"path has no basename '%s'", absolute_path), "path has no basename '%s'", path),
(Stack){NULL, NULL}}; (Stack){NULL, NULL}};
char basename[FILENAME_MAX]; char basename[FILENAME_MAX];
memcpy(basename, basename_ptr, basename_length); memcpy(basename, basename_ptr, basename_length);
size_t parent_directory_length; size_t parent_directory_length;
cwk_path_get_dirname(absolute_path, &parent_directory_length); cwk_path_get_dirname(path, &parent_directory_length);
char parent_directory[FILENAME_MAX]; char parent_directory[FILENAME_MAX];
memcpy(parent_directory, absolute_path, parent_directory_length); memcpy(parent_directory, path, parent_directory_length);
parent_directory[parent_directory_length] = '\0'; parent_directory[parent_directory_length] = '\0';
char cache_folder_path[FILENAME_MAX]; char cache_folder_path[FILENAME_MAX];
@@ -213,10 +218,10 @@ Execution execute(char *absolute_path, Stack *stack) {
cwk_path_change_extension(cache_file_path, BYTECODE_EXTENTION, cwk_path_change_extension(cache_file_path, BYTECODE_EXTENTION,
cache_file_path, sizeof(cache_file_path)); cache_file_path, sizeof(cache_file_path));
FILE *file = fopen(absolute_path, "r"); FILE *file = fopen(path, "r");
if (!file) { if (!file) {
return (Execution){create_err(0, 0, 0, NULL, "File Error", return (Execution){create_err(0, 0, 0, NULL, "File Error",
"Unable to open file '%s'", absolute_path), "Unable to open file '%s'", path),
(Stack){NULL, NULL}}; (Stack){NULL, NULL}};
} }
@@ -240,7 +245,7 @@ Execution execute(char *absolute_path, Stack *stack) {
DArray tokens; DArray tokens;
darray_init(&tokens, sizeof(Token)); darray_init(&tokens, sizeof(Token));
LexerState state = {absolute_path, file, 0, 0, &tokens}; LexerState state = {path, file, 0, 0, &tokens};
start = clock(); start = clock();
ArErr err = lexer(state); ArErr err = lexer(state);
if (err.exists) { if (err.exists) {
@@ -259,7 +264,7 @@ Execution execute(char *absolute_path, Stack *stack) {
darray_init(&ast, sizeof(ParsedValue)); darray_init(&ast, sizeof(ParsedValue));
start = clock(); start = clock();
err = parser(absolute_path, &ast, &tokens, false); err = parser(path, &ast, &tokens, false);
if (err.exists) { if (err.exists) {
free_translator(&translated); free_translator(&translated);
darray_free(&tokens, free_token); darray_free(&tokens, free_token);
@@ -312,8 +317,8 @@ Execution execute(char *absolute_path, Stack *stack) {
} }
start = clock(); start = clock();
RuntimeState state = init_runtime_state(translated, absolute_path); RuntimeState state = init_runtime_state(translated, path);
Stack main_scope = create_scope(stack); 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();
@@ -323,7 +328,7 @@ Execution execute(char *absolute_path, Stack *stack) {
printf("total time taken: %f seconds\n", total_time_spent); printf("total time taken: %f seconds\n", total_time_spent);
free_translator(&translated); free_translator(&translated);
return (Execution){err, main_scope}; return (Execution){err, *main_scope};
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@@ -339,9 +344,11 @@ int main(int argc, char *argv[]) {
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, NULL); Execution resp = execute(path, NULL);
if (runtime_hash_table)
hashmap_free(runtime_hash_table, NULL);
if (resp.err.exists) { if (resp.err.exists) {
output_err(resp.err); output_err(resp.err);
return -1; return 1;
} }
return 0; return 0;
} }

View File

@@ -19,7 +19,12 @@ ParsedValueReturn parse_access(char *file, DArray *tokens, size_t *index,
free(to_access); free(to_access);
darray_init(&parsedAccess->access, sizeof(ParsedValue)); darray_init(&parsedAccess->access, sizeof(ParsedValue));
if (first_token->type == TOKEN_DOT) { if (first_token->type == TOKEN_DOT) {
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
Token *token = darray_get(tokens, *index); Token *token = darray_get(tokens, *index);
ParsedValueReturn parsedString = parse_string(token, false); ParsedValueReturn parsedString = parse_string(token, false);
if (parsedString.err.exists) { if (parsedString.err.exists) {
@@ -35,7 +40,12 @@ ParsedValueReturn parse_access(char *file, DArray *tokens, size_t *index,
Token *token = first_token; Token *token = first_token;
while (true) { while (true) {
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
ParsedValueReturn parsedAccessValue = ParsedValueReturn parsedAccessValue =
parse_token(file, tokens, index, true); parse_token(file, tokens, index, true);
if (parsedAccessValue.err.exists) { if (parsedAccessValue.err.exists) {
@@ -45,22 +55,30 @@ ParsedValueReturn parse_access(char *file, DArray *tokens, size_t *index,
} else if (!parsedAccessValue.value) { } else if (!parsedAccessValue.value) {
free_parsed(parsedValue); free_parsed(parsedValue);
free(parsedValue); free(parsedValue);
return (ParsedValueReturn){ return (ParsedValueReturn){create_err(token->line, token->column,
create_err(token->line, token->column, token->length, file, token->length, file,
"Syntax Error", "expected value"), "Syntax Error", "expected value"),
NULL}; NULL};
} }
darray_push(&parsedAccess->access, parsedAccessValue.value); darray_push(&parsedAccess->access, parsedAccessValue.value);
free(parsedAccessValue.value); free(parsedAccessValue.value);
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
if (token->type == TOKEN_RBRACKET) { if (token->type == TOKEN_RBRACKET) {
break; break;
} else if (token->type != TOKEN_COLON) { } else if (token->type != TOKEN_COLON) {
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line, free_parsed(parsedValue);
token->column); free(parsedValue);
exit(EXIT_FAILURE); return (ParsedValueReturn){create_err(token->line, token->column,
token->length, file,
"Syntax Error", "expected colon"),
NULL};
} }
(*index)++; (*index)++;
} }

View File

@@ -31,14 +31,12 @@ ParsedValueReturn parse_assign(char *file, DArray *tokens,
} }
break; break;
default:; default:;
ArErr err = create_err(token->line, token->column, ArErr err = create_err(token->line, token->column, token->length, file,
token->length, file, "Syntax Error", "Syntax Error", "can't assign to %s",
"can't assign to %s", ValueTypeNames[assign_to->type]);
ValueTypeNames[assign_to->type]);
free_parsed(assign_to); free_parsed(assign_to);
free(assign_to); free(assign_to);
return (ParsedValueReturn){err, return (ParsedValueReturn){err, NULL};
NULL};
} }
ParsedAssign *assign = checked_malloc(sizeof(ParsedAssign)); ParsedAssign *assign = checked_malloc(sizeof(ParsedAssign));
assign->to = assign_to; assign->to = assign_to;
@@ -47,7 +45,12 @@ ParsedValueReturn parse_assign(char *file, DArray *tokens,
parsedValue->type = AST_ASSIGN; parsedValue->type = AST_ASSIGN;
parsedValue->data = assign; parsedValue->data = assign;
(*index)++; (*index)++;
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
ParsedValueReturn from = parse_token(file, tokens, index, true); ParsedValueReturn from = parse_token(file, tokens, index, true);
if (from.err.exists) { if (from.err.exists) {

View File

@@ -15,12 +15,26 @@ ParsedValueReturn parse_call(char *file, DArray *tokens, size_t *index,
parsedValue->type = AST_CALL; parsedValue->type = AST_CALL;
darray_init(&call->args, sizeof(ParsedValue)); darray_init(&call->args, sizeof(ParsedValue));
(*index)++; (*index)++;
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(to_call);
free(to_call);
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
Token *token = darray_get(tokens, *index); Token *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);
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(to_call);
free(to_call);
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
ParsedValueReturn parsedArg = parse_token(file, tokens, index, true); ParsedValueReturn parsedArg = parse_token(file, tokens, index, true);
if (parsedArg.err.exists) { if (parsedArg.err.exists) {
free_parsed(to_call); free_parsed(to_call);
@@ -41,19 +55,46 @@ ParsedValueReturn parse_call(char *file, DArray *tokens, size_t *index,
} }
darray_push(&call->args, parsedArg.value); darray_push(&call->args, parsedArg.value);
free(parsedArg.value); free(parsedArg.value);
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(to_call);
free(to_call);
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(to_call);
free(to_call);
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
if (token->type == TOKEN_RPAREN) { if (token->type == TOKEN_RPAREN) {
break; break;
} else if (token->type != TOKEN_COMMA) { } else if (token->type != TOKEN_COMMA) {
fprintf(stderr, "%s:%zu:%zu error: expected comma\n", file, token->line, free_parsed(to_call);
token->column); free(to_call);
exit(EXIT_FAILURE); free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){create_err(token->line, token->column,
token->length, file,
"Syntax Error", "expected comma"),
NULL};
} }
(*index)++; (*index)++;
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(to_call);
free(to_call);
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
} }
} }
(*index)++; (*index)++;

View File

@@ -12,7 +12,10 @@
ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) { ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) {
(*index)++; (*index)++;
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
return (ParsedValueReturn){err, NULL};
}
Token *token = darray_get(tokens, *index); Token *token = darray_get(tokens, *index);
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
@@ -25,6 +28,8 @@ ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) {
darray_push(declarations, &_declaration); darray_push(declarations, &_declaration);
ParsedSingleDeclaration *declaration = ParsedSingleDeclaration *declaration =
darray_get(declarations, declarations->size - 1); darray_get(declarations, declarations->size - 1);
declaration->line = token->line;
declaration->column = token->column;
bool isFunction = false; bool isFunction = false;
DArray parameters; DArray parameters;
declaration->from = parse_null(); declaration->from = parse_null();
@@ -49,19 +54,34 @@ ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) {
struct hashmap *parameters_hashmap = createHashmap(); struct hashmap *parameters_hashmap = createHashmap();
darray_init(&parameters, sizeof(char *)); darray_init(&parameters, sizeof(char *));
(*index)++; (*index)++;
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
darray_free(&parameters, free_parameter);
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
if (token->type == TOKEN_RPAREN) { if (token->type == TOKEN_RPAREN) {
(*index)++; (*index)++;
if ((*index) >= tokens->size) if ((*index) >= tokens->size) {
declaration->from = create_parsed_function(
declaration->name, parameters, declaration->from);
return (ParsedValueReturn){no_err, parsedValue}; return (ParsedValueReturn){no_err, parsedValue};
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
} else { } else {
while ((*index) < tokens->size) { while ((*index) < tokens->size) {
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
if (token->type != TOKEN_IDENTIFIER) { if (token->type != TOKEN_IDENTIFIER) {
darray_free(&parameters, free_parameter);
free_parsed(parsedValue); free_parsed(parsedValue);
free(parsedValue); free(parsedValue);
return (ParsedValueReturn){ return (ParsedValueReturn){
@@ -75,6 +95,7 @@ ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) {
uint64_t hash = uint64_t hash =
siphash64_bytes(token->value, token->length, siphash_key); siphash64_bytes(token->value, token->length, siphash_key);
if (hashmap_lookup(parameters_hashmap, hash) != NULL) { if (hashmap_lookup(parameters_hashmap, hash) != NULL) {
darray_free(&parameters, free_parameter);
free_parsed(parsedValue); free_parsed(parsedValue);
free(parsedValue); free(parsedValue);
return (ParsedValueReturn){ return (ParsedValueReturn){
@@ -90,9 +111,21 @@ ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) {
0); 0);
darray_push(&parameters, &parameter_name); darray_push(&parameters, &parameter_name);
(*index)++; (*index)++;
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
darray_free(&parameters, free_parameter);
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
darray_free(&parameters, free_parameter);
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
if (token->type == TOKEN_RPAREN) { if (token->type == TOKEN_RPAREN) {
(*index)++; (*index)++;
@@ -101,6 +134,7 @@ ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) {
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
break; break;
} else if (token->type != TOKEN_COMMA) { } else if (token->type != TOKEN_COMMA) {
darray_free(&parameters, free_parameter);
free_parsed(parsedValue); free_parsed(parsedValue);
free(parsedValue); free(parsedValue);
return (ParsedValueReturn){ return (ParsedValueReturn){
@@ -109,25 +143,37 @@ ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) {
NULL}; NULL};
} }
(*index)++; (*index)++;
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
darray_free(&parameters, free_parameter);
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
} }
} }
hashmap_free(parameters_hashmap, NULL); hashmap_free(parameters_hashmap, NULL);
} }
if (token->type == TOKEN_ASSIGN) { if (token->type == TOKEN_ASSIGN) {
(*index)++; (*index)++;
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free(declaration->from); free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
ParsedValueReturn from = parse_token(file, tokens, index, true); ParsedValueReturn from = parse_token(file, tokens, index, true);
if (from.err.exists) { if (from.err.exists) {
darray_free(&parameters, free_parameter);
free_parsed(parsedValue); free_parsed(parsedValue);
free(parsedValue); free(parsedValue);
return from; return from;
} }
free(declaration->from);
declaration->from = from.value; declaration->from = from.value;
if (!declaration->from) { if (!declaration->from) {
darray_free(&parameters, free_parameter);
free_parsed(parsedValue); free_parsed(parsedValue);
free(parsedValue); free(parsedValue);
return (ParsedValueReturn){create_err(token->line, token->column, return (ParsedValueReturn){create_err(token->line, token->column,
@@ -153,9 +199,19 @@ ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) {
break; break;
} }
(*index)++; (*index)++;
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
} }
return (ParsedValueReturn){no_err, parsedValue}; return (ParsedValueReturn){no_err, parsedValue};

View File

@@ -6,6 +6,8 @@
typedef struct { typedef struct {
char * name; char * name;
ParsedValue * from; ParsedValue * from;
uint64_t line;
uint64_t column;
} ParsedSingleDeclaration; } ParsedSingleDeclaration;
// Function declaration for parsing an identifier // Function declaration for parsing an identifier

View File

@@ -15,12 +15,22 @@ ParsedValueReturn parse_dictionary(char *file, DArray *tokens, size_t *index) {
darray_init(dictionary, sizeof(ParsedValue)); darray_init(dictionary, sizeof(ParsedValue));
(*index)++; (*index)++;
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
Token *token = darray_get(tokens, *index); Token *token = darray_get(tokens, *index);
if (token->type != TOKEN_RBRACE) { if (token->type != TOKEN_RBRACE) {
while (true) { while (true) {
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
size_t keyIndex = *index; size_t keyIndex = *index;
Token *keyToken = darray_get(tokens, *index); Token *keyToken = darray_get(tokens, *index);
ParsedValueReturn key; ParsedValueReturn key;
@@ -43,7 +53,12 @@ ParsedValueReturn parse_dictionary(char *file, DArray *tokens, size_t *index) {
NULL}; NULL};
} }
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
ParsedValueReturn value; ParsedValueReturn value;
bool tobreak = false; bool tobreak = false;
@@ -51,7 +66,12 @@ ParsedValueReturn parse_dictionary(char *file, DArray *tokens, size_t *index) {
case TOKEN_COLON: case TOKEN_COLON:
(*index)++; (*index)++;
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
value = parse_token(file, tokens, index, true); value = parse_token(file, tokens, index, true);
if (value.err.exists) { if (value.err.exists) {
free_parsed(parsedValue); free_parsed(parsedValue);
@@ -70,14 +90,30 @@ ParsedValueReturn parse_dictionary(char *file, DArray *tokens, size_t *index) {
NULL}; NULL};
} }
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
free_parsed(key.value);
free(key.value);
free_parsed(value.value);
free(value.value);
return (ParsedValueReturn){err, NULL};
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
if (token->type == TOKEN_RBRACE) { if (token->type == TOKEN_RBRACE) {
tobreak = true; tobreak = true;
} else if (token->type != TOKEN_COMMA) { } else if (token->type != TOKEN_COMMA) {
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line, free_parsed(parsedValue);
token->column); free(parsedValue);
exit(EXIT_FAILURE); free_parsed(key.value);
free(key.value);
free_parsed(value.value);
free(value.value);
return (ParsedValueReturn){
create_err(token->line, token->column, token->length, file,
"Syntax Error", "expected comma"),
NULL};
} }
break; break;
case TOKEN_RBRACE: case TOKEN_RBRACE:
@@ -87,9 +123,14 @@ ParsedValueReturn parse_dictionary(char *file, DArray *tokens, size_t *index) {
value = parse_token(file, tokens, &keyIndex, true); value = parse_token(file, tokens, &keyIndex, true);
break; break;
default: default:
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line, free_parsed(parsedValue);
token->column); free(parsedValue);
exit(EXIT_FAILURE); free_parsed(key.value);
free(key.value);
return (ParsedValueReturn){create_err(token->line, token->column,
token->length, file,
"Syntax Error", "unexpected token"),
NULL};
} }
ParsedDictionaryEntry entry = {key.value, value.value}; ParsedDictionaryEntry entry = {key.value, value.value};
darray_push(dictionary, &entry); darray_push(dictionary, &entry);
@@ -97,7 +138,12 @@ ParsedValueReturn parse_dictionary(char *file, DArray *tokens, size_t *index) {
break; break;
} }
(*index)++; (*index)++;
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
} }
} }
(*index)++; (*index)++;

View File

@@ -14,4 +14,6 @@ ParsedValue *create_parsed_function(char *name, DArray parameters,
void free_function(void *ptr); void free_function(void *ptr);
void free_parameter(void *ptr);
#endif // FUNCTION_H #endif // FUNCTION_H

View File

@@ -3,6 +3,7 @@
#include "../../memory.h" #include "../../memory.h"
#include "../parser.h" #include "../parser.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -18,7 +19,10 @@ void free_conditional(void *ptr) {
ParsedValueReturn parse_if(char *file, DArray *tokens, size_t *index) { ParsedValueReturn parse_if(char *file, DArray *tokens, size_t *index) {
(*index)++; (*index)++;
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
return (ParsedValueReturn){err, NULL};
}
DArray *parsed_if = checked_malloc(sizeof(DArray)); DArray *parsed_if = checked_malloc(sizeof(DArray));
darray_init(parsed_if, sizeof(ParsedConditional)); darray_init(parsed_if, sizeof(ParsedConditional));
@@ -32,15 +36,22 @@ ParsedValueReturn parse_if(char *file, DArray *tokens, size_t *index) {
if (!expect_conditional) { if (!expect_conditional) {
if (token->type != TOKEN_NEW_LINE) if (token->type != TOKEN_NEW_LINE)
break; // no more branches break; // no more branches
(*index)++; size_t current_index = *index;
skip_newlines_and_indents(tokens, index);
if ((*index) >= tokens->size) if ((*index) >= tokens->size)
break; break;
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
if (token->type == TOKEN_ELSE || token->type == TOKEN_ELSE_IF) { if (token->type == TOKEN_ELSE || token->type == TOKEN_ELSE_IF) {
(*index)++; (*index)++;
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
darray_free(parsed_if, free_conditional);
free(parsed_if);
return (ParsedValueReturn){err, NULL};
}
} else { } else {
*index = current_index;
break; // no more branches break; // no more branches
} }
} }
@@ -60,7 +71,12 @@ ParsedValueReturn parse_if(char *file, DArray *tokens, size_t *index) {
} }
(*index)++; (*index)++;
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
darray_free(parsed_if, free_conditional);
free(parsed_if);
return (ParsedValueReturn){err, NULL};
}
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
condition = parse_token(file, tokens, index, true); condition = parse_token(file, tokens, index, true);
if (condition.err.exists) { if (condition.err.exists) {
@@ -92,7 +108,16 @@ ParsedValueReturn parse_if(char *file, DArray *tokens, size_t *index) {
} }
(*index)++; (*index)++;
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
if (condition.value) {
free_parsed(condition.value);
free(condition.value);
}
darray_free(parsed_if, free_conditional);
free(parsed_if);
return (ParsedValueReturn){err, NULL};
}
} }
// Parse the body // Parse the body

View File

@@ -14,7 +14,12 @@ ParsedValueReturn parse_list(char *file, DArray *tokens, size_t *index) {
darray_init(list, sizeof(ParsedValue)); darray_init(list, sizeof(ParsedValue));
(*index)++; (*index)++;
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
Token *token = darray_get(tokens, *index); Token *token = darray_get(tokens, *index);
if (token->type != TOKEN_RBRACKET) { if (token->type != TOKEN_RBRACKET) {
while (true) { while (true) {
@@ -27,19 +32,34 @@ ParsedValueReturn parse_list(char *file, DArray *tokens, size_t *index) {
} }
darray_push(list, parsedItem.value); darray_push(list, parsedItem.value);
free(parsedItem.value); free(parsedItem.value);
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
if (token->type == TOKEN_RBRACKET) { if (token->type == TOKEN_RBRACKET) {
break; break;
} else if (token->type != TOKEN_COMMA) { } else if (token->type != TOKEN_COMMA) {
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line, free_parsed(parsedValue);
token->column); free(parsedValue);
exit(EXIT_FAILURE); return (ParsedValueReturn){create_err(token->line, token->column, token->length, file, "Syntax Error", "expected comma"), NULL};
} }
(*index)++; (*index)++;
error_if_finished(file, tokens, index); err = error_if_finished(file, tokens, index);
if (err.exists) {
free_parsed(parsedValue);
free(parsedValue);
return (ParsedValueReturn){err, NULL};
}
} }
} }
(*index)++; (*index)++;

View File

@@ -55,7 +55,7 @@ ParsedValue convert_to_operation(DArray *to_operate_on, DArray *operations) {
} }
ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index, ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index,
ParsedValue *first_parsed_value) { ParsedValue *first_parsed_value) {
DArray to_operate_on; DArray to_operate_on;
darray_init(&to_operate_on, sizeof(ParsedValue)); darray_init(&to_operate_on, sizeof(ParsedValue));
darray_push(&to_operate_on, first_parsed_value); darray_push(&to_operate_on, first_parsed_value);
@@ -77,7 +77,12 @@ ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index,
break; break;
darray_push(&operations, &token->type); darray_push(&operations, &token->type);
(*index)++; (*index)++;
error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) {
darray_free(&to_operate_on, free_parsed);
darray_free(&operations, NULL);
return (ParsedValueReturn){err, NULL};
}
ParsedValueReturn parsedValue = ParsedValueReturn parsedValue =
parse_token_full(file, tokens, index, true, false); parse_token_full(file, tokens, index, true, false);
if (parsedValue.err.exists) { if (parsedValue.err.exists) {
@@ -87,10 +92,10 @@ ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index,
} else if (!parsedValue.value) { } else if (!parsedValue.value) {
darray_free(&to_operate_on, free_parsed); darray_free(&to_operate_on, free_parsed);
darray_free(&operations, NULL); darray_free(&operations, NULL);
return (ParsedValueReturn){ return (ParsedValueReturn){create_err(token->line, token->column,
create_err(token->line, token->column, token->length, file, token->length, file, "Syntax Error",
"Syntax Error", "expected value"), "expected value"),
NULL}; NULL};
} }
darray_push(&to_operate_on, parsedValue.value); darray_push(&to_operate_on, parsedValue.value);
free(parsedValue.value); free(parsedValue.value);
@@ -100,7 +105,7 @@ ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index,
memcpy(parsedValue, &output, sizeof(ParsedValue)); memcpy(parsedValue, &output, sizeof(ParsedValue));
darray_free(&to_operate_on, NULL); darray_free(&to_operate_on, NULL);
darray_free(&operations, NULL); darray_free(&operations, NULL);
return (ParsedValueReturn){no_err,parsedValue}; return (ParsedValueReturn){no_err, parsedValue};
} }
void free_operation(void *ptr) { void free_operation(void *ptr) {

View File

@@ -27,13 +27,13 @@ const char *ValueTypeNames[] = {
"access", "call", "declaration", "null", "boolean", "access", "call", "declaration", "null", "boolean",
"do wrap", "operations", "list", "dictionary", "function"}; "do wrap", "operations", "list", "dictionary", "function"};
void error_if_finished(char *file, DArray *tokens, size_t *index) { ArErr error_if_finished(char *file, DArray *tokens, size_t *index) {
if ((*index) >= tokens->size) { if ((*index) >= tokens->size) {
Token *token = darray_get(tokens, tokens->size - 1); Token *token = darray_get(tokens, tokens->size - 1);
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line, return create_err(token->line, token->column, token->length, file,
token->column); "Syntax Error", "more code was expected");
exit(EXIT_FAILURE);
} }
return no_err;
} }
size_t skip_newlines_and_indents(DArray *tokens, size_t *index) { size_t skip_newlines_and_indents(DArray *tokens, size_t *index) {
@@ -94,8 +94,9 @@ ParsedValueReturn parse_token_full(char *file, DArray *tokens, size_t *index,
token = darray_get(tokens, (*index) + 1); token = darray_get(tokens, (*index) + 1);
if (token->type != TOKEN_NEW_LINE) { if (token->type != TOKEN_NEW_LINE) {
return (ParsedValueReturn){ return (ParsedValueReturn){
create_err(token_indent->line, token_indent->column, token_indent->length, file, create_err(token_indent->line, token_indent->column,
"Syntax Error", "unexpected indent"), token_indent->length, file, "Syntax Error",
"unexpected indent"),
NULL}; NULL};
} }
} }
@@ -122,9 +123,11 @@ ParsedValueReturn parse_token_full(char *file, DArray *tokens, size_t *index,
output = parse_dictionary(file, tokens, index); output = parse_dictionary(file, tokens, index);
break; break;
default: default:
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line, return (ParsedValueReturn){create_err(token->line,
token->column); token->column,
exit(EXIT_FAILURE); token->length, file,
"Syntax Error", "unexpected token"),
NULL};
} }
// LHS required // LHS required
@@ -179,14 +182,12 @@ 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) {
Token *token = darray_get(tokens, old_index); Token *token = darray_get(tokens, old_index);
fprintf(stderr, "%s:%zu:%zu error: expected a new line\n", file, return create_err(token->line, token->column, token->length, file,
token->line, token->column); "Syntax Error", "expected new line");
exit(EXIT_FAILURE);
} }
expecting_new_line = true; expecting_new_line = true;
darray_push(parsed, parsed_code.value); darray_push(parsed, parsed_code.value);

View File

@@ -67,7 +67,7 @@ ParsedValueReturn parse_token(char *file, DArray *tokens, size_t *index,
void free_parsed(void *ptr); void free_parsed(void *ptr);
void error_if_finished(char *file, DArray *tokens, size_t *index); __attribute__((warn_unused_result)) ArErr error_if_finished(char *file, DArray *tokens, size_t *index);
size_t skip_newlines_and_indents(DArray *tokens, size_t *index); size_t skip_newlines_and_indents(DArray *tokens, size_t *index);

View File

@@ -0,0 +1,18 @@
#include "declaration.h"
ArErr runtime_declaration(Translated *translated, RuntimeState *state,
struct Stack *stack) {
int64_t length = pop_bytecode(translated, state);
int64_t offset = pop_bytecode(translated, state);
int64_t prehash = pop_bytecode(translated, state);
int64_t from_register = pop_byte(translated, state);
int64_t source_location_index = pop_bytecode(translated, state);
uint64_t hash = runtime_hash(arena_get(&translated->constants, offset), length, prehash);
ArgonObject * exists = hashmap_lookup_GC(stack->scope, hash);
if (exists) {
SourceLocation *source_location = darray_get(&translated->source_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);
return no_err;
}

View File

@@ -0,0 +1,8 @@
#ifndef runtime_declaration_H
#define runtime_declaration_H
#include "../runtime.h"
ArErr runtime_declaration(Translated *translated, RuntimeState *state,
struct Stack *stack);
#endif // runtime_declaration_H

View File

@@ -12,7 +12,7 @@ void init_function_type() {
} }
void load_argon_function(Translated *translated, RuntimeState *state, void load_argon_function(Translated *translated, RuntimeState *state,
struct Stack stack) { struct Stack *stack) {
ArgonObject *object = init_child_argon_object(ARGON_FUNCTION_TYPE); ArgonObject *object = init_child_argon_object(ARGON_FUNCTION_TYPE);
object->type = TYPE_FUNCTION; object->type = TYPE_FUNCTION;
uint64_t offset = pop_bytecode(translated, state); uint64_t offset = pop_bytecode(translated, state);
@@ -35,6 +35,6 @@ void load_argon_function(Translated *translated, RuntimeState *state,
darray_armem_init(&object->value.argon_fn.bytecode, sizeof(uint64_t)); darray_armem_init(&object->value.argon_fn.bytecode, sizeof(uint64_t));
darray_armem_resize(&object->value.argon_fn.bytecode, length/object->value.argon_fn.bytecode.element_size); darray_armem_resize(&object->value.argon_fn.bytecode, length/object->value.argon_fn.bytecode.element_size);
memcpy(object->value.argon_fn.bytecode.data, arena_get(&translated->constants, offset), length); memcpy(object->value.argon_fn.bytecode.data, arena_get(&translated->constants, offset), length);
object->value.argon_fn.stack = stack; object->value.argon_fn.stack = *stack;
state->registers[0]=object; state->registers[0]=object;
} }

View File

@@ -4,6 +4,6 @@
void init_function_type(); void init_function_type();
ArgonObject *load_argon_function(Translated *translated, RuntimeState *state, struct Stack stack); ArgonObject *load_argon_function(Translated *translated, RuntimeState *state, struct Stack *stack);
#endif // FUNCTION_H #endif // FUNCTION_H

View File

@@ -0,0 +1,25 @@
#include "../object.h"
#include <string.h>
#include "literals.h"
ArgonObject *ARGON_NULL_TYPE = NULL;
ArgonObject *ARGON_NULL = NULL;
ArgonObject *ARGON_BOOL_TYPE = NULL;
ArgonObject *ARGON_TRUE = NULL;
ArgonObject *ARGON_FALSE = NULL;
void init_literals() {
ARGON_NULL_TYPE = init_argon_class("NULL_TYPE");
ARGON_NULL = init_child_argon_object(ARGON_NULL_TYPE);
ARGON_NULL->type=TYPE_NULL;
ARGON_BOOL_TYPE = init_argon_class("Bool");
ARGON_FALSE = init_child_argon_object(ARGON_BOOL_TYPE);
ARGON_FALSE->type=TYPE_BOOL;
ARGON_TRUE = init_child_argon_object(ARGON_BOOL_TYPE);
ARGON_TRUE->type=TYPE_BOOL;
}

View File

@@ -0,0 +1,12 @@
#ifndef RUNTIME_LITERALS_H
#define RUNTIME_LITERALS_H
#include "../object.h"
extern ArgonObject *ARGON_NULL;
extern ArgonObject *ARGON_FALSE;
extern ArgonObject *ARGON_TRUE;
void init_literals();
#endif // RUNTIME_LITERALS_H

View File

@@ -1,14 +0,0 @@
#include "../../internals/hashmap/hashmap.h"
#include "../object.h"
#include <string.h>
#include "null.h"
ArgonObject *ARGON_NULL_TYPE = NULL;
ArgonObject *ARGON_NULL = NULL;
void init_null() {
ARGON_NULL_TYPE = init_argon_class("NULL_TYPE");
ARGON_NULL = init_child_argon_object(ARGON_NULL_TYPE);
ARGON_NULL->type=TYPE_NULL;
}

View File

@@ -1,10 +0,0 @@
#ifndef NULL_H
#define NULL_H
#include "../object.h"
extern ArgonObject *ARGON_NULL;
void init_null();
#endif // NULL_H

View File

@@ -2,8 +2,9 @@
#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 "declaration/declaration.h"
#include "objects/functions/functions.h" #include "objects/functions/functions.h"
#include "objects/null/null.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/type/type.h" #include "objects/type/type.h"
@@ -29,7 +30,7 @@ void init_types() {
init_type(); init_type();
init_function_type(); init_function_type();
init_null(); init_literals();
init_string_type(); init_string_type();
init_base_field(); init_base_field();
@@ -64,33 +65,50 @@ void load_const(Translated *translated, RuntimeState *state) {
state->registers[to_register] = object; state->registers[to_register] = object;
} }
struct hashmap *runtime_hash_table = NULL;
uint64_t runtime_hash(const void *data, size_t len, uint64_t prehash) {
if (!runtime_hash_table) {
runtime_hash_table = createHashmap();
} else {
void *result = hashmap_lookup(runtime_hash_table, prehash);
if (result) {
return (uint64_t)result;
}
}
uint64_t hash = siphash64_bytes(data, len, siphash_key);
hashmap_insert(runtime_hash_table, prehash, 0, (void *)hash, 0);
return hash;
}
ArErr load_variable(Translated *translated, RuntimeState *state, ArErr load_variable(Translated *translated, RuntimeState *state,
struct Stack stack) { struct Stack *stack) {
int64_t length = pop_bytecode(translated, state); int64_t length = pop_bytecode(translated, state);
int64_t offset = pop_bytecode(translated, state); int64_t offset = pop_bytecode(translated, state);
int64_t prehash = pop_bytecode(translated, state);
int64_t source_location_index = pop_bytecode(translated, state); int64_t source_location_index = pop_bytecode(translated, state);
char *name = checked_malloc(length); uint64_t hash =
memcpy(name, arena_get(&translated->constants, offset), length); runtime_hash(arena_get(&translated->constants, offset), length, prehash);
uint64_t hash = siphash64_bytes(name, length, siphash_key); struct Stack *current_stack = stack;
struct Stack *current_stack = &stack;
while (current_stack) { while (current_stack) {
ArgonObject *result = hashmap_lookup_GC(current_stack->scope, hash); ArgonObject *result = hashmap_lookup_GC(current_stack->scope, hash);
if (result) { if (result) {
state->registers[0] = result; state->registers[0] = result;
free(name);
return no_err; return no_err;
} }
current_stack = current_stack->prev; current_stack = current_stack->prev;
} }
SourceLocation *source_location = darray_get(&translated->source_locations, source_location_index); SourceLocation *source_location =
ArErr err = create_err(source_location->line, source_location->column, length, state->path, "Name Error", "name '%.*s' is not defined", darray_get(&translated->source_locations, source_location_index);
(int)length, name); ArErr err = create_err(source_location->line, source_location->column,
free(name); source_location->length, state->path, "Name Error",
"name '%.*s' is not defined", (int)length,
arena_get(&translated->constants, offset));
return err; 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);
switch (opcode) { switch (opcode) {
case OP_LOAD_NULL: case OP_LOAD_NULL:
@@ -100,10 +118,32 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
load_const(translated, state); load_const(translated, state);
break; break;
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: case OP_IDENTIFIER:
return load_variable(translated, state, stack); return load_variable(translated, state, *stack);
case OP_DECLARE:
return runtime_declaration(translated, state, *stack);
case OP_BOOL:;
uint8_t to_register = pop_byte(translated, state);
state->registers[to_register] = ARGON_TRUE;
break;
case OP_JUMP_IF_FALSE:;
uint8_t from_register = pop_byte(translated, state);
uint64_t to = pop_bytecode(translated, state);
if (state->registers[from_register] == ARGON_FALSE) {
state->head = to;
}
break;
case OP_JUMP:
state->head = pop_bytecode(translated, state);
break;
case OP_NEW_SCOPE:
*stack = create_scope(*stack);
break;
case OP_POP_SCOPE:
*stack = (*stack)->prev;
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",
opcode); opcode);
@@ -113,19 +153,21 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
RuntimeState init_runtime_state(Translated translated, char *path) { 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,
path}; ARGON_NULL};
} }
Stack create_scope(Stack *prev) { Stack *create_scope(Stack *prev) {
struct hashmap_GC *scope = createHashmap_GC(); Stack *stack = ar_alloc(sizeof(Stack));
return (Stack){scope, prev}; stack->scope = createHashmap_GC();
stack->prev = prev;
return stack;
} }
ArErr runtime(Translated translated, RuntimeState state, Stack stack) { ArErr runtime(Translated translated, RuntimeState state, Stack *stack) {
state.head = 0; state.head = 0;
while (state.head < translated.bytecode.size) { while (state.head < translated.bytecode.size) {
ArErr err = run_instruction(&translated, &state, stack); ArErr err = run_instruction(&translated, &state, &stack);
if (err.exists) { if (err.exists) {
return err; return err;
} }

View File

@@ -8,19 +8,26 @@ typedef struct {
ArgonObject **registers; ArgonObject **registers;
size_t head; size_t head;
char*path; char*path;
ArgonObject * return_value;
} RuntimeState; } RuntimeState;
void init_types(); void init_types();
extern struct hashmap * runtime_hash_table;
uint64_t runtime_hash(const void *data, size_t len, uint64_t prehash);
uint8_t pop_byte(Translated *translated, RuntimeState *state);
uint64_t pop_bytecode(Translated *translated, RuntimeState *state); 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, char *path); RuntimeState init_runtime_state(Translated translated, char *path);
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);
#endif // RUNTIME_H #endif // RUNTIME_H

View File

@@ -21,7 +21,9 @@ this operation takes 3 operands.
1. the length of the variable name. 1. the length of the variable name.
2. the offset in the constant buffer of the variable name. 2. the offset in the constant buffer of the variable name.
3. the register of the given value (*) 3. the fixed hash of the variable name.
4. the register of the given value (*)
5. the index of the source location.
## OP_LOAD_NULL ## OP_LOAD_NULL
@@ -50,4 +52,33 @@ initilises a function to a given register.
1. the length of the identifer. 1. the length of the identifer.
2. the offset of the identifier. 2. the offset of the identifier.
3. the index of the source location. 3. the fixed hash of the variable name.
4. the index of the source location.
## OP_BOOL
converts a value in a given register into true or false depending on the result from \_\_bool\_\_
1. the register to read and write to. (*)
## OP_JUMP_IF_FALSE
jumps when a the value in the given register is false.
1. the register to read. (*)
1. the index to jump to.
## OP_JUMP_IF_FALSE
jumps unconditionally to an index.
1. the index to jump to.
## OP_NEW_SCOPE
creates a new stack
## OP_POP_SCOPE
pops the top scope off the current

View File

@@ -1,6 +1,7 @@
#include "declaration.h" #include "declaration.h"
#include "../../parser/declaration/declaration.h" #include "../../parser/declaration/declaration.h"
#include "../translator.h" #include "../translator.h"
#include "../../hash_data/hash_data.h"
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -20,11 +21,12 @@ size_t translate_parsed_declaration(Translated *translated,
push_instruction_byte(translated, OP_DECLARE); push_instruction_byte(translated, OP_DECLARE);
push_instruction_code(translated, length); push_instruction_code(translated, length);
push_instruction_code(translated, offset); push_instruction_code(translated, offset);
push_instruction_code(translated, siphash64_bytes(singleDeclaration->name, length, siphash_key_fixed_for_translator));
push_instruction_byte(translated, 0); push_instruction_byte(translated, 0);
} SourceLocation source_locations = {singleDeclaration->line,
if (delcarations.size != 1) { singleDeclaration->column, length};
push_instruction_byte(translated, OP_LOAD_NULL); push_instruction_code(translated, translated->source_locations.size);
push_instruction_byte(translated, 0); darray_push(&translated->source_locations, &source_locations);
} }
return first; return first;
} }

View File

@@ -10,6 +10,7 @@ size_t translate_parsed_function(Translated *translated,
DArray main_bytecode = translated->bytecode; DArray main_bytecode = translated->bytecode;
DArray _temp_bytecode; DArray _temp_bytecode;
darray_init(&_temp_bytecode, sizeof(uint8_t)); darray_init(&_temp_bytecode, sizeof(uint8_t));
set_registers(translated, 1);
translated->bytecode = _temp_bytecode; translated->bytecode = _temp_bytecode;
translate_parsed(translated, parsedFunction->body); translate_parsed(translated, parsedFunction->body);
size_t function_bytecode_offset = size_t function_bytecode_offset =

View File

@@ -3,6 +3,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "../../hash_data/hash_data.h"
size_t translate_parsed_identifier(Translated *translated, ParsedIdentifier *parsedIdentifier) { size_t translate_parsed_identifier(Translated *translated, ParsedIdentifier *parsedIdentifier) {
size_t length = strlen(parsedIdentifier->name); size_t length = strlen(parsedIdentifier->name);
@@ -11,6 +12,7 @@ size_t translate_parsed_identifier(Translated *translated, ParsedIdentifier *par
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);
push_instruction_code(translated, siphash64_bytes(parsedIdentifier->name, length, siphash_key_fixed_for_translator));
SourceLocation source_locations = { SourceLocation source_locations = {
parsedIdentifier->line, parsedIdentifier->line,
parsedIdentifier->column, parsedIdentifier->column,

45
src/translator/if/if.c Normal file
View File

@@ -0,0 +1,45 @@
#include "../../parser/if/if.h"
#include "../translator.h"
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
size_t translate_parsed_if(Translated *translated, DArray *parsedIf) {
size_t *jump_after_body_positions =
checked_malloc(parsedIf->size * sizeof(size_t));
size_t first = translated->bytecode.size;
set_registers(translated, 1);
for (uint64_t i = 0; i < parsedIf->size; i++) {
ParsedConditional *condition = darray_get(parsedIf, i);
push_instruction_byte(translated, OP_NEW_SCOPE);
if (condition->condition) {
translate_parsed(translated, condition->condition);
push_instruction_byte(translated, OP_BOOL);
push_instruction_byte(translated, 0);
push_instruction_byte(translated, OP_JUMP_IF_FALSE);
push_instruction_byte(translated, 0);
uint64_t last_jump_index = push_instruction_code(translated, 0);
translate_parsed(translated, condition->content);
push_instruction_byte(translated, OP_POP_SCOPE);
push_instruction_byte(translated, OP_JUMP);
jump_after_body_positions[i] = push_instruction_code(translated, 0);
set_instruction_code(translated, last_jump_index,
translated->bytecode.size);
push_instruction_byte(translated, OP_POP_SCOPE);
} else {
translate_parsed(translated, condition->content);
push_instruction_byte(translated, OP_POP_SCOPE);
jump_after_body_positions[i] = 0;
}
}
for (uint64_t i = 0; i < parsedIf->size; i++) {
if (jump_after_body_positions[i])
set_instruction_code(translated, jump_after_body_positions[i],
translated->bytecode.size);
}
free(jump_after_body_positions);
return first;
}

7
src/translator/if/if.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef TRANSLATE_iF_H
#define TRANSLATE_iF_H
#include "../translator.h"
size_t translate_parsed_if(Translated *translated, DArray *parsedIf);
#endif // TRANSLATE_iF_H

View File

@@ -4,6 +4,7 @@
#include "declaration/declaration.h" #include "declaration/declaration.h"
#include "function/function.h" #include "function/function.h"
#include "identifier/identifier.h" #include "identifier/identifier.h"
#include "if/if.h"
#include "number/number.h" #include "number/number.h"
#include "string/string.h" #include "string/string.h"
#include <stddef.h> #include <stddef.h>
@@ -91,6 +92,10 @@ size_t push_instruction_byte(Translated *translator, uint8_t byte) {
return offset; return offset;
} }
void set_instruction_byte(Translated *translator, size_t index, uint8_t byte) {
memcpy(translator->bytecode.data + index, &byte, sizeof(byte));
}
size_t push_instruction_code(Translated *translator, uint64_t code) { size_t push_instruction_code(Translated *translator, uint64_t code) {
size_t offset = translator->bytecode.size; size_t offset = translator->bytecode.size;
uint8_t bytes[8]; uint8_t bytes[8];
@@ -101,6 +106,10 @@ size_t push_instruction_code(Translated *translator, uint64_t code) {
return offset; return offset;
} }
void set_instruction_code(Translated *translator, size_t index, uint64_t code) {
memcpy(translator->bytecode.data + index, &code, sizeof(code));
}
void set_registers(Translated *translator, uint8_t count) { void set_registers(Translated *translator, uint8_t count) {
if (count > translator->registerCount) if (count > translator->registerCount)
translator->registerCount = count; translator->registerCount = count;
@@ -125,7 +134,10 @@ 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, (ParsedIdentifier *)parsedValue->data); return translate_parsed_identifier(translated,
(ParsedIdentifier *)parsedValue->data);
case AST_IF:
return translate_parsed_if(translated, (DArray *)parsedValue->data);
} }
return 0; return 0;
} }

View File

@@ -8,7 +8,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
typedef enum { OP_LOAD_CONST, OP_DECLARE, OP_LOAD_NULL, OP_LOAD_FUNCTION, OP_IDENTIFIER } OperationType; typedef enum { OP_LOAD_CONST, OP_DECLARE, OP_LOAD_NULL, OP_LOAD_FUNCTION, OP_IDENTIFIER, OP_BOOL, OP_JUMP_IF_FALSE, OP_JUMP, OP_NEW_SCOPE, OP_POP_SCOPE } OperationType;
typedef enum { TYPE_OP_STRING, TYPE_OP_NUMBER } types; typedef enum { TYPE_OP_STRING, TYPE_OP_NUMBER } types;
typedef struct { typedef struct {
@@ -39,8 +39,12 @@ size_t arena_push(ConstantArena *arena, const void *data, size_t length);
size_t push_instruction_byte(Translated *translator, uint8_t byte); size_t push_instruction_byte(Translated *translator, uint8_t byte);
void set_instruction_byte(Translated *translator, size_t index, uint8_t byte);
size_t push_instruction_code(Translated *translator, uint64_t code); size_t push_instruction_code(Translated *translator, uint64_t code);
void set_instruction_code(Translated *translator, size_t index, uint64_t code);
void set_registers(Translated *translator, uint8_t count); void set_registers(Translated *translator, uint8_t count);
Translated init_translator(); Translated init_translator();

3
testing.ar Normal file
View File

@@ -0,0 +1,3 @@
let y = 1
if (let x = let z = y, a=null) z
else x