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 }