function Register_Index allocate_register(Bc *b){ if(b->free_registers.len == 0){ Register_Index result = b->registers.addi({}); return result; } Register_Index index = b->free_registers.pop(); b->used_registers.add(index); return index; } function void release_register(Bc *b, Register_Index reg){ if(reg == 0) 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"); } function Register_Index bc_emit_expr(Bc *b, Ast *ast){ if(!ast) return REG_NULL; 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){ Register_Index dst = allocate_register(b); U64 value = bigint_as_unsigned(&node->big_int_val); emit_load_constant_s64(b, dst, value); return dst; BREAK(); } CASE(BINARY, Binary){ Register_Index left = bc_emit_expr(b, node->left); Register_Index right = bc_emit_expr(b, node->right); emit_arithmetic(b, BC_ADD_S64, left, right, left); release_register(b, right); return left; BREAK(); } default:{} } return REG_NULL; } 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); Register_Index index = bc_emit_expr(b, node->expr); if(index!=REG_NULL){ // bc_emit_store(b, ) } release_register(b, index); BREAK(); } default: {} } } emit_end(b); run_bytecode_interp(b); destroy_bytecode_interp(b); }