changeset 367:e2c1309ab750

Use dict hash instead of dict linear in JSON parser. Implement basic string escapes in JSON parser.
author Michael Pavone <pavone@retrodev.com>
date Sun, 09 Aug 2015 18:07:23 -0700
parents 810b6115c1d4
children 0673ccbc7379
files modules/json.tp
diffstat 1 files changed, 43 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/modules/json.tp	Sat Aug 08 21:13:26 2015 -0700
+++ b/modules/json.tp	Sun Aug 09 18:07:23 2015 -0700
@@ -57,11 +57,49 @@
 	}
 
 	parseStrAt <- :src at {
-		//TODO: Deal with escaped characters
-		end <- src find: "\"" startingAt: at + 1 else: { src length }
+		//TODO: Deal with unicode escapes
+		bslash <- "\\" byte: 0
+		quote <- "\"" byte: 0
+		escapes <- dict hash
+		escapes set: bslash "\\"
+		escapes set: quote "\""
+		escapes set: ("n" byte: 0) "\n"
+		escapes set: ("t" byte: 0) "\t"
+		escapes set: ("r" byte: 0) "\r"
+		i <- at + 1
+		chunks <- #[]
+		start <- i
+		continue <- true
+		while: { continue && i < (src byte_length) } do: {
+			b <- src byte: i
+			if: b = bslash {
+				if: i > start {
+					chunks append: (src from: start withLength: i-start)
+				}
+				if: i + 1 < (src byte_length) {
+					i <- i + 1
+					b <- src byte: i
+					start <- i + 1
+					escapes ifget: b :v {
+						chunks append: v
+					} else: {
+						//not a recognized escape, just copy it raw
+						chunks append: (src from: i-1 withLength: 2)
+					}
+				}
+			} else: {
+				if: b = quote {
+					if: i > start {
+						chunks append: (src from: start withLength: i-start)
+					}
+					continue <- false
+				}
+			}
+			i <- i + 1
+		}
 		#{
-			value <- src from: (at + 1) withLength: (end - at - 1)
-			after <- end + 1
+			value <- chunks join: ""
+			after <- i
 		}
 	}
 
@@ -101,7 +139,7 @@
 				} else: {
 					if: b = startObj {
 						len <- text length
-						val <- dict linear
+						val <- dict hash
 						cur <- cur + 1
 						aft <- -1
 						expectKey <- true