change to uint8_t for bytecode to reduce wasted bytes
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,22 +1,24 @@
|
||||
#include "function.h"
|
||||
#include "../translator.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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,
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user