]> gitweb.factorcode.org Git - factor.git/blob - core/parser/parser-tests.factor
Update documentation for stricter vocabulary search path semantics
[factor.git] / core / parser / parser-tests.factor
1 USING: arrays math parser tools.test kernel generic words
2 io.streams.string namespaces classes effects source-files assocs
3 sequences strings io.files io.pathnames definitions
4 continuations sorting classes.tuple compiler.units debugger
5 vocabs vocabs.loader accessors eval combinators lexer
6 vocabs.parser words.symbol multiline source-files.errors
7 tools.crossref grouping ;
8 IN: parser.tests
9
10 [
11     [ 1 [ 2 [ 3 ] 4 ] 5 ]
12     [ "1\n[\n2\n[\n3\n]\n4\n]\n5" eval( -- a b c ) ]
13     unit-test
14
15     [ t t f f ]
16     [ "t t f f" eval( -- ? ? ? ? ) ]
17     unit-test
18
19     [ "hello world" ]
20     [ "\"hello world\"" eval( -- string ) ]
21     unit-test
22
23     [ "\n\r\t\\" ]
24     [ "\"\\n\\r\\t\\\\\"" eval( -- string ) ]
25     unit-test
26
27     [ "hello world" ]
28     [
29         "IN: parser.tests : hello ( -- str ) \"hello world\" ;"
30         eval( -- ) "USE: parser.tests hello" eval( -- string )
31     ] unit-test
32
33     [ ]
34     [ "! This is a comment, people." eval( -- ) ]
35     unit-test
36
37     ! Test escapes
38
39     [ " " ]
40     [ "\"\\u000020\"" eval( -- string ) ]
41     unit-test
42
43     [ "'" ]
44     [ "\"\\u000027\"" eval( -- string ) ]
45     unit-test
46
47     ! Test EOL comments in multiline strings.
48     [ "Hello" ] [ "#! This calls until-eol.\n\"Hello\"" eval( -- string ) ] unit-test
49
50     [ word ] [ \ f class ] unit-test
51
52     ! Test stack effect parsing
53
54     : effect-parsing-test ( a b -- c ) + ;
55
56     [ t ] [
57         "effect-parsing-test" "parser.tests" lookup
58         \ effect-parsing-test eq?
59     ] unit-test
60
61     [ T{ effect f { "a" "b" } { "c" } f } ]
62     [ \ effect-parsing-test "declared-effect" word-prop ] unit-test
63
64     : baz ( a b -- * ) 2array throw ;
65
66     [ t ]
67     [ \ baz "declared-effect" word-prop terminated?>> ]
68     unit-test
69
70     [ ] [ "IN: parser.tests USE: math : effect-parsing-test ( a b -- d ) - ;" eval( -- ) ] unit-test
71
72     [ t ] [
73         "effect-parsing-test" "parser.tests" lookup
74         \ effect-parsing-test eq?
75     ] unit-test
76
77     [ T{ effect f { "a" "b" } { "d" } f } ]
78     [ \ effect-parsing-test "declared-effect" word-prop ] unit-test
79
80     ! Funny bug
81     [ 2 ] [ "IN: parser.tests : \0. ( -- x ) 2 ; \0." eval( -- n ) ] unit-test
82
83     [ "IN: parser.tests : missing-- ( a b ) ;" eval( -- ) ] must-fail
84
85     ! These should throw errors
86     [ "HEX: zzz" eval( -- obj ) ] must-fail
87     [ "OCT: 999" eval( -- obj ) ] must-fail
88     [ "BIN: --0" eval( -- obj ) ] must-fail
89
90     DEFER: foo
91
92     "IN: parser.tests USING: math prettyprint ; SYNTAX: foo 2 2 + . ;" eval( -- )
93
94     [ ] [ "USE: parser.tests foo" eval( -- ) ] unit-test
95
96     "IN: parser.tests USING: math prettyprint ; : foo ( -- ) 2 2 + . ;" eval( -- )
97
98     [ t ] [
99         "USE: parser.tests \\ foo" eval( -- word )
100         "foo" "parser.tests" lookup eq?
101     ] unit-test
102
103     ! Test smudging
104
105     [ 1 ] [
106         "IN: parser.tests : smudge-me ( -- ) ;" <string-reader> "foo"
107         parse-stream drop
108
109         "foo" source-file definitions>> first assoc-size
110     ] unit-test
111
112     [ t ] [ "smudge-me" "parser.tests" lookup >boolean ] unit-test
113
114     [ ] [
115         "IN: parser.tests : smudge-me-more ( -- ) ;" <string-reader> "foo"
116         parse-stream drop
117     ] unit-test
118
119     [ t ] [ "smudge-me-more" "parser.tests" lookup >boolean ] unit-test
120     [ f ] [ "smudge-me" "parser.tests" lookup >boolean ] unit-test
121
122     [ 3 ] [
123         "IN: parser.tests USING: math strings ; GENERIC: smudge-me ( a -- b ) M: integer smudge-me ; M: string smudge-me ;" <string-reader> "foo"
124         parse-stream drop
125
126         "foo" source-file definitions>> first assoc-size
127     ] unit-test
128
129     [ 1 ] [
130         "IN: parser.tests USING: arrays ; M: array smudge-me ;" <string-reader> "bar"
131         parse-stream drop
132
133         "bar" source-file definitions>> first assoc-size
134     ] unit-test
135
136     [ 2 ] [
137         "IN: parser.tests USING: math strings ; GENERIC: smudge-me ( a -- b ) M: integer smudge-me ;" <string-reader> "foo"
138         parse-stream drop
139
140         "foo" source-file definitions>> first assoc-size
141     ] unit-test
142     
143     [ t ] [
144         array "smudge-me" "parser.tests" lookup order memq?
145     ] unit-test
146     
147     [ t ] [
148         integer "smudge-me" "parser.tests" lookup order memq?
149     ] unit-test
150     
151     [ f ] [
152         string "smudge-me" "parser.tests" lookup order memq?
153     ] unit-test
154
155     [ ] [
156         "IN: parser.tests USE: math 2 2 +" <string-reader> "a"
157         parse-stream drop
158     ] unit-test
159     
160     [ t ] [
161         "a" <pathname> \ + usage member?
162     ] unit-test
163
164     [ ] [
165         "IN: parser.tests USE: math 2 2 -" <string-reader> "a"
166         parse-stream drop
167     ] unit-test
168     
169     [ f ] [
170         "a" <pathname> \ + usage member?
171     ] unit-test
172     
173     [ ] [
174         "a" source-files get delete-at
175         2 [
176             "IN: parser.tests DEFER: x : y ( -- ) x ; : x ( -- ) y ;"
177             <string-reader> "a" parse-stream drop
178         ] times
179     ] unit-test
180     
181     "a" source-files get delete-at
182
183     [
184         "IN: parser.tests : x ( -- ) ; : y ( -- * ) 3 throw ; this is an error"
185         <string-reader> "a" parse-stream
186     ] [ source-file-error? ] must-fail-with
187
188     [ t ] [
189         "y" "parser.tests" lookup >boolean
190     ] unit-test
191
192     [ f ] [
193         "IN: parser.tests : x ( -- ) ;"
194         <string-reader> "a" parse-stream drop
195         
196         "y" "parser.tests" lookup
197     ] unit-test
198
199     ! Test new forward definition logic
200     [ ] [
201         "IN: axx : axx ( -- ) ;"
202         <string-reader> "axx" parse-stream drop
203     ] unit-test
204
205     [ ] [
206         "USE: axx IN: bxx : bxx ( -- ) ; : cxx ( -- ) axx bxx ;"
207         <string-reader> "bxx" parse-stream drop
208     ] unit-test
209
210     ! So we move the bxx word to axx...
211     [ ] [
212         "IN: axx : axx ( -- ) ; : bxx ( -- ) ;"
213         <string-reader> "axx" parse-stream drop
214     ] unit-test
215
216     [ t ] [ "bxx" "axx" lookup >boolean ] unit-test
217
218     ! And reload the file that uses it...
219     [ ] [
220         "USE: axx IN: bxx ( -- ) : cxx ( -- ) axx bxx ;"
221         <string-reader> "bxx" parse-stream drop
222     ] unit-test
223     
224     ! And hope not to get a forward-error!
225
226     ! Turning a generic into a non-generic could cause all
227     ! kinds of funnyness
228     [ ] [
229         "IN: ayy USE: kernel GENERIC: ayy ( a -- b ) M: object ayy ;"
230         <string-reader> "ayy" parse-stream drop
231     ] unit-test
232
233     [ ] [
234         "IN: ayy USE: kernel : ayy ( -- ) ;"
235         <string-reader> "ayy" parse-stream drop
236     ] unit-test
237
238     [ ] [
239         "IN: azz TUPLE: my-class ; GENERIC: a-generic ( a -- b )"
240         <string-reader> "azz" parse-stream drop
241     ] unit-test
242
243     [ ] [
244         "USE: azz M: my-class a-generic ;"
245         <string-reader> "azz-2" parse-stream drop
246     ] unit-test
247
248     [ ] [
249         "IN: azz GENERIC: a-generic ( a -- b )"
250         <string-reader> "azz" parse-stream drop
251     ] unit-test
252
253     [ ] [
254         "USE: azz USE: math M: integer a-generic ;"
255         <string-reader> "azz-2" parse-stream drop
256     ] unit-test
257
258     [ ] [
259         "IN: parser.tests : <bogus-error> ( -- ) ; : bogus ( -- error ) <bogus-error> ;"
260         <string-reader> "bogus-error" parse-stream drop
261     ] unit-test
262
263     [ ] [
264         "IN: parser.tests TUPLE: bogus-error ; C: <bogus-error> bogus-error : bogus ( -- error ) <bogus-error> ;"
265         <string-reader> "bogus-error" parse-stream drop
266     ] unit-test
267
268     ! Problems with class predicates -vs- ordinary words
269     [ ] [
270         "IN: parser.tests TUPLE: killer ;"
271         <string-reader> "removing-the-predicate" parse-stream drop
272     ] unit-test
273
274     [ ] [
275         "IN: parser.tests GENERIC: killer? ( a -- b )"
276         <string-reader> "removing-the-predicate" parse-stream drop
277     ] unit-test
278     
279     [ t ] [
280         "killer?" "parser.tests" lookup >boolean
281     ] unit-test
282
283     [
284         "IN: parser.tests TUPLE: another-pred-test ; GENERIC: another-pred-test? ( a -- b )"
285         <string-reader> "removing-the-predicate" parse-stream
286     ] [ error>> error>> error>> redefine-error? ] must-fail-with
287
288     [
289         "IN: parser.tests TUPLE: class-redef-test ; TUPLE: class-redef-test ;"
290         <string-reader> "redefining-a-class-1" parse-stream
291     ] [ error>> error>> error>> redefine-error? ] must-fail-with
292
293     [ ] [
294         "IN: parser.tests TUPLE: class-redef-test ; SYMBOL: class-redef-test"
295         <string-reader> "redefining-a-class-2" parse-stream drop
296     ] unit-test
297
298     [
299         "IN: parser.tests TUPLE: class-redef-test ; SYMBOL: class-redef-test : class-redef-test ( -- ) ;"
300         <string-reader> "redefining-a-class-3" parse-stream drop
301     ] [ error>> error>> error>> redefine-error? ] must-fail-with
302
303     [ ] [
304         "IN: parser.tests TUPLE: class-fwd-test ;"
305         <string-reader> "redefining-a-class-3" parse-stream drop
306     ] unit-test
307
308     [
309         "IN: parser.tests \\ class-fwd-test"
310         <string-reader> "redefining-a-class-3" parse-stream drop
311     ] [ error>> error>> error>> no-word-error? ] must-fail-with
312
313     [ ] [
314         "IN: parser.tests TUPLE: class-fwd-test ; SYMBOL: class-fwd-test"
315         <string-reader> "redefining-a-class-3" parse-stream drop
316     ] unit-test
317
318     [
319         "IN: parser.tests \\ class-fwd-test"
320         <string-reader> "redefining-a-class-3" parse-stream drop
321     ] [ error>> error>> error>> no-word-error? ] must-fail-with
322
323     [
324         "IN: parser.tests : foo ( -- ) ; TUPLE: foo ;"
325         <string-reader> "redefining-a-class-4" parse-stream drop
326     ] [ error>> error>> error>> redefine-error? ] must-fail-with
327
328     [ ] [
329         "IN: parser.tests : foo ( x y -- z ) 1 2 ; : bar ( a -- b ) ;" eval( -- )
330     ] unit-test
331
332     [
333         "IN: parser.tests : foo ( x y -- z) 1 2 ; : bar ( a -- b ) ;" eval( -- )
334     ] must-fail
335 ] with-file-vocabs
336
337 [ ] [
338     "IN: parser.tests USE: kernel PREDICATE: foo < object ( x -- y ) ;" eval( -- )
339 ] unit-test
340
341 [ t ] [
342     "foo?" "parser.tests" lookup word eq?
343 ] unit-test
344
345 [ ] [
346     [
347         "redefining-a-class-5" forget-source
348         "redefining-a-class-6" forget-source
349         "redefining-a-class-7" forget-source
350     ] with-compilation-unit
351 ] unit-test
352
353 2 [
354     [ ] [
355         "IN: parser.tests TUPLE: foo ; GENERIC: foo ( a -- b )"
356         <string-reader> "redefining-a-class-5" parse-stream drop
357     ] unit-test
358
359     [ ] [
360         "IN: parser.tests M: f foo ;"
361         <string-reader> "redefining-a-class-6" parse-stream drop
362     ] unit-test
363
364     [ f ] [ f "foo" "parser.tests" lookup execute ] unit-test
365
366     [ ] [
367         "IN: parser.tests TUPLE: foo ; GENERIC: foo ( a -- b )"
368         <string-reader> "redefining-a-class-5" parse-stream drop
369     ] unit-test
370
371     [ f ] [ f "foo" "parser.tests" lookup execute ] unit-test
372
373     [ ] [
374         "IN: parser.tests TUPLE: foo ; GENERIC: foo ( a -- b )"
375     <string-reader> "redefining-a-class-7" parse-stream drop
376     ] unit-test
377
378     [ f ] [ f "foo" "parser.tests" lookup execute ] unit-test
379
380     [ ] [
381         "IN: parser.tests TUPLE: foo ;"
382         <string-reader> "redefining-a-class-7" parse-stream drop
383     ] unit-test
384
385     [ t ] [ "foo" "parser.tests" lookup symbol? ] unit-test
386 ] times
387
388 [ "vocab:parser/test/assert-depth.factor" run-file ] must-fail
389
390 2 [
391     [ ] [
392         "IN: parser.tests DEFER: d-f-s d-f-s SYMBOL: d-f-s d-f-s"
393         <string-reader> "d-f-s-test" parse-stream drop
394     ] unit-test
395
396     [ ] [
397         "IN: parser.tests DEFER: d-f-s d-f-s FORGET: d-f-s SYMBOL: d-f-s d-f-s"
398         <string-reader> "d-f-s-test" parse-stream drop
399     ] unit-test
400
401     [ ] [
402         "IN: parser.tests DEFER: d-f-s d-f-s SYMBOL: d-f-s d-f-s"
403         <string-reader> "d-f-s-test" parse-stream drop
404     ] unit-test
405 ] times
406
407 [ ] [
408     [ "this-better-not-exist" forget-vocab ] with-compilation-unit
409 ] unit-test
410
411 [
412     "USE: this-better-not-exist" eval( -- )
413 ] must-fail
414
415 [ ": foo ;" eval( -- ) ] [ error>> error>> no-current-vocab? ] must-fail-with
416
417 [ 92 ] [ "CHAR: \\" eval( -- n ) ] unit-test
418 [ 92 ] [ "CHAR: \\\\" eval( -- n ) ] unit-test
419
420 [ ] [
421     {
422         "IN: parser.tests"
423         "USING: math arrays kernel ;"
424         "GENERIC: change-combination ( obj a -- b )"
425         "M: integer change-combination 2drop 1 ;"
426         "M: array change-combination 2drop 2 ;"
427     } "\n" join <string-reader> "change-combination-test" parse-stream drop
428 ] unit-test
429
430 [ ] [
431     {
432         "IN: parser.tests"
433         "USING: math arrays kernel ;"
434         "GENERIC# change-combination 1 ( obj a -- b )"
435         "M: integer change-combination 2drop 1 ;"
436         "M: array change-combination 2drop 2 ;"
437     } "\n" join <string-reader> "change-combination-test" parse-stream drop
438 ] unit-test
439
440 [ 2 ] [
441     "change-combination" "parser.tests" lookup
442     "methods" word-prop assoc-size
443 ] unit-test
444
445 [ ] [
446     2 [
447         "IN: parser.tests DEFER: twice-fails FORGET: twice-fails MIXIN: twice-fails"
448         <string-reader> "twice-fails-test" parse-stream drop
449     ] times
450 ] unit-test
451
452 [ [ ] ] [
453     "IN: parser.tests : staging-problem-test-1 ( -- a ) 1 ; : staging-problem-test-2 ( -- a ) staging-problem-test-1 ;"
454     <string-reader> "staging-problem-test" parse-stream
455 ] unit-test
456
457 [ t ] [ "staging-problem-test-1" "parser.tests" lookup >boolean ] unit-test
458
459 [ t ] [ "staging-problem-test-2" "parser.tests" lookup >boolean ] unit-test
460
461 [ [ ] ] [
462     "IN: parser.tests << : staging-problem-test-1 ( -- a ) 1 ; >> : staging-problem-test-2 ( -- a ) staging-problem-test-1 ;"
463     <string-reader> "staging-problem-test" parse-stream
464 ] unit-test
465
466 [ t ] [ "staging-problem-test-1" "parser.tests" lookup >boolean ] unit-test
467
468 [ t ] [ "staging-problem-test-2" "parser.tests" lookup >boolean ] unit-test
469
470 [ "DEFER: blahy" eval( -- ) ] [ error>> error>> no-current-vocab? ] must-fail-with
471
472 [
473     "IN: parser.tests SYNTAX: blahy ; FORGET: blahy" eval( -- )
474 ] [
475     error>> staging-violation?
476 ] must-fail-with
477
478 ! Bogus error message
479 DEFER: blahy
480
481 [ "IN: parser.tests USE: kernel TUPLE: blahy < tuple ; : blahy ( -- ) ; TUPLE: blahy < tuple ; : blahy ( -- ) ;" eval( -- ) ]
482 [ error>> error>> def>> \ blahy eq? ] must-fail-with
483
484 [ ] [ f lexer set f file set "Hello world" note. ] unit-test
485
486 [ "CHAR: \\u9999999999999" eval( -- n ) ] must-fail
487
488 SYMBOLS: a b c ;
489
490 [ a ] [ a ] unit-test
491 [ b ] [ b ] unit-test
492 [ c ] [ c ] unit-test
493
494 DEFER: blah
495
496 [ ] [ "IN: parser.tests GENERIC: blah ( -- )" eval( -- ) ] unit-test
497 [ ] [ "IN: parser.tests SYMBOLS: blah ;" eval( -- ) ] unit-test
498
499 [ f ] [ \ blah generic? ] unit-test
500 [ t ] [ \ blah symbol? ] unit-test
501
502 DEFER: blah1
503
504 [ "IN: parser.tests SINGLETONS: blah1 blah1 blah1 ;" eval( -- ) ]
505 [ error>> error>> def>> \ blah1 eq? ]
506 must-fail-with
507
508 IN: qualified.tests.foo
509 : x ( -- a ) 1 ;
510 : y ( -- a ) 5 ;
511 IN: qualified.tests.bar
512 : x ( -- a ) 2 ;
513 : y ( -- a ) 4 ;
514 IN: qualified.tests.baz
515 : x ( -- a ) 3 ;
516
517 QUALIFIED: qualified.tests.foo
518 QUALIFIED: qualified.tests.bar
519 [ 1 2 3 ] [ qualified.tests.foo:x qualified.tests.bar:x x ] unit-test
520
521 QUALIFIED-WITH: qualified.tests.bar p
522 [ 2 ] [ p:x ] unit-test
523
524 RENAME: x qualified.tests.baz => y
525 [ 3 ] [ y ] unit-test
526
527 FROM: qualified.tests.baz => x ;
528 [ 3 ] [ x ] unit-test
529 [ 3 ] [ y ] unit-test
530
531 EXCLUDE: qualified.tests.bar => x ;
532 [ 3 ] [ x ] unit-test
533 [ 4 ] [ y ] unit-test
534
535 [ "IN: qualified.tests FROM: qualified.tests => doesnotexist ;" eval( -- ) ]
536 [ error>> no-word-error? ] must-fail-with
537
538 [ "IN: qualified.tests RENAME: doesnotexist qualified.tests => blahx" eval( -- ) ]
539 [ error>> no-word-error? ] must-fail-with
540
541 ! Two similar bugs
542
543 ! Replace : def with something in << >>
544 /* [ [ ] ] [
545     "IN: parser.tests : was-once-a-word-bug ( -- ) ;"
546     <string-reader> "was-once-a-word-test" parse-stream
547 ] unit-test
548
549 [ t ] [ "was-once-a-word-bug" "parser.tests" lookup >boolean ] unit-test
550
551 [ [ ] ] [
552     "IN: parser.tests USE: words << \"was-once-a-word-bug\" \"parser.tests\" create [ ] (( -- )) define-declared >>"
553     <string-reader> "was-once-a-word-test" parse-stream
554 ] unit-test
555
556 [ t ] [ "was-once-a-word-bug" "parser.tests" lookup >boolean ] unit-test */
557
558 ! Replace : def with DEFER:
559 [ [ ] ] [
560     "IN: parser.tests : is-not-deferred ( -- ) ;"
561     <string-reader> "is-not-deferred" parse-stream
562 ] unit-test
563
564 [ t ] [ "is-not-deferred" "parser.tests" lookup >boolean ] unit-test
565 [ f ] [ "is-not-deferred" "parser.tests" lookup deferred? ] unit-test
566
567 [ [ ] ] [
568     "IN: parser.tests DEFER: is-not-deferred"
569     <string-reader> "is-not-deferred" parse-stream
570 ] unit-test
571
572 [ t ] [ "is-not-deferred" "parser.tests" lookup >boolean ] unit-test
573 [ t ] [ "is-not-deferred" "parser.tests" lookup deferred? ] unit-test
574
575 ! Forward-reference resolution case iterated using list in the wrong direction
576 [ [ ] ] [
577     "IN: parser.tests.forward-ref-1 DEFER: x DEFER: y"
578     <string-reader> "forward-ref-1" parse-stream
579 ] unit-test
580
581 [ [ ] ] [
582     "IN: parser.tests.forward-ref-2 DEFER: x DEFER: y"
583     <string-reader> "forward-ref-2" parse-stream
584 ] unit-test
585
586 [ [ ] ] [
587     "IN: parser.tests.forward-ref-3 FROM: parser.tests.forward-ref-1 => x y ; FROM: parser.tests.forward-ref-2 => x y ; : z ( -- ) x y ;"
588     <string-reader> "forward-ref-3" parse-stream
589 ] unit-test
590
591 [ t ] [
592     "z" "parser.tests.forward-ref-3" lookup def>> [ vocabulary>> ] map all-equal?
593 ] unit-test
594
595 [ [ ] ] [
596     "FROM: parser.tests.forward-ref-1 => x y ; FROM: parser.tests.forward-ref-2 => x y ; IN: parser.tests.forward-ref-3 : x ( -- ) ; : z ( -- ) x y ;"
597     <string-reader> "forward-ref-3" parse-stream
598 ] unit-test
599
600 [ f ] [
601     "z" "parser.tests.forward-ref-3" lookup def>> [ vocabulary>> ] map all-equal?
602 ] unit-test
603
604 [ [ ] ] [
605     "IN: parser.tests.forward-ref-3 FROM: parser.tests.forward-ref-1 => x y ; FROM: parser.tests.forward-ref-2 => x y ; : z ( -- ) x y ;"
606     <string-reader> "forward-ref-3" parse-stream
607 ] unit-test
608
609 [ t ] [
610     "z" "parser.tests.forward-ref-3" lookup def>> [ vocabulary>> ] map all-equal?
611 ] unit-test