From e5e4f22481cd21de2c3cfc0d31e31fa719136a9b Mon Sep 17 00:00:00 2001 From: William Bell Date: Sun, 15 Jun 2025 05:05:33 +0100 Subject: [PATCH] write bytecode debugging script and start working on functions --- debug_arbin.py | 126 +++++++++++++++++++++++ src/translator/bytecode_spec.md | 30 ++++++ src/translator/declaration/declaration.c | 28 +++-- src/translator/declaration/declaration.h | 4 +- src/translator/function/function.c | 9 ++ src/translator/function/function.h | 8 ++ src/translator/number/number.c | 7 +- src/translator/number/number.h | 2 +- src/translator/string/string.c | 12 +-- src/translator/string/string.h | 3 +- src/translator/translator.c | 6 +- src/translator/translator.h | 2 +- test.ar | 3 + 13 files changed, 204 insertions(+), 36 deletions(-) create mode 100644 debug_arbin.py create mode 100644 src/translator/bytecode_spec.md create mode 100644 src/translator/function/function.c create mode 100644 src/translator/function/function.h diff --git a/debug_arbin.py b/debug_arbin.py new file mode 100644 index 0000000..2f6d603 --- /dev/null +++ b/debug_arbin.py @@ -0,0 +1,126 @@ +import struct +from enum import Enum, EnumMeta, auto + +class AutoEnumMeta(EnumMeta): + @classmethod + def __prepare__(metacls, clsname, bases, **kwargs): + d = super().__prepare__(clsname, bases, **kwargs) + d['_next_value'] = 254 + return d + + def _generate_next_value_(cls, name, start, count, last_values): + value = cls._next_value + cls._next_value += 1 + return value + +class OperationType(Enum, metaclass=AutoEnumMeta): + OP_LOAD_CONST = auto() + OP_DECLARE = auto() + OP_LOAD_NULL = auto() + OP_JUMP = auto() + +class Types(Enum, metaclass=AutoEnumMeta): + TYPE_OP_STRING = auto() + TYPE_OP_NUMBER = auto() + +def read_arbin(filename): + with open(filename, "rb") as f: + # Read and verify file identifier (4 bytes) + file_id = f.read(4) + if file_id != b"ARBI": + raise ValueError("Invalid file identifier") + + # Read version number (uint64_t, little-endian) + version_number, = struct.unpack(" int: + print("OP_LOAD_CONST ", end="") + i+=1 + register = data["bytecode"][i] + print("To Register",register,"", end="") + i+=1 + match data["bytecode"][i]: + case Types.TYPE_OP_STRING.value: + print("TYPE_OP_STRING ", end="") + case Types.TYPE_OP_NUMBER.value: + print("TYPE_OP_NUMBER ", end="") + i+=1 + length = data["bytecode"][i] + i+=1 + offset = data["bytecode"][i] + i+=1 + print("Length",length,"", end="") + print("Offset",offset,"") + registers[register] = data["constants"][offset:offset+length].decode() + print("const value:", registers[register]) + return i + + def OP_DECLARE(registers,data, i) -> int: + print("OP_DECLARE ", end="") + i+=1 + length = data["bytecode"][i] + i+=1 + offset = data["bytecode"][i] + i+=1 + from_register = data["bytecode"][i] + i+=1 + print("Name Length",length,"", end="") + print("Name Offset",offset,"", end="") + print("From Register",from_register,"") + print("output: let", data['constants'][offset:offset+length].decode(),'=',registers[from_register]) + return i + def OP_LOAD_NULL(registers,data, i) -> int: + print("OP_LOAD_NULL ", end="") + i+=1 + to_register = data["bytecode"][i] + i+=1 + print("To Register",to_register,"") + registers[to_register] = "null" + return i +if __name__ == "__main__": + filename = "out.arbin" + data = read_arbin(filename) + print(f"Version: {data['version']}") + print(f"Register Count: {data['register_count']}") + print(f"Constants Size: {data['constants_size']} bytes") + print(f"Bytecode Length: {data['bytecode_size']} elements") + + registers = ["null"]*data['register_count'] + + i=0 + while i #include #include size_t translate_parsed_declaration(Translated *translated, - ParsedValue *parsedValue) { - DArray *delcarations = (DArray *)parsedValue->data; - set_registers(translated, 2); + DArray delcarations) { + set_registers(translated, 1); size_t first = 0; - for (size_t i = 0; i < delcarations->size; i++) { + for (size_t i = 0; i < delcarations.size; i++) { // TODO: add function delclaration - ParsedSingleDeclaration*singleDeclaration = darray_get(delcarations, i); + ParsedSingleDeclaration *singleDeclaration = darray_get(&delcarations, i); size_t temp = translate_parsed(translated, singleDeclaration->from); - if (i==0) first = temp; + if (i == 0) + first = temp; size_t length = strlen(singleDeclaration->name); - size_t offset = arena_push(&translated->constants, singleDeclaration->name, length); - - push_instruction_code(translated, OP_LOAD_CONST); - push_instruction_code(translated, 1); - push_instruction_code(translated, TYPE_OP_STRING); - push_instruction_code(translated,length); - push_instruction_code(translated, offset); + size_t offset = + arena_push(&translated->constants, singleDeclaration->name, length); push_instruction_code(translated, OP_DECLARE); + push_instruction_code(translated, length); + push_instruction_code(translated, offset); push_instruction_code(translated, 0); - push_instruction_code(translated, 1); } - if (delcarations->size != 1) { + if (delcarations.size != 1) { push_instruction_code(translated, OP_LOAD_NULL); push_instruction_code(translated, 0); } diff --git a/src/translator/declaration/declaration.h b/src/translator/declaration/declaration.h index e27a31f..3fae2c2 100644 --- a/src/translator/declaration/declaration.h +++ b/src/translator/declaration/declaration.h @@ -2,9 +2,7 @@ #define BYTECODE_DECLARATION_H #include "../translator.h" -size_t translate_parsed_string(Translated *translated, ParsedValue *parsedValue); - size_t translate_parsed_declaration(Translated *translated, - ParsedValue *parsedValue); + DArray delcarations); #endif \ No newline at end of file diff --git a/src/translator/function/function.c b/src/translator/function/function.c new file mode 100644 index 0000000..4e88492 --- /dev/null +++ b/src/translator/function/function.c @@ -0,0 +1,9 @@ +#include "function.h" +#include "../translator.h" +#include +#include +#include +size_t translate_parsed_function(Translated *translated, + ParsedValue *parsedValue) { + return 0; +} \ No newline at end of file diff --git a/src/translator/function/function.h b/src/translator/function/function.h new file mode 100644 index 0000000..80002c5 --- /dev/null +++ b/src/translator/function/function.h @@ -0,0 +1,8 @@ +#ifndef BYTECODE_FUNCTION_H +#define BYTECODE_FUNCTION_H +#include "../translator.h" + +size_t translate_parsed_function(Translated *translated, + ParsedValue *parsedValue); + +#endif \ No newline at end of file diff --git a/src/translator/number/number.c b/src/translator/number/number.c index c65d047..21239c8 100644 --- a/src/translator/number/number.c +++ b/src/translator/number/number.c @@ -5,14 +5,13 @@ #include #include -size_t translate_parsed_number(Translated *translated, ParsedValue *parsedValue) { - char *number_str = (char*)parsedValue->data; +size_t translate_parsed_number(Translated *translated, char *number_str, size_t to_register) { size_t length = strlen(number_str); size_t number_pos = arena_push(&translated->constants, number_str, length); - set_registers(translated, 1); + set_registers(translated, to_register+1); size_t start = push_instruction_code(translated, OP_LOAD_CONST); - push_instruction_code(translated, 0); + push_instruction_code(translated, to_register); push_instruction_code(translated, TYPE_OP_NUMBER); push_instruction_code(translated,length); diff --git a/src/translator/number/number.h b/src/translator/number/number.h index a1a452f..e5bb04f 100644 --- a/src/translator/number/number.h +++ b/src/translator/number/number.h @@ -2,6 +2,6 @@ #define BYTECODE_NUMBER_H #include "../translator.h" -size_t translate_parsed_number(Translated *translated, ParsedValue *parsedValue); +size_t translate_parsed_number(Translated *translated, char *number_str, size_t to_register); #endif \ No newline at end of file diff --git a/src/translator/string/string.c b/src/translator/string/string.c index 32e9a7f..14c6687 100644 --- a/src/translator/string/string.c +++ b/src/translator/string/string.c @@ -1,18 +1,16 @@ #include "../translator.h" -#include "../../parser/string/string.h" #include "string.h" #include #include #include -size_t translate_parsed_string(Translated *translated, ParsedValue *parsedValue) { - ParsedString *parsedString = (ParsedString*)parsedValue->data; - size_t string_pos = arena_push(&translated->constants, parsedString->string, parsedString->length); - set_registers(translated, 1); +size_t translate_parsed_string(Translated *translated, ParsedString parsedString, size_t to_register) { + size_t string_pos = arena_push(&translated->constants, parsedString.string, parsedString.length); + set_registers(translated, to_register+1); size_t start = push_instruction_code(translated, OP_LOAD_CONST); - push_instruction_code(translated, 0); + push_instruction_code(translated, to_register); push_instruction_code(translated, TYPE_OP_STRING); - push_instruction_code(translated,parsedString->length); + push_instruction_code(translated,parsedString.length); push_instruction_code(translated, string_pos); return start; } \ No newline at end of file diff --git a/src/translator/string/string.h b/src/translator/string/string.h index 1af0501..4b03039 100644 --- a/src/translator/string/string.h +++ b/src/translator/string/string.h @@ -1,7 +1,8 @@ #ifndef BYTECODE_STRING_H #define BYTECODE_STRING_H #include "../translator.h" +#include "../../parser/string/string.h" -size_t translate_parsed_string(Translated *translated, ParsedValue *parsedValue); +size_t translate_parsed_string(Translated *translated, ParsedString parsedString, size_t to_register); #endif \ No newline at end of file diff --git a/src/translator/translator.c b/src/translator/translator.c index 50d3597..dafd10e 100644 --- a/src/translator/translator.c +++ b/src/translator/translator.c @@ -82,11 +82,11 @@ void set_registers(Translated *translator, size_t count) { size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) { switch (parsedValue->type) { case AST_STRING: - return translate_parsed_string(translated, parsedValue); + return translate_parsed_string(translated, *((ParsedString*)parsedValue->data), 0); case AST_DECLARATION: - return translate_parsed_declaration(translated, parsedValue); + return translate_parsed_declaration(translated, *((DArray*)parsedValue->data)); case AST_NUMBER: - return translate_parsed_number(translated, 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); diff --git a/src/translator/translator.h b/src/translator/translator.h index 6f6a2c8..6136376 100644 --- a/src/translator/translator.h +++ b/src/translator/translator.h @@ -7,7 +7,7 @@ #include #include -typedef enum { OP_LOAD_CONST = 255, OP_DECLARE, OP_LOAD_NULL, OP_JUMP } OperationType; +typedef enum { OP_LOAD_CONST = 255, OP_DECLARE, OP_LOAD_NULL } OperationType; typedef enum { TYPE_OP_STRING = 255, TYPE_OP_NUMBER } types; typedef struct { diff --git a/test.ar b/test.ar index e4ef53d..4d5f9f2 100644 --- a/test.ar +++ b/test.ar @@ -16,6 +16,9 @@ "hello\u0000world" "🇬🇧" "hello\u0000world" +"hello" + +let hello = "helllo\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nbruhhhhh" 1.24323234e2312324