script

script.git
git clone git://git.lenczewski.org/script.git
Log | Files | Refs

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 }