# HG changeset patch # User Mike Pavone # Date 1376160707 25200 # Node ID 6e579a75a0a94fa078c5efe8ffee4162913dd0e9 # Parent 075b1e71feff37013b13ab9f35b1c437a9d29bfd Add JSON parser and sample diff -r 075b1e71feff -r 6e579a75a0a9 modules/json.tp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/json.tp Sat Aug 10 11:51:47 2013 -0700 @@ -0,0 +1,139 @@ +{ + startArr <- "[" byte: 0 + endArr <- "]" byte: 0 + startObj <- "{" byte: 0 + endObj <- "}" byte: 0 + quote <- "\"" byte: 0 + esc <- "\\" byte: 0 + zero <- "0" byte: 0 + nine <- "9" byte: 0 + neg <- "-" byte: 0 + space <- " " byte: 0 + comma <- "," byte: 0 + tab <- "\t" byte: 0 + colon <- ":" byte: 0 + + parseNumAt <- :str :at :recvResult { + num <- 0 + l <- str length + minus <- false + aft <- -1 + while: { at < l } do: { + b <- str byte: at + if: b = neg { + minus <- true + } else: { + if: b >= zero && b <= nine { + num <- num * 10 + (str byte: at) - zero + } else: { + aft <- at + at <- l + } + } + at <- at + 1 + } + if: aft < 0 { + aft <- at + } + if: minus { + num <- 0 - num + } + #{ + value <- num + after <- aft + } + } + + parseStrAt <- :src :at :recvResult { + //TODO: Deal with escaped characters + end <- src find: "\"" startingAt: at + 1 else: { src length } + #{ + value <- src from: (at + 1) withLength: (end - at - 1) + after <- end + 1 + } + } + + _decode:at <- :text :cur { + ret <- false + b <- text byte: cur + if: b = neg || b >= zero && b <= nine { + text parseNumAt: cur + } else: { + if: b = quote { + text parseStrAt: cur + } else: { + if: b = startArr { + len <- text length + val <- #[] + cur <- cur + 1 + aft <- -1 + while: { cur < len } do: { + b <- text byte: cur + if: b = endArr { + aft <- cur + 1 + cur <- len + } else: { + if: b = comma || b = space || b = tab { + cur <- cur + 1 + } else: { + el <- _decode: text at: cur + cur <- el after + val append: (el value) + } + } + } + #{ + value <- val + after <- aft + } + } else: { + if: b = startObj { + len <- text length + val <- dict linear + cur <- cur + 1 + aft <- -1 + expectKey <- true + key <- "" + while: { cur < len } do: { + b <- text byte: cur + if: b = comma || b = space || b = tab || b = colon { + cur <- cur + 1 + } else: { + if: expectKey { + if: b = endObj { + aft <- cur + 1 + cur <- len + } else: { + kd <- _decode: text at: cur + key <- kd value + cur <- kd after + expectKey <- false + } + } else: { + el <- _decode: text at: cur + val set: key (el value) + cur <- el after + expectKey <- true + } + } + } + #{ + after <- aft + value <- val + } + } else: { + #{ + value <- "foobar" + after <- (text length) + } + } + } + } + } + } + #{ + decode <- :text { + (_decode: text at: 0) value + } + } +} diff -r 075b1e71feff -r 6e579a75a0a9 modules/string.tp --- a/modules/string.tp Fri Aug 09 21:01:11 2013 -0700 +++ b/modules/string.tp Sat Aug 10 11:51:47 2013 -0700 @@ -94,16 +94,17 @@ intret } - llMessage: find:else withVars: { + llMessage: find:startingAt:else withVars: { intret <- obj_int32 ptr oneedle <- object ptr + startpos <- obj_int32 ptr ifNotFound <- object ptr sneedle <- string ptr i <- uint32_t notFound <- uint32_t - } andCode: :oneedle :ifNotFound { + } andCode: :oneedle :startpos :ifNotFound { sneedle <- mcall: string 1 oneedle - i <- 0 + i <- startpos num notFound <- 1 while: { notFound && i + (sneedle bytes) <= bytes} do: { if: (memcmp: data + i (sneedle data) (sneedle bytes)) = 0 { @@ -121,6 +122,10 @@ } } + find:else <- :toFind :orElse { + find: toFind startingAt: 0 else: orElse + } + llMessage: from:withLength withVars: { from <- obj_int32 ptr tocopy <- obj_int32 ptr @@ -183,4 +188,5 @@ } isInteger? <- { false } + isString? <- { true } } diff -r 075b1e71feff -r 6e579a75a0a9 samples/json.tp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/json.tp Sat Aug 10 11:51:47 2013 -0700 @@ -0,0 +1,12 @@ +#{ + main <- { + arr <- json decode: "[\"foo\", \"bar\", 13245, \"baz\" ]" + foreach: arr :idx val { + print: (string: idx) . ": " . (string: val) . "\n" + } + obj <- json decode: "{\"foo\": \"bar\", \"baz\": \"qux\", \"meaningOfLife\": 42 }" + foreach: obj :idx val { + print: (string: idx) . ": " . (string: val) . "\n" + } + } +}