Begin to codegen bytecode instructions

This commit is contained in:
Krzosa Karol
2022-06-21 15:49:39 +02:00
parent 6ed17a3c1c
commit 2c3a8dc764
6 changed files with 59 additions and 6 deletions

View File

@@ -259,6 +259,8 @@ struct Ast_Decl: Ast{
Ast_Decl_State state; Ast_Decl_State state;
Intern_String name; Intern_String name;
void *bytecode_data_position;
Ast_Scope *scope; Ast_Scope *scope;
Ast_Expr *typespec; Ast_Expr *typespec;
union{ union{

34
bytecode_codegen.cpp Normal file
View File

@@ -0,0 +1,34 @@
function void
bc_emit_expr(Bc *b, Ast *ast){
if(!ast) return;
if(!is_flag_set(ast->flags, AST_EXPR))
compiler_error(ast->pos, "Internal compiler error: Trying to emit expression but it doesn't have appropriate flag");
switch(ast->kind){
CASE(BINARY, Binary){
BREAK();
}
default:{}
}
}
function void
compile_to_bc(){
Bc bc = create_bytecode_interp();
Bc *b = &bc;
For_Named(pctx->ordered_decls, ast){
switch(ast->kind){
CASE(LAMBDA, Decl){
unused(node);
BREAK();
}
CASE(VAR, Decl){
node->bytecode_data_position = exp_alloc(&b->memory, node->type->size, AF_ZeroMemory);
bc_emit_assign(b, node);
BREAK();
}
default: {}
}
}
}

View File

@@ -170,6 +170,7 @@ struct Bc{
U64 dis; // @debug_id U64 dis; // @debug_id
U8 *stack_bottom; U8 *stack_bottom;
Register registers[256]; Register registers[256];
Arena memory;
Arena instructions; Arena instructions;
Arena stack; // We reserve 4 gibs and allocate only 4 kibs to make sure we know when we Arena stack; // We reserve 4 gibs and allocate only 4 kibs to make sure we know when we
// accidently overshoot the stack by 2 gigabytes woo yeee // accidently overshoot the stack by 2 gigabytes woo yeee
@@ -180,7 +181,6 @@ create_bytecode_interp(){
Bc b = {}; Bc b = {};
{ {
arena_init(&b.instructions, "Bytecode instructions"_s); arena_init(&b.instructions, "Bytecode instructions"_s);
b.instructions.alignment = 1;
// Commit // Commit
arena_push_size(&b.instructions, 16); arena_push_size(&b.instructions, 16);
@@ -190,16 +190,24 @@ create_bytecode_interp(){
{ {
arena_init(&b.stack, "Bytecode stack"_s); arena_init(&b.stack, "Bytecode stack"_s);
b.stack.alignment = 8;
// Setup a 4 kilobyte stack // Setup a 4 kilobyte stack
arena_push_size(&b.stack, kib(4)); arena_push_size(&b.stack, kib(4));
b.registers[REG_STACK_POINTER].pointer = b.stack_bottom = b.stack.memory.data; b.registers[REG_STACK_POINTER].pointer = b.stack_bottom = b.stack.memory.data;
} }
arena_init(&b.memory, "Bytecode memory"_s);
return b; return b;
} }
function void
destroy_bytecode_interp(Bc *b){
arena_release(&b->instructions);
arena_release(&b->stack);
}
function void function void
emit_load_constant_f64(Bc *b, U8 dst, F64 constant){ emit_load_constant_f64(Bc *b, U8 dst, F64 constant){
auto i = exp_alloc_type(&b->instructions, Instruction_Constant); auto i = exp_alloc_type(&b->instructions, Instruction_Constant);
@@ -287,6 +295,7 @@ run_bytecode_interp(Bc *b){
b->registers[REG_INS_POINTER].pointer += sizeof(Instruction); b->registers[REG_INS_POINTER].pointer += sizeof(Instruction);
switch(instr->operation){ switch(instr->operation){
default:{}
case BC_LOAD_FROM_MEMORY64:{ case BC_LOAD_FROM_MEMORY64:{
U64 *load_address = b->registers[instr->src].pointer64; U64 *load_address = b->registers[instr->src].pointer64;
b->registers[instr->dst].u64 = *load_address; b->registers[instr->dst].u64 = *load_address;
@@ -722,4 +731,5 @@ test_interpreter(){
emit_pop(&b, 5); emit_pop(&b, 5);
emit_end(&b); emit_end(&b);
run_bytecode_interp(&b); run_bytecode_interp(&b);
destroy_bytecode_interp(&b);
} }

View File

@@ -161,8 +161,10 @@ want to export all the symbols, we can namespace them optionally.
#include "parsing.cpp" #include "parsing.cpp"
#include "typechecking.h" #include "typechecking.h"
#include "typechecking.cpp" #include "typechecking.cpp"
#include "ccodegen.cpp" #include "c_codegen.cpp"
#include "bytecode_interpreter.cpp" #include "bytecode_interpreter.cpp"
#include "bytecode_codegen.cpp"
int main(int argument_count, char **arguments){ int main(int argument_count, char **arguments){
@@ -176,11 +178,9 @@ int main(int argument_count, char **arguments){
test_intern_table(); test_intern_table();
test_interpreter(); test_interpreter();
__debugbreak();
exit(0);
emit_line_directives = true; emit_line_directives = true;
String program_name = "main.kl"_s; String program_name = "vm.kl"_s;
if(argument_count > 1){ if(argument_count > 1){
program_name = string_from_cstring(arguments[1]); program_name = string_from_cstring(arguments[1]);
} }
@@ -211,6 +211,8 @@ int main(int argument_count, char **arguments){
arena_clear(&pctx->stage_arena); arena_clear(&pctx->stage_arena);
compile_to_bc();
__debugbreak();
String result = get_compilation_result(); String result = get_compilation_result();
assert(os_write_file("program.c"_s, result)); assert(os_write_file("program.c"_s, result));
{ {

5
programs/vm.kl Normal file
View File

@@ -0,0 +1,5 @@
global_variable := 10 + 29
main :: ()
pass // a := 10 + 20