diff --git a/bshell/debug.c b/bshell/debug.c index c8e6ca1..55984fb 100644 --- a/bshell/debug.c +++ b/bshell/debug.c @@ -2,6 +2,8 @@ #include "ast/ast.h" #include "parse/token.h" +#include "runtime/opcode.h" +#include "script-block.h" #include #include @@ -81,9 +83,65 @@ extern void print_lex_token(struct lex_token *tok) } void print_ast_node(struct ast_node *node) +{ + for (unsigned long i = 0; i < node->n_it.e_depth; i++) { + fx_puts(" "); + } + + switch (node->n_type) { + case AST_IF: + case AST_IF_BRANCH: + case AST_BLOCK: + case AST_FUNC: + case AST_STMT_LIST: + fx_puts("[magenta]"); + break; + case AST_REDIRECTION: + case AST_PIPELINE: + case AST_OP: + case AST_ARRAY: + case AST_HASHTABLE: + case AST_HASHTABLE_ITEM: + fx_puts("[blue]"); + break; + case AST_CMDCALL: + case AST_NULL: + fx_puts("[red]"); + break; + case AST_INT: + case AST_DOUBLE: + case AST_VAR: + fx_puts("[yellow]"); + break; + case AST_WORD: + fx_puts("[cyan]"); + break; + case AST_STRING: + case AST_FSTRING: + fx_puts("[green]"); + break; + default: + break; + } + + fx_printf("%s", ast_node_type_to_string(node->n_type)); + + char s[128] = {0}; + fx_bstr str; + fx_bstr_begin(&str, s, sizeof s); + ast_node_to_string(node, &str); + + if (fx_bstr_get_size(&str)) { + fx_printf("(%s)", fx_bstr_end(&str)); + } + + fx_printf("[reset]\n"); +} + +void print_ast_node_recursive(struct ast_node *node) { struct ast_iterator it = {0}; - ast_node_iterate(node, &it); + ast_iterator_enqueue(&it, node); while (1) { node = ast_iterator_peek(&it); @@ -91,59 +149,302 @@ void print_ast_node(struct ast_node *node) break; } - for (unsigned long i = 0; i < node->n_it.e_depth; i++) { - fx_puts(" "); - } - - switch (node->n_type) { - case AST_IF: - case AST_IF_BRANCH: - case AST_BLOCK: - case AST_FUNC: - case AST_STMT_LIST: - fx_puts("[magenta]"); - break; - case AST_REDIRECTION: - case AST_PIPELINE: - case AST_OP: - case AST_ARRAY: - case AST_HASHTABLE: - case AST_HASHTABLE_ITEM: - fx_puts("[blue]"); - break; - case AST_CMDCALL: - case AST_NULL: - fx_puts("[red]"); - break; - case AST_INT: - case AST_DOUBLE: - case AST_VAR: - fx_puts("[yellow]"); - break; - case AST_WORD: - fx_puts("[cyan]"); - break; - case AST_STRING: - case AST_FSTRING: - fx_puts("[green]"); - break; - default: - break; - } - - fx_printf("%s", ast_node_type_to_string(node->n_type)); - - char s[128] = {0}; - fx_bstr str; - fx_bstr_begin(&str, s, sizeof s); - ast_node_to_string(node, &str); - - if (fx_bstr_get_size(&str)) { - fx_printf("(%s)", fx_bstr_end(&str)); - } - - fx_printf("[reset]\n"); - + print_ast_node(node); ast_iterator_dequeue(&it); } } + +void print_scriptblock(bshell_scriptblock *block, size_t depth) +{ + bshell_instruction *instr = NULL; + size_t nr_instr = 0; + + bshell_scriptblock_get_text(block, &instr, &nr_instr); + for (size_t i = 0; i < nr_instr; i++) { + size_t offset = i * sizeof *instr; + for (size_t ii = 0; ii < depth; ii++) { + fputs("| ", stdout); + } + + printf("%04zx: ", offset); + print_instruction(offset, instr[i], block, depth); + } +} + +void print_instruction( + size_t offset, + bshell_instruction instr, + bshell_scriptblock *container, + size_t depth) +{ + enum bshell_opcode opcode = 0; + uint32_t arg = 0; + fx_value *pool_value = NULL; + + bshell_instruction_decode(instr, &opcode, &arg); + + fx_printf("%08x [blue]", instr); + switch (opcode) { + case OPCODE_LDC_INT: + fx_printf("ldc.int [yellow]#0x%02x", arg); + break; + case OPCODE_LDC_STR: + pool_value = bshell_scriptblock_get_pool_value( + container, + arg, + FX_TYPE_STRING); + if (!pool_value) { + pool_value = bshell_scriptblock_get_pool_value( + container, + arg, + FX_TYPE_CSTR); + } + fx_printf("ldc.str [cyan]@0x%02x ", arg); + if (pool_value) { + fx_printf( + "[reset][[[green]%s[reset]]", + fx_value_get_cstr(pool_value)); + } else { + fx_printf("[red][reset]"); + } + + break; + case OPCODE_LDGLOBAL: + fx_printf("ldglobal [cyan]@0x%02x", arg); + break; + case OPCODE_LDBLOCK: + pool_value = bshell_scriptblock_get_pool_value( + container, + arg, + BSHELL_TYPE_SCRIPTBLOCK); + fx_printf("ldblock [cyan]@0x%02x ", arg); + if (pool_value) { + fx_printf("[reset][[[magenta]vvv[reset]]\n"); + print_scriptblock( + fx_value_get_object(pool_value), + depth + 1); + } else { + fx_printf("[red][reset]"); + } + + break; + case OPCODE_LDLOCAL: + pool_value = bshell_scriptblock_get_pool_value( + container, + arg, + FX_TYPE_STRING); + if (!pool_value) { + pool_value = bshell_scriptblock_get_pool_value( + container, + arg, + FX_TYPE_CSTR); + } + fx_printf("ldlocal [cyan]@0x%02x ", arg); + if (pool_value) { + fx_printf( + "[reset][[[green]%s[reset]]", + fx_value_get_cstr(pool_value)); + } else { + fx_printf("[red]"); + } + + break; + case OPCODE_LDENV: + fx_printf("ldenv [cyan]@0x%02x", arg); + break; + case OPCODE_LDSTATIC: + fx_printf("ldstatic [cyan]@0x%02x", arg); + break; + case OPCODE_LDARG: + fx_printf("ldarg [cyan]@0x%02x", arg); + break; + case OPCODE_LDPROP: + fx_printf("ldprop [cyan]@0x%02x", arg); + break; + case OPCODE_LDELEM: + fx_printf("ldelem [cyan]@0x%02x", arg); + break; + case OPCODE_LDELEM_C: + fx_printf("ldelem.c [cyan]@0x%02x", arg); + break; + case OPCODE_STLOCAL: + pool_value = bshell_scriptblock_get_pool_value( + container, + arg, + FX_TYPE_STRING); + if (!pool_value) { + pool_value = bshell_scriptblock_get_pool_value( + container, + arg, + FX_TYPE_CSTR); + } + fx_printf("stlocal [cyan]@0x%02x ", arg); + if (pool_value) { + fx_printf("[%s]", fx_value_get_cstr(pool_value)); + fx_printf( + "[reset][[[green]%s[reset]]", + fx_value_get_cstr(pool_value)); + } else { + fx_printf(""); + } + + break; + case OPCODE_STPROP: + fx_printf("stprop [cyan]@0x%02x", arg); + break; + case OPCODE_STELEM: + fx_printf("stelem [cyan]@0x%02x", arg); + break; + case OPCODE_LDCMD: + fx_printf("ldcmd [yellow]#0x%02x", arg); + break; + case OPCODE_PEXEC: + fx_printf("pexec [yellow]#0x%02x", arg); + break; + case OPCODE_CALL: + fx_printf("call"); + break; + case OPCODE_MK_STR: + fx_printf("mk.str [yellow]#0x%02x", arg); + break; + case OPCODE_MK_ARRAY: + fx_printf("mk.array [yellow]#0x%02x", arg); + break; + case OPCODE_MK_HTAB: + fx_printf("mk.htab [yellow]#0x%02x", arg); + break; + case OPCODE_POP: + fx_printf("pop"); + break; + case OPCODE_ADD: + fx_printf("add"); + break; + case OPCODE_SUB: + fx_printf("sub"); + break; + case OPCODE_MUL: + fx_printf("mul"); + break; + case OPCODE_DIV: + fx_printf("div"); + break; + case OPCODE_ADD_IP: + fx_printf("add.ip"); + break; + case OPCODE_MOD: + fx_printf("mod"); + break; + case OPCODE_INC: + fx_printf("inc"); + break; + case OPCODE_DEC: + fx_printf("dec"); + break; + case OPCODE_SHL: + fx_printf("shl"); + break; + case OPCODE_SHR: + fx_printf("shr"); + break; + case OPCODE_BAND: + fx_printf("band"); + break; + case OPCODE_BOR: + fx_printf("bor"); + break; + case OPCODE_BXOR: + fx_printf("bxor"); + break; + case OPCODE_BNOT: + fx_printf("bnot"); + break; + case OPCODE_CMP_NULL: + fx_printf("cmp.null"); + break; + case OPCODE_CMP_EQ: + fx_printf("cmp.eq"); + break; + case OPCODE_CMP_NE: + fx_printf("cmp.ne"); + break; + case OPCODE_CMP_LT: + fx_printf("cmp.lt"); + break; + case OPCODE_CMP_GT: + fx_printf("cmp.gt"); + break; + case OPCODE_CMP_LE: + fx_printf("cmp.le"); + break; + case OPCODE_CMP_GE: + fx_printf("cmp.ge"); + break; + case OPCODE_LAND: + fx_printf("land"); + break; + case OPCODE_LOR: + fx_printf("lor"); + break; + case OPCODE_LXOR: + fx_printf("lxor"); + break; + case OPCODE_LNOT: + fx_printf("lnot"); + break; + case OPCODE_BR: + fx_printf( + "br [yellow]#0x%04x [=%04llx]", + arg, + (long long)arg + (long long)offset); + break; + case OPCODE_BR_TRUE: + fx_printf( + "br.true [yellow]#0x%04x [=%04llx]", + arg, + (long long)arg + (long long)offset); + break; + case OPCODE_RANGE: + fx_printf("range"); + break; + case OPCODE_MATCH: + fx_printf("match"); + break; + case OPCODE_REPLACE: + fx_printf("replace"); + break; + case OPCODE_LIKE: + fx_printf("like"); + break; + case OPCODE_IN: + fx_printf("in"); + break; + case OPCODE_FMT: + fx_printf("fmt"); + break; + case OPCODE_CONTAINS: + fx_printf("contains"); + break; + case OPCODE_SPLIT: + fx_printf("split"); + break; + case OPCODE_JOIN: + fx_printf("join"); + break; + case OPCODE_IS: + fx_printf("is"); + break; + case OPCODE_AS: + fx_printf("as"); + break; + default: + fx_printf("INVALID\n"); + break; + } + + fx_printf("[reset]\n"); +} + +void print_value(fx_value *val) +{ + fx_printf("[yellow]%d[reset]\n", val->v_int); +} diff --git a/bshell/debug.h b/bshell/debug.h index 3374f50..30b4bf4 100644 --- a/bshell/debug.h +++ b/bshell/debug.h @@ -1,6 +1,9 @@ #ifndef DEBUG_H_ #define DEBUG_H_ +#include "runtime/opcode.h" +#include "script-block.h" + #include struct ast_node; @@ -8,5 +11,13 @@ struct lex_token; extern void print_lex_token(struct lex_token *tok); extern void print_ast_node(struct ast_node *node); +extern void print_ast_node_recursive(struct ast_node *node); +extern void print_scriptblock(bshell_scriptblock *block, size_t depth); +extern void print_instruction( + size_t offset, + bshell_instruction instr, + bshell_scriptblock *container, + size_t depth); +extern void print_value(fx_value *val); #endif