ox

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

parser_utils.c (11246B)


      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 bool
     28 span_ident_same(Span a, Span b, const char* src)
     29 {
     30 	const char* a_name = span_str(src, a, (char[IDENTSZ]) { 0 });
     31 	const char* b_name = span_str(src, b, (char[IDENTSZ]) { 0 });
     32 	return strcmp(a_name, b_name) == 0;
     33 }
     34 
     35 // int span_to_str(const char* src, size_t start, size_t end, char* out_buf) {
     36 //     if (!src || !out_buf) return -1; /* Null pointer passed */
     37 //     if (start >= end) return -2;     /* Empty or inverted span */
     38 //     const size_t len = end - start;
     39 //     if (len >= IDENTSZ) return -4; /* Identifier too long */
     40 //     const char* src_end = strchr(src, '\0');
     41 //     if (!src_end) return -5; /* src not NUL‑terminated */
     42 //     const size_t src_len = (size_t)(src_end - src);
     43 
     44 //     if (end > src_len) return -6; /* Span overruns source */
     45 
     46 //     if (memchr(src + start, '\0', len))
     47 //         return -7; /* span crosses a NUL byte */
     48 
     49 //     memcpy(out_buf, src + start, len);
     50 //     out_buf[len] = '\0';
     51 
     52 //     return 0;
     53 // }
     54 
     55 // char* span_to_str_alloc(const char* src, size_t start, size_t end) {
     56 //     if (!src || start >= end) return NULL;
     57 //     const char* src_end = strchr(src, '\0');
     58 //     if (!src_end) return NULL;
     59 //     size_t src_len = (size_t)(src_end - src);
     60 //     if (end > src_len) return NULL;
     61 //     size_t n = end - start;
     62 //     if (memchr(src + start, '\0', n)) return NULL;
     63 //     char* s = calloc(1, n + 1);
     64 //     if (!s) return NULL;
     65 //     memcpy(s, src + start, n);
     66 //     s[n] = '\0';
     67 //     return s;
     68 // }
     69 
     70 static void
     71 print_node(const char* source, Node* node, int level)
     72 {
     73 	assert(node != NULL);
     74 	assert(level < 192);
     75 
     76 	const char* name;
     77 	switch (node->type) {
     78 	case NODE_FUNCTION_DECL:
     79 		name = range_str(
     80 			source, node->data.function_decl.name.start, node->data.function_decl.name.end, (char[IDENTSZ]) { 0 });
     81 		printf("%*s FUNC DECL: name='%s'\n", level, "", name);
     82 		if (node->data.function_decl.return_type) {
     83 			printf("%*s ↳ return type:\n", level * 2, "");
     84 			print_node(source, node->data.function_decl.return_type, level + 1);
     85 		}
     86 		if (node->data.function_decl.params) {
     87 			printf("%*s ↳ params:\n", level * 2, "");
     88 			for (size_t i = 0; i < node->data.function_decl.p_len; i++) {
     89 				Node* param = node->data.function_decl.params[i];
     90 				print_node(source, param, level + 1);
     91 			}
     92 		} else {
     93 			printf("%*s ↳ params: N/A\n", level * 2, "");
     94 		}
     95 		if (node->data.function_decl.body) {
     96 			printf("%*s ↳ body:\n", level * 2, "");
     97 			print_node(source, node->data.function_decl.body, level + 1);
     98 		}
     99 		break;
    100 	case NODE_PARAM:
    101 		name = range_str(source, node->data.param.name.start, node->data.param.name.end, (char[IDENTSZ]) { 0 });
    102 		printf("%*s ↳ param: name='%s'\n", level * 2, "", name);
    103 		if (node->data.param.type) { print_node(source, node->data.param.type, level + 1); }
    104 		break;
    105 	case NODE_VAR_DECL:
    106 		name = range_str(source, node->data.var_decl.name.start, node->data.var_decl.name.end, (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_INT_LITERAL:
    156 		printf("%*s ↳ LITERAL INT NUMBER value=%f\n", level * 2, "", node->data.number.value);
    157 		break;
    158 	case NODE_FLOAT_LITERAL:
    159 		printf("%*s ↳ LITERAL FLOAT NUMBER value=%f\n", level * 2, "", node->data.number.value);
    160 		break;
    161 	case NODE_BOOL_LITERAL:
    162 		if (node->data.boolean.value)
    163 			printf("%*s   LITERAL BOOL TRUE\n", level * 2, "");
    164 		else
    165 			printf("%*s   LITERAL BOOL FALSE\n", level * 2, "");
    166 		break;
    167 	case NODE_STRING_LITERAL: {
    168 		const char* lit = span_str(source, node->data.string.value, (char[IDENTSZ]) { 0 });
    169 		printf("%*s ↳ LITERAL STRING value=\"%s\"\n", level * 2, "", lit);
    170 		break;
    171 	}
    172 	case NODE_TYPE:
    173 		name = range_str(source, node->data.ident.name.start, node->data.ident.name.end, (char[IDENTSZ]) { 0 });
    174 		printf("%*s ↳ TYPE name='%s'\n", level * 2, "", name);
    175 		break;
    176 	case NODE_IDENT:
    177 		name = range_str(source, node->data.ident.name.start, node->data.ident.name.end, (char[IDENTSZ]) { 0 });
    178 		printf("%*s ↳ IDENT name='%s'\n", level * 2, "", name);
    179 		break;
    180 	// case NODE_VOID:
    181 	//     printf("%*s  <VOID>\n", level * 2, "");
    182 	//     break;
    183 	// case NODE_FLOAT:
    184 	//     printf("%*s  <FLOAT>\n", level * 2, "");
    185 	//     break;
    186 	// case NODE_INT:
    187 	//     printf("%*s  <INT>\n", level * 2, "");
    188 	//     break;
    189 	// case NODE_STRING:
    190 	//     printf("%*s  <STRING>\n", level * 2, "");
    191 	//     break;
    192 	case NODE_UNKNOWN:
    193 		break;
    194 	case NODE_VAR_ASSIGN: {
    195 		const Span name_s = node->data.var_assign.lhs->data.ident.name;
    196 		name = range_str(source, name_s.start, name_s.end, (char[IDENTSZ]) { 0 });
    197 		printf("%*s VAR ASSIGN: name='%s'\n", level, "", name);
    198 		break;
    199 	}
    200 	case NODE_BREAK:
    201 		printf("%*s BREAK statement\n", level, "");
    202 		break;
    203 	case NODE_BINARY_EXPR:
    204 		printf("%*s BINARY EXPR op='%c'\n", level, "", node->data.binary_expr.op);
    205 		if (node->data.binary_expr.lhs) {
    206 			printf("%*s ↳ lhs:\n", level * 2, "");
    207 			print_node(source, node->data.binary_expr.lhs, level + 1);
    208 		}
    209 		if (node->data.binary_expr.rhs) {
    210 			printf("%*s ↳ rhs:\n", level * 2, "");
    211 			print_node(source, node->data.binary_expr.rhs, level + 1);
    212 		}
    213 		break;
    214 	case NODE_UNARY_EXPR:
    215 		printf("%*s UNARY EXPR: op='%d' is_postfix='%s'\n",
    216 			level,
    217 			"",
    218 			node->data.unary_expr.op,
    219 			node->data.unary_expr.is_postfix ? "true" : "false");
    220 		if (node->data.unary_expr.operand) {
    221 			printf("%*s ↳ operand:\n", level * 2, "");
    222 			print_node(source, node->data.unary_expr.operand, level + 1);
    223 		}
    224 		break;
    225 	case NODE_EXPR_STATEMENT:
    226 		printf("%*s EXPR STMT:\n", level, "");
    227 		if (node->data.expr_statement.expr) { print_node(source, node->data.expr_statement.expr, level + 1); }
    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_INT_LITERAL] = "NODE_INT_LITERAL",
    320 		[NODE_FLOAT_LITERAL] = "NODE_FLOAT_LITERAL",
    321 		[NODE_STRING_LITERAL] = "NODE_STRING_LITERAL",
    322 		[NODE_TYPE] = "NODE_TYPE",
    323 		[NODE_IDENT] = "NODE_IDENT",
    324 		[NODE_UNKNOWN] = "NODE_UNKNOWN",
    325 		[NODE_VAR_ASSIGN] = "NODE_VAR_ASSIGN",
    326 		[NODE_BREAK] = "NODE_BREAK",
    327 		[NODE_BINARY_EXPR] = "NODE_BINARY_EXPR",
    328 		[NODE_UNARY_EXPR] = "NODE_UNARY_EXPR",
    329 		[NODE_EXPR_STATEMENT] = "NODE_EXPR_STATEMENT",
    330 		[NODE_SUBSCRIPT_EXPR] = "NODE_SUBSCRIPT_EXPR",
    331 		[NODE_IF] = "NODE_IF",
    332 		[NODE_WHILE] = "NODE_WHILE",
    333 		[NODE_FOR] = "NODE_FOR",
    334 		[NODE_EMPTY_STATEMENT] = "NODE_EMPTY_STATEMENT" };
    335 	if (t >= NODE_PROGRAM && t <= NODE_EMPTY_STATEMENT) {
    336 		return type_strings[t];
    337 	} else {
    338 		return "UNKNOWN_NODE_TYPE";
    339 	}
    340 }