From dfd848bced277cd64ca5dcf5c9d6544f78ed7bb3 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Fri, 24 Jun 2022 12:59:41 +0200 Subject: [PATCH] Delete bytecode codegen, starting from scratch --- .gitignore | 2 +- bytecode_codegen.cpp | 130 ------ bytecode_interpreter.cpp | 886 --------------------------------------- main.cpp | 80 +--- 4 files changed, 2 insertions(+), 1096 deletions(-) delete mode 100644 bytecode_codegen.cpp delete mode 100644 bytecode_interpreter.cpp diff --git a/.gitignore b/.gitignore index 4527475..e923190 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ *.bin *.c -backup \ No newline at end of file +backup* \ No newline at end of file diff --git a/bytecode_codegen.cpp b/bytecode_codegen.cpp deleted file mode 100644 index b1d33df..0000000 --- a/bytecode_codegen.cpp +++ /dev/null @@ -1,130 +0,0 @@ - -struct Incomplete_Instruction{ - Instruction *instruction; - Ast_Decl *decl; -}; - -function void -bc_emit_expr(Bc *b, Ast *ast, Register_Index result_index){ - 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(VALUE, Atom){ - emit_load_constant(b, node->pos, result_index, node->value); - BREAK(); - } - - CASE(IDENT, Atom){ - emit_load_constant(b, node->pos, result_index, node->resolved_decl->value); - BREAK(); - } - - CASE(BINARY, Binary){ - Register_Index left_index = allocate_register(b); - Register_Index right_index = allocate_register(b); - bc_emit_expr(b, node->left, left_index); - bc_emit_expr(b, node->right, right_index); - - emit_arithmetic(b, node->pos, BC_ADD_S64, left_index, right_index, result_index); - release_register(b, left_index); - release_register(b, right_index); - BREAK(); - } - - invalid_default_case; - } -} - -function void -emit_stmt(Bc *b, Ast *ast){ - switch(ast->kind){ - CASE(VAR, Decl){ - node->register_index = allocate_register(b); - bc_emit_expr(b, node->expr, node->register_index); - BREAK(); - } - - CASE(RETURN, Return){ - - emit_return(b, node->pos); - 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, 0, {}); - emit_call(b, 0, 0); - - For_Named(pctx->ordered_decls, ast){ - switch(ast->kind){ - - CASE(LAMBDA, Decl){ - Ast_Lambda *lambda = node->lambda; - if(!lambda->scope) break; - if(node->pos->file.s == "language.kl"_s) 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); - } - - For(node->lambda->args){ - release_register(b, it->register_index); - } - - - 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){ - if(node->pos->file.s == "language.kl"_s) break; - node->bytecode_data_position = exp_alloc(&b->memory, node->type->size, AF_ZeroMemory); - 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"); - BREAK(); - } - default: {} - } - } - - if(!found_main){ - compiler_error(0, "Having a [main] function is required, it's an entry point of the application"); - } - - release_register(b, main_call_register); - emit_end(b); - run_bytecode_interp(b); - destroy_bytecode_interp(b); -} \ No newline at end of file diff --git a/bytecode_interpreter.cpp b/bytecode_interpreter.cpp deleted file mode 100644 index 0572cb3..0000000 --- a/bytecode_interpreter.cpp +++ /dev/null @@ -1,886 +0,0 @@ -#define BC_LOG 1 -#define BC_ASSERTS 1 - -#if BC_LOG -#define bc_log(...) log_info(__VA_ARGS__) -#else -#define bc_log(...) -#endif - -// -// *Begin* of enum generated using code_generating_script.py -// -enum Operation: U16{ - BC_END_OF_INSTRUCTIONS, - BC_POP_STACK, - BC_PUSH_STACK, - BC_LOAD_CONSTANT, - BC_STORE_CONSTANT, - BC_CALL, - BC_CALL_RETURN, - BC_LOAD_FROM_MEMORY64, - BC_LOAD_FROM_MEMORY32, - BC_LOAD_FROM_MEMORY16, - BC_LOAD_FROM_MEMORY8, - BC_STORE_TO_MEMORY64, - BC_STORE_TO_MEMORY32, - BC_STORE_TO_MEMORY16, - BC_STORE_TO_MEMORY8, - BC_ADD_S64, - BC_SUB_S64, - BC_DIV_S64, - BC_MUL_S64, - BC_MOD_S64, - BC_SHR_S64, - BC_SHL_S64, - BC_BITAND_S64, - BC_BITOR_S64, - BC_BITXOR_S64, - BC_BITNOT_S64, - BC_EQ_S64, - BC_NEQ_S64, - BC_GT_S64, - BC_LT_S64, - BC_OR_S64, - BC_GTE_S64, - BC_LTE_S64, - BC_ADD_U64, - BC_SUB_U64, - BC_DIV_U64, - BC_MUL_U64, - BC_MOD_U64, - BC_SHR_U64, - BC_SHL_U64, - BC_BITAND_U64, - BC_BITOR_U64, - BC_BITXOR_U64, - BC_BITNOT_U64, - BC_EQ_U64, - BC_NEQ_U64, - BC_GT_U64, - BC_LT_U64, - BC_OR_U64, - BC_GTE_U64, - BC_LTE_U64, - BC_ADD_F64, - BC_SUB_F64, - BC_DIV_F64, - BC_MUL_F64, - BC_EQ_F64, - BC_NEQ_F64, - BC_GT_F64, - BC_LT_F64, - BC_GTE_F64, - BC_LTE_F64, -}; -const char *op_name[] = { - "BC_END_OF_INSTRUCTIONS", - "BC_POP_STACK", - "BC_PUSH_STACK", - "BC_LOAD_CONSTANT", - "BC_STORE_CONSTANT", - "BC_CALL", - "BC_CALL_RETURN", - "BC_LOAD_FROM_MEMORY64", - "BC_LOAD_FROM_MEMORY32", - "BC_LOAD_FROM_MEMORY16", - "BC_LOAD_FROM_MEMORY8", - "BC_STORE_TO_MEMORY64", - "BC_STORE_TO_MEMORY32", - "BC_STORE_TO_MEMORY16", - "BC_STORE_TO_MEMORY8", - "BC_ADD_S64", - "BC_SUB_S64", - "BC_DIV_S64", - "BC_MUL_S64", - "BC_MOD_S64", - "BC_SHR_S64", - "BC_SHL_S64", - "BC_BITAND_S64", - "BC_BITOR_S64", - "BC_BITXOR_S64", - "BC_BITNOT_S64", - "BC_EQ_S64", - "BC_NEQ_S64", - "BC_GT_S64", - "BC_LT_S64", - "BC_OR_S64", - "BC_GTE_S64", - "BC_LTE_S64", - "BC_ADD_U64", - "BC_SUB_U64", - "BC_DIV_U64", - "BC_MUL_U64", - "BC_MOD_U64", - "BC_SHR_U64", - "BC_SHL_U64", - "BC_BITAND_U64", - "BC_BITOR_U64", - "BC_BITXOR_U64", - "BC_BITNOT_U64", - "BC_EQ_U64", - "BC_NEQ_U64", - "BC_GT_U64", - "BC_LT_U64", - "BC_OR_U64", - "BC_GTE_U64", - "BC_LTE_U64", - "BC_ADD_F64", - "BC_SUB_F64", - "BC_DIV_F64", - "BC_MUL_F64", - "BC_EQ_F64", - "BC_NEQ_F64", - "BC_GT_F64", - "BC_LT_F64", - "BC_GTE_F64", - "BC_LTE_F64", -}; - -// -// *End* of enum generated using code_generating_script.py -// - -union Register{ - F64 f64; - S64 s64; - - S64 *pointer_s64; - F64 *pointer_f64; - U8 *pointer; - U64 *pointer64; - - U64 *pointer_u64; - U32 *pointer_u32; - U16 *pointer_u16; - U8 *pointer_u8; - - U64 u64; - U32 u32; - U16 u16; - U8 u8; - -}; -static_assert(sizeof(Register) == 8, "not 8 bytes"); - - -struct Instruction{ - Operation operation; - S32 index_c; - union{ - struct{ - S32 index_a; - S32 index_b; - }; - Register constant; - }; - - U32 di; // @debug_id - U32 debug_type_flag; - Token *debug_pos; -}; - -struct Call_Frame{ - Call_Frame *previous_call; - Instruction *saved_instruction_pointer; - Register_Index first_register_index_in_window; -}; - -struct Bc{ - U32 dis; // @debug_ids - - U8 *stack_base; - U8 *stack_pointer; - U8 *stack_top; - - Call_Frame *top_call; - - Array registers; - Array used_registers; - Array free_registers; - - Instruction *instruction_pointer; - Arena instructions; - - Arena memory; - 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 -}; - -// -// Allocating and releasing is for codegen ! -// -function Register_Index -allocate_register(Bc *b){ - Register_Index result = -1; - if(b->free_registers.len == 0) - result = b->registers.addi({}); - else - result = b->free_registers.pop(); - - b->used_registers.add(result); - return result; -} - -function void -release_register(Bc *b, Register_Index reg){ - if(reg == -1) return; - - B32 found = false; - For(b->used_registers){ - if(it == reg){ - b->used_registers.unordered_remove(&it); - found = true; - break; - } - } - - assert_msg(found, "Trying to release register that is not used"); - b->free_registers.add(reg); -} - -function Bc -create_bytecode_interp(){ - Bc b = {}; - - b.registers = array_make(pctx->heap, 1024); - b.free_registers = array_make(pctx->heap, 1024); - b.used_registers = array_make(pctx->heap, 1024); - - { - arena_init(&b.instructions, "Bytecode instructions"_s); - arena_push_size(&b.instructions, 16); // Commit - arena_clear(&b.instructions); - } - - { - arena_init(&b.stack, "Bytecode stack"_s); - arena_push_size(&b.stack, kib(4)); // Setup a 4 kilobyte stack - } - - arena_init(&b.memory, "Bytecode memory"_s); - - return b; -} - -function void -destroy_bytecode_interp(Bc *b){ - arena_release(&b->instructions); - arena_release(&b->stack); - arena_release(&b->memory); -} - -function Instruction * -new_instruction(Bc *b, Token *pos){ - Instruction *i = exp_alloc_type(&b->instructions, Instruction); - b->instruction_pointer = i + 1; - - i->di = b->dis++; - i->debug_pos = pos; - return i; -} - -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; - return i; -} - -function void -emit_return(Bc *b, Token *pos){ - auto i = new_instruction(b, pos); - i->operation = BC_CALL_RETURN; -} - -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->index_c = dst; - - 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; - case TYPE_TYPE: i->constant.u64 = value.type_val->type_id; break; - invalid_default_case; - } - } - - return i; -} - -function Instruction * -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->index_c = dst; - i->constant.u64 = (U64)address; - i->debug_type_flag = TYPE_POINTER; - return i; -} - -function void -emit_push(Bc *b, Token *pos, Register_Index src){ - auto i = new_instruction(b, pos); - i->operation = BC_PUSH_STACK; - i->index_a = src; -} - -function void -emit_pop(Bc *b, Token *pos, Register_Index dst){ - auto i = new_instruction(b, pos); - i->operation = BC_POP_STACK; - i->index_c = dst; -} - -function void -emit_memory(Bc *b, Token *pos, Operation ins, Register_Index dst, Register_Index src){ - auto i = new_instruction(b, pos); - i->operation = ins; - i->index_c = dst; - i->index_a = src; -} - -function void -emit_arithmetic(Bc *b, Token *pos, Operation ins, Register_Index left, Register_Index right, Register_Index dst){ - Instruction *i = new_instruction(b, pos); - i->operation = ins; - i->index_a = left; - i->index_b = right; - i->index_c = dst; -} - -function void -emit_end(Bc *b){ - Instruction *i = new_instruction(b, 0); - 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_size(b, sizeof(T)) - -function U8 * -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); - return result; -} - -function Call_Frame * -bc_push_call_frame(Bc *b, Register_Index function_address_register){ - auto call = bc_stack_push(b, Call_Frame); - call->first_register_index_in_window = function_address_register; - call->previous_call = b->top_call; - call->saved_instruction_pointer = 0; - - b->stack_pointer = b->stack_base = (U8 *)(call+1); - b->top_call = call; - return call; -} - -function void -run_bytecode_interp(Bc *b){ - b->instruction_pointer = (Instruction *)b->instructions.memory.data; - b->stack_pointer = b->stack_base = b->stack.memory.data; - b->stack_top = (b->stack.memory.data + b->stack.len); - bc_push_call_frame(b, 0); - - for(;;){ - Instruction *instr = b->instruction_pointer++; - -#if BC_ASSERTS - print_token_line(instr->debug_pos); - assert_msg(b->stack_pointer < b->stack_top, "Bytecode stack overflow"); - assert_msg(b->stack_pointer >= b->stack_base, "Bytecode stack underflow"); - assert_msg(b->top_call->first_register_index_in_window < b->registers.cap, "Bytecode interpreter bug, register pointer is pointing over last possible register"); -#endif - - bc_log("i%u[0x%llx] %s ", instr->di, instr, op_name[instr->operation]); - switch(instr->operation){ - invalid_default_case; - - case BC_PUSH_STACK:{ - U64 *stack = (U64 *)b->stack_pointer; - b->stack_pointer += sizeof(U64); - - U64 src = R(instr->index_a).u64; - bc_log("r%u(src) [0x%llx|%lld|%f]", instr->index_a, src, src, src); - *stack = src; - }break; - - case BC_POP_STACK:{ - b->stack_pointer -= sizeof(U64); - U64 *stack = (U64 *)b->stack_pointer; - bc_log("r%u(dst) [0x%llx|%lld|%f]", instr->index_c, *stack, *stack, *stack); - R(instr->index_c).u64 = *stack; - }break; - - case BC_LOAD_CONSTANT: { - R(instr->index_c) = instr->constant; -#if BC_LOG - switch(instr->debug_type_flag){ - case TYPE_S64: bc_log("dst[r%u] S64[%lld]", instr->index_c, instr->constant.s64); break; - case TYPE_U64: bc_log("dst[r%u] U64[%llu]", instr->index_c, instr->constant.u64); break; - case TYPE_F64: bc_log("dst[r%u] F64[%f]" , instr->index_c, instr->constant.f64); break; - case TYPE_POINTER: bc_log("dst[r%u] Pointer[0x%llx]" , instr->index_c, instr->constant.pointer64); break; - invalid_default_case; - } -#endif - }break; - - case BC_CALL:{ - Register_Index register_with_call_address = instr->index_a; - 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; - }break; - - case BC_CALL_RETURN:{ - Call_Frame *call = b->top_call; - Call_Frame *prev = call->previous_call; - assert(prev); - - b->stack_base = (U8 *)(prev + 1); - b->stack_pointer = (U8 *)call; - b->top_call = prev; - }break; - - case BC_END_OF_INSTRUCTIONS:{ - goto end_of_program; - }break; -// -// *Begin* of switch_cases generated using code_generating_script.py -// - - case BC_LOAD_FROM_MEMORY64:{ - U64 *load_address = R(instr->index_a).pointer_u64; - R(instr->index_c).u64 = *load_address; - bc_log("load_address[r%u, %llx] dst[r%u] [0x%llx|%lld|%f]", instr->index_a, load_address, instr->index_c, R(instr->index_c).u64, R(instr->index_c).u64, R(instr->index_c).u64); - }break; - - case BC_STORE_TO_MEMORY64:{ - U64 *store_address = R(instr->index_c).pointer_u64; - *store_address = R(instr->index_a).u64; - bc_log("src[r%u] store_address[r%u, %llx] value_written[0x%llx|%lld|%f]", instr->index_a, instr->index_c, store_address, *store_address, *store_address, *store_address); - }break; - - case BC_LOAD_FROM_MEMORY32:{ - U32 *load_address = R(instr->index_a).pointer_u32; - R(instr->index_c).u32 = *load_address; - bc_log("load_address[r%u, %llx] dst[r%u] [0x%llx|%lld|%f]", instr->index_a, load_address, instr->index_c, R(instr->index_c).u32, R(instr->index_c).u32, R(instr->index_c).u32); - }break; - - case BC_STORE_TO_MEMORY32:{ - U32 *store_address = R(instr->index_c).pointer_u32; - *store_address = R(instr->index_a).u32; - bc_log("src[r%u] store_address[r%u, %llx] value_written[0x%llx|%lld|%f]", instr->index_a, instr->index_c, store_address, *store_address, *store_address, *store_address); - }break; - - case BC_LOAD_FROM_MEMORY16:{ - U16 *load_address = R(instr->index_a).pointer_u16; - R(instr->index_c).u16 = *load_address; - bc_log("load_address[r%u, %llx] dst[r%u] [0x%llx|%lld|%f]", instr->index_a, load_address, instr->index_c, R(instr->index_c).u16, R(instr->index_c).u16, R(instr->index_c).u16); - }break; - - case BC_STORE_TO_MEMORY16:{ - U16 *store_address = R(instr->index_c).pointer_u16; - *store_address = R(instr->index_a).u16; - bc_log("src[r%u] store_address[r%u, %llx] value_written[0x%llx|%lld|%f]", instr->index_a, instr->index_c, store_address, *store_address, *store_address, *store_address); - }break; - - case BC_LOAD_FROM_MEMORY8:{ - U8 *load_address = R(instr->index_a).pointer_u8; - R(instr->index_c).u8 = *load_address; - bc_log("load_address[r%u, %llx] dst[r%u] [0x%llx|%lld|%f]", instr->index_a, load_address, instr->index_c, R(instr->index_c).u8, R(instr->index_c).u8, R(instr->index_c).u8); - }break; - - case BC_STORE_TO_MEMORY8:{ - U8 *store_address = R(instr->index_c).pointer_u8; - *store_address = R(instr->index_a).u8; - bc_log("src[r%u] store_address[r%u, %llx] value_written[0x%llx|%lld|%f]", instr->index_a, instr->index_c, store_address, *store_address, *store_address, *store_address); - }break; - - case BC_ADD_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left + right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] + [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_SUB_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left - right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] - [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_DIV_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left / right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] / [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_MUL_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left * right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] * [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_MOD_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left % right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] % [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_SHR_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left >> right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] >> [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_SHL_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left << right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] << [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_BITAND_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left & right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] & [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_BITOR_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left | right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] | [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_BITXOR_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left ^ right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] ^ [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_BITNOT_S64:{ - S64 left = (S64)R(instr->index_a).s64; - S64 result = ~left; - S64 *dst = R(instr->index_c).pointer_s64; - *dst = result; - bc_log("~ [%lld] = [%lld]", left, result); - }break; - - case BC_EQ_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left == right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] == [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_NEQ_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left != right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] != [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_GT_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left > right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] > [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_LT_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left < right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] < [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_OR_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left || right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] || [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_GTE_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left >= right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] >= [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_LTE_S64:{ - S64 left = R(instr->index_a).s64; - S64 right = R(instr->index_b).s64; - S64 result = left <= right; - R(instr->index_c).s64 = result; - bc_log("[r%d, %lld] <= [r%d, %lld] = [r%d, %lld]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_ADD_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left + right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] + [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_SUB_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left - right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] - [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_DIV_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left / right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] / [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_MUL_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left * right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] * [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_MOD_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left % right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] % [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_SHR_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left >> right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] >> [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_SHL_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left << right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] << [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_BITAND_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left & right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] & [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_BITOR_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left | right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] | [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_BITXOR_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left ^ right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] ^ [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_BITNOT_U64:{ - U64 left = (U64)R(instr->index_a).u64; - U64 result = ~left; - U64 *dst = R(instr->index_c).pointer_u64; - *dst = result; - bc_log("~ [%llu] = [%llu]", left, result); - }break; - - case BC_EQ_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left == right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] == [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_NEQ_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left != right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] != [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_GT_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left > right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] > [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_LT_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left < right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] < [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_OR_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left || right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] || [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_GTE_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left >= right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] >= [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_LTE_U64:{ - U64 left = R(instr->index_a).u64; - U64 right = R(instr->index_b).u64; - U64 result = left <= right; - R(instr->index_c).u64 = result; - bc_log("[r%d, %llu] <= [r%d, %llu] = [r%d, %llu]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_ADD_F64:{ - F64 left = R(instr->index_a).f64; - F64 right = R(instr->index_b).f64; - F64 result = left + right; - R(instr->index_c).f64 = result; - bc_log("[r%d, %f] + [r%d, %f] = [r%d, %f]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_SUB_F64:{ - F64 left = R(instr->index_a).f64; - F64 right = R(instr->index_b).f64; - F64 result = left - right; - R(instr->index_c).f64 = result; - bc_log("[r%d, %f] - [r%d, %f] = [r%d, %f]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_DIV_F64:{ - F64 left = R(instr->index_a).f64; - F64 right = R(instr->index_b).f64; - F64 result = left / right; - R(instr->index_c).f64 = result; - bc_log("[r%d, %f] / [r%d, %f] = [r%d, %f]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_MUL_F64:{ - F64 left = R(instr->index_a).f64; - F64 right = R(instr->index_b).f64; - F64 result = left * right; - R(instr->index_c).f64 = result; - bc_log("[r%d, %f] * [r%d, %f] = [r%d, %f]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_EQ_F64:{ - F64 left = R(instr->index_a).f64; - F64 right = R(instr->index_b).f64; - F64 result = left == right; - R(instr->index_c).f64 = result; - bc_log("[r%d, %f] == [r%d, %f] = [r%d, %f]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_NEQ_F64:{ - F64 left = R(instr->index_a).f64; - F64 right = R(instr->index_b).f64; - F64 result = left != right; - R(instr->index_c).f64 = result; - bc_log("[r%d, %f] != [r%d, %f] = [r%d, %f]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_GT_F64:{ - F64 left = R(instr->index_a).f64; - F64 right = R(instr->index_b).f64; - F64 result = left > right; - R(instr->index_c).f64 = result; - bc_log("[r%d, %f] > [r%d, %f] = [r%d, %f]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_LT_F64:{ - F64 left = R(instr->index_a).f64; - F64 right = R(instr->index_b).f64; - F64 result = left < right; - R(instr->index_c).f64 = result; - bc_log("[r%d, %f] < [r%d, %f] = [r%d, %f]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_GTE_F64:{ - F64 left = R(instr->index_a).f64; - F64 right = R(instr->index_b).f64; - F64 result = left >= right; - R(instr->index_c).f64 = result; - bc_log("[r%d, %f] >= [r%d, %f] = [r%d, %f]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - - case BC_LTE_F64:{ - F64 left = R(instr->index_a).f64; - F64 right = R(instr->index_b).f64; - F64 result = left <= right; - R(instr->index_c).f64 = result; - bc_log("[r%d, %f] <= [r%d, %f] = [r%d, %f]", instr->index_a, left, instr->index_b, right, instr->index_c, result); - }break; - -// -// *End* of switch_cases generated using code_generating_script.py -// - - } - bc_log("\n"); - } - end_of_program:; -} \ No newline at end of file diff --git a/main.cpp b/main.cpp index 9ca1679..19d2a64 100644 --- a/main.cpp +++ b/main.cpp @@ -169,88 +169,10 @@ want to export all the symbols, we can namespace them optionally. #include "typechecking.cpp" #include "c_language_codegen.cpp" +#include "intermediate_representation.cpp" // #include "bytecode_interpreter.cpp" // #include "bytecode_codegen.cpp" -template -struct Simple_Bucket_Array{ - struct Bucket{ Bucket *next; T data[bucket_size]; S64 len; }; - Bucket *first; - Bucket *last ; - - void grow(Allocator *allocator){ - if(!first){ - Bucket *bucket = exp_alloc_type(allocator, Bucket); - bucket->next = 0; bucket->len = 0; - first = last = bucket; - } - - if(last->len >= bucket_size){ - Bucket *bucket = exp_alloc_type(allocator, Bucket); - bucket->next = 0; bucket->len = 0; - last = last->next = bucket; - } - } - - void add(Allocator *allocator, T item){ - grow(allocator); - last->data[last->len++] = item; - } - - struct Iter{ - Simple_Bucket_Array *ref; - Bucket *bucket; - T *it; - S64 iter_i; - S64 i; - - force_inline void next(){ - if(iter_i >= bucket->len){ - if(bucket->next){ - bucket = bucket->next; - iter_i = 0; - } - else{ - it = 0; - return; - } - } - - it = bucket->data + iter_i++; - i += 1; - } - force_inline B32 should_continue(){ return it != 0; } - }; - - force_inline Iter iter(){ - if(!this->first || this->first->len == 0) return {}; - return {this, this->first, this->first->data, 1}; - } -}; - -function void -test_bucket_arrays(){ - Scratch scratch; - Simple_Bucket_Array a = {}; - for(int i = 0; i < 32; i++) - a.add(scratch, i); - - For_It(a){ - assert(*it.it == it.i); - } - - for(auto i = a.iter(); i.should_continue(); i.next()){ - assert(*i.it == i.i); - } - - int total_i = 0; - for(auto bucket = a.first; bucket; bucket=bucket->next){ - for(int i = 0; i < bucket->len; i++){ - assert(bucket->data[i] == total_i++); - } - } -} - int main(int argument_count, char **arguments){