diff modules/parser.tp @ 208:a1b4a2bc8d72

Initial work on pattern match macrosfor the new parser
author Mike Pavone <pavone@retrodev.com>
date Fri, 22 Nov 2013 19:37:25 -0800
parents
children 4b3b57f39f10
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/parser.tp	Fri Nov 22 19:37:25 2013 -0800
@@ -0,0 +1,109 @@
+#{
+	expandClass <- :chars {
+		if: (chars length) > 0 {
+			pos <- 0
+			inverted <- false
+			if: (chars byte: 0) = ("^" byte: 0) {
+				pos <- 1
+				inverted <- true
+			}
+			state_begin <- 0
+			state_normal <- 1
+			state_rangeend <- 2
+			state <- state_begin
+			out <- ""
+			while: { pos < (chars byte_length)} do: {
+				if: state = state_begin {
+					out <- out . (chars from: pos withLength: 1)
+					state <- state_normal
+				} else: {
+					if: state = state_normal {
+						if: (chars byte: pos) = ("-" byte: 0) {
+							state <- state_rangeend
+						} else: {
+							out <- out . (chars from: pos withLength: 1)
+						}
+					} else: {
+						rangestart <- out byte: ((out byte_length) - 1)
+						rangeend <- chars byte: pos
+						if: rangeend < rangestart {
+							tmp <- rangeend
+							rangeend <- rangestart
+							rangestart <- tmp
+						}
+						out <- out from: 0 withLength: ((out length) - 1)
+						while: { rangestart <= rangeend } do: {
+							out <- out . (rangestart asStringChar)
+							rangestart <- rangestart + 1
+						}
+						state <- state_begin
+					}
+				}
+				pos <- pos + 1
+			}
+			if: inverted {
+				old <- out
+				out <- ""
+				cur <- 0
+				while: { cur < 256 } do: {
+					out <- out . (cur asStringChar)
+					cur <- cur + 1
+				}
+			}
+			out
+		} else: {
+			""
+		}
+	}
+	charClass <- macro: :rawchars {
+		eval: rawchars :chars {
+			chars <- expandClass: chars
+			//TODO: Use a more sophisticated approach for large classes
+			quote: :tomatch {
+				if: (tomatch isString?) {
+					check <- 0
+
+					nomatch <- true
+					while: { nomatch && check < (chars byte_length) } do: {
+						if: (tomatch byte: 0) = (chars byte: check) {
+							nomatch <- false
+						}
+						check <- check + 1
+					}
+					if: nomatch {
+						#{
+							matched? <- { false }
+						}
+					} else: {
+						#{
+							matched? <- { true }
+							matchlen <- { 1 }
+						}
+					}
+				} else: {
+					#{
+						matched? <- { false }
+					}
+				}
+			}
+		} else: {
+			print: "uh oh"
+		}
+	}
+	alpha <- charClass: "a-zA-Z"
+
+	main <- {
+		cmatch <- alpha: "c0123"
+		zeromatch <- alpha: "01234"
+		if: (cmatch matched?) {
+			print: "c0123 matched with length " . (cmatch matchlen) . "\n"
+		} else: {
+			print: "c0123 didn't match\n"
+		}
+		if: (zeromatch matched?) {
+			print: "0123 matched with length " . (zeromatch matchlen) . "\n"
+		} else: {
+			print: "0123 didn't match\n"
+		}
+	}
+}