Compare commits

...

1 Commits

Author SHA1 Message Date
e5e4f22481 write bytecode debugging script and start working on functions 2025-06-15 05:05:33 +01:00
13 changed files with 204 additions and 36 deletions

126
debug_arbin.py Normal file
View File

@@ -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("<Q", f.read(8))
# Read regCount, constantsSize, bytecodeSize (all uint64_t, little-endian)
reg_count, = struct.unpack("<Q", f.read(8))
constants_size, = struct.unpack("<Q", f.read(8))
bytecode_size, = struct.unpack("<Q", f.read(8))
# Read constants buffer (raw bytes)
constants = f.read(constants_size)
# Read bytecode array (uint64_t, little-endian)
bytecode = []
for _ in range(bytecode_size):
instr, = struct.unpack("<Q", f.read(8))
bytecode.append(instr)
return {
"version": version_number,
"register_count": reg_count,
"constants_size": constants_size,
"bytecode_size": bytecode_size,
"constants": constants,
"bytecode": bytecode,
}
class print_opcode:
def start(registers,data, i):
print()
match data['bytecode'][i]:
case OperationType.OP_LOAD_CONST.value:
return print_opcode.OP_LOAD_CONST(registers,data, i)
case OperationType.OP_DECLARE.value:
return print_opcode.OP_DECLARE(registers,data, i)
case OperationType.OP_LOAD_NULL.value:
return print_opcode.OP_LOAD_NULL(registers,data, i)
def OP_LOAD_CONST(registers,data, i) -> 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<len(data["bytecode"]):
i=print_opcode.start(registers,data,i)

View File

@@ -0,0 +1,30 @@
# Bytecode Specification
## 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.
3. the length of the data in the constant buffer.
4. the offset in the constant buffer.
## OP_DECLARE
initilises a variable on the current scope with a given value. errors if the variable is already initilises on the current scope.
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
## OP_LOAD_NULL
sets a given register to null.
this operation takes 1 operand.
1. the register to set to null.

View File

@@ -1,33 +1,29 @@
#include "../translator.h"
#include "declaration.h" #include "declaration.h"
#include "../../parser/declaration/declaration.h" #include "../../parser/declaration/declaration.h"
#include "../translator.h"
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
size_t translate_parsed_declaration(Translated *translated, size_t translate_parsed_declaration(Translated *translated,
ParsedValue *parsedValue) { DArray delcarations) {
DArray *delcarations = (DArray *)parsedValue->data; set_registers(translated, 1);
set_registers(translated, 2);
size_t first = 0; 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 // TODO: add function delclaration
ParsedSingleDeclaration*singleDeclaration = darray_get(delcarations, i); ParsedSingleDeclaration *singleDeclaration = darray_get(&delcarations, i);
size_t temp = translate_parsed(translated, singleDeclaration->from); 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 length = strlen(singleDeclaration->name);
size_t offset = arena_push(&translated->constants, singleDeclaration->name, length); 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);
push_instruction_code(translated, OP_DECLARE); 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, 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, OP_LOAD_NULL);
push_instruction_code(translated, 0); push_instruction_code(translated, 0);
} }

View File

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

View File

@@ -0,0 +1,9 @@
#include "function.h"
#include "../translator.h"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
size_t translate_parsed_function(Translated *translated,
ParsedValue *parsedValue) {
return 0;
}

View File

@@ -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

View File

@@ -5,14 +5,13 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
size_t translate_parsed_number(Translated *translated, ParsedValue *parsedValue) { size_t translate_parsed_number(Translated *translated, char *number_str, size_t to_register) {
char *number_str = (char*)parsedValue->data;
size_t length = strlen(number_str); size_t length = strlen(number_str);
size_t number_pos = arena_push(&translated->constants, number_str, length); 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); 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, TYPE_OP_NUMBER);
push_instruction_code(translated,length); push_instruction_code(translated,length);

View File

@@ -2,6 +2,6 @@
#define BYTECODE_NUMBER_H #define BYTECODE_NUMBER_H
#include "../translator.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 #endif

View File

@@ -1,18 +1,16 @@
#include "../translator.h" #include "../translator.h"
#include "../../parser/string/string.h"
#include "string.h" #include "string.h"
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
size_t translate_parsed_string(Translated *translated, ParsedValue *parsedValue) { size_t translate_parsed_string(Translated *translated, ParsedString parsedString, size_t to_register) {
ParsedString *parsedString = (ParsedString*)parsedValue->data; size_t string_pos = arena_push(&translated->constants, parsedString.string, parsedString.length);
size_t string_pos = arena_push(&translated->constants, parsedString->string, parsedString->length); set_registers(translated, to_register+1);
set_registers(translated, 1);
size_t start = push_instruction_code(translated, OP_LOAD_CONST); 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, TYPE_OP_STRING);
push_instruction_code(translated,parsedString->length); push_instruction_code(translated,parsedString.length);
push_instruction_code(translated, string_pos); push_instruction_code(translated, string_pos);
return start; return start;
} }

View File

@@ -1,7 +1,8 @@
#ifndef BYTECODE_STRING_H #ifndef BYTECODE_STRING_H
#define BYTECODE_STRING_H #define BYTECODE_STRING_H
#include "../translator.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 #endif

View File

@@ -82,11 +82,11 @@ void set_registers(Translated *translator, size_t count) {
size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) { size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) {
switch (parsedValue->type) { switch (parsedValue->type) {
case AST_STRING: case AST_STRING:
return translate_parsed_string(translated, parsedValue); return translate_parsed_string(translated, *((ParsedString*)parsedValue->data), 0);
case AST_DECLARATION: case AST_DECLARATION:
return translate_parsed_declaration(translated, parsedValue); return translate_parsed_declaration(translated, *((DArray*)parsedValue->data));
case AST_NUMBER: case AST_NUMBER:
return translate_parsed_number(translated, parsedValue); return translate_parsed_number(translated, (char*)parsedValue->data, 0);
case AST_NULL: case AST_NULL:
set_registers(translated, 1); set_registers(translated, 1);
size_t output = push_instruction_code(translated, OP_LOAD_NULL); size_t output = push_instruction_code(translated, OP_LOAD_NULL);

View File

@@ -7,7 +7,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
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 enum { TYPE_OP_STRING = 255, TYPE_OP_NUMBER } types;
typedef struct { typedef struct {

View File

@@ -16,6 +16,9 @@
"hello\u0000world" "hello\u0000world"
"🇬🇧" "🇬🇧"
"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 1.24323234e2312324