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 }