Mercurial > repos > tabletprog
comparison modules/parser.tp @ 213:e00a8bc6361b
Implement match:yield macro
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 02 Dec 2013 00:50:16 -0800 |
parents | 32080f96c3a0 |
children | b799192e404b |
comparison
equal
deleted
inserted
replaced
212:32080f96c3a0 | 213:e00a8bc6361b |
---|---|
14 } | 14 } |
15 if: str = tomatch { | 15 if: str = tomatch { |
16 #{ | 16 #{ |
17 matched? <- { true } | 17 matched? <- { true } |
18 matchlen <- { str length } | 18 matchlen <- { str length } |
19 basicYield? <- { true } | |
20 yield <- { str } | |
19 } | 21 } |
20 } else: { | 22 } else: { |
21 #{ | 23 #{ |
22 matched? <- { false } | 24 matched? <- { false } |
23 } | 25 } |
69 if: (rm matched?) { | 71 if: (rm matched?) { |
70 total <- (rm matchlen) + (lm matchlen) | 72 total <- (rm matchlen) + (lm matchlen) |
71 #{ | 73 #{ |
72 matched? <- { true } | 74 matched? <- { true } |
73 matchlen <- { total } | 75 matchlen <- { total } |
76 basicYield? <- { true } | |
77 yield <- { tomatch from: 0 withLen: total } | |
74 } | 78 } |
75 } else: { | 79 } else: { |
76 rm | 80 rm |
77 } | 81 } |
78 } else: { | 82 } else: { |
186 } | 190 } |
187 } else: { | 191 } else: { |
188 #{ | 192 #{ |
189 matched? <- { true } | 193 matched? <- { true } |
190 matchlen <- { 1 } | 194 matchlen <- { 1 } |
195 basicYield? <- { true } | |
196 yield <- { tomatch from: 0 withLength: 1 } | |
191 } | 197 } |
192 } | 198 } |
193 } else: { | 199 } else: { |
194 #{ | 200 #{ |
195 matched? <- { false } | 201 matched? <- { false } |
210 quote: :tomatch { | 216 quote: :tomatch { |
211 cur <- 0 | 217 cur <- 0 |
212 n <- tomatch byte_length | 218 n <- tomatch byte_length |
213 orig <- tomatch | 219 orig <- tomatch |
214 match <- true | 220 match <- true |
221 allBasic? <- true | |
222 yieldvals <- [] | |
215 while: { match && cur < n } do: { | 223 while: { match && cur < n } do: { |
216 res <- mcall | 224 res <- mcall |
217 match <- res matched? | 225 match <- res matched? |
218 if: match { | 226 if: match { |
219 //TODO: Use some kind of lightweight substring wrapper here | 227 //TODO: Use some kind of lightweight substring wrapper here |
220 tomatch <- tomatch from: (res matchlen) | 228 tomatch <- tomatch from: (res matchlen) |
229 if: allBasic? { | |
230 ifnot: (res basicYield?) { | |
231 allBasic? <- false | |
232 yieldvals <- (orig from: 0 withLength: cur) | yieldvals | |
233 } | |
234 } else: { | |
235 yieldvals <- (res yield) | yieldvals | |
236 } | |
237 allBasic? <- allBasic? && (res basicYield?) | |
221 cur <- cur + (res matchlen) | 238 cur <- cur + (res matchlen) |
222 } | 239 } |
223 } | 240 } |
224 if: cur > 0 { | 241 if: cur > 0 { |
225 #{ | 242 if: allBasic? { |
226 matched? <- { true } | 243 #{ |
227 matchlen <- { cur } | 244 matched? <- { true } |
245 matchlen <- { cur } | |
246 basicYield? <- { true } | |
247 yield <- { orig from: 0 withLength: cur } | |
248 } | |
249 } else: { | |
250 yieldvals <- yieldvals reverse | |
251 #{ | |
252 matched? <- { true } | |
253 matchlen <- { cur } | |
254 basicYield? <- { false } | |
255 yield <- { yieldvals } | |
256 } | |
228 } | 257 } |
229 } else: { | 258 } else: { |
230 #{ | 259 #{ |
231 matched? <- { false } | 260 matched? <- { false } |
232 } | 261 } |
255 quote: :tomatch { | 284 quote: :tomatch { |
256 body | 285 body |
257 } | 286 } |
258 } | 287 } |
259 | 288 |
289 match:yield <- macro: :matchexpr :ylambda { | |
290 mc <- _makeMatchCall: matchexpr | |
291 if: (mc valid?) { | |
292 mcall <- mc matchcall | |
293 quote: :tomatch { | |
294 res <- mcall | |
295 if: (res matched?) { | |
296 #{ | |
297 matched? <- { true } | |
298 matchlen <- { res matchlen } | |
299 basicYield? <- { false } | |
300 yield <- ylambda | |
301 } | |
302 } else: { | |
303 res | |
304 } | |
305 } | |
306 } else: { | |
307 print: "#error Invalid macth:yield macro call: " . (mc message) . "\n" | |
308 } | |
309 } | |
310 | |
260 | 311 |
261 _alpha <- charClass: "a-zA-Z" | 312 _alpha <- charClass: "a-zA-Z" |
262 alpha <- zeroPlus: _alpha | 313 alpha <- zeroPlus: _alpha |
263 alphaNum <- zeroPlus: (charClass: "a-zA-Z0-9") | 314 alphaNum <- zeroPlus: (charClass: "a-zA-Z0-9") |
264 hws <- zeroPlus: (matchOne: [ | 315 hws <- zeroPlus: (matchOne: [ |
265 (charClass: " \t") | 316 (charClass: " \t") |
266 "/*" . (zeroPlus: (matchOne: [(charClass: "^*") "*" . (charClass: "^/")])) . "*/" | 317 "/*" . (zeroPlus: (matchOne: [(charClass: "^*") "*" . (charClass: "^/")])) . "*/" |
267 ]) | 318 ]) |
268 | 319 |
320 digit <- matchOne: [ | |
321 (match: "0" yield: {0}) | |
322 (match: "1" yield: {1}) | |
323 (match: "2" yield: {2}) | |
324 (match: "3" yield: {3}) | |
325 (match: "4" yield: {4}) | |
326 (match: "5" yield: {5}) | |
327 (match: "6" yield: {6}) | |
328 (match: "7" yield: {7}) | |
329 (match: "8" yield: {8}) | |
330 (match: "9" yield: {9}) | |
331 ] | |
269 | 332 |
270 main <- { | 333 main <- { |
271 cmatch <- alpha: "czx0123" | 334 cmatch <- alpha: "czx0123" |
272 zeromatch <- alpha: "01234" | 335 zeromatch <- alpha: "01234" |
273 if: (cmatch matched?) { | 336 if: (cmatch matched?) { |
291 if: (hwsmatch matched?) { | 354 if: (hwsmatch matched?) { |
292 print: "'" . (stuff from: (hwsmatch matchlen)) . "' found after hws\n" | 355 print: "'" . (stuff from: (hwsmatch matchlen)) . "' found after hws\n" |
293 } else: { | 356 } else: { |
294 print: stuff . " did not match hws rule\n" | 357 print: stuff . " did not match hws rule\n" |
295 } | 358 } |
359 tmatch <- digit: "3" | |
360 if: (tmatch matched?) { | |
361 print: "3 matched with yield " . (tmatch yield) . ", yield + 1 = " . ((tmatch yield) + 1) . "\n" | |
362 } else: { | |
363 print: "3 did not match\n" | |
364 } | |
296 } | 365 } |
297 } | 366 } |