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