Files
bshell/bshell/debug.c
T

451 lines
8.4 KiB
C

#include "debug.h"
#include "ast/ast.h"
#include "parse/token.h"
#include "runtime/opcode.h"
#include "script-block.h"
#include <fx/string.h>
#include <fx/term/print.h>
#include <stdio.h>
extern void print_lex_token(struct lex_token *tok)
{
printf("[%lu:%lu - %lu:%lu] ",
tok->tok_start.c_row,
tok->tok_start.c_col,
tok->tok_end.c_row,
tok->tok_end.c_col);
switch (tok->tok_type) {
case TOK_KEYWORD:
fx_puts("[magenta]");
break;
case TOK_SYMBOL:
fx_puts("[blue]");
break;
case TOK_INT:
case TOK_DOUBLE:
case TOK_VAR:
case TOK_VAR_SPLAT:
fx_puts("[yellow]");
break;
case TOK_OPERATOR:
fx_puts("[red]");
break;
case TOK_WORD:
case TOK_WORD_START:
case TOK_WORD_END:
fx_puts("[cyan]");
break;
case TOK_STRING:
case TOK_STR_START:
case TOK_STR_END:
fx_puts("[green]");
break;
case TOK_LINEFEED:
fx_puts("[dark_grey]");
break;
default:
break;
}
fx_puts(token_type_to_string(tok->tok_type));
switch (tok->tok_type) {
case TOK_WORD:
case TOK_FLAG:
case TOK_STRING:
case TOK_VAR:
case TOK_VAR_SPLAT:
printf("(%s)", tok->tok_str);
break;
case TOK_OPERATOR:
printf("(%s)", token_operator_to_string(tok->tok_operator));
break;
case TOK_SYMBOL:
printf("(%s)", token_symbol_to_string(tok->tok_symbol));
break;
case TOK_KEYWORD:
printf("(%s)", token_keyword_to_string(tok->tok_keyword));
break;
case TOK_INT:
printf("(%lld)", tok->tok_int);
break;
case TOK_DOUBLE:
printf("(%lf)", tok->tok_double);
break;
default:
break;
}
fx_puts("[reset]\n");
}
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_iterator_enqueue(&it, node);
while (1) {
node = ast_iterator_peek(&it);
if (!node) {
break;
}
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]<INVALID>[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]<INVALID>[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]<INVALID>");
}
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("<INVALID>");
}
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);
}