From a36747bc9c2cd41e72cc0911e4644d3344cf721a Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Wed, 22 Jun 2022 18:14:43 +0200 Subject: [PATCH] Change error printing to use colors, enable colors on windows cmd, print bytecode instruction line --- bytecode_codegen.cpp | 13 ++-- bytecode_interpreter.cpp | 141 ++++++++++++++++++++------------------- main.cpp | 24 +++++++ parsing.cpp | 34 +++++++--- 4 files changed, 128 insertions(+), 84 deletions(-) diff --git a/bytecode_codegen.cpp b/bytecode_codegen.cpp index 7f8f2cc..beb5b49 100644 --- a/bytecode_codegen.cpp +++ b/bytecode_codegen.cpp @@ -10,9 +10,9 @@ bc_emit_expr(Bc *b, Ast *ast){ CASE(VALUE, Atom){ Register_Index dst = allocate_register(b); switch(node->type->kind){ - CASE_UINT: emit_load_constant_u64(b, dst, bigint_as_unsigned(&node->big_int_val)); break; - CASE_SINT: emit_load_constant_s64(b, dst, bigint_as_signed(&node->big_int_val)); break; - CASE_FLOAT: emit_load_constant_f64(b, dst, node->f64_val); break; + 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; } @@ -23,7 +23,7 @@ bc_emit_expr(Bc *b, Ast *ast){ 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); + emit_arithmetic(b, node->pos, BC_ADD_S64, left, right, left); release_register(b, right); return left; BREAK(); @@ -42,6 +42,7 @@ compile_to_bc(){ switch(ast->kind){ CASE(LAMBDA, Decl){ + unused(node); // node->bytecode_data_position = emit_lambda(); BREAK(); } @@ -51,8 +52,8 @@ compile_to_bc(){ 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, address_index, node->bytecode_data_position); - emit_memory(b, BC_STORE_TO_MEMORY64, address_index, expression_index); + 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); } diff --git a/bytecode_interpreter.cpp b/bytecode_interpreter.cpp index b8de4a4..4583e36 100644 --- a/bytecode_interpreter.cpp +++ b/bytecode_interpreter.cpp @@ -1,4 +1,6 @@ #define BC_LOG 1 +#define BC_ASSERTS 1 + #if BC_LOG #define bc_log(...) log_info(__VA_ARGS__) #else @@ -159,6 +161,7 @@ struct Instruction{ U32 di; // @debug_id U32 debug_type_flag; + Token *debug_pos; }; // @@ -169,8 +172,13 @@ struct Bc{ U64 *stack_bottom; U64 *stack_pointer; - Instruction *instruction_pointer; - Array registers; + U64 *stack_top; + Instruction *instruction_pointer; // @todo Array can change location !!!!!! + + Register *registers; + Register *register_end; + + Array all_registers; Array used_registers; Array free_registers; @@ -187,7 +195,7 @@ function Register_Index allocate_register(Bc *b){ Register_Index result = -1; if(b->free_registers.len == 0) - result = b->registers.addi({}); + result = b->all_registers.addi({}); else result = b->free_registers.pop(); @@ -214,7 +222,7 @@ function Bc create_bytecode_interp(){ Bc b = {}; - b.registers = array_make(pctx->heap, 1024); + b.all_registers = array_make(pctx->heap, 1024); b.free_registers = array_make(pctx->heap, 1024); b.used_registers = array_make(pctx->heap, 1024); @@ -242,84 +250,85 @@ destroy_bytecode_interp(Bc *b){ } function Instruction * -new_instruction(Bc *b){ - Instruction *i = exp_alloc_type(&b->instructions, Instruction); - i->di = b->dis++; +new_instruction(Bc *b, Token *pos){ + Instruction *i = exp_alloc_type(&b->instructions, Instruction); + i->di = b->dis++; + i->debug_pos = pos; return i; } function void -emit_load_constant_f64(Bc *b, Register_Index dst, F64 constant){ - auto i = new_instruction(b); - i->operation = BC_LOAD_CONSTANT; - i->constant.f64 = constant; - i->index_c = dst; - i->debug_type_flag = TYPE_F64; +emit_load_constant_f64(Bc *b, Token *pos, Register_Index dst, F64 constant){ + 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; } function void -emit_load_constant_s64(Bc *b, Register_Index dst, S64 constant){ - auto i = new_instruction(b); - i->operation = BC_LOAD_CONSTANT; - i->constant.s64 = constant; - i->index_c = dst; - i->debug_type_flag = TYPE_S64; +emit_load_constant_s64(Bc *b, Token *pos, Register_Index dst, S64 constant){ + 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, Register_Index dst, U64 constant){ - auto i = new_instruction(b); - i->operation = BC_LOAD_CONSTANT; - i->constant.u64 = constant; - i->index_c = dst; - i->debug_type_flag = TYPE_U64; +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; } function void -emit_load_constant_address(Bc *b, Register_Index dst, void *address){ - auto i = new_instruction(b); - i->operation = BC_LOAD_CONSTANT; +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; + i->index_c = dst; + i->debug_type_flag = TYPE_POINTER; } function void -emit_push(Bc *b, Register_Index src){ - auto i = new_instruction(b); - i->operation = BC_PUSH_STACK; - i->index_a = src; +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, Register_Index dst){ - auto i = new_instruction(b); - i->operation = BC_POP_STACK; - i->index_c = dst; +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, Operation ins, Register_Index dst, Register_Index src){ - auto i = new_instruction(b); - i->operation = ins; - i->index_c = dst; - i->index_a = src; +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, Operation ins, Register_Index left, Register_Index right, Register_Index dst){ - Instruction *i = new_instruction(b); - i->operation = ins; - i->index_a = left; - i->index_b = right; - i->index_c = dst; +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 = exp_alloc_type(&b->instructions, Instruction); - i->di = b->dis++; - i->operation = BC_END_OF_INSTRUCTIONS; + Instruction *i = new_instruction(b, 0); + i->di = b->dis++; + i->operation = BC_END_OF_INSTRUCTIONS; } function void @@ -327,13 +336,24 @@ run_bytecode_interp(Bc *b){ // Setup registers b->instruction_pointer = (Instruction *)b->instructions.memory.data; b->stack_pointer = b->stack_bottom = (U64 *)b->stack.memory.data; + b->stack_top = (U64 *)(b->stack.memory.data + b->stack.len); + b->registers = &b->all_registers[0]; + b->register_end = b->all_registers.end(); for(;;){ Instruction *instr = b->instruction_pointer++; - bc_log("i%u[0x%llx] %s ", instr->di, instr, op_name[instr->operation]); + +#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_bottom, "Bytecode stack underflow"); + assert_msg(b->registers < b->register_end, "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){ - default:{} + invalid_default_case; case BC_LOAD_FROM_MEMORY64:{ U64 *load_address = b->registers[instr->index_a].pointer64; b->registers[instr->index_c].u64 = *load_address; @@ -758,16 +778,3 @@ run_bytecode_interp(Bc *b){ } end_of_program:; } - -function void -test_interpreter(){ - Bc b = create_bytecode_interp(); - emit_load_constant_f64(&b, 3, 100.32); - emit_load_constant_f64(&b, 4, 200.68); - emit_arithmetic(&b, BC_ADD_F64, 3, 4, 3); - emit_push(&b, 3); - emit_pop(&b, 3); - emit_end(&b); - run_bytecode_interp(&b); - destroy_bytecode_interp(&b); -} diff --git a/main.cpp b/main.cpp index 93876d0..d65c2cb 100644 --- a/main.cpp +++ b/main.cpp @@ -41,6 +41,12 @@ want to export all the symbols, we can namespace them optionally. ------------------------------------------------------------------------------- @todo +[ ] - Add token information to instructions +[ ] - print those token lines nicely +[ ] - Implement functions +[ ] - Improve the python metaprogram + + [ ] - Probably need to give Ast_Expr a Value field, then I can express Type nicely [ ] - I would love for String, slice, Any etc. to have their struct declarations in source files, I also would want for stuff like string.str to work without weird special cases [ ] - Var args with Any @@ -168,6 +174,24 @@ want to export all the symbols, we can namespace them optionally. int main(int argument_count, char **arguments){ +#if OS_WINDOWS + // Set output mode to handle virtual terminal sequences + HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (hOut == INVALID_HANDLE_VALUE) { + return GetLastError(); + } + + DWORD dwMode = 0; + if (!GetConsoleMode(hOut, &dwMode)) { + return GetLastError(); + } + + dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + if (!SetConsoleMode(hOut, dwMode)) { + return GetLastError(); + } +#endif + test_os_memory(); thread_ctx_init(); test_unicode(); diff --git a/parsing.cpp b/parsing.cpp index 31dfce2..8c4531c 100644 --- a/parsing.cpp +++ b/parsing.cpp @@ -1,20 +1,32 @@ function Ast_Decl *parse_decl(B32 is_global); +function void +print_token_line(Token *token){ + if(!token) return; + +#define PRINTF_RED "\033[31m" +#define PRINTF_RESET "\033[0m" + + // Print from line begin to token + int i1 = token->str - token->line_begin; + printf("%.*s", i1, token->line_begin); + + // Print token part + printf( PRINTF_RED "%.*s" PRINTF_RESET, (int)token->len, token->str); + + // Print to end of line from token + int iend = 0; + U8 *pointer = token->str + token->len; + while(pointer[iend]!='\n' && pointer[iend]!=0) iend++; + printf("%.*s", iend, pointer); + printf("\n"); +} + function void print_token_context(Token *token){ if(!token) return; printf(" :: tdi:%u %s:%d\n", token->di, token->file.str, (S32)token->line + 1); - // @Note(Krzosa): Print error line - { - int i = 0; - while(token->line_begin[i]!='\n' && token->line_begin[i]!=0) i++; - printf("%.*s\n", i, token->line_begin); - - // @Note(Krzosa): Print error marker - int token_i = token->str - token->line_begin; - for(int i = 0; i < token_i-2; i++) printf(" "); - printf("^^^^^^\n"); - } + print_token_line(token); } function void