Mercurial > repos > tabletprog
comparison modules/parser.tp @ 222:c6e321a538d4
Implemented more of the grammar. Dealt with some name conflicts along the way.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 29 Dec 2013 13:08:01 -0800 |
parents | a1a80af71b05 |
children | 25db1c7c7300 |
comparison
equal
deleted
inserted
replaced
221:218b11ec8fa2 | 222:c6e321a538d4 |
---|---|
218 quote: :tomatch { | 218 quote: :tomatch { |
219 cur <- 0 | 219 cur <- 0 |
220 count <- 0 | 220 count <- 0 |
221 n <- tomatch byte_length | 221 n <- tomatch byte_length |
222 orig <- tomatch | 222 orig <- tomatch |
223 match <- true | 223 _match <- true |
224 allBasic? <- true | 224 allBasic? <- true |
225 yieldvals <- [] | 225 yieldvals <- [] |
226 while: { match && cur < n } do: { | 226 while: { _match && cur < n } do: { |
227 res <- mcall | 227 res <- mcall |
228 match <- res matched? | 228 _match <- res matched? |
229 if: match { | 229 if: _match { |
230 count <- count + 1 | 230 count <- count + 1 |
231 //TODO: Use some kind of lightweight substring wrapper here | 231 //TODO: Use some kind of lightweight substring wrapper here |
232 tomatch <- tomatch from: (res matchlen) | 232 tomatch <- tomatch from: (res matchlen) |
233 if: allBasic? { | 233 if: allBasic? { |
234 ifnot: (res basicYield?) { | 234 ifnot: (res basicYield?) { |
296 acc | 296 acc |
297 } | 297 } |
298 } | 298 } |
299 quote: :tomatch { | 299 quote: :tomatch { |
300 body | 300 body |
301 } | |
302 } | |
303 | |
304 match <- macro: :matchexpr { | |
305 mc <- _makeMatchCall: matchexpr | |
306 if: (mc valid?) { | |
307 mcall <- mc matchcall | |
308 quote: :tomatch { | |
309 mcall | |
310 } | |
311 } else: { | |
312 print: "#error Invalid macth macro call: " . (mc message) . "\n" | |
301 } | 313 } |
302 } | 314 } |
303 | 315 |
304 match:yield <- macro: :matchexpr :ylambda { | 316 match:yield <- macro: :matchexpr :ylambda { |
305 mc <- _makeMatchCall: matchexpr | 317 mc <- _makeMatchCall: matchexpr |
493 } | 505 } |
494 #{ | 506 #{ |
495 litval <- num | 507 litval <- num |
496 signed? <- signed | 508 signed? <- signed |
497 bits <- litbits | 509 bits <- litbits |
510 string <- { | |
511 str <- "0b" | |
512 i <- bits - 1 | |
513 printzero <- false | |
514 while: { i >= 0 } do: { | |
515 str <- str . (if: (lshift: 1 by: i) and num > 0 { | |
516 printzero <- true | |
517 "1" | |
518 } else: { | |
519 if: printzero {"0"} else: {""} | |
520 }) | |
521 i <- i - 1 | |
522 } | |
523 if: (not: signed?) || bits != 32 { | |
524 str <- str . (if: signed { "i" } else: { "u" }) . bits | |
525 } | |
526 str | |
527 } | |
498 } | 528 } |
499 } | 529 } |
500 | 530 |
501 decimal <- match: Sign . Digits . Suffix where: { | 531 decimal <- match: Sign . Digits . Suffix where: { |
502 Sign <- matchOne: ["-" ""] | 532 Sign <- matchOne: ["-" ""] |
523 } | 553 } |
524 #{ | 554 #{ |
525 litval <- num | 555 litval <- num |
526 signed? <- signed | 556 signed? <- signed |
527 bits <- litbits | 557 bits <- litbits |
528 } | 558 string <- { |
529 } | 559 str <- string: litval |
530 | 560 if: (not: signed?) || bits != 32 { |
531 hex <- match: "0x" . Digits . Suffix where: { | 561 str <- str . (if: signed? {"i"} else: {"u"}) . bits |
562 } | |
563 str | |
564 } | |
565 } | |
566 } | |
567 | |
568 hexlit <- match: "0x" . Digits . Suffix where: { | |
532 Digits <- onePlus: hdigit | 569 Digits <- onePlus: hdigit |
533 Suffix <- matchOne: [ | 570 Suffix <- matchOne: [ |
534 (charClass: "ui") . (matchOne: ["8" "16" "32" "64"]) | 571 (charClass: "ui") . (matchOne: ["8" "16" "32" "64"]) |
535 "" | 572 "" |
536 ] | 573 ] |
548 } | 585 } |
549 #{ | 586 #{ |
550 litval <- num | 587 litval <- num |
551 signed? <- signed | 588 signed? <- signed |
552 bits <- litbits | 589 bits <- litbits |
553 } | 590 string <- { |
591 str <- "0x" . (hex: litval) | |
592 if: (not: signed?) || bits != 32 { | |
593 str <- str . (if: signed? {"i"} else: {"u"}) . bits | |
594 } | |
595 str | |
596 } | |
597 } | |
598 } | |
599 | |
600 symexpr <- match: Name where: { | |
601 Name <- match: (onePlus: (charClass: "a-zA-Z_@!?")) . (zeroPlus: ((matchOne: [":" ""]) . (charClass: "a-zA-Z_@!?0-9"))) | |
602 } yield: { | |
603 #{ | |
604 name <- Name | |
605 string <- { | |
606 name | |
607 } | |
608 } | |
609 } | |
610 | |
611 namepart <- match: hws . Symbol . ":" where: { | |
612 Symbol <- match: symexpr | |
613 } yield: { | |
614 #{ | |
615 isNamePart? <- { true } | |
616 val <- Symbol name | |
617 } | |
618 } | |
619 | |
620 argpart <- matchOne: [ | |
621 match: namepart | |
622 match: Arg where: { | |
623 Arg <- opexpr | |
624 } yield: { | |
625 #{ | |
626 isNamePart? <- { false } | |
627 val <- Arg | |
628 } | |
629 } | |
630 ] | |
631 | |
632 funcall <- match: hws . Initial . Parts where: { | |
633 Initial <- match: namepart | |
634 Parts <- onePlus: argpart | |
635 } yield: { | |
636 Initial | Parts foldr: #{ | |
637 name <- "" | |
638 args <- [] | |
639 } with: :acc el { | |
640 nextName <- acc name | |
641 nextArgs <- acc args | |
642 if: (el isNamePart?) { | |
643 nextName <- if: ((acc name) length) > 0 { (el val) . ":" . (acc name) } else: { el val } | |
644 } else: { | |
645 nextArgs <- (el val) | nextArgs | |
646 } | |
647 | |
648 #{ | |
649 name <- nextName | |
650 args <- nextArgs | |
651 string <- { | |
652 str <- "" | |
653 curArgs <- args | |
654 nameParts <- name splitOn: ":" | |
655 foreach: nameParts :part { | |
656 str <- str . part . ":" | |
657 if: (not: (curArgs empty?)) { | |
658 str <- str . " " . (curArgs value) | |
659 curArgs <- curArgs tail | |
660 } | |
661 } | |
662 str | |
663 } | |
664 } | |
665 } | |
666 } | |
667 | |
668 methcall <- match: Receiver . hws . Rest where: { | |
669 Receiver <- match: opexpr | |
670 Rest <- matchOne: [funcall ( | |
671 match: Name where: { Name <- match: symexpr } yield: { | |
672 #{ | |
673 name <- Name name | |
674 args <- [] | |
675 } | |
676 } | |
677 )] | |
678 } yield: { | |
679 #{ | |
680 receiver <- Receiver | |
681 name <- Rest name | |
682 args <- Rest args | |
683 string <- { | |
684 nameParts <- name splitOn: ":" | |
685 curArgs <- args | |
686 str <- (string: receiver) . " " | |
687 foreach: nameParts :part { | |
688 str <- str . part . ":" | |
689 if: (not: (curArgs empty?)) { | |
690 str <- str . " " . (curArgs value) | |
691 curArgs <- curArgs tail | |
692 } | |
693 } | |
694 str | |
695 } | |
696 } | |
697 } | |
698 | |
699 //TODO: Implement operator expressions | |
700 opexpr <- match: primlitsym | |
701 | |
702 expr <- match: (hws . Expr . ws) where: { | |
703 Expr <- matchOne: [ | |
704 funcall | |
705 methcall | |
706 opexpr | |
707 ] | |
708 } yield: { | |
709 Expr | |
710 } | |
711 | |
712 assignment <- match: ws . Symbol . hws . "<-" . Expr where: { | |
713 Symbol <- match: symexpr | |
714 Expr <- match: expr | |
715 } yield: { | |
716 #{ | |
717 assign <- Expr | |
718 to <- Symbol | |
719 string <- { | |
720 (string: to) . " <- " . assign | |
721 } | |
722 } | |
723 } | |
724 | |
725 object <- match: "#{" . ws . Messages . "}" where: { | |
726 Messages <- zeroPlus: assignment | |
727 } yield: { | |
728 #{ | |
729 messages <- Messages | |
730 string <- { | |
731 "#{\n\t". ((messages map: :el { | |
732 string: el | |
733 }) join: "\n\t") . "\n}" | |
734 } | |
735 } | |
736 } | |
737 | |
738 primlitsym <- match: hws . Lit where: { | |
739 Lit <- matchOne: [ | |
740 hexlit | |
741 binary | |
742 decimal | |
743 symexpr | |
744 object | |
745 ] | |
746 } yield: { | |
747 Lit | |
554 } | 748 } |
555 | 749 |
556 testmatchintlit <- :val matchfun { | 750 testmatchintlit <- :val matchfun { |
557 res <- matchfun: val | 751 res <- matchfun: val |
558 if: (res matched?) { | 752 if: (res matched?) { |
597 } | 791 } |
598 | 792 |
599 testmatchintlit: "345" :s {decimal: s} | 793 testmatchintlit: "345" :s {decimal: s} |
600 testmatchintlit: "-567" :s {decimal: s} | 794 testmatchintlit: "-567" :s {decimal: s} |
601 testmatchintlit: "123u16" :s {decimal: s} | 795 testmatchintlit: "123u16" :s {decimal: s} |
602 testmatchintlit: "0x20" :s {hex: s} | 796 testmatchintlit: "0x20" :s {hexlit: s} |
603 testmatchintlit: "0x42u64" :s {hex: s} | 797 testmatchintlit: "0x42u64" :s {hexlit: s} |
604 testmatchintlit: "0b10101" :s {binary: s} | 798 testmatchintlit: "0b10101" :s {binary: s} |
799 code <- "#{ foo <- 123\n bar <- 0xABC\n baz <- 0b1010\n qux <- fo: 38 shizzle: bam\n}" | |
800 codem <- expr: code | |
801 if: (codem matched?) { | |
802 print: code . "\nmatched with yield:\n" . (codem yield) . "\n" | |
803 } else: { | |
804 print: code . "\ndid not match\n" | |
805 } | |
605 } | 806 } |
606 } | 807 } |