Mercurial > repos > blastem
comparison debug.c @ 2364:c822bb628fc3
Add support for function call expressions in debug parser
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 08 Nov 2023 00:09:33 -0800 |
parents | b865f33fd47e |
children | 8c060849a503 |
comparison
equal
deleted
inserted
replaced
2363:b865f33fd47e | 2364:c822bb628fc3 |
---|---|
185 static const char *token_type_names[] = { | 185 static const char *token_type_names[] = { |
186 "TOKEN_NONE", | 186 "TOKEN_NONE", |
187 "TOKEN_INT", | 187 "TOKEN_INT", |
188 "TOKEN_DECIMAL", | 188 "TOKEN_DECIMAL", |
189 "TOKEN_NAME", | 189 "TOKEN_NAME", |
190 "TOKEN_ARRAY", | |
191 "TOKEN_FUNCALL", | |
190 "TOKEN_OPER", | 192 "TOKEN_OPER", |
191 "TOKEN_SIZE", | 193 "TOKEN_SIZE", |
192 "TOKEN_LBRACKET", | 194 "TOKEN_LBRACKET", |
193 "TOKEN_RBRACKET", | 195 "TOKEN_RBRACKET", |
194 "TOKEN_LPAREN", | 196 "TOKEN_LPAREN", |
308 uint8_t done = 0; | 310 uint8_t done = 0; |
309 switch (**end) | 311 switch (**end) |
310 { | 312 { |
311 case '[': | 313 case '[': |
312 type = TOKEN_ARRAY; | 314 type = TOKEN_ARRAY; |
315 done = 1; | |
316 break; | |
317 case '(': | |
318 type = TOKEN_FUNCALL; | |
313 case '+': | 319 case '+': |
314 case '-': | 320 case '-': |
315 case '*': | 321 case '*': |
316 case '/': | 322 case '/': |
317 case '&': | 323 case '&': |
322 case '!': | 328 case '!': |
323 case '>': | 329 case '>': |
324 case '<': | 330 case '<': |
325 case '.': | 331 case '.': |
326 case ']': | 332 case ']': |
327 case '(': | |
328 case ')': | 333 case ')': |
329 done = 1; | 334 done = 1; |
330 break; | 335 break; |
331 } | 336 } |
332 if (done) { | 337 if (done) { |
344 .str = name | 349 .str = name |
345 } | 350 } |
346 }; | 351 }; |
347 } | 352 } |
348 | 353 |
354 static void free_expr(expr *e); | |
355 static void free_expr_int(expr *e) | |
356 { | |
357 free_expr(e->left); | |
358 if (e->type == EXPR_FUNCALL) { | |
359 for (uint32_t i = 0; i < e->op.v.num; i++) | |
360 { | |
361 free_expr_int(e->right + i); | |
362 } | |
363 free(e->right); | |
364 } else { | |
365 free_expr(e->right); | |
366 } | |
367 if (e->op.type == TOKEN_NAME) { | |
368 free(e->op.v.str); | |
369 } | |
370 } | |
371 | |
349 static void free_expr(expr *e) | 372 static void free_expr(expr *e) |
350 { | 373 { |
351 if (!e) { | 374 if (!e) { |
352 return; | 375 return; |
353 } | 376 } |
354 free_expr(e->left); | 377 free_expr_int(e); |
355 free_expr(e->right); | |
356 if (e->op.type == TOKEN_NAME) { | |
357 free(e->op.v.str); | |
358 } | |
359 free(e); | 378 free(e); |
360 } | 379 } |
361 | 380 |
362 static expr *parse_scalar_or_muldiv(char *start, char **end); | 381 static expr *parse_scalar_or_muldiv(char *start, char **end); |
363 static expr *parse_expression(char *start, char **end); | 382 static expr *parse_expression(char *start, char **end); |
459 return NULL; | 478 return NULL; |
460 } | 479 } |
461 token rparen = parse_token(*end, end); | 480 token rparen = parse_token(*end, end); |
462 if (rparen.type != TOKEN_RPAREN) { | 481 if (rparen.type != TOKEN_RPAREN) { |
463 fprintf(stderr, "Missing closing `)`"); | 482 fprintf(stderr, "Missing closing `)`"); |
483 free_expr(ret); | |
484 return NULL; | |
485 } | |
486 return ret; | |
487 } | |
488 if (first.type == TOKEN_FUNCALL) { | |
489 expr *ret = calloc(1, sizeof(expr)); | |
490 ret->left = calloc(1, sizeof(expr)); | |
491 ret->left->type = EXPR_SCALAR; | |
492 ret->left->op = first; | |
493 ret->left->op.type = TOKEN_NAME; | |
494 uint32_t storage = 0; | |
495 ret->op.v.num = 0; | |
496 token next = parse_token(after_first, end); | |
497 while (next.type != TOKEN_RPAREN && next.type != TOKEN_NONE) | |
498 { | |
499 expr *e = parse_expression(after_first, end); | |
500 if (!e) { | |
501 fprintf(stderr, "Expression expected after '('\n"); | |
502 free_expr(ret); | |
503 return NULL; | |
504 } | |
505 if (storage == ret->op.v.num) { | |
506 storage = storage ? storage * 2 : 1; | |
507 ret->right = realloc(ret->right, storage * sizeof(expr)); | |
508 } | |
509 ret->right[ret->op.v.num++] = *e; | |
510 free(e); | |
511 after_first = *end; | |
512 next = parse_token(after_first, end); | |
513 } | |
514 if (next.type != TOKEN_RPAREN) { | |
515 fprintf(stderr, "Missing ')' after '('\n"); | |
464 free_expr(ret); | 516 free_expr(ret); |
465 return NULL; | 517 return NULL; |
466 } | 518 } |
467 return ret; | 519 return ret; |
468 } | 520 } |
618 return NULL; | 670 return NULL; |
619 } | 671 } |
620 token rparen = parse_token(*end, end); | 672 token rparen = parse_token(*end, end); |
621 if (rparen.type != TOKEN_RPAREN) { | 673 if (rparen.type != TOKEN_RPAREN) { |
622 fprintf(stderr, "Missing closing `)`"); | 674 fprintf(stderr, "Missing closing `)`"); |
675 free_expr(ret); | |
676 return NULL; | |
677 } | |
678 return maybe_muldiv(ret, *end, end); | |
679 } | |
680 if (first.type == TOKEN_FUNCALL) { | |
681 expr *ret = calloc(1, sizeof(expr)); | |
682 ret->left = calloc(1, sizeof(expr)); | |
683 ret->left->type = EXPR_SCALAR; | |
684 ret->left->op = first; | |
685 ret->left->op.type = TOKEN_NAME; | |
686 uint32_t storage = 0; | |
687 ret->op.v.num = 0; | |
688 token next = parse_token(after_first, end); | |
689 while (next.type != TOKEN_RPAREN && next.type != TOKEN_NONE) | |
690 { | |
691 expr *e = parse_expression(after_first, end); | |
692 if (!e) { | |
693 fprintf(stderr, "Expression expected after '('\n"); | |
694 free_expr(ret); | |
695 return NULL; | |
696 } | |
697 if (storage == ret->op.v.num) { | |
698 storage = storage ? storage * 2 : 1; | |
699 ret->right = realloc(ret->right, storage * sizeof(expr)); | |
700 } | |
701 ret->right[ret->op.v.num++] = *e; | |
702 free(e); | |
703 after_first = *end; | |
704 next = parse_token(after_first, end); | |
705 } | |
706 if (next.type != TOKEN_RPAREN) { | |
707 fprintf(stderr, "Missing ')' after '('\n"); | |
623 free_expr(ret); | 708 free_expr(ret); |
624 return NULL; | 709 return NULL; |
625 } | 710 } |
626 return maybe_muldiv(ret, *end, end); | 711 return maybe_muldiv(ret, *end, end); |
627 } | 712 } |
747 return NULL; | 832 return NULL; |
748 } | 833 } |
749 token rparen = parse_token(*end, end); | 834 token rparen = parse_token(*end, end); |
750 if (rparen.type != TOKEN_RPAREN) { | 835 if (rparen.type != TOKEN_RPAREN) { |
751 fprintf(stderr, "Missing closing `)`"); | 836 fprintf(stderr, "Missing closing `)`"); |
837 free_expr(ret); | |
838 return NULL; | |
839 } | |
840 return maybe_binary(ret, *end, end); | |
841 } | |
842 if (first.type == TOKEN_FUNCALL) { | |
843 expr *ret = calloc(1, sizeof(expr)); | |
844 ret->type = EXPR_FUNCALL; | |
845 ret->left = calloc(1, sizeof(expr)); | |
846 ret->left->type = EXPR_SCALAR; | |
847 ret->left->op = first; | |
848 ret->left->op.type = TOKEN_NAME; | |
849 uint32_t storage = 0; | |
850 ret->op.v.num = 0; | |
851 //consume LPAREN | |
852 parse_token(after_first, end); | |
853 after_first = *end; | |
854 token next = parse_token(after_first, end); | |
855 while (next.type != TOKEN_RPAREN && next.type != TOKEN_NONE) | |
856 { | |
857 expr *e = parse_expression(after_first, end); | |
858 if (!e) { | |
859 fprintf(stderr, "Expression expected after '('\n"); | |
860 free_expr(ret); | |
861 return NULL; | |
862 } | |
863 if (storage == ret->op.v.num) { | |
864 storage = storage ? storage * 2 : 1; | |
865 ret->right = realloc(ret->right, storage * sizeof(expr)); | |
866 } | |
867 ret->right[ret->op.v.num++] = *e; | |
868 free(e); | |
869 after_first = *end; | |
870 next = parse_token(after_first, end); | |
871 } | |
872 if (next.type != TOKEN_RPAREN) { | |
873 fprintf(stderr, "Missing ')' after '('\n"); | |
752 free_expr(ret); | 874 free_expr(ret); |
753 return NULL; | 875 return NULL; |
754 } | 876 } |
755 return maybe_binary(ret, *end, end); | 877 return maybe_binary(ret, *end, end); |
756 } | 878 } |