|
1 "{ Package: 'stx:goodies/petitparser/compiler/tests' }" |
|
2 |
|
3 "{ NameSpace: Smalltalk }" |
|
4 |
|
5 PPAbstractParserTest subclass:#PPCCodeGeneratorTest |
|
6 instanceVariableNames:'visitor node result compiler parser context arguments' |
|
7 classVariableNames:'' |
|
8 poolDictionaries:'' |
|
9 category:'PetitCompiler-Tests-Visitors' |
|
10 ! |
|
11 |
|
12 !PPCCodeGeneratorTest methodsFor:'as yet unclassified'! |
|
13 |
|
14 context |
|
15 ^ context := PPCProfilingContext new |
|
16 ! |
|
17 |
|
18 setUp |
|
19 arguments := PPCArguments default |
|
20 profile: true; |
|
21 yourself. |
|
22 |
|
23 compiler := PPCCompiler new. |
|
24 compiler arguments: arguments. |
|
25 |
|
26 visitor := PPCCodeGenerator new. |
|
27 visitor compiler: compiler. |
|
28 visitor arguments: arguments. |
|
29 ! |
|
30 |
|
31 tearDown |
|
32 | class | |
|
33 |
|
34 class := (Smalltalk at: #PPGeneratedParser ifAbsent: [nil]). |
|
35 class notNil ifTrue:[ |
|
36 class removeFromSystem |
|
37 ]. |
|
38 ! ! |
|
39 |
|
40 !PPCCodeGeneratorTest methodsFor:'generating'! |
|
41 |
|
42 compileTree: root |
|
43 |
|
44 | configuration | |
|
45 |
|
46 |
|
47 configuration := PPCPluggableConfiguration on: [ :_self | |
|
48 result := (visitor visit: _self ir). |
|
49 |
|
50 compiler compileParser. |
|
51 compiler compiledParser startSymbol: result methodName. |
|
52 parser := compiler compiledParser new. |
|
53 _self ir: parser |
|
54 ]. |
|
55 parser := configuration compile: root arguments: arguments. |
|
56 |
|
57 ! ! |
|
58 |
|
59 !PPCCodeGeneratorTest methodsFor:'testing'! |
|
60 |
|
61 assert: whatever parse: input |
|
62 result := super assert: whatever parse: input. |
|
63 ! |
|
64 |
|
65 testActionNode |
|
66 node := PPCActionNode new |
|
67 block: [ :res | res collect: [:each | each asUppercase ]]; |
|
68 child: #letter asParser plus asCompilerTree; |
|
69 yourself. |
|
70 |
|
71 self compileTree: node. |
|
72 |
|
73 self assert: parser parse: 'foo' to: { $F . $O . $O}. |
|
74 self assert: parser parse: 'bar' to: { $B . $A . $R}. |
|
75 self assert: parser fail: ''. |
|
76 ! |
|
77 |
|
78 testAnyNode |
|
79 node := PPCForwardNode new |
|
80 child: PPCAnyNode new; |
|
81 yourself. |
|
82 self compileTree: node. |
|
83 |
|
84 self assert: parser class methodDictionary size = 2. |
|
85 |
|
86 self assert: parser parse: 'a' to: $a. |
|
87 self assert: parser parse: '_' to: $_. |
|
88 self assert: parser parse: Character cr asString to: Character cr. |
|
89 |
|
90 "Modified: / 23-04-2015 / 12:43:24 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
91 ! |
|
92 |
|
93 testAnyNode2 |
|
94 node := PPCForwardNode new |
|
95 child: (PPCAnyNode new markForInline; yourself); |
|
96 yourself. |
|
97 |
|
98 self compileTree: node. |
|
99 |
|
100 self assert: parser class methodDictionary size = 1. |
|
101 |
|
102 self assert: parser parse: 'a' to: $a. |
|
103 self assert: parser parse: '_' to: $_. |
|
104 self assert: parser parse: Character cr asString to: Character cr. |
|
105 |
|
106 "Modified: / 23-04-2015 / 12:43:43 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
107 ! |
|
108 |
|
109 testCharSetPredicateNode |
|
110 | charNode | |
|
111 charNode := PPCCharSetPredicateNode new |
|
112 predicate: (PPCharSetPredicate on: [ :e | e = $a ]); |
|
113 yourself. |
|
114 node := PPCForwardNode new |
|
115 child: charNode; |
|
116 yourself. |
|
117 |
|
118 self compileTree: node. |
|
119 |
|
120 self assert: parser class methodDictionary size = 2. |
|
121 |
|
122 self assert: parser parse: 'a' to: $a. |
|
123 self assert: parser fail: 'b'. |
|
124 ! |
|
125 |
|
126 testCharSetPredicateNode2 |
|
127 | charNode | |
|
128 charNode := PPCCharSetPredicateNode new |
|
129 predicate: (PPCharSetPredicate on: [ :e | e = $a ]); |
|
130 markForInline; |
|
131 yourself. |
|
132 node := PPCForwardNode new |
|
133 child: charNode; |
|
134 yourself. |
|
135 |
|
136 self compileTree: node. |
|
137 |
|
138 self assert: parser class methodDictionary size = 1. |
|
139 |
|
140 self assert: parser parse: 'a' to: $a. |
|
141 self assert: context invocationCount = 1. |
|
142 |
|
143 self assert: parser fail: 'b'. |
|
144 ! |
|
145 |
|
146 testCharacterNode |
|
147 | charNode | |
|
148 charNode := PPCCharacterNode new |
|
149 character: $a; yourself. |
|
150 node := PPCForwardNode new |
|
151 child: charNode; yourself. |
|
152 self compileTree: node. |
|
153 |
|
154 self assert: result class == PPCMethod. |
|
155 |
|
156 self assert: parser class methodDictionary size = 2. |
|
157 self assert: parser parse: 'a' to: $a. |
|
158 self assert: parser fail: 'b'. |
|
159 ! |
|
160 |
|
161 testCharacterNode2 |
|
162 node := (PPCCharacterNode new character: $#; yourself). |
|
163 self compileTree: node. |
|
164 |
|
165 self assert: parser parse: '#' |
|
166 ! |
|
167 |
|
168 testCharacterNode3 |
|
169 node := PPCCharacterNode new character: Character lf; yourself. |
|
170 self compileTree: node. |
|
171 |
|
172 self assert: parser parse: String lf. |
|
173 ! |
|
174 |
|
175 testCharacterNode4 |
|
176 | charNode | |
|
177 charNode := PPCCharacterNode new |
|
178 character: $a; |
|
179 markForInline; |
|
180 yourself. |
|
181 node := PPCForwardNode new |
|
182 child: charNode; yourself. |
|
183 |
|
184 self compileTree: node. |
|
185 |
|
186 self assert: parser class methodDictionary size = 1. |
|
187 self assert: parser parse: 'a' to: $a. |
|
188 self assert: parser fail: 'b'. |
|
189 ! |
|
190 |
|
191 testChoiceNode |
|
192 node := PPCChoiceNode new |
|
193 children: { #digit asParser asCompilerNode. #letter asParser asCompilerNode }; |
|
194 yourself. |
|
195 self compileTree: node. |
|
196 |
|
197 self assert: parser class methodDictionary size = 3. |
|
198 |
|
199 self assert: parser parse: '1' to: $1. |
|
200 self assert: parser parse: 'a' to: $a. |
|
201 self assert: parser fail: '_'. |
|
202 ! |
|
203 |
|
204 testChoiceNode2 |
|
205 | digitNode letterNode | |
|
206 digitNode := PPCMessagePredicateNode new |
|
207 message: #isDigit; |
|
208 markForInline; |
|
209 yourself. |
|
210 |
|
211 letterNode := PPCMessagePredicateNode new |
|
212 message: #isLetter; |
|
213 markForInline; |
|
214 yourself. |
|
215 |
|
216 |
|
217 node := PPCChoiceNode new |
|
218 children: { digitNode . letterNode }; |
|
219 yourself. |
|
220 self compileTree: node. |
|
221 |
|
222 self assert: parser class methodDictionary size = 1. |
|
223 |
|
224 self assert: parser parse: '1' to: $1. |
|
225 self assert: parser parse: 'a' to: $a. |
|
226 self assert: parser fail: '_'. |
|
227 ! |
|
228 |
|
229 testForwardNode |
|
230 | letterNode forwardNode | |
|
231 letterNode := PPCMessagePredicateNode new |
|
232 message: #isLetter; |
|
233 yourself. |
|
234 forwardNode := PPCForwardNode new |
|
235 child: letterNode; |
|
236 yourself. |
|
237 node := PPCForwardNode new |
|
238 child: forwardNode; |
|
239 yourself. |
|
240 |
|
241 self compileTree: node. |
|
242 |
|
243 self assert: parser class methodDictionary size = 3. |
|
244 |
|
245 self assert: parser parse: 'a' to: $a. |
|
246 self assert: parser parse: 'bc' to: $b end: 1. |
|
247 self assert: parser fail: ''. |
|
248 ! |
|
249 |
|
250 testForwardNode2 |
|
251 | letterNode forwardNode | |
|
252 letterNode := PPCMessagePredicateNode new |
|
253 message: #isLetter; |
|
254 markForInline; |
|
255 yourself. |
|
256 |
|
257 forwardNode := PPCForwardNode new |
|
258 child: letterNode; |
|
259 yourself. |
|
260 node := PPCForwardNode new |
|
261 child: forwardNode; |
|
262 yourself. |
|
263 |
|
264 |
|
265 self compileTree: node. |
|
266 |
|
267 self assert: parser class methodDictionary size = 2. |
|
268 |
|
269 self assert: parser parse: 'a' to: $a. |
|
270 self assert: parser parse: 'bc' to: $b end: 1. |
|
271 self assert: parser fail: ''. |
|
272 ! |
|
273 |
|
274 testForwardNode3 |
|
275 | letterNode forwardNode | |
|
276 letterNode := PPCMessagePredicateNode new |
|
277 message: #isLetter; |
|
278 yourself. |
|
279 forwardNode := PPCForwardNode new |
|
280 child: letterNode; |
|
281 markForInline; |
|
282 yourself. |
|
283 node := PPCForwardNode new |
|
284 child: forwardNode; |
|
285 yourself. |
|
286 |
|
287 |
|
288 self compileTree: node. |
|
289 |
|
290 self assert: parser class methodDictionary size = 2. |
|
291 |
|
292 self assert: parser parse: 'a' to: $a. |
|
293 self assert: parser parse: 'bc' to: $b end: 1. |
|
294 self assert: parser fail: ''. |
|
295 ! |
|
296 |
|
297 testForwardNode4 |
|
298 | letterNode forwardNode | |
|
299 letterNode := PPCMessagePredicateNode new |
|
300 message: #isLetter; |
|
301 markForInline; |
|
302 yourself. |
|
303 |
|
304 forwardNode := PPCForwardNode new |
|
305 child: letterNode; |
|
306 markForInline; |
|
307 yourself. |
|
308 node := PPCForwardNode new |
|
309 child: forwardNode; |
|
310 yourself. |
|
311 |
|
312 |
|
313 self compileTree: node. |
|
314 |
|
315 self assert: parser class methodDictionary size = 1. |
|
316 |
|
317 self assert: parser parse: 'a' to: $a. |
|
318 self assert: parser parse: 'bc' to: $b end: 1. |
|
319 self assert: parser fail: ''. |
|
320 ! |
|
321 |
|
322 testInlinePluggableNode |
|
323 "Sadly, on Smalltalk/X blocks cannot be inlined because |
|
324 the VM does not provide enough information to map |
|
325 it back to source code. Very bad indeed!!" |
|
326 ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[ |
|
327 self skipIf: true description: 'Blocks cannot be inlined due to a lack of proper VM support'. |
|
328 ]. |
|
329 |
|
330 node := PPCSequenceNode new |
|
331 children: { |
|
332 PPCPluggableNode new block: [ :ctx | ctx next ]; markForInline; yourself. |
|
333 $a asParser asCompilerNode }. |
|
334 |
|
335 self compileTree: node. |
|
336 |
|
337 self assert: parser class methodDictionary size = 2. |
|
338 self assert: parser parse: 'ba' to: #($b $a). |
|
339 ! |
|
340 |
|
341 testLiteralNode |
|
342 node := PPCLiteralNode new |
|
343 literal: 'foo'; |
|
344 yourself. |
|
345 self compileTree: node. |
|
346 |
|
347 self assert: result class == PPCMethod. |
|
348 self assert: result methodName = 'lit_0'. |
|
349 |
|
350 self assert: parser class methodDictionary size = 1. |
|
351 self assert: parser parse: 'foo' to: 'foo'. |
|
352 self assert: parser parse: 'foobar' to: 'foo' end: 3. |
|
353 self assert: parser fail: 'boo'. |
|
354 ! |
|
355 |
|
356 testLiteralNode2 |
|
357 node := PPCLiteralNode new |
|
358 literal: ''''''; |
|
359 yourself. |
|
360 self compileTree: node. |
|
361 |
|
362 self assert: parser parse: '''''' to: ''''''. |
|
363 ! |
|
364 |
|
365 testLiteralNode3 |
|
366 | literalNode | |
|
367 literalNode := PPCLiteralNode new |
|
368 literal: 'foo'; |
|
369 markForInline; |
|
370 yourself. |
|
371 node := PPCForwardNode new |
|
372 child: literalNode; |
|
373 yourself. |
|
374 self compileTree: node. |
|
375 |
|
376 self assert: parser class methodDictionary size = 1. |
|
377 self assert: parser parse: 'foo' to: 'foo'. |
|
378 self assert: parser parse: 'foobar' to: 'foo' end: 3. |
|
379 self assert: parser fail: 'boo'. |
|
380 ! |
|
381 |
|
382 testMessagePredicate |
|
383 | messageNode | |
|
384 messageNode := PPCMessagePredicateNode new |
|
385 message: #isDigit; |
|
386 yourself. |
|
387 node := PPCForwardNode new |
|
388 child: messageNode; |
|
389 yourself. |
|
390 |
|
391 self compileTree: node. |
|
392 |
|
393 self assert: parser class methodDictionary size = 2. |
|
394 self assert: parser parse: '1' to: $1 end: 1. |
|
395 self assert: context invocationCount = 2. |
|
396 |
|
397 self assert: parser fail: 'a'. |
|
398 self assert: parser fail: ''. |
|
399 ! |
|
400 |
|
401 testMessagePredicate2 |
|
402 | messageNode | |
|
403 messageNode := PPCMessagePredicateNode new |
|
404 message: #isDigit; |
|
405 markForInline; |
|
406 yourself. |
|
407 node := PPCForwardNode new |
|
408 child: messageNode; |
|
409 yourself. |
|
410 |
|
411 self compileTree: node. |
|
412 |
|
413 self assert: parser class methodDictionary size = 1. |
|
414 self assert: parser parse: '1' to: $1 end: 1. |
|
415 self assert: context invocationCount = 1. |
|
416 |
|
417 self assert: parser fail: 'a'. |
|
418 self assert: parser fail: ''. |
|
419 ! |
|
420 |
|
421 testNilNode |
|
422 | nilNode | |
|
423 nilNode := PPCNilNode new. |
|
424 node := PPCForwardNode new child: nilNode; yourself. |
|
425 self compileTree: node. |
|
426 |
|
427 self assert: result class = PPCMethod. |
|
428 |
|
429 self assert: parser class methodDictionary size = 2. |
|
430 self assert: parser parse: 'a' to: nil end: 0. |
|
431 self assert: parser parse: '' to: nil end: 0. |
|
432 ! |
|
433 |
|
434 testNilNode2 |
|
435 | nilNode | |
|
436 nilNode := PPCNilNode new markForInline; yourself. |
|
437 node := PPCForwardNode new child: nilNode; yourself. |
|
438 self compileTree: node. |
|
439 |
|
440 self assert: parser class methodDictionary size = 1. |
|
441 self assert: parser parse: 'a' to: nil end: 0. |
|
442 self assert: parser parse: '' to: nil end: 0. |
|
443 ! |
|
444 |
|
445 testNotCharSetPredicateNode |
|
446 | charNode | |
|
447 charNode := PPCNotCharSetPredicateNode new |
|
448 predicate: (PPCharSetPredicate on: [ :e | e = $a ]); |
|
449 yourself. |
|
450 node := PPCForwardNode new |
|
451 child: charNode; yourself. |
|
452 |
|
453 self compileTree: node. |
|
454 |
|
455 self assert: parser class methodDictionary size = 2. |
|
456 self assert: parser parse: 'b' to: nil end: 0. |
|
457 self assert: context invocationCount = 2. |
|
458 |
|
459 self assert: parser fail: 'a'. |
|
460 self assert: parser parse: '' to: nil end: 0. |
|
461 ! |
|
462 |
|
463 testNotCharSetPredicateNode2 |
|
464 | charNode | |
|
465 charNode := PPCNotCharSetPredicateNode new |
|
466 predicate: (PPCharSetPredicate on: [ :e | e = $a ]); |
|
467 markForInline; |
|
468 yourself. |
|
469 node := PPCForwardNode new |
|
470 child: charNode; yourself. |
|
471 |
|
472 self compileTree: node. |
|
473 |
|
474 self assert: parser class methodDictionary size = 1. |
|
475 self assert: parser parse: 'b' to: nil end: 0. |
|
476 self assert: context invocationCount = 1. |
|
477 |
|
478 self assert: parser fail: 'a'. |
|
479 self assert: parser parse: '' to: nil end: 0. |
|
480 ! |
|
481 |
|
482 testNotLiteralNode |
|
483 | literalNode | |
|
484 literalNode := PPCNotLiteralNode new |
|
485 literal: 'foo'; |
|
486 yourself. |
|
487 node := PPCForwardNode new |
|
488 child: literalNode; yourself. |
|
489 |
|
490 self compileTree: node. |
|
491 |
|
492 self assert: parser class methodDictionary size = 2. |
|
493 self assert: parser parse: 'bar' to: nil end: 0. |
|
494 self assert: context invocationCount = 2. |
|
495 |
|
496 self assert: parser fail: 'foo'. |
|
497 self assert: parser parse: '' to: nil end: 0. |
|
498 ! |
|
499 |
|
500 testNotLiteralNode2 |
|
501 | literalNode | |
|
502 literalNode := PPCNotLiteralNode new |
|
503 literal: 'foo'; |
|
504 markForInline; |
|
505 yourself. |
|
506 node := PPCForwardNode new |
|
507 child: literalNode; yourself. |
|
508 |
|
509 self compileTree: node. |
|
510 |
|
511 self assert: parser class methodDictionary size = 1. |
|
512 self assert: parser parse: 'bar' to: nil end: 0. |
|
513 self assert: context invocationCount = 1. |
|
514 |
|
515 self assert: parser fail: 'foo'. |
|
516 self assert: parser parse: '' to: nil end: 0. |
|
517 ! |
|
518 |
|
519 testNotMessagePredicateNode |
|
520 | messageNode | |
|
521 messageNode := PPCNotMessagePredicateNode new |
|
522 message: #isDigit; |
|
523 yourself. |
|
524 node := PPCForwardNode new |
|
525 child: messageNode; |
|
526 yourself. |
|
527 |
|
528 |
|
529 self compileTree: node. |
|
530 |
|
531 self assert: parser class methodDictionary size = 2. |
|
532 self assert: parser parse: 'a' to: nil end: 0. |
|
533 self assert: context invocationCount = 2. |
|
534 |
|
535 self assert: parser fail: '1'. |
|
536 self assert: parser parse: '' to: nil end: 0. |
|
537 ! |
|
538 |
|
539 testNotMessagePredicateNode2 |
|
540 | messageNode | |
|
541 messageNode := PPCNotMessagePredicateNode new |
|
542 message: #isDigit; |
|
543 markForInline; |
|
544 yourself. |
|
545 node := PPCForwardNode new |
|
546 child: messageNode; |
|
547 yourself. |
|
548 |
|
549 self compileTree: node. |
|
550 |
|
551 self assert: parser class methodDictionary size = 1. |
|
552 self assert: parser parse: 'a' to: nil end: 0. |
|
553 self assert: context invocationCount = 1. |
|
554 |
|
555 self assert: parser fail: '1'. |
|
556 self assert: parser parse: '' to: nil end: 0. |
|
557 ! |
|
558 |
|
559 testNotNode |
|
560 node := PPCNotNode new |
|
561 child: #digit asParser asCompilerNode; |
|
562 yourself. |
|
563 |
|
564 self compileTree: node. |
|
565 |
|
566 self assert: parser parse: 'a' to: nil end: 0. |
|
567 self assert: parser fail: '1'. |
|
568 self assert: parser parse: '' to: nil end: 0. |
|
569 ! |
|
570 |
|
571 testOptionalNode |
|
572 node := PPCOptionalNode new |
|
573 child: ($a asParser asCompilerNode); |
|
574 yourself. |
|
575 self compileTree: node. |
|
576 |
|
577 self assert: parser parse: 'b' to: nil end: 0. |
|
578 self assert: parser parse: 'a' to: $a. |
|
579 self assert: parser parse: '' to: nil end: 0. |
|
580 ! |
|
581 |
|
582 testPluggableNode |
|
583 node := PPCPluggableNode new |
|
584 block: [:ctx | ctx next ]; |
|
585 yourself. |
|
586 self compileTree: node. |
|
587 |
|
588 self assert: parser parse: 'foo' to: $f end: 1. |
|
589 self assert: parser parse: 'bar' to: $b end: 1. |
|
590 self assert: parser parse: '' to: nil. |
|
591 ! |
|
592 |
|
593 testPlusNode |
|
594 node := PPCPlusNode new |
|
595 child: ($a asParser asCompilerNode); |
|
596 yourself. |
|
597 |
|
598 self compileTree: node. |
|
599 self assert: result class = PPCMethod. |
|
600 |
|
601 self assert: parser parse: 'aaa' to: #($a $a $a) end: 3. |
|
602 self assert: parser parse: 'ab' to: #( $a ) end: 1. |
|
603 self assert: parser fail: 'b'. |
|
604 ! |
|
605 |
|
606 testPlusNode2 |
|
607 node := PPCPlusNode new |
|
608 child: (#letter asParser asCompilerNode markForInline); |
|
609 yourself. |
|
610 |
|
611 self compileTree: node. |
|
612 self assert: result class = PPCMethod. |
|
613 |
|
614 self assert: parser parse: 'abc' to: #($a $b $c) end: 3. |
|
615 self assert: parser parse: 'ab1' to: #( $a $b ) end: 2. |
|
616 self assert: parser fail: '1'. |
|
617 ! |
|
618 |
|
619 testPredicateNode |
|
620 | predicateNode | |
|
621 predicateNode := PPCPredicateNode new |
|
622 predicate: (PPCharSetPredicate on: [ :e | e isDigit ]); |
|
623 yourself. |
|
624 node := PPCForwardNode new |
|
625 child: predicateNode; |
|
626 yourself. |
|
627 self compileTree: node. |
|
628 |
|
629 self assert: parser class methodDictionary size = 2. |
|
630 self assert: parser parse: '1' to: $1 end: 1. |
|
631 self assert: context invocationCount = 2. |
|
632 |
|
633 self assert: parser fail: 'a'. |
|
634 self assert: parser fail: ''. |
|
635 ! |
|
636 |
|
637 testPredicateNode2 |
|
638 | predicateNode | |
|
639 predicateNode := PPCPredicateNode new |
|
640 predicate: (PPCharSetPredicate on: [ :e | e isDigit ]); |
|
641 markForInline; |
|
642 yourself. |
|
643 node := PPCForwardNode new |
|
644 child: predicateNode; |
|
645 yourself. |
|
646 |
|
647 self compileTree: node. |
|
648 |
|
649 self assert: parser class methodDictionary size = 1. |
|
650 self assert: parser parse: '1' to: $1 end: 1. |
|
651 self assert: context invocationCount = 1. |
|
652 |
|
653 self assert: parser fail: 'a'. |
|
654 self assert: parser fail: ''. |
|
655 ! |
|
656 |
|
657 testSequenceNode |
|
658 node := PPCSequenceNode new |
|
659 children: { $a asParser asCompilerNode . |
|
660 $b asParser asCompilerNode . |
|
661 $c asParser asCompilerNode }; |
|
662 yourself. |
|
663 self compileTree: node. |
|
664 |
|
665 self assert: parser parse: 'abc' to: #($a $b $c) end: 3. |
|
666 self assert: parser parse: 'abcd' to: #( $a $b $c ) end: 3. |
|
667 self assert: parser fail: 'ab'. |
|
668 ! |
|
669 |
|
670 testStarAnyNode |
|
671 node := PPCStarAnyNode new |
|
672 child: PPCNilNode new; |
|
673 yourself. |
|
674 self compileTree: node. |
|
675 |
|
676 self assert: parser parse: 'abc' to: #($a $b $c). |
|
677 self assert: parser parse: 'a' to: #($a). |
|
678 self assert: parser parse: '' to: #(). |
|
679 ! |
|
680 |
|
681 testStarCharSetPredicateNode |
|
682 node := PPCStarCharSetPredicateNode new |
|
683 predicate: (PPCharSetPredicate on: [:e | e = $a ]); |
|
684 child: PPCSentinelNode new; |
|
685 yourself. |
|
686 |
|
687 self compileTree: node. |
|
688 |
|
689 self assert: parser class methodDictionary size = 1. |
|
690 self assert: parser parse: 'aaa1' to: #( $a $a $a) end: 3. |
|
691 self assert: context invocationCount = 1. |
|
692 self assert: parser parse: 'bba' to: #() end: 0. |
|
693 self assert: context invocationCount = 1. |
|
694 |
|
695 ! |
|
696 |
|
697 testStarMessagePredicateNode |
|
698 node := PPCStarMessagePredicateNode new |
|
699 message: #isLetter; |
|
700 child: PPCSentinelNode new; |
|
701 yourself. |
|
702 |
|
703 self compileTree: node. |
|
704 |
|
705 self assert: parser class methodDictionary size = 1. |
|
706 self assert: parser parse: 'abc1' to: #( $a $b $c) end: 3. |
|
707 self assert: context invocationCount = 1. |
|
708 |
|
709 self assert: parser parse: '123a' to: #() end: 0. |
|
710 self assert: context invocationCount = 1. |
|
711 |
|
712 ! |
|
713 |
|
714 testStarNode |
|
715 node := PPCStarNode new |
|
716 child: ($a asParser asCompilerNode); |
|
717 yourself. |
|
718 |
|
719 self compileTree: node. |
|
720 |
|
721 self assert: parser parse: 'aaa' to: #($a $a $a) end: 3. |
|
722 self assert: parser parse: 'ab' to: #( $a ) end: 1. |
|
723 self assert: parser parse: 'b' to: #( ) end: 0. |
|
724 ! |
|
725 |
|
726 testSymbolActionNode |
|
727 node := PPCSymbolActionNode new |
|
728 block: #second; |
|
729 child: #letter asParser plus asCompilerTree; |
|
730 yourself. |
|
731 |
|
732 self compileTree: node. |
|
733 |
|
734 self assert: parser parse: 'foo' to: $o. |
|
735 self assert: parser parse: 'bar' to: $a. |
|
736 self assert: parser fail: ''. |
|
737 ! |
|
738 |
|
739 testTokenNode |
|
740 node := PPCTokenNode new |
|
741 child: #letter asParser plus asCompilerTree; |
|
742 tokenClass: PPToken; |
|
743 yourself. |
|
744 |
|
745 self compileTree: node. |
|
746 |
|
747 self assert: parser parse: 'abc'. |
|
748 self assert: result class = PPToken. |
|
749 self assert: result inputValue = 'abc'. |
|
750 |
|
751 self assert: parser fail: '1a'. |
|
752 ! |
|
753 |
|
754 testTokenSequenceNode |
|
755 | letterNode | |
|
756 letterNode := PPCMessagePredicateNode new |
|
757 message: #isLetter; |
|
758 yourself. |
|
759 |
|
760 node := PPCTokenSequenceNode new |
|
761 children: { letterNode }; |
|
762 yourself. |
|
763 |
|
764 self compileTree: node. |
|
765 |
|
766 self assert: parser class methodDictionary size = 2. |
|
767 self assert: parser parse: 'a'. |
|
768 self assert: parser fail: '1'. |
|
769 ! |
|
770 |
|
771 testTokenSequenceNode2 |
|
772 | letterNode | |
|
773 letterNode := PPCMessagePredicateNode new |
|
774 message: #isLetter; |
|
775 markForInline; |
|
776 yourself. |
|
777 |
|
778 node := PPCTokenSequenceNode new |
|
779 children: { letterNode }; |
|
780 yourself. |
|
781 |
|
782 self compileTree: node. |
|
783 |
|
784 self assert: parser class methodDictionary size = 1. |
|
785 self assert: parser parse: 'a'. |
|
786 self assert: parser fail: '1'. |
|
787 ! |
|
788 |
|
789 testTokenStarMessagePredicateNode |
|
790 |
|
791 node := PPCTokenStarMessagePredicateNode new |
|
792 message: #isLetter; |
|
793 child: PPCSentinelNode new; |
|
794 yourself. |
|
795 |
|
796 arguments guards: false. |
|
797 self compileTree: node. |
|
798 |
|
799 self assert: parser class methodDictionary size = 1. |
|
800 |
|
801 self assert: parser parse: 'foo' to: parser. |
|
802 self assert: context invocationCount = 1. |
|
803 self assert: context lwRememberCount = 0. |
|
804 self assert: context lwRestoreCount = 0. |
|
805 self assert: context rememberCount = 0. |
|
806 |
|
807 self assert: parser parse: 'foo123' to: parser end: 3. |
|
808 ! |
|
809 |
|
810 testTokenStarSeparatorNode |
|
811 |
|
812 | starNode | |
|
813 starNode := PPCTokenStarSeparatorNode new |
|
814 message: #isSeparator; |
|
815 child: PPCSentinelNode new; |
|
816 yourself. |
|
817 node := PPCForwardNode new |
|
818 child: starNode; |
|
819 yourself. |
|
820 self compileTree: node. |
|
821 |
|
822 self assert: parser class methodDictionary size = 2. |
|
823 |
|
824 self assert: parser parse: ' a' to: parser end: 3. |
|
825 self assert: context invocationCount = 2. |
|
826 |
|
827 ! |
|
828 |
|
829 testTokenStarSeparatorNode2 |
|
830 |
|
831 | starNode | |
|
832 starNode := PPCTokenStarSeparatorNode new |
|
833 message: #isSeparator; |
|
834 child: PPCSentinelNode new; |
|
835 markForInline; |
|
836 yourself. |
|
837 node := PPCForwardNode new |
|
838 child: starNode; |
|
839 yourself. |
|
840 self compileTree: node. |
|
841 |
|
842 self assert: parser class methodDictionary size = 1. |
|
843 |
|
844 self assert: parser parse: ' a' to: context end: 3. |
|
845 self assert: context invocationCount = 1. |
|
846 |
|
847 ! |
|
848 |
|
849 testTrimNode |
|
850 node := PPCTrimNode new |
|
851 child: #letter asParser asCompilerNode; |
|
852 yourself. |
|
853 |
|
854 self compileTree: node. |
|
855 |
|
856 self assert: parser parse: ' a '. |
|
857 self assert: parser fail: ' 1 '. |
|
858 ! |
|
859 |
|
860 testTrimmingTokenNode |
|
861 node := PPCTrimmingTokenNode new |
|
862 child: #letter asParser plus asCompilerTree; |
|
863 tokenClass: PPToken; |
|
864 whitespace: #space asParser star asCompilerTree; |
|
865 yourself. |
|
866 |
|
867 self compileTree: node. |
|
868 |
|
869 self assert: parser parse: 'abc'. |
|
870 self assert: result class = PPToken. |
|
871 self assert: result inputValue = 'abc'. |
|
872 |
|
873 self assert: parser parse: ' abc '. |
|
874 self assert: result class = PPToken. |
|
875 self assert: result inputValue = 'abc'. |
|
876 |
|
877 |
|
878 self assert: parser fail: '1a'. |
|
879 ! |
|
880 |
|
881 testUnknownNode |
|
882 node := PPCUnknownNode new |
|
883 parser: [:ctx | ctx next ] asParser; |
|
884 yourself. |
|
885 self compileTree: node. |
|
886 |
|
887 self assert: parser parse: 'foo' to: $f end: 1. |
|
888 self assert: parser parse: 'bar' to: $b end: 1. |
|
889 self assert: parser parse: '' to: nil. |
|
890 ! ! |
|
891 |