Mercurial > repos > tabletprog
comparison modules/parser.tp @ 242:0e7982adc76b
Make the successful return value from a match expression be truthy and the failure value false. This avoids an extra method call when checking the result and avoids allocating a new object when a match fails.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 05 Jan 2014 20:56:25 -0800 |
parents | 6aab8a5a2be9 |
children | 5b830147c1cd |
comparison
equal
deleted
inserted
replaced
241:c50f77de41d1 | 242:0e7982adc76b |
---|---|
3 fun: tomatch | 3 fun: tomatch |
4 } | 4 } |
5 _matchString <- :str tomatch { | 5 _matchString <- :str tomatch { |
6 if: (tomatch isString?) { | 6 if: (tomatch isString?) { |
7 if: (tomatch length) < (str length) { | 7 if: (tomatch length) < (str length) { |
8 #{ | 8 false |
9 matched? <- { false } | |
10 } | |
11 } else: { | 9 } else: { |
12 if: (tomatch length) > (str length) { | 10 if: (tomatch length) > (str length) { |
13 tomatch <- tomatch from: 0 withLength: (str length) | 11 tomatch <- tomatch from: 0 withLength: (str length) |
14 } | 12 } |
15 if: str = tomatch { | 13 if: str = tomatch { |
16 #{ | 14 #{ |
17 matched? <- { true } | 15 if <- :self trueblock { |
16 trueblock: | |
17 } | |
18 ifnot <- :self falseblock { | |
19 self | |
20 } | |
21 if:else <- :self trueblock :elseblock { | |
22 trueblock: | |
23 } | |
18 matchlen <- { str length } | 24 matchlen <- { str length } |
19 basicYield? <- { true } | 25 basicYield? <- { true } |
20 yield <- { str } | 26 yield <- { str } |
21 } | 27 } |
22 } else: { | 28 } else: { |
23 #{ | 29 false |
24 matched? <- { false } | |
25 } | |
26 } | 30 } |
27 } | 31 } |
28 } else: { | 32 } else: { |
29 #{ | 33 false |
30 matched? <- { false } | |
31 } | |
32 } | 34 } |
33 } | 35 } |
34 _makeMatchCall <- :matchexpr { | 36 _makeMatchCall <- :matchexpr { |
35 if: (matchexpr nodeType) = "lambda" { | 37 if: (matchexpr nodeType) = "lambda" { |
36 #{ | 38 #{ |
56 right <- (_makeMatchCall: (matchexpr right)) matchcall | 58 right <- (_makeMatchCall: (matchexpr right)) matchcall |
57 #{ | 59 #{ |
58 valid? <- { true } | 60 valid? <- { true } |
59 matchcall <- quote: (_applyMatch: :tomatch { | 61 matchcall <- quote: (_applyMatch: :tomatch { |
60 lm <- left | 62 lm <- left |
61 if: (lm matched?) { | 63 if: lm { |
62 orig <- tomatch | 64 orig <- tomatch |
63 tomatch <- tomatch from: (lm matchlen) | 65 tomatch <- tomatch from: (lm matchlen) |
64 rm <- right | 66 rm <- right |
65 if: (rm matched?) { | 67 if: rm { |
66 total <- (rm matchlen) + (lm matchlen) | 68 total <- (rm matchlen) + (lm matchlen) |
67 #{ | 69 #{ |
68 matched? <- { true } | 70 if <- :self trueblock { |
71 trueblock: | |
72 } | |
73 ifnot <- :self falseblock { | |
74 self | |
75 } | |
76 if:else <- :self trueblock :elseblock { | |
77 trueblock: | |
78 } | |
69 matchlen <- { total } | 79 matchlen <- { total } |
70 basicYield? <- { true } | 80 basicYield? <- { true } |
71 yield <- { orig from: 0 withLength: total } | 81 yield <- { orig from: 0 withLength: total } |
72 } | 82 } |
73 } else: { | 83 } else: { |
108 _match <- true | 118 _match <- true |
109 allBasic? <- true | 119 allBasic? <- true |
110 yieldvals <- [] | 120 yieldvals <- [] |
111 while: { _match && cur < n } do: { | 121 while: { _match && cur < n } do: { |
112 res <- mcall | 122 res <- mcall |
113 _match <- res matched? | 123 _match <- if: res { |
114 if: _match { | |
115 count <- count + 1 | 124 count <- count + 1 |
116 //TODO: Use some kind of lightweight substring wrapper here | 125 //TODO: Use some kind of lightweight substring wrapper here |
117 tomatch <- tomatch from: (res matchlen) | 126 tomatch <- tomatch from: (res matchlen) |
118 if: allBasic? { | 127 if: allBasic? { |
119 ifnot: (res basicYield?) { | 128 ifnot: (res basicYield?) { |
126 } else: { | 135 } else: { |
127 yieldvals <- (res yield) | yieldvals | 136 yieldvals <- (res yield) | yieldvals |
128 } | 137 } |
129 allBasic? <- allBasic? && (res basicYield?) | 138 allBasic? <- allBasic? && (res basicYield?) |
130 cur <- cur + (res matchlen) | 139 cur <- cur + (res matchlen) |
140 true | |
131 } | 141 } |
132 } | 142 } |
133 if: count >= min { | 143 if: count >= min { |
134 if: allBasic? { | 144 if: allBasic? { |
135 #{ | 145 #{ |
136 matched? <- { true } | 146 if <- :self trueblock { |
147 trueblock: | |
148 } | |
149 ifnot <- :self falseblock { | |
150 self | |
151 } | |
152 if:else <- :self trueblock :elseblock { | |
153 trueblock: | |
154 } | |
137 matchlen <- { cur } | 155 matchlen <- { cur } |
138 basicYield? <- { true } | 156 basicYield? <- { true } |
139 yield <- { orig from: 0 withLength: cur } | 157 yield <- { orig from: 0 withLength: cur } |
140 } | 158 } |
141 } else: { | 159 } else: { |
142 yieldvals <- yieldvals reverse | 160 yieldvals <- yieldvals reverse |
143 #{ | 161 #{ |
144 matched? <- { true } | 162 if <- :self trueblock { |
163 trueblock: | |
164 } | |
165 ifnot <- :self falseblock { | |
166 self | |
167 } | |
168 if:else <- :self trueblock :elseblock { | |
169 trueblock: | |
170 } | |
145 matchlen <- { cur } | 171 matchlen <- { cur } |
146 basicYield? <- { false } | 172 basicYield? <- { false } |
147 yield <- { yieldvals } | 173 yield <- { yieldvals } |
148 } | 174 } |
149 } | 175 } |
150 } else: { | 176 } else: { |
151 #{ | 177 false |
152 matched? <- { false } | |
153 } | |
154 } | 178 } |
155 } | 179 } |
156 } else: { | 180 } else: { |
157 print: "#error Invalid nPlus macro call: " . (mc message) . "\n" | 181 print: "#error Invalid nPlus macro call: " . (mc message) . "\n" |
158 } | 182 } |
225 } else: { | 249 } else: { |
226 "" | 250 "" |
227 } | 251 } |
228 } | 252 } |
229 _charClass <- :chars { | 253 _charClass <- :chars { |
254 orig <- chars | |
230 chars <- _expandClass: chars | 255 chars <- _expandClass: chars |
231 charmap <- "" | 256 charmap <- "" |
232 char <- 0 | 257 char <- 0 |
233 while: { char < 256 } do: { | 258 while: { char < 256 } do: { |
234 mchar <- 0 | 259 mchar <- 0 |
246 t <- "t" byte: 0 | 271 t <- "t" byte: 0 |
247 quote: :tomatch { | 272 quote: :tomatch { |
248 if: (tomatch isString?) { | 273 if: (tomatch isString?) { |
249 if: (charmap byte: (tomatch byte: 0)) = t { | 274 if: (charmap byte: (tomatch byte: 0)) = t { |
250 #{ | 275 #{ |
251 matched? <- { true } | 276 if <- :self trueblock { |
277 trueblock: | |
278 } | |
279 ifnot <- :self falseblock { | |
280 self | |
281 } | |
282 if:else <- :self trueblock :elseblock { | |
283 trueblock: | |
284 } | |
252 matchlen <- { 1 } | 285 matchlen <- { 1 } |
253 basicYield? <- { true } | 286 basicYield? <- { true } |
254 yield <- { tomatch from: 0 withLength: 1 } | 287 yield <- { tomatch from: 0 withLength: 1 } |
255 } | 288 } |
256 } else: { | 289 } else: { |
257 #{ | 290 false |
258 matched? <- { false } | 291 } |
259 } | 292 } else: { |
260 } | 293 false |
261 } else: { | |
262 #{ | |
263 matched? <- { false } | |
264 } | |
265 } | 294 } |
266 } | 295 } |
267 } | 296 } |
268 #{ | 297 #{ |
269 ifmatch:else <- :matchres :elseblock { | |
270 if: (matchres matched?) { | |
271 matchres | |
272 } else: { | |
273 elseblock: | |
274 } | |
275 } | |
276 charClass <- macro: :rawchars { | 298 charClass <- macro: :rawchars { |
277 eval: rawchars :chars { | 299 eval: rawchars :chars { |
278 _charClass: chars | 300 _charClass: chars |
279 } else: { | 301 } else: { |
280 print: "#error Argument to charClass macro must be a compile-time constant\n" | 302 print: "#error Argument to charClass macro must be a compile-time constant\n" |
291 | 313 |
292 matchOne <- macro: :options { | 314 matchOne <- macro: :options { |
293 options <- (options value) map: :option { | 315 options <- (options value) map: :option { |
294 _makeMatchCall: option | 316 _makeMatchCall: option |
295 } | 317 } |
296 body <- options foldr: (quote: #{ | 318 body <- options foldr: (quote: false) with: :acc el { |
297 matched? <- { false } | |
298 }) with: :acc el { | |
299 if: (el valid?) { | 319 if: (el valid?) { |
300 mcall <- el matchcall | 320 mcall <- el matchcall |
301 quote: (ifmatch: mcall else: { acc }) | 321 quote: (ifnot: mcall { acc }) |
302 } else: { | 322 } else: { |
303 print: "#error Invalid matchOne macro call: " . (el message) . "\n" | 323 print: "#error Invalid matchOne macro call: " . (el message) . "\n" |
304 acc | 324 acc |
305 } | 325 } |
306 } | 326 } |
325 mc <- _makeMatchCall: matchexpr | 345 mc <- _makeMatchCall: matchexpr |
326 if: (mc valid?) { | 346 if: (mc valid?) { |
327 mcall <- mc matchcall | 347 mcall <- mc matchcall |
328 quote: :tomatch { | 348 quote: :tomatch { |
329 res <- mcall | 349 res <- mcall |
330 if: (res matched?) { | 350 if: res { |
331 #{ | 351 #{ |
332 matched? <- { true } | 352 if <- :self trueblock { |
353 trueblock: | |
354 } | |
355 ifnot <- :self falseblock { | |
356 self | |
357 } | |
358 if:else <- :self trueblock :elseblock { | |
359 trueblock: | |
360 } | |
333 matchlen <- { res matchlen } | 361 matchlen <- { res matchlen } |
334 basicYield? <- { false } | 362 basicYield? <- { false } |
335 yield <- ylambda | 363 yield <- ylambda |
336 } | 364 } |
337 } else: { | 365 } else: { |
366 mcall <- mc matchcall | 394 mcall <- mc matchcall |
367 matchfun <- quote: :tomatch { | 395 matchfun <- quote: :tomatch { |
368 if: matchsym { | 396 if: matchsym { |
369 if: valsym = tomatch { | 397 if: valsym = tomatch { |
370 #{ | 398 #{ |
371 matched? <- { true } | 399 if <- :self trueblock { |
400 trueblock: | |
401 } | |
402 ifnot <- :self falseblock { | |
403 self | |
404 } | |
405 if:else <- :self trueblock :elseblock { | |
406 trueblock: | |
407 } | |
372 matchlen <- { valsym length } | 408 matchlen <- { valsym length } |
373 basicYield? <- { true } //TODO: Check if this is correct | 409 basicYield? <- { true } //TODO: Check if this is correct |
374 yield <- { valsym } | 410 yield <- { valsym } |
375 } | 411 } |
376 } else: { | 412 } else: { |
377 #{ | 413 false |
378 matched? <- { false } | |
379 } | |
380 } | 414 } |
381 } else: { | 415 } else: { |
382 mr <- mcall | 416 mr <- mcall |
383 if: (mr matched?) { | 417 if: mr { |
384 matchsym <- true | 418 matchsym <- true |
385 valsym <- (mr yield) | 419 valsym <- (mr yield) |
386 } | 420 } |
387 mr | 421 mr |
388 } | 422 } |
408 withwhere addExpression: (quote: (matchres <- mcall)) | 442 withwhere addExpression: (quote: (matchres <- mcall)) |
409 successLambda <- quote: { | 443 successLambda <- quote: { |
410 //Extra assignments will be added here | 444 //Extra assignments will be added here |
411 mlen <- matchres matchlen | 445 mlen <- matchres matchlen |
412 #{ | 446 #{ |
413 matched? <- { true } | 447 if <- :self trueblock { |
448 trueblock: | |
449 } | |
450 ifnot <- :self falseblock { | |
451 self | |
452 } | |
453 if:else <- :self trueblock :elseblock { | |
454 trueblock: | |
455 } | |
414 matchlen <- { mlen } | 456 matchlen <- { mlen } |
415 basicYield? <- { false } | 457 basicYield? <- { false } |
416 yield <- ylambda | 458 yield <- ylambda |
417 } | 459 } |
418 } | 460 } |
420 lsym <- el orig | 462 lsym <- el orig |
421 rsym <- el matchval | 463 rsym <- el matchval |
422 (quote: (lsym <- rsym)) | acc | 464 (quote: (lsym <- rsym)) | acc |
423 } | 465 } |
424 successLambda <- successLambda expressions!: sucexp | 466 successLambda <- successLambda expressions!: sucexp |
425 withwhere addExpression: (quote: (if: (matchres matched?) successLambda else: { | 467 withwhere addExpression: (quote: (if: matchres successLambda else: { |
426 matchres | 468 matchres |
427 })) | 469 })) |
428 withwhere | 470 withwhere |
429 } else: { | 471 } else: { |
430 print: "#error Error in main match expression of match:where:yield: " . (mcMain message) . "\n" | 472 print: "#error Error in main match expression of match:where:yield: " . (mcMain message) . "\n" |
926 lambda | 968 lambda |
927 ] | 969 ] |
928 | 970 |
929 testmatchintlit <- :val matchfun { | 971 testmatchintlit <- :val matchfun { |
930 res <- matchfun: val | 972 res <- matchfun: val |
931 if: (res matched?) { | 973 if: res { |
932 y <- res yield | 974 y <- res yield |
933 print: val . " matched with litval " . (y litval) . ", bits " . (y bits) . " and singned? " . (y signed?) . "\n" | 975 print: val . " matched with litval " . (y litval) . ", bits " . (y bits) . " and singned? " . (y signed?) . "\n" |
934 } else: { | 976 } else: { |
935 print: val . " did not match\n" | 977 print: val . " did not match\n" |
936 } | 978 } |
937 } | 979 } |
938 | 980 |
939 main <- :args { | 981 main <- :args { |
940 cmatch <- alpha: "czx0123" | 982 cmatch <- alpha: "czx0123" |
941 zeromatch <- alpha: "01234" | 983 zeromatch <- alpha: "01234" |
942 if: (cmatch matched?) { | 984 if: cmatch { |
943 print: "czx0123 matched with length " . (cmatch matchlen) . "\n" | 985 print: "czx0123 matched with length " . (cmatch matchlen) . "\n" |
944 } else: { | 986 } else: { |
945 print: "czx0123 didn't match\n" | 987 print: "czx0123 didn't match\n" |
946 } | 988 } |
947 if: (zeromatch matched?) { | 989 if: zeromatch { |
948 print: "0123 matched with length " . (zeromatch matchlen) . "\n" | 990 print: "0123 matched with length " . (zeromatch matchlen) . "\n" |
949 } else: { | 991 } else: { |
950 print: "0123 didn't match\n" | 992 print: "0123 didn't match\n" |
951 } | 993 } |
952 zeromatchanum <- alphaNum: "01234" | 994 zeromatchanum <- alphaNum: "01234" |
953 if: (zeromatchanum matched?) { | 995 if: zeromatchanum { |
954 print: "01234 matched with length " . (zeromatchanum matchlen) . "\n" | 996 print: "01234 matched with length " . (zeromatchanum matchlen) . "\n" |
955 } else: { | 997 } else: { |
956 print: "01234 didn't match\n" | 998 print: "01234 didn't match\n" |
957 } | 999 } |
958 stuff <- " \t/* blah blah blah * blah */ foo" | 1000 stuff <- " \t/* blah blah blah * blah */ foo" |
959 hwsmatch <- hws: stuff | 1001 hwsmatch <- hws: stuff |
960 if: (hwsmatch matched?) { | 1002 if: hwsmatch { |
961 print: "'" . (stuff from: (hwsmatch matchlen)) . "' found after hws\n" | 1003 print: "'" . (stuff from: (hwsmatch matchlen)) . "' found after hws\n" |
962 } else: { | 1004 } else: { |
963 print: stuff . " did not match hws rule\n" | 1005 print: stuff . " did not match hws rule\n" |
964 } | 1006 } |
965 tmatch <- digit: "3" | 1007 tmatch <- digit: "3" |
966 if: (tmatch matched?) { | 1008 if: tmatch { |
967 print: "3 matched with yield " . (tmatch yield) . ", yield + 1 = " . ((tmatch yield) + 1) . "\n" | 1009 print: "3 matched with yield " . (tmatch yield) . ", yield + 1 = " . ((tmatch yield) + 1) . "\n" |
968 } else: { | 1010 } else: { |
969 print: "3 did not match\n" | 1011 print: "3 did not match\n" |
970 } | 1012 } |
971 | 1013 |
986 code <- code . seg | 1028 code <- code . seg |
987 readsize <- seg byte_length | 1029 readsize <- seg byte_length |
988 } | 1030 } |
989 } | 1031 } |
990 codem <- top: code | 1032 codem <- top: code |
991 if: (codem matched?) { | 1033 if: codem { |
992 print: code . "\nmatched with yield:\n" . (codem yield) . "\n" | 1034 print: code . "\nmatched with yield:\n" . (codem yield) . "\n" |
993 } else: { | 1035 } else: { |
994 print: code . "\ndid not match\n" | 1036 print: code . "\ndid not match\n" |
995 } | 1037 } |
996 } | 1038 } |