view 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 source

#{
	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"
		}
	}
}