comparison modules/json.tp @ 154:6e579a75a0a9

Add JSON parser and sample
author Mike Pavone <pavone@retrodev.com>
date Sat, 10 Aug 2013 11:51:47 -0700
parents
children fe816637fcc4
comparison
equal deleted inserted replaced
153:075b1e71feff 154:6e579a75a0a9
1 {
2 startArr <- "[" byte: 0
3 endArr <- "]" byte: 0
4 startObj <- "{" byte: 0
5 endObj <- "}" byte: 0
6 quote <- "\"" byte: 0
7 esc <- "\\" byte: 0
8 zero <- "0" byte: 0
9 nine <- "9" byte: 0
10 neg <- "-" byte: 0
11 space <- " " byte: 0
12 comma <- "," byte: 0
13 tab <- "\t" byte: 0
14 colon <- ":" byte: 0
15
16 parseNumAt <- :str :at :recvResult {
17 num <- 0
18 l <- str length
19 minus <- false
20 aft <- -1
21 while: { at < l } do: {
22 b <- str byte: at
23 if: b = neg {
24 minus <- true
25 } else: {
26 if: b >= zero && b <= nine {
27 num <- num * 10 + (str byte: at) - zero
28 } else: {
29 aft <- at
30 at <- l
31 }
32 }
33 at <- at + 1
34 }
35 if: aft < 0 {
36 aft <- at
37 }
38 if: minus {
39 num <- 0 - num
40 }
41 #{
42 value <- num
43 after <- aft
44 }
45 }
46
47 parseStrAt <- :src :at :recvResult {
48 //TODO: Deal with escaped characters
49 end <- src find: "\"" startingAt: at + 1 else: { src length }
50 #{
51 value <- src from: (at + 1) withLength: (end - at - 1)
52 after <- end + 1
53 }
54 }
55
56 _decode:at <- :text :cur {
57 ret <- false
58 b <- text byte: cur
59 if: b = neg || b >= zero && b <= nine {
60 text parseNumAt: cur
61 } else: {
62 if: b = quote {
63 text parseStrAt: cur
64 } else: {
65 if: b = startArr {
66 len <- text length
67 val <- #[]
68 cur <- cur + 1
69 aft <- -1
70 while: { cur < len } do: {
71 b <- text byte: cur
72 if: b = endArr {
73 aft <- cur + 1
74 cur <- len
75 } else: {
76 if: b = comma || b = space || b = tab {
77 cur <- cur + 1
78 } else: {
79 el <- _decode: text at: cur
80 cur <- el after
81 val append: (el value)
82 }
83 }
84 }
85 #{
86 value <- val
87 after <- aft
88 }
89 } else: {
90 if: b = startObj {
91 len <- text length
92 val <- dict linear
93 cur <- cur + 1
94 aft <- -1
95 expectKey <- true
96 key <- ""
97 while: { cur < len } do: {
98 b <- text byte: cur
99 if: b = comma || b = space || b = tab || b = colon {
100 cur <- cur + 1
101 } else: {
102 if: expectKey {
103 if: b = endObj {
104 aft <- cur + 1
105 cur <- len
106 } else: {
107 kd <- _decode: text at: cur
108 key <- kd value
109 cur <- kd after
110 expectKey <- false
111 }
112 } else: {
113 el <- _decode: text at: cur
114 val set: key (el value)
115 cur <- el after
116 expectKey <- true
117 }
118 }
119 }
120 #{
121 after <- aft
122 value <- val
123 }
124 } else: {
125 #{
126 value <- "foobar"
127 after <- (text length)
128 }
129 }
130 }
131 }
132 }
133 }
134 #{
135 decode <- :text {
136 (_decode: text at: 0) value
137 }
138 }
139 }