diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-18 08:53:34 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-18 08:53:34 +0200 |
commit | f392b0818e651ece33cec091eac0639883a126ec (patch) | |
tree | 94b8409b940d16004bb49438c528ef49fb17e28e /src | |
parent | c581804c6ffa5824a9b762097a990425007e49cf (diff) | |
download | bdl-f392b0818e651ece33cec091eac0639883a126ec.tar.gz bdl-f392b0818e651ece33cec091eac0639883a126ec.zip |
Add let, set and struct definitions
Diffstat (limited to 'src')
-rw-r--r-- | src/badlib.h | 3 | ||||
-rw-r--r-- | src/main.c | 409 |
2 files changed, 221 insertions, 191 deletions
diff --git a/src/badlib.h b/src/badlib.h index 6432562..25bb92b 100644 --- a/src/badlib.h +++ b/src/badlib.h | |||
@@ -930,7 +930,8 @@ typedef struct ArrayHeader { | |||
930 | (ARR)[array_head(ARR)->size++] = (T)) | 930 | (ARR)[array_head(ARR)->size++] = (T)) |
931 | 931 | ||
932 | // Return the last element of the array. Can be used to build stacks. | 932 | // Return the last element of the array. Can be used to build stacks. |
933 | #define array_pop(ARR) (ARR)[--array_head(ARR)->size] | 933 | #define array_pop(ARR) \ |
934 | ((ARR) && array_size(ARR) ? (ARR)[--array_head(ARR)->size] : NULL) | ||
934 | 935 | ||
935 | // Return the value stored at the OFFSET position from the tail of the array. | 936 | // Return the value stored at the OFFSET position from the tail of the array. |
936 | #define array_peek(ARR, OFFSET) (ARR)[array_head(ARR)->size - 1 - (OFFSET)] | 937 | #define array_peek(ARR, OFFSET) (ARR)[array_head(ARR)->size - 1 - (OFFSET)] |
@@ -70,13 +70,15 @@ typedef enum NodeKind { | |||
70 | NODE_TRUE, | 70 | NODE_TRUE, |
71 | NODE_FALSE, | 71 | NODE_FALSE, |
72 | NODE_NIL, | 72 | NODE_NIL, |
73 | NODE_STRUCT_LIT, | ||
73 | // Keywords. | 74 | // Keywords. |
74 | NODE_LET, | 75 | NODE_LET, |
75 | NODE_SET, | 76 | NODE_SET, |
76 | NODE_STRUCT, | 77 | NODE_STRUCT, |
77 | // Helpers. | 78 | // Helpers. |
78 | NODE_NODE_LIST, | 79 | NODE_TYPE, |
79 | NODE_NODE_TYPE, | 80 | NODE_COMPOUND_TYPE, |
81 | NODE_STRUCT_FIELD, | ||
80 | } NodeKind; | 82 | } NodeKind; |
81 | 83 | ||
82 | Str node_str[] = { | 84 | Str node_str[] = { |
@@ -111,12 +113,15 @@ Str node_str[] = { | |||
111 | [NODE_TRUE] = cstr("TRUE"), | 113 | [NODE_TRUE] = cstr("TRUE"), |
112 | [NODE_FALSE] = cstr("FALSE"), | 114 | [NODE_FALSE] = cstr("FALSE"), |
113 | [NODE_NIL] = cstr("NIL"), | 115 | [NODE_NIL] = cstr("NIL"), |
116 | [NODE_STRUCT_LIT] = cstr("STRUCT LITERAL"), | ||
117 | // Keywords. | ||
114 | [NODE_LET] = cstr("LET"), | 118 | [NODE_LET] = cstr("LET"), |
115 | [NODE_SET] = cstr("SET"), | 119 | [NODE_SET] = cstr("SET"), |
116 | [NODE_STRUCT] = cstr("STRUCT"), | 120 | [NODE_STRUCT] = cstr("STRUCT"), |
117 | // Helpers. | 121 | // Helpers. |
118 | [NODE_NODE_LIST] = cstr("..."), | 122 | [NODE_TYPE] = cstr("TYPE"), |
119 | [NODE_NODE_TYPE] = cstr("TYPE"), | 123 | [NODE_COMPOUND_TYPE] = cstr("COMPOUND TYPE"), |
124 | [NODE_STRUCT_FIELD] = cstr("FIELD"), | ||
120 | }; | 125 | }; |
121 | 126 | ||
122 | typedef struct Node { | 127 | typedef struct Node { |
@@ -133,13 +138,27 @@ typedef struct Node { | |||
133 | Str sym; | 138 | Str sym; |
134 | } value; | 139 | } value; |
135 | union { | 140 | union { |
136 | struct Node *left; | 141 | struct { |
137 | struct Node *varname; | 142 | struct Node *left; |
138 | }; | 143 | struct Node *right; |
139 | union { | 144 | }; |
140 | struct Node *right; | 145 | struct Node *next; |
141 | struct Node *vartype; | 146 | struct Node *initializer; |
142 | struct Node *varvalue; | 147 | struct { |
148 | struct Node *var_name; | ||
149 | struct Node *var_type; | ||
150 | struct Node *var_val; | ||
151 | }; | ||
152 | struct { | ||
153 | struct Node *field_name; | ||
154 | struct Node *field_type; | ||
155 | struct Node *field_val; | ||
156 | }; | ||
157 | struct { | ||
158 | struct Node *struct_name; | ||
159 | struct Node **struct_field; | ||
160 | }; | ||
161 | struct Node **elements; | ||
143 | }; | 162 | }; |
144 | } Node; | 163 | } Node; |
145 | 164 | ||
@@ -197,14 +216,13 @@ void parse_number(Parser *parser); | |||
197 | void parse_literal(Parser *parser); | 216 | void parse_literal(Parser *parser); |
198 | void parse_string(Parser *parser); | 217 | void parse_string(Parser *parser); |
199 | void parse_symbol(Parser *parser); | 218 | void parse_symbol(Parser *parser); |
200 | void parse_symbol_chain(Parser *parser); | ||
201 | void parse_keyword(Parser *parser); | 219 | void parse_keyword(Parser *parser); |
202 | void parse_struct(Parser *parser); | 220 | void parse_type(Parser *parser); |
203 | Node *parse_struct_field(Parser *parser); | ||
204 | Node *parse_type(Parser *parser); | ||
205 | 221 | ||
206 | ParseRule parse_rules[] = { | 222 | ParseRule parse_rules[] = { |
207 | [TOK_LPAREN] = {parse_grouping, NULL, PREC_NONE}, | 223 | [TOK_LPAREN] = {parse_grouping, NULL, PREC_NONE}, |
224 | [TOK_LCURLY] = {NULL, NULL, PREC_NONE}, | ||
225 | |||
208 | // Arithmetic. | 226 | // Arithmetic. |
209 | [TOK_SUB] = {parse_unary, parse_binary, PREC_TERM}, | 227 | [TOK_SUB] = {parse_unary, parse_binary, PREC_TERM}, |
210 | [TOK_ADD] = {NULL, parse_binary, PREC_TERM}, | 228 | [TOK_ADD] = {NULL, parse_binary, PREC_TERM}, |
@@ -232,7 +250,7 @@ ParseRule parse_rules[] = { | |||
232 | 250 | ||
233 | // Literals. | 251 | // Literals. |
234 | [TOK_STRING] = {parse_string, NULL, PREC_NONE}, | 252 | [TOK_STRING] = {parse_string, NULL, PREC_NONE}, |
235 | [TOK_SYMBOL] = {parse_symbol_chain, NULL, PREC_NONE}, | 253 | [TOK_SYMBOL] = {parse_symbol, NULL, PREC_NONE}, |
236 | [TOK_NUM_INT] = {parse_number, NULL, PREC_NONE}, | 254 | [TOK_NUM_INT] = {parse_number, NULL, PREC_NONE}, |
237 | [TOK_NUM_FLOAT] = {parse_number, NULL, PREC_NONE}, | 255 | [TOK_NUM_FLOAT] = {parse_number, NULL, PREC_NONE}, |
238 | [TOK_TRUE] = {parse_literal, NULL, PREC_NONE}, | 256 | [TOK_TRUE] = {parse_literal, NULL, PREC_NONE}, |
@@ -256,12 +274,10 @@ ParseRule parse_rules[] = { | |||
256 | }; | 274 | }; |
257 | 275 | ||
258 | Node * | 276 | Node * |
259 | node_alloc(NodeKind kind, Token tok, Parser *p) { | 277 | node_alloc(Parser *parser, NodeKind kind, Token tok) { |
260 | if (p->panic) { | 278 | if (parser->panic) return NULL; |
261 | return NULL; | ||
262 | } | ||
263 | static sz id = 0; | 279 | static sz id = 0; |
264 | Node *node = arena_calloc((sz)sizeof(Node), p->storage); | 280 | Node *node = arena_calloc((sz)sizeof(Node), parser->storage); |
265 | node->id = id++; | 281 | node->id = id++; |
266 | node->kind = kind; | 282 | node->kind = kind; |
267 | node->line = tok.line; | 283 | node->line = tok.line; |
@@ -271,17 +287,15 @@ node_alloc(NodeKind kind, Token tok, Parser *p) { | |||
271 | 287 | ||
272 | void | 288 | void |
273 | parse_emit_err(Parser *parser, Token token, Str msg) { | 289 | parse_emit_err(Parser *parser, Token token, Str msg) { |
274 | if (parser->panic) { | 290 | if (parser->panic) return; |
275 | return; | ||
276 | } | ||
277 | parser->panic = true; | 291 | parser->panic = true; |
278 | parser->err = true; | 292 | parser->err = true; |
279 | eprint("%d:%d: error: %s", token.line, token.col, msg); | 293 | eprint("%d:%d: error: %s", token.line, token.col, msg); |
280 | 294 | ||
281 | if (token.kind == TOK_EOF) { | 295 | if (token.kind == TOK_EOF) { |
282 | eprintln(" -> at end of the file"); | 296 | eprintln(" at end of the file"); |
283 | } else if (token.kind != TOK_UNKNOWN) { | 297 | } else if (token.kind != TOK_UNKNOWN) { |
284 | eprintln(" -> at %s", token.val); | 298 | eprintln(" at %s", token.val); |
285 | } | 299 | } |
286 | } | 300 | } |
287 | 301 | ||
@@ -318,9 +332,7 @@ void | |||
318 | parse_expr(Parser *parser, ParsePrecedence precedence) { | 332 | parse_expr(Parser *parser, ParsePrecedence precedence) { |
319 | parse_advance(parser); | 333 | parse_advance(parser); |
320 | // TODO: synchronize panic mode on keywords. | 334 | // TODO: synchronize panic mode on keywords. |
321 | if (parser->panic) { | 335 | if (parser->panic) return; |
322 | return; | ||
323 | } | ||
324 | ParseFn prefix = parse_rules[parser->previous.kind].prefix; | 336 | ParseFn prefix = parse_rules[parser->previous.kind].prefix; |
325 | if (prefix == NULL) { | 337 | if (prefix == NULL) { |
326 | parse_emit_err(parser, parser->previous, cstr("expected expression")); | 338 | parse_emit_err(parser, parser->previous, cstr("expected expression")); |
@@ -342,6 +354,7 @@ parse_expr(Parser *parser, ParsePrecedence precedence) { | |||
342 | 354 | ||
343 | void | 355 | void |
344 | parse_unary(Parser *parser) { | 356 | parse_unary(Parser *parser) { |
357 | if (parser->panic) return; | ||
345 | Token prev = parser->previous; | 358 | Token prev = parser->previous; |
346 | #if DEBUG == 1 | 359 | #if DEBUG == 1 |
347 | print("parsing unary "); | 360 | print("parsing unary "); |
@@ -350,19 +363,18 @@ parse_unary(Parser *parser) { | |||
350 | parse_expr(parser, PREC_UNARY); | 363 | parse_expr(parser, PREC_UNARY); |
351 | Node *node = NULL; | 364 | Node *node = NULL; |
352 | switch (prev.kind) { | 365 | switch (prev.kind) { |
353 | case TOK_NOT: node = node_alloc(NODE_NOT, prev, parser); break; | 366 | case TOK_NOT: node = node_alloc(parser, NODE_NOT, prev); break; |
354 | case TOK_BITNOT: node = node_alloc(NODE_BITNOT, prev, parser); break; | 367 | case TOK_BITNOT: node = node_alloc(parser, NODE_BITNOT, prev); break; |
355 | default: break; // Unreachable. | 368 | default: break; // Unreachable. |
356 | } | 369 | } |
357 | if (!node) { | 370 | if (!node) return; |
358 | return; | ||
359 | } | ||
360 | node->left = array_pop(parser->nodes); | 371 | node->left = array_pop(parser->nodes); |
361 | array_push(parser->nodes, node, parser->storage); | 372 | array_push(parser->nodes, node, parser->storage); |
362 | } | 373 | } |
363 | 374 | ||
364 | void | 375 | void |
365 | parse_literal(Parser *parser) { | 376 | parse_literal(Parser *parser) { |
377 | if (parser->panic) return; | ||
366 | Token prev = parser->previous; | 378 | Token prev = parser->previous; |
367 | #if DEBUG == 1 | 379 | #if DEBUG == 1 |
368 | print("parsing literal "); | 380 | print("parsing literal "); |
@@ -370,74 +382,68 @@ parse_literal(Parser *parser) { | |||
370 | #endif | 382 | #endif |
371 | Node *node = NULL; | 383 | Node *node = NULL; |
372 | switch (prev.kind) { | 384 | switch (prev.kind) { |
373 | case TOK_TRUE: { | 385 | case TOK_TRUE: node = node_alloc(parser, NODE_TRUE, prev); break; |
374 | node = node_alloc(NODE_TRUE, prev, parser); | 386 | case TOK_FALSE: node = node_alloc(parser, NODE_FALSE, prev); break; |
375 | } break; | 387 | case TOK_NIL: node = node_alloc(parser, NODE_NIL, prev); break; |
376 | case TOK_FALSE: { | ||
377 | node = node_alloc(NODE_FALSE, prev, parser); | ||
378 | } break; | ||
379 | case TOK_NIL: { | ||
380 | node = node_alloc(NODE_NIL, prev, parser); | ||
381 | } break; | ||
382 | default: return; // Unreachable. | 388 | default: return; // Unreachable. |
383 | } | 389 | } |
390 | if (!node) return; | ||
384 | array_push(parser->nodes, node, parser->storage); | 391 | array_push(parser->nodes, node, parser->storage); |
385 | } | 392 | } |
386 | 393 | ||
387 | Node * | 394 | // Node * |
395 | // parse_struct_field(Parser *parser) { | ||
396 | // #if DEBUG == 1 | ||
397 | // println("parsing struct field "); | ||
398 | // print_token(parser->previous); | ||
399 | // #endif | ||
400 | // parse_consume(parser, TOK_SYMBOL, cstr("expected struct field name")); | ||
401 | // parse_symbol(parser); | ||
402 | // Node *field = array_pop(parser->nodes); | ||
403 | // parse_consume(parser, TOK_COLON, | ||
404 | // cstr("invalid type name given for struct field")); | ||
405 | // field->right = parse_type(parser); | ||
406 | // if (parse_match(parser, TOK_ASSIGN)) { | ||
407 | // parse_expr(parser, PREC_LOW); | ||
408 | // field->left = array_pop(parser->nodes); | ||
409 | // } | ||
410 | |||
411 | // Node *list = node_alloc(NODE_NODE_LIST, parser->previous, parser); | ||
412 | // list->left = field; | ||
413 | // return list; | ||
414 | // } | ||
415 | |||
416 | void | ||
388 | parse_type(Parser *parser) { | 417 | parse_type(Parser *parser) { |
389 | Token prev = parser->previous; | 418 | Token prev = parser->previous; |
390 | #if DEBUG == 1 | 419 | #if DEBUG == 1 |
391 | print("parsing type "); | 420 | print("parsing type "); |
392 | print_token(prev); | 421 | print_token(prev); |
393 | #endif | 422 | #endif |
394 | Node *node = node_alloc(NODE_NODE_TYPE, prev, parser); | 423 | Node *node = node_alloc(parser, NODE_TYPE, prev); |
424 | if (!node) return; | ||
395 | if (parse_match(parser, TOK_LCURLY)) { | 425 | if (parse_match(parser, TOK_LCURLY)) { |
396 | node->value.sym = cstr("..."); | 426 | node->kind = NODE_COMPOUND_TYPE; |
397 | Node *l = parse_struct_field(parser); | ||
398 | if (!l) { | ||
399 | return NULL; | ||
400 | } | ||
401 | node->vartype = l; | ||
402 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | 427 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { |
403 | Node *tmp = parse_struct_field(parser); | 428 | parse_consume(parser, TOK_SYMBOL, cstr("expected name")); |
404 | if (!tmp) { | 429 | parse_symbol(parser); |
405 | return NULL; | 430 | Node *next = array_pop(parser->nodes); |
406 | } | 431 | parse_consume(parser, TOK_COLON, cstr("incomplete type")); |
407 | l->vartype = tmp; | 432 | parse_type(parser); |
408 | l = tmp; | 433 | next->next = array_pop(parser->nodes); |
434 | array_push(node->elements, next, parser->storage); | ||
409 | } | 435 | } |
410 | return node; | 436 | } else { |
411 | } | 437 | parse_consume(parser, TOK_SYMBOL, |
412 | parse_consume(parser, TOK_SYMBOL, cstr("no type given for struct field")); | 438 | cstr("no type given for struct field")); |
413 | node->value.sym = parser->previous.val; | 439 | node->value.sym = parser->previous.val; |
414 | return node; | ||
415 | } | ||
416 | |||
417 | Node * | ||
418 | parse_struct_field(Parser *parser) { | ||
419 | #if DEBUG == 1 | ||
420 | println("parsing struct field "); | ||
421 | print_token(parser->previous); | ||
422 | #endif | ||
423 | parse_consume(parser, TOK_SYMBOL, cstr("expected struct field name")); | ||
424 | parse_symbol(parser); | ||
425 | Node *field = array_pop(parser->nodes); | ||
426 | parse_consume(parser, TOK_COLON, | ||
427 | cstr("invalid type name given for struct field")); | ||
428 | field->vartype = parse_type(parser); | ||
429 | if (parse_match(parser, TOK_ASSIGN)) { | ||
430 | parse_expr(parser, PREC_LOW); | ||
431 | field->varname = array_pop(parser->nodes); | ||
432 | } | 440 | } |
433 | 441 | array_push(parser->nodes, node, parser->storage); | |
434 | Node *list = node_alloc(NODE_NODE_LIST, parser->previous, parser); | ||
435 | list->varname = field; | ||
436 | return list; | ||
437 | } | 442 | } |
438 | 443 | ||
439 | void | 444 | void |
440 | parse_keyword(Parser *parser) { | 445 | parse_keyword(Parser *parser) { |
446 | if (parser->panic) return; | ||
441 | Token prev = parser->previous; | 447 | Token prev = parser->previous; |
442 | #if DEBUG == 1 | 448 | #if DEBUG == 1 |
443 | print("parsing keyword "); | 449 | print("parsing keyword "); |
@@ -446,66 +452,70 @@ parse_keyword(Parser *parser) { | |||
446 | Node *node = NULL; | 452 | Node *node = NULL; |
447 | switch (prev.kind) { | 453 | switch (prev.kind) { |
448 | case TOK_LET: { | 454 | case TOK_LET: { |
455 | node = node_alloc(parser, NODE_LET, prev); | ||
456 | if (!node) return; | ||
449 | parse_consume(parser, TOK_SYMBOL, | 457 | parse_consume(parser, TOK_SYMBOL, |
450 | cstr("expected symbol name on let expression")); | 458 | cstr("expected symbol name on let expression")); |
451 | parse_symbol(parser); | 459 | parse_symbol(parser); |
460 | node->var_name = array_pop(parser->nodes); | ||
452 | 461 | ||
453 | // Optional type declaration. | 462 | // Optional type declaration. |
454 | Node *type = NULL; | ||
455 | if (parse_match(parser, TOK_COLON)) { | 463 | if (parse_match(parser, TOK_COLON)) { |
456 | type = parse_type(parser); | 464 | parse_type(parser); |
457 | } | 465 | node->var_type = array_pop(parser->nodes); |
458 | |||
459 | node = node_alloc(NODE_LET, prev, parser); | ||
460 | if (!node) { | ||
461 | return; | ||
462 | } | 466 | } |
463 | 467 | ||
464 | // Optional assignment. | 468 | // Optional assignment. |
465 | if (parse_match(parser, TOK_ASSIGN)) { | 469 | if (parse_match(parser, TOK_ASSIGN)) { |
466 | parse_expr(parser, PREC_LOW); | 470 | parse_expr(parser, PREC_LOW); |
467 | node->varvalue = array_pop(parser->nodes); | 471 | node->var_val = array_pop(parser->nodes); |
468 | } | 472 | } |
469 | node->varname = array_pop(parser->nodes); | ||
470 | node->varname->vartype = type; | ||
471 | } break; | 473 | } break; |
472 | case TOK_SET: { | 474 | case TOK_SET: { |
475 | node = node_alloc(parser, NODE_SET, prev); | ||
476 | if (!node) return; | ||
473 | parse_consume(parser, TOK_SYMBOL, | 477 | parse_consume(parser, TOK_SYMBOL, |
474 | cstr("expected symbol name on set expression")); | 478 | cstr("expected symbol name on let expression")); |
475 | parse_symbol_chain(parser); | 479 | parse_symbol(parser); |
480 | node->var_name = array_pop(parser->nodes); | ||
476 | parse_consume(parser, TOK_ASSIGN, | 481 | parse_consume(parser, TOK_ASSIGN, |
477 | cstr("expected assignment on set expression")); | 482 | cstr("expected assignment on set expression")); |
478 | parse_expr(parser, PREC_LOW); | 483 | parse_expr(parser, PREC_LOW); |
479 | node = node_alloc(NODE_SET, prev, parser); | 484 | node->var_val = array_pop(parser->nodes); |
480 | if (!node) { | ||
481 | return; | ||
482 | } | ||
483 | node->varvalue = array_pop(parser->nodes); | ||
484 | node->varname = array_pop(parser->nodes); | ||
485 | } break; | 485 | } break; |
486 | case TOK_STRUCT: { | 486 | case TOK_STRUCT: { |
487 | node = node_alloc(parser, NODE_STRUCT, prev); | ||
488 | if (!node) return; | ||
487 | parse_consume(parser, TOK_SYMBOL, | 489 | parse_consume(parser, TOK_SYMBOL, |
488 | cstr("expected symbol name on struct definition")); | 490 | cstr("expected symbol name on struct definition")); |
489 | parse_symbol(parser); | 491 | parse_symbol(parser); |
492 | node->struct_name = array_pop(parser->nodes); | ||
493 | |||
490 | parse_consume(parser, TOK_LCURLY, | 494 | parse_consume(parser, TOK_LCURLY, |
491 | cstr("expected '{' on struct definition")); | 495 | cstr("expected '{' on struct definition")); |
492 | node = node_alloc(NODE_STRUCT, prev, parser); | 496 | |
493 | if (!node) { | ||
494 | return; | ||
495 | } | ||
496 | node->varname = array_pop(parser->nodes); | ||
497 | Node *l = parse_struct_field(parser); | ||
498 | if (!l) { | ||
499 | return; | ||
500 | } | ||
501 | node->vartype = l; | ||
502 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | 497 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { |
503 | Node *tmp = parse_struct_field(parser); | 498 | Node *field = |
504 | if (!tmp) { | 499 | node_alloc(parser, NODE_STRUCT_FIELD, parser->current); |
505 | return; | 500 | if (!field) return; |
501 | parse_consume( | ||
502 | parser, TOK_SYMBOL, | ||
503 | cstr("expected symbol name on struct definition")); | ||
504 | parse_symbol(parser); | ||
505 | field->field_name = array_pop(parser->nodes); | ||
506 | parse_consume( | ||
507 | parser, TOK_COLON, | ||
508 | cstr("expected symbol name on struct definition")); | ||
509 | parse_type(parser); | ||
510 | field->field_type = array_pop(parser->nodes); | ||
511 | |||
512 | // Optional assignment. | ||
513 | if (parse_match(parser, TOK_ASSIGN)) { | ||
514 | parse_expr(parser, PREC_LOW); | ||
515 | field->field_val = array_pop(parser->nodes); | ||
506 | } | 516 | } |
507 | l->vartype = tmp; | 517 | |
508 | l = tmp; | 518 | array_push(node->struct_field, field, parser->storage); |
509 | } | 519 | } |
510 | } break; | 520 | } break; |
511 | default: return; // Unreachable. | 521 | default: return; // Unreachable. |
@@ -515,6 +525,7 @@ parse_keyword(Parser *parser) { | |||
515 | 525 | ||
516 | void | 526 | void |
517 | parse_binary(Parser *parser) { | 527 | parse_binary(Parser *parser) { |
528 | if (parser->panic) return; | ||
518 | Token prev = parser->previous; | 529 | Token prev = parser->previous; |
519 | #if DEBUG == 1 | 530 | #if DEBUG == 1 |
520 | print("parsing binary "); | 531 | print("parsing binary "); |
@@ -525,39 +536,37 @@ parse_binary(Parser *parser) { | |||
525 | 536 | ||
526 | Node *node; | 537 | Node *node; |
527 | switch (prev.kind) { | 538 | switch (prev.kind) { |
528 | case TOK_ADD: node = node_alloc(NODE_ADD, prev, parser); break; | 539 | case TOK_ADD: node = node_alloc(parser, NODE_ADD, prev); break; |
529 | case TOK_SUB: node = node_alloc(NODE_SUB, prev, parser); break; | 540 | case TOK_SUB: node = node_alloc(parser, NODE_SUB, prev); break; |
530 | case TOK_MUL: node = node_alloc(NODE_MUL, prev, parser); break; | 541 | case TOK_MUL: node = node_alloc(parser, NODE_MUL, prev); break; |
531 | case TOK_DIV: node = node_alloc(NODE_DIV, prev, parser); break; | 542 | case TOK_DIV: node = node_alloc(parser, NODE_DIV, prev); break; |
532 | case TOK_MOD: node = node_alloc(NODE_MOD, prev, parser); break; | 543 | case TOK_MOD: node = node_alloc(parser, NODE_MOD, prev); break; |
533 | case TOK_AND: node = node_alloc(NODE_AND, prev, parser); break; | 544 | case TOK_AND: node = node_alloc(parser, NODE_AND, prev); break; |
534 | case TOK_OR: node = node_alloc(NODE_OR, prev, parser); break; | 545 | case TOK_OR: node = node_alloc(parser, NODE_OR, prev); break; |
535 | case TOK_EQ: node = node_alloc(NODE_EQ, prev, parser); break; | 546 | case TOK_EQ: node = node_alloc(parser, NODE_EQ, prev); break; |
536 | case TOK_NEQ: node = node_alloc(NODE_NEQ, prev, parser); break; | 547 | case TOK_NEQ: node = node_alloc(parser, NODE_NEQ, prev); break; |
537 | case TOK_LT: node = node_alloc(NODE_LT, prev, parser); break; | 548 | case TOK_LT: node = node_alloc(parser, NODE_LT, prev); break; |
538 | case TOK_GT: node = node_alloc(NODE_GT, prev, parser); break; | 549 | case TOK_GT: node = node_alloc(parser, NODE_GT, prev); break; |
539 | case TOK_LE: node = node_alloc(NODE_LE, prev, parser); break; | 550 | case TOK_LE: node = node_alloc(parser, NODE_LE, prev); break; |
540 | case TOK_GE: node = node_alloc(NODE_GE, prev, parser); break; | 551 | case TOK_GE: node = node_alloc(parser, NODE_GE, prev); break; |
541 | case TOK_BITAND: { | 552 | case TOK_BITAND: { |
542 | node = node_alloc(NODE_BITAND, prev, parser); | 553 | node = node_alloc(parser, NODE_BITAND, prev); |
543 | } break; | 554 | } break; |
544 | case TOK_BITOR: { | 555 | case TOK_BITOR: { |
545 | node = node_alloc(NODE_BITOR, prev, parser); | 556 | node = node_alloc(parser, NODE_BITOR, prev); |
546 | } break; | 557 | } break; |
547 | case TOK_BITLSHIFT: { | 558 | case TOK_BITLSHIFT: { |
548 | node = node_alloc(NODE_BITLSHIFT, prev, parser); | 559 | node = node_alloc(parser, NODE_BITLSHIFT, prev); |
549 | } break; | 560 | } break; |
550 | case TOK_BITRSHIFT: { | 561 | case TOK_BITRSHIFT: { |
551 | node = node_alloc(NODE_BITRSHIFT, prev, parser); | 562 | node = node_alloc(parser, NODE_BITRSHIFT, prev); |
552 | } break; | 563 | } break; |
553 | default: { | 564 | default: { |
554 | parse_emit_err(parser, prev, cstr("unreachable")); | 565 | parse_emit_err(parser, prev, cstr("unreachable")); |
555 | return; | 566 | return; |
556 | } | 567 | } |
557 | } | 568 | } |
558 | if (!node) { | 569 | if (!node) return; |
559 | return; | ||
560 | } | ||
561 | node->right = array_pop(parser->nodes); | 570 | node->right = array_pop(parser->nodes); |
562 | node->left = array_pop(parser->nodes); | 571 | node->left = array_pop(parser->nodes); |
563 | array_push(parser->nodes, node, parser->storage); | 572 | array_push(parser->nodes, node, parser->storage); |
@@ -565,6 +574,7 @@ parse_binary(Parser *parser) { | |||
565 | 574 | ||
566 | void | 575 | void |
567 | parse_number(Parser *parser) { | 576 | parse_number(Parser *parser) { |
577 | if (parser->panic) return; | ||
568 | Token prev = parser->previous; | 578 | Token prev = parser->previous; |
569 | #if DEBUG == 1 | 579 | #if DEBUG == 1 |
570 | print("parsing number "); | 580 | print("parsing number "); |
@@ -575,24 +585,18 @@ parse_number(Parser *parser) { | |||
575 | case TOK_NUM_INT: { | 585 | case TOK_NUM_INT: { |
576 | if (str_has_prefix(prev.val, cstr("0x")) || | 586 | if (str_has_prefix(prev.val, cstr("0x")) || |
577 | str_has_prefix(prev.val, cstr("0b"))) { | 587 | str_has_prefix(prev.val, cstr("0b"))) { |
578 | node = node_alloc(NODE_NUM_UINT, prev, parser); | 588 | node = node_alloc(parser, NODE_NUM_UINT, prev); |
579 | if (!node) { | 589 | if (!node) return; |
580 | return; | ||
581 | } | ||
582 | node->value.u = str_to_uint(prev.val); | 590 | node->value.u = str_to_uint(prev.val); |
583 | } else { | 591 | } else { |
584 | node = node_alloc(NODE_NUM_INT, prev, parser); | 592 | node = node_alloc(parser, NODE_NUM_INT, prev); |
585 | if (!node) { | 593 | if (!node) return; |
586 | return; | ||
587 | } | ||
588 | node->value.i = str_to_int(prev.val); | 594 | node->value.i = str_to_int(prev.val); |
589 | } | 595 | } |
590 | } break; | 596 | } break; |
591 | case TOK_NUM_FLOAT: { | 597 | case TOK_NUM_FLOAT: { |
592 | node = node_alloc(NODE_NUM_FLOAT, prev, parser); | 598 | node = node_alloc(parser, NODE_NUM_FLOAT, prev); |
593 | if (!node) { | 599 | if (!node) return; |
594 | return; | ||
595 | } | ||
596 | node->value.d = str_to_float(prev.val); | 600 | node->value.d = str_to_float(prev.val); |
597 | } break; | 601 | } break; |
598 | default: break; | 602 | default: break; |
@@ -602,15 +606,14 @@ parse_number(Parser *parser) { | |||
602 | 606 | ||
603 | void | 607 | void |
604 | parse_string(Parser *parser) { | 608 | parse_string(Parser *parser) { |
609 | if (parser->panic) return; | ||
605 | Token prev = parser->previous; | 610 | Token prev = parser->previous; |
606 | #if DEBUG == 1 | 611 | #if DEBUG == 1 |
607 | print("parsing string "); | 612 | print("parsing string "); |
608 | print_token(prev); | 613 | print_token(prev); |
609 | #endif | 614 | #endif |
610 | Node *node = node_alloc(NODE_STRING, prev, parser); | 615 | Node *node = node_alloc(parser, NODE_STRING, prev); |
611 | if (!node) { | 616 | if (!node) return; |
612 | return; | ||
613 | } | ||
614 | node->value.str = str_remove_prefix(prev.val, cstr("\"")); | 617 | node->value.str = str_remove_prefix(prev.val, cstr("\"")); |
615 | node->value.str = str_remove_suffix(node->value.str, cstr("\"")); | 618 | node->value.str = str_remove_suffix(node->value.str, cstr("\"")); |
616 | array_push(parser->nodes, node, parser->storage); | 619 | array_push(parser->nodes, node, parser->storage); |
@@ -618,42 +621,32 @@ parse_string(Parser *parser) { | |||
618 | 621 | ||
619 | void | 622 | void |
620 | parse_symbol(Parser *parser) { | 623 | parse_symbol(Parser *parser) { |
624 | if (parser->panic) return; | ||
621 | Token prev = parser->previous; | 625 | Token prev = parser->previous; |
622 | #if DEBUG == 1 | 626 | #if DEBUG == 1 |
623 | print("parsing symbol "); | 627 | print("parsing symbol "); |
624 | print_token(prev); | 628 | print_token(prev); |
625 | #endif | 629 | #endif |
626 | Node *node = node_alloc(NODE_SYMBOL, prev, parser); | 630 | Node *node; |
627 | if (!node) { | ||
628 | return; | ||
629 | } | ||
630 | node->value.sym = prev.val; | ||
631 | array_push(parser->nodes, node, parser->storage); | ||
632 | } | ||
633 | |||
634 | void | ||
635 | parse_symbol_chain(Parser *parser) { | ||
636 | Token prev = parser->previous; | ||
637 | #if DEBUG == 1 | ||
638 | print("parsing symbol "); | ||
639 | print_token(prev); | ||
640 | #endif | ||
641 | Node *node = node_alloc(NODE_SYMBOL, prev, parser); | ||
642 | if (!node) { | ||
643 | return; | ||
644 | } | ||
645 | node->value.sym = prev.val; | ||
646 | if (parse_match(parser, TOK_DOT)) { | 631 | if (parse_match(parser, TOK_DOT)) { |
632 | // Symbol chain. | ||
647 | parse_consume(parser, TOK_SYMBOL, | 633 | parse_consume(parser, TOK_SYMBOL, |
648 | cstr("expected symbol after '.' operator")); | 634 | cstr("expected symbol after '.' operator")); |
649 | parse_symbol_chain(parser); | 635 | node = node_alloc(parser, NODE_SYMBOL, prev); |
650 | node->varname = array_pop(parser->nodes); | 636 | if (!node) return; |
637 | parse_symbol(parser); | ||
638 | node->next = array_pop(parser->nodes); | ||
639 | } else { | ||
640 | node = node_alloc(parser, NODE_SYMBOL, prev); | ||
641 | if (!node) return; | ||
651 | } | 642 | } |
643 | node->value.sym = prev.val; | ||
652 | array_push(parser->nodes, node, parser->storage); | 644 | array_push(parser->nodes, node, parser->storage); |
653 | } | 645 | } |
654 | 646 | ||
655 | void | 647 | void |
656 | parse_grouping(Parser *parser) { | 648 | parse_grouping(Parser *parser) { |
649 | if (parser->panic) return; | ||
657 | #if DEBUG == 1 | 650 | #if DEBUG == 1 |
658 | print("parsing group "); | 651 | print("parsing group "); |
659 | print_token(parser->previous); | 652 | print_token(parser->previous); |
@@ -664,37 +657,73 @@ parse_grouping(Parser *parser) { | |||
664 | 657 | ||
665 | void | 658 | void |
666 | graph_node(Node *node) { | 659 | graph_node(Node *node) { |
667 | if (node == NULL) { | 660 | if (node == NULL) return; |
668 | return; | ||
669 | } | ||
670 | print("%d [width=2.5,shape=Mrecord,label=\"", node->id); | 661 | print("%d [width=2.5,shape=Mrecord,label=\"", node->id); |
671 | print("{ %s | { L: %d | C: %d } } ", node_str[node->kind], node->line, | 662 | print("{ <type> %s | { L: %d | C: %d } } ", node_str[node->kind], |
672 | node->col); | 663 | node->line, node->col); |
673 | switch (node->kind) { | 664 | switch (node->kind) { |
674 | case NODE_NUM_INT: print("| Value: %d", node->value.i); break; | 665 | case NODE_NUM_INT: print("| Value: %d", node->value.i); break; |
675 | case NODE_NUM_UINT: print("| Value: %x", node->value.u); break; | 666 | case NODE_NUM_UINT: print("| Value: %x", node->value.u); break; |
676 | case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break; | 667 | case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break; |
677 | case NODE_STRING: print("| Value: %s", node->value.str); break; | 668 | case NODE_STRING: print("| Value: %s", node->value.str); break; |
678 | case NODE_SYMBOL: print("| Value: %s", node->value.sym); break; | 669 | case NODE_SYMBOL: print("| Value: %s", node->value.sym); break; |
679 | case NODE_NODE_TYPE: print("| Value: %s", node->value.sym); break; | 670 | case NODE_STRUCT_LIT: print("| Value: %s", node->value.sym); break; |
671 | case NODE_TYPE: print("| Value: %s", node->value.sym); break; | ||
680 | default: break; | 672 | default: break; |
681 | } | 673 | } |
682 | println("\"];"); | 674 | println("\"];"); |
683 | if (node->left) { | 675 | |
684 | println("%d:e->%d:w;", node->id, node->left->id); | 676 | switch (node->kind) { |
685 | graph_node(node->left); | 677 | case NODE_COMPOUND_TYPE: { |
686 | } | 678 | for (sz i = 0; i < array_size(node->elements); i++) { |
687 | if (node->right) { | 679 | Node *next = node->elements[i]; |
688 | println("%d:e->%d:w;", node->id, node->right->id); | 680 | println("%d:e->%d:w;", node->id, next->id); |
689 | graph_node(node->right); | 681 | graph_node(next); |
682 | } | ||
683 | } break; | ||
684 | case NODE_STRUCT: { | ||
685 | if (node->struct_name) { | ||
686 | println("%d:e->%d:w;", node->id, node->struct_name->id); | ||
687 | graph_node(node->struct_name); | ||
688 | } | ||
689 | for (sz i = 0; i < array_size(node->struct_field); i++) { | ||
690 | Node *next = node->struct_field[i]; | ||
691 | println("%d:e->%d:w;", node->id, next->id); | ||
692 | graph_node(next); | ||
693 | } | ||
694 | } break; | ||
695 | case NODE_STRUCT_FIELD: | ||
696 | case NODE_SET: | ||
697 | case NODE_LET: { | ||
698 | if (node->var_name) { | ||
699 | println("%d:e->%d:w;", node->id, node->var_name->id); | ||
700 | graph_node(node->var_name); | ||
701 | } | ||
702 | if (node->var_type) { | ||
703 | println("%d:e->%d:w;", node->id, node->var_type->id); | ||
704 | graph_node(node->var_type); | ||
705 | } | ||
706 | if (node->var_val) { | ||
707 | println("%d:e->%d:w;", node->id, node->var_val->id); | ||
708 | graph_node(node->var_val); | ||
709 | } | ||
710 | } break; | ||
711 | default: { | ||
712 | if (node->left) { | ||
713 | println("%d:e->%d:w;", node->id, node->left->id); | ||
714 | graph_node(node->left); | ||
715 | } | ||
716 | if (node->right) { | ||
717 | println("%d:e->%d:w;", node->id, node->right->id); | ||
718 | graph_node(node->right); | ||
719 | } | ||
720 | } break; | ||
690 | } | 721 | } |
691 | } | 722 | } |
692 | 723 | ||
693 | void | 724 | void |
694 | graph_ast(Node **roots) { | 725 | graph_ast(Node **roots) { |
695 | if (roots == NULL) { | 726 | if (roots == NULL) return; |
696 | return; | ||
697 | } | ||
698 | println("digraph ast {"); | 727 | println("digraph ast {"); |
699 | println("rankdir=LR;"); | 728 | println("rankdir=LR;"); |
700 | println("ranksep=\"0.95 equally\";"); | 729 | println("ranksep=\"0.95 equally\";"); |