changeset 256:03a07e540b9f

Memoize results of match:where:yield and matchOne: macros. Fix opsym rule to use the symbol ast node.
author Michael Pavone <pavone@retrodev.com>
date Sun, 01 Jun 2014 00:14:36 -0700
parents 08081b0a9382
children be224817a14b
files modules/parser.tp
diffstat 1 files changed, 60 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/modules/parser.tp	Sat May 31 22:51:00 2014 -0700
+++ b/modules/parser.tp	Sun Jun 01 00:14:36 2014 -0700
@@ -1,7 +1,39 @@
 {
+	_matchid <- 0
+	getMatchId <- {
+		id <- _matchid
+		_matchid <- _matchid + 1
+		id
+	}
+	matchMemo <- {
+		_posdata <- #[]
+		_checkInitData <- :len {
+			len <- len + 1
+			while: { (_posdata length) < len } do: {
+				_posdata append: (dict hash)
+			}
+		}
+		#{
+			memo:at:withId:length <- :val :at :id :len {
+				_checkInitData: len
+				(_posdata get: at) set: id val
+				self
+			}
+			
+			getMemo:at:else <- :id :at :else {
+				if: (_posdata length) > at {
+					(_posdata get: at) ifget: id :val {
+						val
+					} else: else
+				} else: else
+			}
+		}
+	}
 light:from:withLength <- :_base :_start :_len {
+	_matchmemo <- matchMemo:
 	if: (not: (_base isBasicString?)) {
 		_start <- _start + (_base start)
+		_matchmemo <- _base memoData
 		_base <- _base base
 	}
 	_needsflat? <- true
@@ -53,6 +85,16 @@
 		isBasicString? <- { false }
 		base <- { _base }
 		start <- { _start }
+		memoData <- { _matchmemo }
+		
+		memo:at:withId <- :val :at :id {
+			_matchmemo memo: val at: (at + _start) withId: id length: (_base length)
+			self
+		}
+		
+		getMemo:at:else <- :id :at :else {
+			_matchmemo getMemo: id at: (at + _start) else: else
+		}
 	}
 }
 
@@ -371,6 +413,7 @@
 	}
 
 	matchOne <- macro: :options {
+		myid <- getMatchId:
 		options <- (options value) map: :option {
 			_makeMatchCall: option
 		}
@@ -384,7 +427,12 @@
 			}
 		}
 		quote: :tomatch {
-			body
+			tomatch <- light: tomatch from: 0
+			tomatch getMemo: myid at: 0 else: {
+				ret <- body
+				tomatch memo: ret at: 0 withId: myid
+				ret
+			}
 		}
 	}
 
@@ -431,8 +479,9 @@
 	}
 
 	match:where:yield <- macro: :matchexpr :whereclause :ylambda {
+		myid <- getMatchId:
 		syms <- []
-		withwhere <- (whereclause expressions) fold: (quote: :tomatch {}) with: :acc el {
+		withwhere <- (whereclause expressions) fold: (quote: {}) with: :acc el {
 
 			if: (el nodeType) = "assignment" {
 				valassign <- quote: (val <- false)
@@ -523,10 +572,16 @@
 				(quote: (lsym <- rsym)) | acc
 			}
 			successLambda <- successLambda expressions!: sucexp
-			withwhere addExpression: (quote: (if: matchres successLambda else: {
+			withwhere addExpression: (quote: (ret <- if: matchres successLambda else: {
 				matchres
 			}))
-			withwhere
+			withwhere addExpression: (quote: (tomatch memo: ret at: 0 withId: myid))
+			withwhere addExpression: (quote: ret)
+			
+			quote: :tomatch {
+				tomatch <- light: tomatch from: 0
+				tomatch getMemo: myid at: 0 else: withwhere
+			}
 		} else: {
 			print: "#error Error in main match expression of match:where:yield: " . (mcMain message) . "\n"
 		}
@@ -797,12 +852,7 @@
 	opsym <- match: Name where: {
 		Name <- matchOne: ["&&" "||" "<=" ">=" "<" ">" "=" "!=" "=" "-" "." "*" "/" "%" "|"]
 	} yield: {
-		#{
-			name <- Name
-			string <- {
-				name
-			}
-		}
+		ast symbol: Name
 	}
 
 	assignment <- match: ws . Symbol . hws . "<-" . Expr where: {