Mercurial > repos > tabletprog
comparison modules/parser.tp @ 218:b799192e404b
Implemented match:where:yield and fixed a bug in zeroPlus
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 21 Dec 2013 12:08:06 -0800 |
parents | e00a8bc6361b |
children | a1a80af71b05 |
comparison
equal
deleted
inserted
replaced
217:adad61ea2f3a | 218:b799192e404b |
---|---|
143 pos <- pos + 1 | 143 pos <- pos + 1 |
144 } | 144 } |
145 if: inverted { | 145 if: inverted { |
146 old <- out | 146 old <- out |
147 out <- "" | 147 out <- "" |
148 cur <- 0 | 148 //skip control characters for now |
149 cur <- 32 | |
149 while: { cur < 256 } do: { | 150 while: { cur < 256 } do: { |
150 notfound <- true | 151 notfound <- true |
151 idx <- 0 | 152 idx <- 0 |
152 len <- (old length) | 153 len <- (old length) |
153 while: { notfound && idx < len } do: { | 154 while: { notfound && idx < len } do: { |
227 //TODO: Use some kind of lightweight substring wrapper here | 228 //TODO: Use some kind of lightweight substring wrapper here |
228 tomatch <- tomatch from: (res matchlen) | 229 tomatch <- tomatch from: (res matchlen) |
229 if: allBasic? { | 230 if: allBasic? { |
230 ifnot: (res basicYield?) { | 231 ifnot: (res basicYield?) { |
231 allBasic? <- false | 232 allBasic? <- false |
232 yieldvals <- (orig from: 0 withLength: cur) | yieldvals | 233 if: cur > 0 { |
234 yieldvals <- (orig from: 0 withLength: cur) | yieldvals | |
235 } | |
236 yieldvals <- (res yield) | yieldvals | |
233 } | 237 } |
234 } else: { | 238 } else: { |
235 yieldvals <- (res yield) | yieldvals | 239 yieldvals <- (res yield) | yieldvals |
236 } | 240 } |
237 allBasic? <- allBasic? && (res basicYield?) | 241 allBasic? <- allBasic? && (res basicYield?) |
303 res | 307 res |
304 } | 308 } |
305 } | 309 } |
306 } else: { | 310 } else: { |
307 print: "#error Invalid macth:yield macro call: " . (mc message) . "\n" | 311 print: "#error Invalid macth:yield macro call: " . (mc message) . "\n" |
312 } | |
313 } | |
314 | |
315 match:where:yield <- macro: :matchexpr :whereclause :ylambda { | |
316 syms <- [] | |
317 withwhere <- (whereclause expressions) fold: (quote: :tomatch {}) with: :acc el { | |
318 | |
319 if: (el nodeType) = "assignment" { | |
320 valassign <- quote: (val <- false) | |
321 valsym <- (valassign) symbol | |
322 valsym <- valsym name!: (valsym name) . ((el symbol) name) | |
323 valassign <- valassign symbol!: valsym | |
324 acc addExpression: valassign | |
325 | |
326 matchassign <- quote: (hasmatch <- false) | |
327 matchsym <- (matchassign) symbol | |
328 matchsym <- matchsym name!: (matchsym name) . ((el symbol) name) | |
329 matchassign <- matchassign symbol!: matchsym | |
330 acc addExpression: matchassign | |
331 | |
332 mc <- _makeMatchCall: (el expression) | |
333 | |
334 if: (mc valid?) { | |
335 mcall <- mc matchcall | |
336 matchfun <- quote: :tomatch { | |
337 if: matchsym { | |
338 if: valsym = tomatch { | |
339 #{ | |
340 matched? <- { true } | |
341 matchlen <- { valsym length } | |
342 basicYield? <- { true } //TODO: Check if this is correct | |
343 yield <- { valsym } | |
344 } | |
345 } else: { | |
346 #{ | |
347 matched? <- { false } | |
348 } | |
349 } | |
350 } else: { | |
351 mr <- mcall | |
352 if: (mr matched?) { | |
353 matchsym <- true | |
354 valsym <- (mr yield) | |
355 } | |
356 mr | |
357 } | |
358 } | |
359 acc <- acc addExpression: (el expression!: matchfun) | |
360 syms <- list node: #{ | |
361 orig <- el symbol | |
362 matchval <- valsym | |
363 } withTail: syms | |
364 acc | |
365 } else: { | |
366 print: "#error " . ((el symbol) name) . " does not have a valid match expression: " . (mc message) . "\n" | |
367 } | |
368 | |
369 } else: { | |
370 print: "#error Nodes of type " . (el nodeType) . " are not allowed in match where clauses\n" | |
371 acc | |
372 } | |
373 } | |
374 mcMain <- _makeMatchCall: matchexpr | |
375 if: (mcMain valid?) { | |
376 mcall <- mcMain matchcall | |
377 withwhere addExpression: (quote: (matchres <- mcall)) | |
378 successLambda <- quote: { | |
379 //Extra assignments will be added here | |
380 mlen <- matchres matchlen | |
381 #{ | |
382 matched? <- { true } | |
383 matchlen <- { mlen } | |
384 basicYield? <- { false } | |
385 yield <- ylambda | |
386 } | |
387 } | |
388 sucexp <- syms fold: (successLambda expressions) with: :acc el { | |
389 lsym <- el orig | |
390 rsym <- el matchval | |
391 (quote: (lsym <- rsym)) | acc | |
392 } | |
393 successLambda <- successLambda expressions!: sucexp | |
394 withwhere addExpression: (quote: (if: (matchres matched?) successLambda else: { | |
395 matchres | |
396 })) | |
397 withwhere | |
398 } else: { | |
399 print: "#error Error in main match expression of match:where:yield: " . (mcMain message) . "\n" | |
308 } | 400 } |
309 } | 401 } |
310 | 402 |
311 | 403 |
312 _alpha <- charClass: "a-zA-Z" | 404 _alpha <- charClass: "a-zA-Z" |
328 (match: "7" yield: {7}) | 420 (match: "7" yield: {7}) |
329 (match: "8" yield: {8}) | 421 (match: "8" yield: {8}) |
330 (match: "9" yield: {9}) | 422 (match: "9" yield: {9}) |
331 ] | 423 ] |
332 | 424 |
425 posint <- match: Digits where: { | |
426 Digits <- zeroPlus: digit | |
427 } yield: { | |
428 num <- Digits fold: 0 with: :acc el { | |
429 print: "Element " . el . "\n" | |
430 acc * 10 + el | |
431 } | |
432 #{ | |
433 litval <- num | |
434 } | |
435 } | |
436 | |
333 main <- { | 437 main <- { |
334 cmatch <- alpha: "czx0123" | 438 cmatch <- alpha: "czx0123" |
335 zeromatch <- alpha: "01234" | 439 zeromatch <- alpha: "01234" |
336 if: (cmatch matched?) { | 440 if: (cmatch matched?) { |
337 print: "czx0123 matched with length " . (cmatch matchlen) . "\n" | 441 print: "czx0123 matched with length " . (cmatch matchlen) . "\n" |
360 if: (tmatch matched?) { | 464 if: (tmatch matched?) { |
361 print: "3 matched with yield " . (tmatch yield) . ", yield + 1 = " . ((tmatch yield) + 1) . "\n" | 465 print: "3 matched with yield " . (tmatch yield) . ", yield + 1 = " . ((tmatch yield) + 1) . "\n" |
362 } else: { | 466 } else: { |
363 print: "3 did not match\n" | 467 print: "3 did not match\n" |
364 } | 468 } |
469 | |
470 posintm <- posint: "345" | |
471 if: (posintm matched?) { | |
472 print: "345 matched with intlit value " . ((posintm yield) litval) . "\n" | |
473 } else: { | |
474 print: "345 did not match\n" | |
475 } | |
365 } | 476 } |
366 } | 477 } |