ox

The Ox programming language, compiler and tools (WIP)
Log | Files | Refs | README | LICENSE

parser_utils.c (10726B)


      1 #include "../parser.h"
      2 
      3 #include <assert.h>
      4 #include <stdio.h>
      5 #include <string.h>
      6 #include <stdbool.h>
      7 
      8 /* basic range to str */
      9 const char*
     10 range_str(const char* src, size_t start, size_t end, char* stack_alloc_chptr)
     11 {
     12 	const size_t len = end - start;
     13 	if (!src || !stack_alloc_chptr) return NULL;
     14 	if (!strchr(src, '\0')) return NULL; // src has no '\0'
     15 	if (len <= 0) return NULL;
     16 	memcpy(stack_alloc_chptr, src + start, len);
     17 	stack_alloc_chptr[len] = '\0';
     18 	return stack_alloc_chptr;
     19 }
     20 
     21 const char*
     22 span_str(const char* src, Span s, char* stack_alloc_chptr)
     23 {
     24 	return range_str(src, s.start, s.end, stack_alloc_chptr);
     25 }
     26 
     27 // int span_to_str(const char* src, size_t start, size_t end, char* out_buf) {
     28 //     if (!src || !out_buf) return -1; /* Null pointer passed */
     29 //     if (start >= end) return -2;     /* Empty or inverted span */
     30 //     const size_t len = end - start;
     31 //     if (len >= IDENTSZ) return -4; /* Identifier too long */
     32 //     const char* src_end = strchr(src, '\0');
     33 //     if (!src_end) return -5; /* src not NUL‑terminated */
     34 //     const size_t src_len = (size_t)(src_end - src);
     35 
     36 //     if (end > src_len) return -6; /* Span overruns source */
     37 
     38 //     if (memchr(src + start, '\0', len))
     39 //         return -7; /* span crosses a NUL byte */
     40 
     41 //     memcpy(out_buf, src + start, len);
     42 //     out_buf[len] = '\0';
     43 
     44 //     return 0;
     45 // }
     46 
     47 // char* span_to_str_alloc(const char* src, size_t start, size_t end) {
     48 //     if (!src || start >= end) return NULL;
     49 //     const char* src_end = strchr(src, '\0');
     50 //     if (!src_end) return NULL;
     51 //     size_t src_len = (size_t)(src_end - src);
     52 //     if (end > src_len) return NULL;
     53 //     size_t n = end - start;
     54 //     if (memchr(src + start, '\0', n)) return NULL;
     55 //     char* s = calloc(1, n + 1);
     56 //     if (!s) return NULL;
     57 //     memcpy(s, src + start, n);
     58 //     s[n] = '\0';
     59 //     return s;
     60 // }
     61 
     62 static void
     63 print_node(const char* source, Node* node, int level)
     64 {
     65 	assert(node != NULL);
     66 	assert(level < 192);
     67 
     68 	const char* name;
     69 	switch (node->type) {
     70 	case NODE_FUNCTION_DECL:
     71 		name = range_str(source,
     72 			node->data.function_decl.name.start,
     73 			node->data.function_decl.name.end,
     74 			(char[IDENTSZ]) { 0 });
     75 		printf("%*s FUNC DECL: name='%s'\n", level, "", name);
     76 		if (node->data.function_decl.return_type) {
     77 			printf("%*s ↳ return type:\n", level * 2, "");
     78 			print_node(source, node->data.function_decl.return_type, level + 1);
     79 		}
     80 		if (node->data.function_decl.params) {
     81 			printf("%*s ↳ params:\n", level * 2, "");
     82 			for (size_t i = 0; i < node->data.function_decl.p_len; i++) {
     83 				Node* param = node->data.function_decl.params[i];
     84 				print_node(source, param, level + 1);
     85 			}
     86 		} else {
     87 			printf("%*s ↳ params: N/A\n", level * 2, "");
     88 		}
     89 		if (node->data.function_decl.body) {
     90 			printf("%*s ↳ body:\n", level * 2, "");
     91 			print_node(source, node->data.function_decl.body, level + 1);
     92 		}
     93 		break;
     94 	case NODE_PARAM:
     95 		name = range_str(source,
     96 			node->data.param.name.start,
     97 			node->data.param.name.end,
     98 			(char[IDENTSZ]) { 0 });
     99 		printf("%*s ↳ param: name='%s'\n", level * 2, "", name);
    100 		if (node->data.param.type) { print_node(source, node->data.param.type, level + 1); }
    101 		break;
    102 	case NODE_VAR_DECL:
    103 		name = range_str(source,
    104 			node->data.var_decl.name.start,
    105 			node->data.var_decl.name.end,
    106 			(char[IDENTSZ]) { 0 });
    107 		printf("%*s VAR DECL: name='%s'\n", level, "", name);
    108 		if (node->data.var_decl.type) {
    109 			printf("%*s ↳ type:\n", level * 2, "");
    110 			print_node(source, node->data.var_decl.type, level + 1);
    111 		}
    112 		if (node->data.var_decl.init) {
    113 			printf("%*s ↳ init:\n", level * 2, "");
    114 			print_node(source, node->data.var_decl.init, level + 1);
    115 		}
    116 		break;
    117 	case NODE_PROGRAM:
    118 		printf("%*s PROGRAM:\n", level, "");
    119 		if (node->data.program.decl) {
    120 			for (size_t i = 0; i < node->data.program.len; i++) {
    121 				print_node(source, node->data.program.decl[i], level + 1);
    122 			}
    123 		}
    124 		break;
    125 	case NODE_BLOCK:
    126 		printf("%*s BLOCK:\n", level, "");
    127 		if (node->data.block.stmts) {
    128 			for (size_t i = 0; i < node->data.block.len; i++) {
    129 				print_node(source, node->data.block.stmts[i], level + 1);
    130 			}
    131 		}
    132 		break;
    133 	case NODE_CALL_EXPR:
    134 		printf("%*s ↳ FUNC CALL:\n", level, "");
    135 		if (node->data.call_expr.callee) {
    136 			printf("%*s ↳ callee:\n", level * 2, "");
    137 			print_node(source, node->data.call_expr.callee, level + 1);
    138 		}
    139 		if (node->data.call_expr.args) {
    140 			printf("%*s ↳ args:\n", level * 2, "");
    141 			for (size_t i = 0; i < node->data.call_expr.len; i++) {
    142 				Node* arg = node->data.call_expr.args[i];
    143 				print_node(source, arg, level + 1);
    144 			}
    145 		}
    146 		break;
    147 	case NODE_RETURN:
    148 		printf("%*s RETURN statement:\n", level, "");
    149 		if (node->data.ret.expr) { print_node(source, node->data.ret.expr, level + 1); }
    150 		break;
    151 	case NODE_CONTINUE:
    152 		printf("%*s CONTINUE statement\n", level, "");
    153 		if (node->data.cont.expr) { print_node(source, node->data.cont.expr, level + 1); }
    154 		break;
    155 	case NODE_NUMBER_LITERAL:
    156 		printf("%*s ↳ LITERAL NUMBER value=%f\n", level * 2, "", node->data.number.value);
    157 		break;
    158 	case NODE_STRING_LITERAL: {
    159 		const char* lit = span_str(source, node->data.string.value, (char[IDENTSZ]) { 0 });
    160 		printf("%*s ↳ LITERAL STRING value=\"%s\"\n", level * 2, "", lit);
    161 		break;
    162 	}
    163 	case NODE_TYPE:
    164 		name = range_str(source,
    165 			node->data.ident.name.start,
    166 			node->data.ident.name.end,
    167 			(char[IDENTSZ]) { 0 });
    168 		printf("%*s ↳ TYPE name='%s'\n", level * 2, "", name);
    169 		break;
    170 	case NODE_IDENT:
    171 		name = range_str(source,
    172 			node->data.ident.name.start,
    173 			node->data.ident.name.end,
    174 			(char[IDENTSZ]) { 0 });
    175 		printf("%*s ↳ IDENT name='%s'\n", level * 2, "", name);
    176 		break;
    177 	// case NODE_VOID:
    178 	//     printf("%*s  <VOID>\n", level * 2, "");
    179 	//     break;
    180 	// case NODE_FLOAT:
    181 	//     printf("%*s  <FLOAT>\n", level * 2, "");
    182 	//     break;
    183 	// case NODE_INT:
    184 	//     printf("%*s  <INT>\n", level * 2, "");
    185 	//     break;
    186 	// case NODE_STRING:
    187 	//     printf("%*s  <STRING>\n", level * 2, "");
    188 	//     break;
    189 	case NODE_UNKNOWN:
    190 		break;
    191 	case NODE_VAR_ASSIGN:
    192 		name = range_str(source,
    193 			node->data.var_assign.lhs->data.ident.name.start,
    194 			node->data.var_assign.lhs->data.ident.name.end,
    195 			(char[IDENTSZ]) { 0 });
    196 		printf("%*s VAR ASSIGN: name='%s'\n", level, "", name);
    197 		break;
    198 	case NODE_BREAK:
    199 		printf("%*s BREAK statement\n", level, "");
    200 		break;
    201 	case NODE_BINARY_EXPR:
    202 		printf("%*s BINARY EXPR op='%c'\n", level, "", node->data.binary_expr.op);
    203 		if (node->data.binary_expr.lhs) {
    204 			printf("%*s ↳ lhs:\n", level * 2, "");
    205 			print_node(source, node->data.binary_expr.lhs, level + 1);
    206 		}
    207 		if (node->data.binary_expr.rhs) {
    208 			printf("%*s ↳ rhs:\n", level * 2, "");
    209 			print_node(source, node->data.binary_expr.rhs, level + 1);
    210 		}
    211 		break;
    212 	case NODE_UNARY_EXPR:
    213 		printf("%*s UNARY EXPR: op='%d' is_postfix='%s'\n",
    214 			level,
    215 			"",
    216 			node->data.unary_expr.op,
    217 			node->data.unary_expr.is_postfix ? "true" : "false");
    218 		if (node->data.unary_expr.operand) {
    219 			printf("%*s ↳ operand:\n", level * 2, "");
    220 			print_node(source, node->data.unary_expr.operand, level + 1);
    221 		}
    222 		break;
    223 	case NODE_EXPR_STATEMENT:
    224 		printf("%*s EXPR STMT:\n", level, "");
    225 		if (node->data.expr_statement.expr) {
    226 			print_node(source, node->data.expr_statement.expr, level + 1);
    227 		}
    228 		break;
    229 	case NODE_SUBSCRIPT_EXPR:
    230 		printf("%*s SUBSCRIPT expr:\n", level, "");
    231 		if (node->data.subscript_expr.array) {
    232 			printf("%*s ↳ array:\n", level * 2, "");
    233 			print_node(source, node->data.subscript_expr.array, level + 1);
    234 		}
    235 		if (node->data.subscript_expr.index) {
    236 			printf("%*s ↳ index:\n", level * 2, "");
    237 			print_node(source, node->data.subscript_expr.index, level + 1);
    238 		}
    239 		break;
    240 	case NODE_IF:
    241 		printf("%*s IF Statement:\n", level, "");
    242 		if (node->data.if_statement.cond) {
    243 			printf("%*s ↳ cond:\n", level * 2, "");
    244 			print_node(source, node->data.if_statement.cond, level + 1);
    245 		}
    246 		if (node->data.if_statement.then_body) {
    247 			printf("%*s ↳ then body:\n", level * 2, "");
    248 			print_node(source, node->data.if_statement.then_body, level + 1);
    249 		}
    250 		if (node->data.if_statement.else_body) {
    251 			printf("%*s ↳ else body:\n", level * 2, "");
    252 			print_node(source, node->data.if_statement.else_body, level + 1);
    253 		}
    254 		break;
    255 	case NODE_WHILE:
    256 		printf("%*s WHILE Statement:\n", level, "");
    257 		if (node->data.while_statement.cond) {
    258 			printf("%*s ↳ cond:\n", level * 2, "");
    259 			print_node(source, node->data.while_statement.cond, level + 1);
    260 		}
    261 		if (node->data.while_statement.body) {
    262 			printf("%*s ↳ body:\n", level * 2, "");
    263 			print_node(source, node->data.while_statement.body, level + 1);
    264 		}
    265 		break;
    266 	case NODE_FOR:
    267 		printf("%*s FOR Statement:\n", level, "");
    268 		if (node->data.for_statement.init) {
    269 			printf("%*s ↳ init:\n", level * 2, "");
    270 			print_node(source, node->data.for_statement.init, level + 1);
    271 		}
    272 		if (node->data.for_statement.cond) {
    273 			printf("%*s ↳ cond:\n", level * 2, "");
    274 			print_node(source, node->data.for_statement.cond, level + 1);
    275 		}
    276 		if (node->data.for_statement.increment) {
    277 			printf("%*s ↳ increment:\n", level * 2, "");
    278 			print_node(source, node->data.for_statement.increment, level + 1);
    279 		}
    280 		if (node->data.for_statement.body) {
    281 			printf("%*s ↳ body:\n", level * 2, "");
    282 			print_node(source, node->data.for_statement.body, level + 1);
    283 		}
    284 		break;
    285 	case NODE_EMPTY_STATEMENT:
    286 		printf("%*s EMPTY Statement\n", level, "");
    287 		break;
    288 	}
    289 
    290 	while (node->next) {
    291 		print_node(source, node->next, level);
    292 		node = node->next;
    293 	}
    294 }
    295 
    296 void
    297 ast_print(Ast* ast)
    298 {
    299 	print_node(ast->src, ast->node, 0);
    300 }
    301 
    302 void
    303 print_node_type_str(NodeType t)
    304 {
    305 	printf("print_node_type_str: %s\n", node_type_str(t));
    306 }
    307 
    308 const char*
    309 node_type_str(NodeType t)
    310 {
    311 	static const char* type_strings[] = { [NODE_PROGRAM] = "NODE_PROGRAM",
    312 		[NODE_FUNCTION_DECL] = "NODE_FUNCTION_DECL",
    313 		[NODE_PARAM] = "NODE_PARAM",
    314 		[NODE_VAR_DECL] = "NODE_VAR_DECL",
    315 		[NODE_BLOCK] = "NODE_BLOCK",
    316 		[NODE_CALL_EXPR] = "NODE_CALL_EXPR",
    317 		[NODE_RETURN] = "NODE_RETURN",
    318 		[NODE_CONTINUE] = "NODE_CONTINUE",
    319 		[NODE_NUMBER_LITERAL] = "NODE_NUMBER_LITERAL",
    320 		[NODE_STRING_LITERAL] = "NODE_STRING_LITERAL",
    321 		[NODE_TYPE] = "NODE_TYPE",
    322 		[NODE_IDENT] = "NODE_IDENT",
    323 		[NODE_UNKNOWN] = "NODE_UNKNOWN",
    324 		[NODE_VAR_ASSIGN] = "NODE_VAR_ASSIGN",
    325 		[NODE_BREAK] = "NODE_BREAK",
    326 		[NODE_BINARY_EXPR] = "NODE_BINARY_EXPR",
    327 		[NODE_UNARY_EXPR] = "NODE_UNARY_EXPR",
    328 		[NODE_EXPR_STATEMENT] = "NODE_EXPR_STATEMENT",
    329 		[NODE_SUBSCRIPT_EXPR] = "NODE_SUBSCRIPT_EXPR",
    330 		[NODE_IF] = "NODE_IF",
    331 		[NODE_WHILE] = "NODE_WHILE",
    332 		[NODE_FOR] = "NODE_FOR",
    333 		[NODE_EMPTY_STATEMENT] = "NODE_EMPTY_STATEMENT" };
    334 	if (t >= NODE_PROGRAM && t <= NODE_EMPTY_STATEMENT) {
    335 		return type_strings[t];
    336 	} else {
    337 		return "UNKNOWN_NODE_TYPE";
    338 	}
    339 }