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 }