changeset 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 218b11ec8fa2
children 25db1c7c7300
files modules/parser.tp
diffstat 1 files changed, 208 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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"
+		}
 	}
 }