diff modules/parser.tp @ 209:4b3b57f39f10

Implement zeroPlus macro
author Michael Pavone <pavone@retrodev.com>
date Wed, 27 Nov 2013 23:36:24 -0800
parents a1b4a2bc8d72
children 32080f96c3a0
line wrap: on
line diff
--- a/modules/parser.tp	Fri Nov 22 19:37:25 2013 -0800
+++ b/modules/parser.tp	Wed Nov 27 23:36:24 2013 -0800
@@ -1,4 +1,7 @@
 #{
+	_applyMatch <- :fun tomatch {
+		fun: tomatch
+	}
 	expandClass <- :chars {
 		if: (chars length) > 0 {
 			pos <- 0
@@ -90,20 +93,73 @@
 			print: "uh oh"
 		}
 	}
-	alpha <- charClass: "a-zA-Z"
+
+	zeroPlus <- macro: :matchexpr {
+		funexpr <- false
+		valid <- false
+		matchcall <- if: (matchexpr nodeType) = "lambda" {
+			valid <- true
+			quote: (_applyMatch: matchexpr tomatch)
+		} else: {
+			if: (matchexpr nodeType) = "symbol" {
+				valid <- true
+				quote: (matchexpr: tomatch)
+			}
+		}
+		if: valid {
+			quote: :tomatch {
+				cur <- 0
+				n <- tomatch byte_length
+				orig <- tomatch
+				match <- true
+				while: { match && cur < n } do: {
+					res <- matchcall
+					match <- res matched?
+					if: match {
+						//TODO: Use some kind of lightweight substring wrapper here
+						tomatch <- tomatch from: (res matchlen)
+						cur <- cur + (res matchlen)
+					}
+				}
+				if: cur > 0 {
+					#{
+						matched? <- { true }
+						matchlen <- { cur }
+					}
+				} else: {
+					#{
+						matched? <- { false }
+					}
+				}
+			}
+		} else: {
+			print: "#error Invalid zeroPlus macro call\n"
+		}
+	}
+
+
+	_alpha <- charClass: "a-zA-Z"
+	alpha <- zeroPlus: _alpha
+	alphaNum <- zeroPlus: (charClass: "a-zA-Z0-9")
 
 	main <- {
-		cmatch <- alpha: "c0123"
+		cmatch <- alpha: "czx0123"
 		zeromatch <- alpha: "01234"
 		if: (cmatch matched?) {
-			print: "c0123 matched with length " . (cmatch matchlen) . "\n"
+			print: "czx0123 matched with length " . (cmatch matchlen) . "\n"
 		} else: {
-			print: "c0123 didn't match\n"
+			print: "czx0123 didn't match\n"
 		}
 		if: (zeromatch matched?) {
 			print: "0123 matched with length " . (zeromatch matchlen) . "\n"
 		} else: {
 			print: "0123 didn't match\n"
 		}
+		zeromatchanum <- alphaNum: "01234"
+		if: (zeromatchanum matched?) {
+			print: "01234 matched with length " . (zeromatchanum matchlen) . "\n"
+		} else: {
+			print: "01234 didn't match\n"
+		}
 	}
 }