debug.c (9625B)
1 #include "libscript_internal.h" 2 3 char const * 4 script_token_type_str(enum script_token_type type) 5 { 6 switch (type) { 7 case SCR_TOKEN_EOF: return "EOF"; 8 9 case SCR_TOKEN_LPAREN: return "("; 10 case SCR_TOKEN_RPAREN: return ")"; 11 case SCR_TOKEN_LBRACK: return "["; 12 case SCR_TOKEN_RBRACK: return "]"; 13 case SCR_TOKEN_LBRACE: return "{"; 14 case SCR_TOKEN_RBRACE: return "}"; 15 case SCR_TOKEN_LANGLE: return "<"; 16 case SCR_TOKEN_RANGLE: return ">"; 17 case SCR_TOKEN_LSLASH: return "\\"; 18 case SCR_TOKEN_RSLASH: return "/"; 19 case SCR_TOKEN_COLON: return ":"; 20 case SCR_TOKEN_SEMICOLON: return ";"; 21 case SCR_TOKEN_DOT: return "."; 22 case SCR_TOKEN_COMMA: return ","; 23 case SCR_TOKEN_EQUALS: return "="; 24 case SCR_TOKEN_PLUS: return "+"; 25 case SCR_TOKEN_MINUS: return "-"; 26 case SCR_TOKEN_STAR: return "*"; 27 28 case SCR_TOKEN_DOUBLE_COLON: return "::"; 29 case SCR_TOKEN_DOUBLE_EQUALS: return "=="; 30 31 case SCR_TOKEN_IDENT: return "IDENT"; 32 case SCR_TOKEN_LITERAL_INT: return "LITERAL_INT"; 33 34 case SCR_TOKEN_U8: return "U8"; 35 case SCR_TOKEN_U16: return "U16"; 36 case SCR_TOKEN_U32: return "U32"; 37 case SCR_TOKEN_U64: return "U64"; 38 39 case SCR_TOKEN_S8: return "S8"; 40 case SCR_TOKEN_S16: return "S16"; 41 case SCR_TOKEN_S32: return "S32"; 42 case SCR_TOKEN_S64: return "S64"; 43 44 case SCR_TOKEN_F32: return "F32"; 45 case SCR_TOKEN_F64: return "F64"; 46 47 case SCR_TOKEN_C8: return "C8"; 48 49 case SCR_TOKEN_RETURN: return "RETURN"; 50 case SCR_TOKEN_IF: return "IF"; 51 case SCR_TOKEN_ELSE: return "ELSE"; 52 case SCR_TOKEN_WHILE: return "WHILE"; 53 54 case _SCR_TOKEN_MULTICHAR: return NULL; 55 } 56 } 57 58 static int 59 dump_token(struct script_token *token, char *buf, size_t cap) 60 { 61 switch (token->type) { 62 case SCR_TOKEN_IDENT: 63 return snprintf(buf, cap, "Token %s, %" PRIu64, 64 script_token_type_str(token->type), token->ident.v); 65 66 case SCR_TOKEN_LITERAL_INT: 67 return snprintf(buf, cap, "Token %s, %" PRIu64, 68 script_token_type_str(token->type), token->literal_int); 69 70 default: 71 return snprintf(buf, cap, "Token %s", script_token_type_str(token->type)); 72 } 73 } 74 75 static void 76 dump_token_stream(struct compile_ctx *ctx) 77 { 78 struct script_token *ptr = ctx->stream.ptr; 79 struct script_token *end = ctx->stream.ptr + ctx->stream.len; 80 81 dbglog(ctx, "token stream: %zu tokens\n", ctx->stream.len); 82 83 char buf[64]; 84 while (ptr < end) { 85 int written = dump_token(ptr, buf, sizeof buf); 86 assert(written); 87 88 dbglog(ctx, "\t%.*s\n", written, buf); 89 90 ptr++; 91 } 92 93 dbglog(ctx, "\n"); 94 } 95 96 static void 97 dump_typeinfo(struct compile_ctx *ctx, struct script_typeinfo *typeinfo, size_t indent) 98 { 99 static char const *type_strs[] = { 100 [SCR_TYPE_U8] = "U8", 101 [SCR_TYPE_U16] = "U16", 102 [SCR_TYPE_U32] = "U32", 103 [SCR_TYPE_U64] = "U64", 104 105 [SCR_TYPE_S8] = "S8", 106 [SCR_TYPE_S16] = "S16", 107 [SCR_TYPE_S32] = "S32", 108 [SCR_TYPE_S64] = "S64", 109 }; 110 111 #define leader(indent) \ 112 for (size_t i = 0; i < indent; i++) dbglog(ctx, " "); 113 114 leader(indent) 115 dbglog(ctx, "Typeinfo { type: %s, size: %zu, alignment: %zu }\n", 116 type_strs[typeinfo->type], typeinfo->size, typeinfo->alignment); 117 118 #undef leader 119 } 120 121 static void 122 dump_symbol(struct compile_ctx *ctx, struct script_symbol *sym, size_t indent) 123 { 124 #define leader(indent) \ 125 for (size_t i = 0; i < indent; i++) dbglog(ctx, " "); 126 127 char *str; 128 size_t len; 129 ident_pool_get(&ctx->ident_pool, sym->ident, &str, &len); 130 131 switch (sym->type) { 132 case SCR_SYMBOL_VARIABLE: 133 leader(indent) 134 dbglog(ctx, "variable: global: %d, ident: %.*s, addr: 0x%lx\n", 135 sym->parent_scope == NULL, (int) len, str, sym->variable.addr); 136 137 leader(indent + 1) 138 dbglog(ctx, "typeinfo:\n"); 139 dump_typeinfo(ctx, sym->variable.typeinfo, indent + 2); 140 break; 141 } 142 143 #undef leader 144 } 145 146 static void 147 dump_expr(struct compile_ctx *ctx, struct script_expr *expr, size_t indent) 148 { 149 #define leader(indent) \ 150 for (size_t i = 0; i < indent; i++) dbglog(ctx, " "); 151 152 char *str; 153 size_t len; 154 155 switch (expr->type) { 156 case SCR_EXPR_IDENT: 157 ident_pool_get(&ctx->ident_pool, expr->ident, &str, &len); 158 159 leader(indent) 160 dbglog(ctx, "ident: %.*s\n", (int) len, str); 161 162 leader(indent + 1) 163 dbglog(ctx, "typeinfo:\n"); 164 dump_typeinfo(ctx, expr->typeinfo, indent + 2); 165 break; 166 167 case SCR_EXPR_LITERAL_INT: 168 leader(indent) 169 dbglog(ctx, "literal int: %" PRIu64 "\n", expr->literal_int); 170 171 leader(indent + 1) 172 dbglog(ctx, "typeinfo:\n"); 173 dump_typeinfo(ctx, expr->typeinfo, indent + 2); 174 break; 175 176 case SCR_EXPR_ASSIGNMENT: 177 ident_pool_get(&ctx->ident_pool, expr->assignment.ident, &str, &len); 178 179 leader(indent) 180 dbglog(ctx, "assignment: %.*s\n", (int) len, str); 181 182 leader(indent + 1) 183 dbglog(ctx, "value:\n"); 184 dump_expr(ctx, expr->assignment.rhs, indent + 2); 185 break; 186 187 case SCR_EXPR_BINARY_OP: { 188 static char const *binary_op_str[] = { 189 [SCR_BINARY_OP_ADD] = "+", 190 [SCR_BINARY_OP_SUB] = "-", 191 [SCR_BINARY_OP_MUL] = "*", 192 [SCR_BINARY_OP_DIV] = "/", 193 [SCR_BINARY_OP_EQU] = "==", 194 }; 195 196 leader(indent) 197 dbglog(ctx, "binary op: %s\n", binary_op_str[expr->binary_op.type]); 198 199 leader(indent + 1) 200 dbglog(ctx, "typeinfo:\n"); 201 dump_typeinfo(ctx, expr->typeinfo, indent + 2); 202 203 leader(indent + 1) 204 dbglog(ctx, "lhs:\n"); 205 dump_expr(ctx, expr->binary_op.lhs, indent + 2); 206 207 leader(indent + 1) 208 dbglog(ctx, "rhs:\n"); 209 dump_expr(ctx, expr->binary_op.rhs, indent + 2); 210 } break; 211 } 212 213 #undef leader 214 } 215 216 static void 217 dump_stmt(struct compile_ctx *ctx, struct script_stmt *node, size_t indent) 218 { 219 #define leader(indent) \ 220 for (size_t i = 0; i < indent; i++) dbglog(ctx, " "); 221 222 char *str; 223 size_t len; 224 225 switch (node->type) { 226 case SCR_STMT_BLOCK: 227 leader(indent) 228 dbglog(ctx, "block\n"); 229 230 SCRIPT_LIST_ITER(&node->block.children) { 231 struct script_stmt *child = 232 SCRIPT_FROM_NODE(it, struct script_stmt, list_node); 233 234 dump_stmt(ctx, child, indent + 1); 235 } 236 break; 237 238 case SCR_STMT_DECL: 239 ident_pool_get(&ctx->ident_pool, node->decl.ident, &str, &len); 240 241 leader(indent) 242 dbglog(ctx, "decl: ident: %.*s\n", (int) len, str); 243 244 leader(indent + 1) 245 dbglog(ctx, "typeinfo:\n"); 246 dump_typeinfo(ctx, node->decl.typeinfo, indent + 2); 247 248 leader(indent + 1) 249 dbglog(ctx, "expr:\n"); 250 dump_expr(ctx, node->decl.expr, indent + 2); 251 break; 252 253 case SCR_STMT_EXPR: 254 leader(indent) 255 dbglog(ctx, "expr:\n"); 256 dump_expr(ctx, node->expr, indent + 1); 257 break; 258 259 case SCR_STMT_IF_ELSE: 260 leader(indent) 261 dbglog(ctx, "if-else:\n"); 262 263 leader(indent + 1) 264 dbglog(ctx, "cond:\n"); 265 dump_expr(ctx, node->if_else.cond, indent + 2); 266 267 leader(indent + 1) 268 dbglog(ctx, "success:\n"); 269 dump_stmt(ctx, node->if_else.if_body, indent + 2); 270 271 leader(indent + 1) 272 dbglog(ctx, "failure:\n"); 273 if (node->if_else.else_body) 274 dump_stmt(ctx, node->if_else.else_body, indent + 2); 275 break; 276 277 case SCR_STMT_WHILE_LOOP: 278 leader(indent) 279 dbglog(ctx, "while-loop:\n"); 280 281 leader(indent + 1) 282 dbglog(ctx, "cond:\n"); 283 dump_expr(ctx, node->while_loop.cond, indent + 2); 284 285 leader(indent + 1) 286 dbglog(ctx, "body:\n"); 287 dump_stmt(ctx, node->while_loop.while_body, indent + 2); 288 break; 289 290 case SCR_STMT_RET: 291 leader(indent) 292 dbglog(ctx, "return\n"); 293 294 leader(indent + 1) 295 dbglog(ctx, "expr:\n"); 296 dump_expr(ctx, node->ret.expr, indent + 2); 297 break; 298 } 299 300 #undef leader 301 } 302 303 static void 304 dump_symbol_table(struct compile_ctx *ctx) 305 { 306 dbglog(ctx, "info: symbol table:\n"); 307 for (size_t i = 0; i < ctx->symtab.len; i++) { 308 struct script_symbol *sym = &ctx->symtab.ptr[i]; 309 310 dump_symbol(ctx, sym, 1); 311 } 312 } 313 314 static void 315 dump_ast(struct compile_ctx *ctx) 316 { 317 dbglog(ctx, "info: ast:\n"); 318 SCRIPT_LIST_ITER(&ctx->ast.roots) { 319 struct script_stmt *stmt = SCRIPT_FROM_NODE(it, struct script_stmt, list_node); 320 321 dump_stmt(ctx, stmt, 1); 322 } 323 } 324 325 char const * 326 script_ir_opcode_str(enum script_ir_opcode opcode) 327 { 328 switch (opcode) { 329 case SCR_IR_LOAD: return "LOAD"; 330 case SCR_IR_STORE: return "STORE"; 331 case SCR_IR_PUSH: return "PUSH"; 332 case SCR_IR_POP: return "POP"; 333 case SCR_IR_RET: return "RET"; 334 case SCR_IR_CMP: return "CMP"; 335 case SCR_IR_JMP: return "JMP"; 336 case SCR_IR_JNE: return "JNE"; 337 case SCR_IR_JEQ: return "JEQ"; 338 case SCR_IR_ADD: return "ADD"; 339 case SCR_IR_SUB: return "SUB"; 340 case SCR_IR_MUL: return "MUL"; 341 case SCR_IR_DIV: return "DIV"; 342 } 343 } 344 345 char const * 346 script_ir_type_str(enum script_ir_type type) 347 { 348 switch (type) { 349 case SCR_IR_TYPE_U8: return "U8"; 350 case SCR_IR_TYPE_U16: return "U16"; 351 case SCR_IR_TYPE_U32: return "U32"; 352 case SCR_IR_TYPE_U64: return "U64"; 353 case SCR_IR_TYPE_S8: return "S8"; 354 case SCR_IR_TYPE_S16: return "S16"; 355 case SCR_IR_TYPE_S32: return "S32"; 356 case SCR_IR_TYPE_S64: return "S64"; 357 case SCR_IR_TYPE_F32: return "F32"; 358 case SCR_IR_TYPE_F64: return "F64"; 359 case SCR_IR_TYPE_C8: return "C8"; 360 case SCR_IR_TYPE_PTR: return "PTR"; 361 } 362 } 363 364 static void 365 dump_ir_operands(struct compile_ctx *ctx, struct script_ir_operand *buf, size_t len) 366 { 367 for (size_t i = 0; i < len; i++) { 368 struct script_ir_operand *operand = &buf[i]; 369 370 switch (operand->type) { 371 case SCR_IR_OPERAND_LITERAL: 372 dbglog(ctx, "LITERAL{0x%" PRIx64 "}", operand->literal); 373 break; 374 375 case SCR_IR_OPERAND_ADDRESS: 376 dbglog(ctx, "ADDRESS{0x%" PRIx64 "}", operand->address); 377 break; 378 379 case SCR_IR_OPERAND_OFFSET: 380 dbglog(ctx, "OFFSET{%" PRIi64 "}", operand->offset); 381 break; 382 } 383 384 dbglog(ctx, ", "); 385 } 386 } 387 388 static void 389 dump_ir(struct compile_ctx *ctx) 390 { 391 dbglog(ctx, "info: ir:\n"); 392 for (size_t i = 0; i < ctx->ir.len; i++) { 393 struct script_ir_inst *inst = &ctx->ir.ptr[i]; 394 395 dbglog(ctx, "\t[%03zu] %5s ", i, script_ir_opcode_str(inst->opcode)); 396 397 if (inst->typeinfo) 398 dbglog(ctx, "<%s> ", script_ir_type_str(inst->typeinfo->type)); 399 400 dump_ir_operands(ctx, inst->operands, inst->operand_count); 401 402 dbglog(ctx, "\n"); 403 } 404 }