From d33a18c8fec0fc164e0a4a69e35e865a814c36d3 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Thu, 23 Jun 2022 12:09:23 +0200 Subject: [PATCH] Calling main --- ast.cpp | 5 +++ bytecode_codegen.cpp | 87 ++++++++++++++++++++++++++++++++------- bytecode_interpreter.cpp | 57 +++++++++++-------------- code_generating_script.py | 2 + programs/vm.kl | 2 +- typechecking.cpp | 4 ++ 6 files changed, 107 insertions(+), 50 deletions(-) diff --git a/ast.cpp b/ast.cpp index bfa7e17..fa4792e 100644 --- a/ast.cpp +++ b/ast.cpp @@ -63,6 +63,7 @@ enum{ AST_DECL = bit_flag(9), AST_GLOBAL = bit_flag(10), AST_FLAG = bit_flag(11), + AST_VAR_IS_CONST = bit_flag(12), }; struct Ast{ @@ -255,11 +256,15 @@ enum Ast_Decl_State{ DECL_RESOLVING, }; +typedef S32 Register_Index; struct Ast_Decl: Ast{ Ast_Decl_State state; Intern_String name; + // Bytecode void *bytecode_data_position; + Register_Index register_index; + Ast_Scope *scope; Ast_Expr *typespec; diff --git a/bytecode_codegen.cpp b/bytecode_codegen.cpp index beb5b49..5da5010 100644 --- a/bytecode_codegen.cpp +++ b/bytecode_codegen.cpp @@ -9,12 +9,7 @@ bc_emit_expr(Bc *b, Ast *ast){ // @todo pass type and figure out what to do with untyped ?? CASE(VALUE, Atom){ Register_Index dst = allocate_register(b); - switch(node->type->kind){ - CASE_UINT: emit_load_constant_u64(b, node->pos, dst, bigint_as_unsigned(&node->big_int_val)); break; - CASE_SINT: emit_load_constant_s64(b, node->pos, dst, bigint_as_signed(&node->big_int_val)); break; - CASE_FLOAT: emit_load_constant_f64(b, node->pos, dst, node->f64_val); break; - invalid_default_case; - } + emit_load_constant(b, node->pos, dst, node->value); return dst; BREAK(); @@ -34,34 +29,96 @@ bc_emit_expr(Bc *b, Ast *ast){ return -1; } +struct Incomplete_Instruction{ + Instruction *instruction; + Ast_Decl *decl; +}; + +function void +emit_stmt(Bc *b, Ast *ast){ + switch(ast->kind){ + CASE(VAR, Decl){ + node->register_index = allocate_register(b); + if(is_flag_set(node->flags, AST_VAR_IS_CONST)){ + // emit_load_ + } + BREAK(); + } + default:{} + } +} + function void compile_to_bc(){ + Intern_String intern_main = pctx->intern("main"_s); + B32 found_main = false; + Bc bc = create_bytecode_interp(); Bc *b = &bc; + + // Scratch scratch; + // auto incomplete = array_make(scratch, 512); + + Register_Index main_call_register = allocate_register(b); + Instruction *load_main_address = emit_load_constant(b, 0, main_call_register, {}); + emit_call(b, 0, 0); + For_Named(pctx->ordered_decls, ast){ switch(ast->kind){ CASE(LAMBDA, Decl){ - unused(node); - // node->bytecode_data_position = emit_lambda(); + Ast_Lambda *lambda = node->lambda; + if(!lambda->scope) break; + node->bytecode_data_position = b->instruction_pointer; + + For(node->lambda->args){ + it->register_index = allocate_register(b); + } + + For(lambda->scope->stmts){ + emit_stmt(b, it); + } + + + if(node->name == intern_main){ + found_main = true; + load_main_address->constant.pointer = (U8 *)node->bytecode_data_position; + load_main_address->debug_pos = node->pos; + load_main_address->debug_type_flag = TYPE_POINTER; + } BREAK(); } CASE(VAR, Decl){ node->bytecode_data_position = exp_alloc(&b->memory, node->type->size, AF_ZeroMemory); - if(node->expr){ - Register_Index expression_index = bc_emit_expr(b, node->expr); - Register_Index address_index = allocate_register(b); - emit_load_constant_address(b, node->pos, address_index, node->bytecode_data_position); - emit_memory(b, node->pos, BC_STORE_TO_MEMORY64, address_index, expression_index); - release_register(b, expression_index); - release_register(b, address_index); + if(is_flag_set(node->flags, AST_VAR_IS_CONST)){ + switch(node->type->kind){ + CASE_UINT: *(U64 *)node->bytecode_data_position = bigint_as_unsigned(&node->big_int_val); break; + CASE_SINT: *(S64 *)node->bytecode_data_position = bigint_as_signed(&node->big_int_val); break; + CASE_FLOAT: *(F64 *)node->bytecode_data_position = node->f64_val; break; + invalid_default_case; + } } + else if(node->expr) compiler_error(node->pos, "Todo: Global variable with non constant expression"); + + // if(node->expr){ + // Register_Index expression_index = bc_emit_expr(b, node->expr); + // Register_Index address_index = allocate_register(b); + // emit_load_constant_address(b, node->pos, address_index, node->bytecode_data_position); + // emit_memory(b, node->pos, BC_STORE_TO_MEMORY64, address_index, expression_index); + // release_register(b, expression_index); + // release_register(b, address_index); + // } BREAK(); } default: {} } } + + if(!found_main){ + compiler_error(0, "Having a [main] function is required, it's an entry point of the application"); + } + emit_end(b); run_bytecode_interp(b); destroy_bytecode_interp(b); diff --git a/bytecode_interpreter.cpp b/bytecode_interpreter.cpp index b25fa53..470fef7 100644 --- a/bytecode_interpreter.cpp +++ b/bytecode_interpreter.cpp @@ -141,7 +141,6 @@ const char *op_name[] = { // *End* of enum generated using code_generating_script.py // -typedef S32 Register_Index; union Register{ F64 f64; S64 s64; @@ -272,54 +271,46 @@ destroy_bytecode_interp(Bc *b){ function Instruction * new_instruction(Bc *b, Token *pos){ - Instruction *i = exp_alloc_type(&b->instructions, Instruction); + Instruction *i = exp_alloc_type(&b->instructions, Instruction); + b->instruction_pointer = i + 1; + i->di = b->dis++; i->debug_pos = pos; return i; } -function void -emit_call(Bc *b, Token *pos, Register_Index register_with_call_address, Register_Index register_with_last_argument){ +function Instruction * +emit_call(Bc *b, Token *pos, Register_Index register_with_call_address){ auto i = new_instruction(b, pos); i->operation = BC_CALL; i->index_a = register_with_call_address; - i->index_b = register_with_last_argument; + return i; } function void -emit_load_constant_f64(Bc *b, Token *pos, Register_Index dst, F64 constant){ +emit_return(Bc *b, Token *pos){ auto i = new_instruction(b, pos); - i->operation = BC_LOAD_CONSTANT; - i->constant.f64 = constant; - i->index_c = dst; - i->debug_type_flag = TYPE_F64; + i->operation = BC_CALL_RETURN; } -function void -emit_load_constant_s64(Bc *b, Token *pos, Register_Index dst, S64 constant){ +function Instruction * +emit_load_constant(Bc *b, Token *pos, Register_Index dst, Value value){ auto i = new_instruction(b, pos); i->operation = BC_LOAD_CONSTANT; - i->constant.s64 = constant; i->index_c = dst; - i->debug_type_flag = TYPE_S64; -} -function void -emit_load_constant_u64(Bc *b, Token *pos, Register_Index dst, U64 constant){ - auto i = new_instruction(b, pos); - i->operation = BC_LOAD_CONSTANT; - i->constant.u64 = constant; - i->index_c = dst; - i->debug_type_flag = TYPE_U64; -} + if(value.type){ + i->debug_type_flag = value.type->kind; + switch(value.type->kind){ + case TYPE_POINTER: + CASE_UINT: i->constant.u64 = bigint_as_unsigned(&value.big_int_val); break; + CASE_SINT: i->constant.s64 = bigint_as_signed(&value.big_int_val); break; + CASE_FLOAT: i->constant.f64 = value.f64_val; break; + invalid_default_case; + } + } -function void -emit_load_constant_address(Bc *b, Token *pos, Register_Index dst, void *address){ - auto i = new_instruction(b, pos); - i->operation = BC_LOAD_CONSTANT; - i->constant.pointer = (U8 *)address; - i->index_c = dst; - i->debug_type_flag = TYPE_POINTER; + return i; } function void @@ -356,15 +347,14 @@ emit_arithmetic(Bc *b, Token *pos, Operation ins, Register_Index left, Register_ function void emit_end(Bc *b){ Instruction *i = new_instruction(b, 0); - i->di = b->dis++; i->operation = BC_END_OF_INSTRUCTIONS; } #define R(x) (b->registers[b->top_call->first_register_index_in_window + (x)]) // Get register -#define bc_stack_push(b, T) (T *)bc__stack_push(b, sizeof(T)) +#define bc_stack_push(b, T) (T *)bc_stack_push_size(b, sizeof(T)) function U8 * -bc__stack_push(Bc *b, U64 size){ +bc_stack_push_size(Bc *b, U64 size){ U8 *result = (U8 *)b->stack_pointer; b->stack_pointer += size; assert(b->stack_pointer < b->stack_top); @@ -435,7 +425,6 @@ run_bytecode_interp(Bc *b){ case BC_CALL:{ Register_Index register_with_call_address = instr->index_a; - // Register_Index register_with_last_argument = instr->index_b; Call_Frame *call = bc_push_call_frame(b, register_with_call_address); call->saved_instruction_pointer = b->instruction_pointer; b->instruction_pointer = (Instruction *)R(register_with_call_address).pointer; diff --git a/code_generating_script.py b/code_generating_script.py index 7e2580f..4b003ba 100644 --- a/code_generating_script.py +++ b/code_generating_script.py @@ -91,6 +91,8 @@ if True: result += "};\n" update_file("bytecode_interpreter.cpp", "enum", result) + + # # Generate switch cases # diff --git a/programs/vm.kl b/programs/vm.kl index e848aba..2b5b066 100644 --- a/programs/vm.kl +++ b/programs/vm.kl @@ -2,4 +2,4 @@ global_variable := 10 + 29 main :: () - pass // a := 10 + 20 \ No newline at end of file + a := 10 + 20 // a := 10 + 20 \ No newline at end of file diff --git a/typechecking.cpp b/typechecking.cpp index fcb1c4f..0114555 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -1395,6 +1395,10 @@ resolve_decl(Ast_Decl *ast){ } try_propagating_resolved_type_to_untyped_literals(node->expr, node->type); + + if(op.is_const){ + set_flag(node->flags, AST_VAR_IS_CONST); + } BREAK(); }