Begin to codegen bytecode instructions
This commit is contained in:
2
ast.cpp
2
ast.cpp
@@ -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
34
bytecode_codegen.cpp
Normal 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: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
10
main.cpp
10
main.cpp
@@ -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
5
programs/vm.kl
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
global_variable := 10 + 29
|
||||||
|
|
||||||
|
main :: ()
|
||||||
|
pass // a := 10 + 20
|
||||||
Reference in New Issue
Block a user