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 }