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 }