diff --git a/null_test.ar b/null_test.ar deleted file mode 100644 index c156d2e..0000000 --- a/null_test.ar +++ /dev/null @@ -1 +0,0 @@ -let x(hello,lol,world, WORLD,HELLOOOO,LOLLLLLL, WORLD)=let f(x)="bruh" \ No newline at end of file diff --git a/src/main.c b/src/main.c index 96cf474..71dfe6d 100644 --- a/src/main.c +++ b/src/main.c @@ -13,12 +13,15 @@ #include #include #include +#include #include const char FILE_IDENTIFIER[] = "ARBI"; -const uint64_t version_number = 0; +const uint32_t version_number = 0; int main(int argc, char *argv[]) { + clock_t start,end; + double time_spent; setlocale(LC_ALL, ""); if (argc <= 1) return -1; @@ -35,37 +38,48 @@ int main(int argc, char *argv[]) { } LexerState state = {path, file, 0, 0, &tokens}; + start = clock(); lexer(state); + end = clock(); + time_spent = (double)(end - start) / CLOCKS_PER_SEC; + printf("Lexer time taken: %f seconds\n", time_spent); fclose(state.file); DArray ast; darray_init(&ast, sizeof(ParsedValue)); + + start = clock(); parser(path, &ast, &tokens, false); + end = clock(); + time_spent = (double)(end - start) / CLOCKS_PER_SEC; + printf("Parser time taken: %f seconds\n", time_spent); darray_free(&tokens, free_token); Translated translated = init_translator(); + + start = clock(); translate(&translated, &ast); + end = clock(); + time_spent = (double)(end - start) / CLOCKS_PER_SEC; + printf("Translation time taken: %f seconds\n", time_spent); darray_free(&ast, free_parsed); file = fopen("out.arbin", "wb"); - uint64_t regCount = (uint64_t)translated.registerCount; uint64_t constantsSize = (uint64_t)translated.constants.size; uint64_t bytecodeSize = (uint64_t)translated.bytecode.size; - uint64_t version_number_htole64ed = htole64(version_number); - regCount = htole64(regCount); - regCount = htole64(regCount); + uint32_t version_number_htole32ed = htole32(version_number); constantsSize = htole64(constantsSize); bytecodeSize = htole64(bytecodeSize); fwrite(&FILE_IDENTIFIER, sizeof(char), strlen(FILE_IDENTIFIER), file); - fwrite(&version_number_htole64ed, sizeof(uint64_t), 1, file); - fwrite(®Count, sizeof(uint64_t), 1, file); + fwrite(&version_number_htole32ed, sizeof(uint32_t), 1, file); + fwrite(&translated.registerCount, sizeof(uint8_t), 1, file); fwrite(&constantsSize, sizeof(uint64_t), 1, file); fwrite(&bytecodeSize, sizeof(uint64_t), 1, file); fwrite(translated.constants.data, 1, translated.constants.size, file); @@ -77,8 +91,15 @@ int main(int argc, char *argv[]) { generate_siphash_key(); init_types(); + + start = clock(); runtime(translated); + end = clock(); + time_spent = (double)(end - start) / CLOCKS_PER_SEC; + + printf("Execution time taken: %f seconds\n", time_spent); + free_translator(&translated); return 0; } diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 552ef15..1747818 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -14,6 +14,14 @@ #include #include +uint64_t bytes_to_uint64(const uint8_t bytes[8]) { + uint64_t value = 0; + for (int i = 0; i < 8; i++) { + value |= ((uint64_t)bytes[i]) << (i * 8); + } + return value; +} + void init_types() { BASE_CLASS = init_argon_class("BASE_CLASS"); @@ -25,14 +33,22 @@ void init_types() { init_base_field(); } + +uint8_t pop_byte(Translated *translated, RuntimeState *state) { + return *((uint8_t *)darray_get(&translated->bytecode, state->head++)); +} + uint64_t pop_bytecode(Translated *translated, RuntimeState *state) { - uint64_t *instruction = darray_get(&translated->bytecode, state->head++); - return *instruction; + uint8_t bytes[8]; + for (size_t i = 0; i < sizeof(bytes); i++) { + bytes[i] = *((uint8_t *)darray_get(&translated->bytecode, state->head++)); + } + return bytes_to_uint64(bytes); } void load_const(Translated *translated, RuntimeState *state) { - uint64_t to_register = pop_bytecode(translated, state); - types type = pop_bytecode(translated, state); + uint64_t to_register = pop_byte(translated, state); + types type = pop_byte(translated, state); size_t length = pop_bytecode(translated, state); uint64_t offset = pop_bytecode(translated, state); @@ -49,10 +65,10 @@ void load_const(Translated *translated, RuntimeState *state) { void run_instruction(Translated *translated, RuntimeState *state, struct Stack stack) { - OperationType opcode = pop_bytecode(translated, state); + OperationType opcode = pop_byte(translated, state); switch (opcode) { case OP_LOAD_NULL: - state->registers[pop_bytecode(translated, state)] = ARGON_NULL; + state->registers[pop_byte(translated, state)] = ARGON_NULL; break; case OP_LOAD_CONST: load_const(translated, state); diff --git a/src/translator/bytecode_spec.md b/src/translator/bytecode_spec.md index 93503a3..a13f029 100644 --- a/src/translator/bytecode_spec.md +++ b/src/translator/bytecode_spec.md @@ -1,13 +1,15 @@ # Bytecode Specification +all opcodes are uint8_t, and all operands are uint64_t unless marked with an asterisk (*), where it is marked as uint8_t + ## OP_LOAD_CONST loads and initialises a value from the constant buffer into the provided register. this operation 4 operands. -1. the register to write to. -2. the type of data from the constant buffer. +1. the register to write to. (*) +2. the type of data from the constant buffer. (*) 3. the length of the data in the constant buffer. 4. the offset in the constant buffer. @@ -19,7 +21,7 @@ this operation takes 3 operands. 1. the length of the variable name. 2. the offset in the constant buffer of the variable name. -3. the register of the given value +3. the register of the given value (*) ## OP_LOAD_NULL @@ -27,7 +29,7 @@ sets a given register to null. this operation takes 1 operand. -1. the register to set to null. +1. the register to set to null. (*) ## OP_LOAD_FUNCTION diff --git a/src/translator/declaration/declaration.c b/src/translator/declaration/declaration.c index ed73cc5..ba86a92 100644 --- a/src/translator/declaration/declaration.c +++ b/src/translator/declaration/declaration.c @@ -17,14 +17,14 @@ size_t translate_parsed_declaration(Translated *translated, size_t offset = arena_push(&translated->constants, singleDeclaration->name, length); - push_instruction_code(translated, OP_DECLARE); + push_instruction_byte(translated, OP_DECLARE); push_instruction_code(translated, length); push_instruction_code(translated, offset); - push_instruction_code(translated, 0); + push_instruction_byte(translated, 0); } if (delcarations.size != 1) { - push_instruction_code(translated, OP_LOAD_NULL); - push_instruction_code(translated, 0); + push_instruction_byte(translated, OP_LOAD_NULL); + push_instruction_byte(translated, 0); } return first; } \ No newline at end of file diff --git a/src/translator/function/function.c b/src/translator/function/function.c index e9cd8a2..9ad8d8d 100644 --- a/src/translator/function/function.c +++ b/src/translator/function/function.c @@ -1,22 +1,24 @@ #include "function.h" #include "../translator.h" #include +#include #include +#include #include size_t translate_parsed_function(Translated *translated, ParsedFunction *parsedFunction) { - DArray temp_bytecode; - darray_init(&temp_bytecode, sizeof(uint64_t)); DArray main_bytecode = translated->bytecode; - translated->bytecode = temp_bytecode; + DArray _temp_bytecode; + darray_init(&_temp_bytecode, sizeof(uint8_t)); + translated->bytecode = _temp_bytecode; translate_parsed(translated, parsedFunction->body); size_t function_bytecode_offset = arena_push(&translated->constants, translated->bytecode.data, translated->bytecode.size*translated->bytecode.element_size); size_t function_bytecode_length = translated->bytecode.size; + darray_free(&translated->bytecode, NULL); translated->bytecode = main_bytecode; - darray_free(&temp_bytecode, NULL); - size_t start = push_instruction_code(translated, OP_LOAD_FUNCTION); + size_t start = push_instruction_byte(translated, OP_LOAD_FUNCTION); size_t offset = arena_push(&translated->constants, parsedFunction->name, strlen(parsedFunction->name)); push_instruction_code(translated, offset); diff --git a/src/translator/number/number.c b/src/translator/number/number.c index 21239c8..28220a5 100644 --- a/src/translator/number/number.c +++ b/src/translator/number/number.c @@ -10,10 +10,10 @@ size_t translate_parsed_number(Translated *translated, char *number_str, size_t size_t number_pos = arena_push(&translated->constants, number_str, length); set_registers(translated, to_register+1); - size_t start = push_instruction_code(translated, OP_LOAD_CONST); - push_instruction_code(translated, to_register); + size_t start = push_instruction_byte(translated, OP_LOAD_CONST); + push_instruction_byte(translated, to_register); - push_instruction_code(translated, TYPE_OP_NUMBER); + push_instruction_byte(translated, TYPE_OP_NUMBER); push_instruction_code(translated,length); push_instruction_code(translated, number_pos); return start; diff --git a/src/translator/string/string.c b/src/translator/string/string.c index 91aff1b..2ffb276 100644 --- a/src/translator/string/string.c +++ b/src/translator/string/string.c @@ -7,9 +7,9 @@ size_t translate_parsed_string(Translated *translated, ParsedString parsedString) { size_t string_pos = arena_push(&translated->constants, parsedString.string, parsedString.length); set_registers(translated, 1); - size_t start = push_instruction_code(translated, OP_LOAD_CONST); - push_instruction_code(translated, 0); - push_instruction_code(translated, TYPE_OP_STRING); + size_t start = push_instruction_byte(translated, OP_LOAD_CONST); + push_instruction_byte(translated, 0); + push_instruction_byte(translated, TYPE_OP_STRING); push_instruction_code(translated,parsedString.length); push_instruction_code(translated, string_pos); return start; diff --git a/src/translator/translator.c b/src/translator/translator.c index fd2b0f1..53db10c 100644 --- a/src/translator/translator.c +++ b/src/translator/translator.c @@ -9,6 +9,12 @@ #include #include +void uint64_to_bytes(uint64_t value, uint8_t bytes[8]) { + for (int i = 0; i < 8; i++) { + bytes[i] = (value >> (i * 8)) & 0xFF; + } +} + void arena_init(ConstantArena *arena) { arena->data = checked_malloc(CHUNK_SIZE); arena->capacity = CHUNK_SIZE; @@ -56,25 +62,29 @@ size_t arena_push(ConstantArena *arena, const void *data, size_t length) { Translated init_translator() { Translated translated; translated.registerCount = 0; - darray_init(&translated.bytecode, sizeof(uint64_t)); + darray_init(&translated.bytecode, sizeof(uint8_t)); arena_init(&translated.constants); return translated; } -void set_instruction_code(Translated *translator, size_t offset, - uint64_t code) { - size_t *ptr = (translator->bytecode.data + offset); - *ptr = code; -} -size_t push_instruction_code(Translated *translator, uint64_t code) { - code = htole64(code); +size_t push_instruction_byte(Translated *translator, uint8_t byte) { size_t offset = translator->bytecode.size; - darray_push(&translator->bytecode, &code); + darray_push(&translator->bytecode, &byte); return offset; } -void set_registers(Translated *translator, size_t count) { +size_t push_instruction_code(Translated *translator, uint64_t code) { + size_t offset = translator->bytecode.size; + uint8_t bytes[8]; + uint64_to_bytes(code, bytes); + for (size_t i = 0; i < sizeof(bytes); i++) { + darray_push(&translator->bytecode, &(bytes[i])); + } + return offset; +} + +void set_registers(Translated *translator, uint8_t count) { if (count > translator->registerCount) translator->registerCount = count; } @@ -91,8 +101,8 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) { return translate_parsed_number(translated, (char *)parsedValue->data, 0); case AST_NULL: set_registers(translated, 1); - size_t output = push_instruction_code(translated, OP_LOAD_NULL); - push_instruction_code(translated, 0); + size_t output = push_instruction_byte(translated, OP_LOAD_NULL); + push_instruction_byte(translated, 0); return output; case AST_FUNCTION: return translate_parsed_function(translated, diff --git a/src/translator/translator.h b/src/translator/translator.h index 00959f2..852d036 100644 --- a/src/translator/translator.h +++ b/src/translator/translator.h @@ -7,8 +7,8 @@ #include #include -typedef enum { OP_LOAD_CONST = 255, OP_DECLARE, OP_LOAD_NULL, OP_LOAD_FUNCTION } OperationType; -typedef enum { TYPE_OP_STRING = 255, TYPE_OP_NUMBER } types; +typedef enum { OP_LOAD_CONST, OP_DECLARE, OP_LOAD_NULL, OP_LOAD_FUNCTION } OperationType; +typedef enum { TYPE_OP_STRING, TYPE_OP_NUMBER } types; typedef struct { void *data; @@ -17,7 +17,7 @@ typedef struct { } ConstantArena; typedef struct { - size_t registerCount; + uint8_t registerCount; DArray bytecode; ConstantArena constants; } Translated; @@ -26,11 +26,11 @@ void *arena_get(ConstantArena *arena, size_t offset); size_t arena_push(ConstantArena *arena, const void *data, size_t length); -void set_instruction_code(Translated * translator, size_t offset, uint64_t code); +size_t push_instruction_byte(Translated *translator, uint8_t byte); size_t push_instruction_code(Translated *translator, uint64_t code); -void set_registers(Translated *translator, size_t count); +void set_registers(Translated *translator, uint8_t count); Translated init_translator(); diff --git a/test.ar b/test.ar index 4c92512..69966a8 100644 --- a/test.ar +++ b/test.ar @@ -1,6 +1,3 @@ -null - - "h" "e" "ll"