# HG changeset patch # User Michael Pavone # Date 1388351281 28800 # Node ID c6e321a538d4984b79a3e6b1745f6fbb12b422b5 # Parent 218b11ec8fa2f86fccf1fd8e65438f6d76966d32 Implemented more of the grammar. Dealt with some name conflicts along the way. diff -r 218b11ec8fa2 -r c6e321a538d4 modules/parser.tp --- a/modules/parser.tp Sun Dec 29 13:07:10 2013 -0800 +++ b/modules/parser.tp Sun Dec 29 13:08:01 2013 -0800 @@ -220,13 +220,13 @@ count <- 0 n <- tomatch byte_length orig <- tomatch - match <- true + _match <- true allBasic? <- true yieldvals <- [] - while: { match && cur < n } do: { + while: { _match && cur < n } do: { res <- mcall - match <- res matched? - if: match { + _match <- res matched? + if: _match { count <- count + 1 //TODO: Use some kind of lightweight substring wrapper here tomatch <- tomatch from: (res matchlen) @@ -301,6 +301,18 @@ } } + match <- macro: :matchexpr { + mc <- _makeMatchCall: matchexpr + if: (mc valid?) { + mcall <- mc matchcall + quote: :tomatch { + mcall + } + } else: { + print: "#error Invalid macth macro call: " . (mc message) . "\n" + } + } + match:yield <- macro: :matchexpr :ylambda { mc <- _makeMatchCall: matchexpr if: (mc valid?) { @@ -495,6 +507,24 @@ litval <- num signed? <- signed bits <- litbits + string <- { + str <- "0b" + i <- bits - 1 + printzero <- false + while: { i >= 0 } do: { + str <- str . (if: (lshift: 1 by: i) and num > 0 { + printzero <- true + "1" + } else: { + if: printzero {"0"} else: {""} + }) + i <- i - 1 + } + if: (not: signed?) || bits != 32 { + str <- str . (if: signed { "i" } else: { "u" }) . bits + } + str + } } } @@ -525,10 +555,17 @@ litval <- num signed? <- signed bits <- litbits + string <- { + str <- string: litval + if: (not: signed?) || bits != 32 { + str <- str . (if: signed? {"i"} else: {"u"}) . bits + } + str + } } } - hex <- match: "0x" . Digits . Suffix where: { + hexlit <- match: "0x" . Digits . Suffix where: { Digits <- onePlus: hdigit Suffix <- matchOne: [ (charClass: "ui") . (matchOne: ["8" "16" "32" "64"]) @@ -550,9 +587,166 @@ litval <- num signed? <- signed bits <- litbits + string <- { + str <- "0x" . (hex: litval) + if: (not: signed?) || bits != 32 { + str <- str . (if: signed? {"i"} else: {"u"}) . bits + } + str + } } } + symexpr <- match: Name where: { + Name <- match: (onePlus: (charClass: "a-zA-Z_@!?")) . (zeroPlus: ((matchOne: [":" ""]) . (charClass: "a-zA-Z_@!?0-9"))) + } yield: { + #{ + name <- Name + string <- { + name + } + } + } + + namepart <- match: hws . Symbol . ":" where: { + Symbol <- match: symexpr + } yield: { + #{ + isNamePart? <- { true } + val <- Symbol name + } + } + + argpart <- matchOne: [ + match: namepart + match: Arg where: { + Arg <- opexpr + } yield: { + #{ + isNamePart? <- { false } + val <- Arg + } + } + ] + + funcall <- match: hws . Initial . Parts where: { + Initial <- match: namepart + Parts <- onePlus: argpart + } yield: { + Initial | Parts foldr: #{ + name <- "" + args <- [] + } with: :acc el { + nextName <- acc name + nextArgs <- acc args + if: (el isNamePart?) { + nextName <- if: ((acc name) length) > 0 { (el val) . ":" . (acc name) } else: { el val } + } else: { + nextArgs <- (el val) | nextArgs + } + + #{ + name <- nextName + args <- nextArgs + string <- { + str <- "" + curArgs <- args + nameParts <- name splitOn: ":" + foreach: nameParts :part { + str <- str . part . ":" + if: (not: (curArgs empty?)) { + str <- str . " " . (curArgs value) + curArgs <- curArgs tail + } + } + str + } + } + } + } + + methcall <- match: Receiver . hws . Rest where: { + Receiver <- match: opexpr + Rest <- matchOne: [funcall ( + match: Name where: { Name <- match: symexpr } yield: { + #{ + name <- Name name + args <- [] + } + } + )] + } yield: { + #{ + receiver <- Receiver + name <- Rest name + args <- Rest args + string <- { + nameParts <- name splitOn: ":" + curArgs <- args + str <- (string: receiver) . " " + foreach: nameParts :part { + str <- str . part . ":" + if: (not: (curArgs empty?)) { + str <- str . " " . (curArgs value) + curArgs <- curArgs tail + } + } + str + } + } + } + + //TODO: Implement operator expressions + opexpr <- match: primlitsym + + expr <- match: (hws . Expr . ws) where: { + Expr <- matchOne: [ + funcall + methcall + opexpr + ] + } yield: { + Expr + } + + assignment <- match: ws . Symbol . hws . "<-" . Expr where: { + Symbol <- match: symexpr + Expr <- match: expr + } yield: { + #{ + assign <- Expr + to <- Symbol + string <- { + (string: to) . " <- " . assign + } + } + } + + object <- match: "#{" . ws . Messages . "}" where: { + Messages <- zeroPlus: assignment + } yield: { + #{ + messages <- Messages + string <- { + "#{\n\t". ((messages map: :el { + string: el + }) join: "\n\t") . "\n}" + } + } + } + + primlitsym <- match: hws . Lit where: { + Lit <- matchOne: [ + hexlit + binary + decimal + symexpr + object + ] + } yield: { + Lit + } + testmatchintlit <- :val matchfun { res <- matchfun: val if: (res matched?) { @@ -599,8 +793,15 @@ testmatchintlit: "345" :s {decimal: s} testmatchintlit: "-567" :s {decimal: s} testmatchintlit: "123u16" :s {decimal: s} - testmatchintlit: "0x20" :s {hex: s} - testmatchintlit: "0x42u64" :s {hex: s} + testmatchintlit: "0x20" :s {hexlit: s} + testmatchintlit: "0x42u64" :s {hexlit: s} testmatchintlit: "0b10101" :s {binary: s} + code <- "#{ foo <- 123\n bar <- 0xABC\n baz <- 0b1010\n qux <- fo: 38 shizzle: bam\n}" + codem <- expr: code + if: (codem matched?) { + print: code . "\nmatched with yield:\n" . (codem yield) . "\n" + } else: { + print: code . "\ndid not match\n" + } } }