1#lang racket
2
3(require (only-in srfi/13 string-contains))
4
5; Single-line comment style.
6
7;; Single-line comment style.
8
9#| Multi-line comment style ... on one line |#
10
11#|
12Multi-line comment style ...
13#|### #| nested |#||| |#
14... on multiple lines
15|#
16
17#;(s-expression comment (one line))
18
19#;
20(s-expression comment
21              (multiple lines))
22
23#! shebang comment
24
25#!/shebang comment
26
27#! shebang \
28comment
29
30#!/shebang \
31comment
32
33;; Uncommented numbers after single-line comments
34;; NEL…133
35;; LS
8232
36;; PS
8233
37
38#reader racket
39(define(a-function x #:keyword [y 0])
40  (define foo0 'symbol) ; ()
41  [define foo1 'symbol] ; []
42  {define foo2 'symbol} ; {}
43  (define 100-Continue 'symbol)
44  (and (append (car'(1 2 3))))
45  (regexp-match? #rx"foobar" "foobar")
46  (regexp-match? #px"\"foo\\(bar\\)?\"" "foobar")
47  (regexp-match? #rx#"foobar" "foobar")
48  (regexp-match? #px#"foobar" "foobar")
49  (define #csa 1)
50  #Ci (let ([#%A|||b #true C
51\|d "foo"])
52        (displayln #cS #%\ab\ #true\ C\
53\\d||))
54  (for/list ([x (in-list (list 1 2 (list 3 4)))])
55    (cond
56      [(pair? x) (car x)]
57      [else x])))
58
59;; Literals
60(values
61 ;; #b
62 #b1
63 #b+1
64 #b-1
65 #b.1
66 #b1.
67 #b0.1
68 #b+0.1
69 #b-0.1
70 #b1/10
71 #b+1/10
72 #b-1/10
73 #b1e11
74 #b+1e11
75 #b-1e11
76 #b.1e11
77 #b1.e11
78 #b0.1e11
79 #b+0.1e11
80 #b-0.1e11
81 #b1/10e11
82 #b+1/10e11
83 #b-1/10e11
84 #b+i
85 #b1+i
86 #b+1+i
87 #b-1+i
88 #b.1+i
89 #b1.+i
90 #b0.1+i
91 #b+0.1+i
92 #b-0.1+i
93 #b1/10+i
94 #b+1/10+i
95 #b-1/10+i
96 #b1e11+i
97 #b+1e11+i
98 #b-1e11+i
99 #b1.e11+i
100 #b.1e11+i
101 #b0.1e11+i
102 #b+0.1e11+i
103 #b-0.1e11+i
104 #b1/10e11+i
105 #b+1/10e11+i
106 #b-1/10e11+i
107 #b+1i
108 #b1+1i
109 #b+1+1i
110 #b-1+1i
111 #b1.+1i
112 #b.1+1i
113 #b0.1+1i
114 #b+0.1+1i
115 #b-0.1+1i
116 #b1/10+1i
117 #b+1/10+1i
118 #b-1/10+1i
119 #b1e11+1i
120 #b+1e11+1i
121 #b-1e11+1i
122 #b.1e11+1i
123 #b0.1e11+1i
124 #b+0.1e11+1i
125 #b-0.1e11+1i
126 #b1/10e11+1i
127 #b+1/10e11+1i
128 #b-1/10e11+1i
129 #b+1/10e11i
130 #b1+1/10e11i
131 #b+1+1/10e11i
132 #b-1+1/10e11i
133 #b.1+1/10e11i
134 #b0.1+1/10e11i
135 #b+0.1+1/10e11i
136 #b-0.1+1/10e11i
137 #b1/10+1/10e11i
138 #b+1/10+1/10e11i
139 #b-1/10+1/10e11i
140 #b1e11+1/10e11i
141 #b+1e11+1/10e11i
142 #b-1e11+1/10e11i
143 #b.1e11+1/10e11i
144 #b0.1e11+1/10e11i
145 #b+0.1e11+1/10e11i
146 #b-0.1e11+1/10e11i
147 #b1/10e11+1/10e11i
148 #b+1/10e11+1/10e11i
149 #b-1/10e11+1/10e11i
150 ;; #d
151 #d1
152 #d+1
153 #d-1
154 #d.1
155 #d1.
156 #d1.2
157 #d+1.2
158 #d-1.2
159 #d1/2
160 #d+1/2
161 #d-1/2
162 #d1e3
163 #d+1e3
164 #d-1e3
165 #d.1e3
166 #d1.e3
167 #d1.2e3
168 #d+1.2e3
169 #d-1.2e3
170 #d1/2e3
171 #d+1/2e3
172 #d-1/2e3
173 #d+i
174 #d1+i
175 #d+1+i
176 #d-1+i
177 #d.1+i
178 #d1.+i
179 #d1.2+i
180 #d+1.2+i
181 #d-1.2+i
182 #d1/2+i
183 #d+1/2+i
184 #d-1/2+i
185 #d1e3+i
186 #d+1e3+i
187 #d-1e3+i
188 #d1.e3+i
189 #d.1e3+i
190 #d1.2e3+i
191 #d+1.2e3+i
192 #d-1.2e3+i
193 #d1/2e3+i
194 #d+1/2e3+i
195 #d-1/2e3+i
196 #d+1i
197 #d1+1i
198 #d+1+1i
199 #d-1+1i
200 #d1.+1i
201 #d.1+1i
202 #d1.2+1i
203 #d+1.2+1i
204 #d-1.2+1i
205 #d1/2+1i
206 #d+1/2+1i
207 #d-1/2+1i
208 #d1e3+1i
209 #d+1e3+1i
210 #d-1e3+1i
211 #d.1e3+1i
212 #d1.2e3+1i
213 #d+1.2e3+1i
214 #d-1.2e3+1i
215 #d1/2e3+1i
216 #d+1/2e3+1i
217 #d-1/2e3+1i
218 #d+1/2e3i
219 #d1+1/2e3i
220 #d+1+1/2e3i
221 #d-1+1/2e3i
222 #d.1+1/2e3i
223 #d1.2+1/2e3i
224 #d+1.2+1/2e3i
225 #d-1.2+1/2e3i
226 #d1/2+1/2e3i
227 #d+1/2+1/2e3i
228 #d-1/2+1/2e3i
229 #d1e3+1/2e3i
230 #d+1e3+1/2e3i
231 #d-1e3+1/2e3i
232 #d.1e3+1/2e3i
233 #d1.2e3+1/2e3i
234 #d+1.2e3+1/2e3i
235 #d-1.2e3+1/2e3i
236 #d1/2e3+1/2e3i
237 #d+1/2e3+1/2e3i
238 #d-1/2e3+1/2e3i
239 ;; Extflonums
240 +nan.t
241 1t3
242 +1t3
243 -1t3
244 .1t3
245 1.t3
246 1.2t3
247 +1.2t3
248 -1.2t3
249 1/2t3
250 +1/2t3
251 -1/2t3
252 1#t0
253 1.#t0
254 .2#t0
255 1.2#t0
256 1#/2t0
257 1/2#t0
258 1#/2#t0
259 1#t3
260 1.#t3
261 .2#t3
262 1.2#t3
263 1#/2t3
264 1/2#t3
265 1#/2#t3
266 ;; No # reader prefix -- same as #d
267 -1.23
268 1.123
269 1e3
270 1e-22
271 1/2
272 -1/2
273 1
274 -1
275 ;; #e
276 #e-1.23
277 #e1.123
278 #e1e3
279 #e1e-22
280 #e1
281 #e-1
282 #e1/2
283 #e-1/2
284 ;; #d#e
285 #d#e-1.23
286 #d#e1.123
287 #d#e1e3
288 #d#e1e-22
289 #d#e1
290 #d#e-1
291 #d#e1/2
292 #d#e-1/2
293 ;; #e#d
294 #e#d-1.23
295 #e#d1.123
296 #e#d1e3
297 #e#d1e-22
298 #e#d1
299 #e#d-1
300 #e#d1/2
301 #e#d-1/2
302 ;; #i always float
303 #i-1.23
304 #i1.123
305 #i1e3
306 #i1e-22
307 #i1/2
308 #i-1/2
309 #i1
310 #i-1
311 ;; Implicitly inexact numbers
312 +nan.0
313 1#
314 1.#
315 .2#
316 1.2#
317 1#/2
318 1/2#
319 1#/2#
320 1#e3
321 1.#e3
322 .2#e3
323 1.2#e3
324 1#/2e3
325 1/2#e3
326 1#/2#e3
327 +nan.0+i
328 1#+i
329 1.#+i
330 .2#+i
331 1.2#+i
332 1#/2+i
333 1/2#+i
334 1#/2#+i
335 1#e3+i
336 1.#e3+i
337 .2#e3+i
338 1.2#e3+i
339 1#/2e3+i
340 1/2#e3+i
341 1#/2#e3+i
342 +nan.0i
343 +1#i
344 +1.#i
345 +.2#i
346 +1.2#i
347 +1#/2i
348 +1/2#i
349 +1#/2#i
350 +1#e3i
351 +1.#e3i
352 +.2#e3i
353 +1.2#e3i
354 +1#/2e3i
355 +1/2#e3i
356 +1#/2#e3i
357 0+nan.0i
358 0+1#i
359 0+1.#i
360 0+.2#i
361 0+1.2#i
362 0+1#/2i
363 0+1/2#i
364 0+1#/2#i
365 0+1#e3i
366 0+1.#e3i
367 0+.2#e3i
368 0+1.2#e3i
369 0+1#/2e3i
370 0+1/2#e3i
371 0+1#/2#e3i
372 1#/2#e3+nan.0i
373 1#/2#e3+1#i
374 1#/2#e3+1.#i
375 1#/2#e3+.2#i
376 1#/2#e3+1.2#i
377 1#/2#e3+1#/2i
378 1#/2#e3+1/2#i
379 1#/2#e3+1#/2#i
380 1#/2#e3+1#e3i
381 1#/2#e3+1.#e3i
382 1#/2#e3+.2#e3i
383 1#/2#e3+1.2#e3i
384 1#/2#e3+1#/2e3i
385 1#/2#e3+1/2#e3i
386 1#/2#e3+1#/2#e3i
387 +nan.0@1
388 1#@1
389 1.#@1
390 .2#@1
391 1.2#@1
392 1#/2@1
393 1/2#@1
394 1#/2#@1
395 1#e3@1
396 1.#e3@1
397 .2#e3@1
398 1.2#e3@1
399 1#/2e3@1
400 1/2#e3@1
401 1#/2#e3@1
402 1@+nan.0
403 1@1#
404 1@1.#
405 1@.2#
406 1@1.2#
407 1@1#/2
408 1@1/2#
409 1@1#/2#
410 1@1#e3
411 1@1.#e3
412 1@.2#e3
413 1@1.2#e3
414 1@1#/2e3
415 1@1/2#e3
416 1@1#/2#e3
417 1#/2#e3@1#
418 1#/2#e3@1.#
419 1#/2#e3@.2#
420 1#/2#e3@1.2#
421 1#/2#e3@1#/2
422 1#/2#e3@1/2#
423 1#/2#e3@1#/2#
424 1#/2#e3@1#e3
425 1#/2#e3@1.#e3
426 1#/2#e3@.2#e3
427 1#/2#e3@1.2#e3
428 1#/2#e3@1#/2e3
429 1#/2#e3@1/2#e3
430 1#/2#e3@1#/2#e3
431 ;; #o
432 #o777.777
433 #o-777.777
434 #o777e777
435 #o777e-777
436 #o3/7
437 #o-3/7
438 #o777
439 #o-777
440 #e#o777.777
441 #e#o-777.777
442 #e#o777e777
443 #e#o777e-777
444 #e#o3/7
445 #e#o-3/7
446 #e#o777
447 #e#o-777
448 #i#o777.777
449 #i#o-777.777
450 #i#o777e777
451 #i#o777e-777
452 #i#o3/7
453 #i#o-3/7
454 #i#o777
455 #i#o-777
456 ;; #x
457 #x-f.f
458 #xf.f
459 #xfsf
460 #xfs-f
461 #x7/f
462 #x-7/f
463 #x-f
464 #xf
465 #e#x-f.f
466 #e#xf.f
467 #e#xfsf
468 #e#xfs-f
469 #e#x7/f
470 #e#x-7/f
471 #e#x-f
472 #e#xf
473 #i#x-f.f
474 #i#xf.f
475 #i#xfsf
476 #i#xfs-f
477 #i#x7/f
478 #i#x-7/f
479 #i#x-f
480 #i#xf
481 ;; Not numbers
482 '-1.23x
483 '1.123x
484 '1e3x
485 '1e-22x
486 '1/2x
487 '-1/2x
488 '1x
489 '-1x
490 '/
491 '1/
492 '/2
493 '1//2
494 '1e3.
495 '1e
496 'e3
497 '.i
498 '1.2.3
499 '1..2
500 '.1.
501 '@
502 '1@
503 '@2
504 '1@@2
505 '1@2@3
506 '1@2i
507 '1+-2i
508 '1i+2
509 '1i+2i
510 '1+2i+3i
511 '-
512 '--1
513 '+
514 '++1
515 '1/2.3
516 '1#2
517 '1#.2
518 '1.#2
519 '.#2
520 '+nan.t+nan.ti
521 '+nan.t@nan.t
522 ;; Booleans
523 #t
524 #T
525 #true
526 #f
527 #F
528 #false
529 ;; Characters, strings, and byte strings
530 #\
531 #\Null9
532 #\n9
533 #\99
534 #\0009
535 #\u3BB
536 #\u03BB9
537 #\U3BB
538 #\U000003BB9
539 #\λ9
540 "string\
541 \a.\b.\t.\n.\v.\f.\r.\e.\".\'.\\.\1.\123.\1234.\x9.\x30.\x303"
542 "\u9.\u1234.\u12345.\U9.\U00100000.\U001000000"
543 #"byte-string\7\xff\t"
544 #<<HERE STRING
545lorem ipsum
546dolor sit amet
547consectetur HERE STRING
548HERE STRING adipisicing elit
549HERE STRING
550 #|
551HERE STRING
552|#
553 ;; Other literals
554 #(vector)
555 #20()
556 #s[prefab-structure 1 2 3]
557 #&{box}
558 #hash(("a" . 5))
559 #hasheq((a . 5) (b . 7))
560 #hasheqv((a . 5) (b . 7))
561 #'(define x 1)
562 #`(define x #,pi)
563 ;; quote, quasiquote, and unquote
564 'pi
565 ' pi
566 ''pi
567 '`pi
568 '`,pi
569 ',pi
570 `pi
571 ` pi
572 `'pi
573 ``pi
574 `,pi
575 ` , pi
576 `,'pi
577 `,`pi
578 `,`,pi
579 '(+)
580 ' (+)
581 ''(+)
582 '`(+)
583 ',(+)
584 `(+)
585 ` (+)
586 `'(+)
587 ``(+)
588 `,(+)
589 ` , (+)
590 `,'(+)
591 `,`(+)
592 `,`,(+)
593 #readerracket/base'pi.f
594 '#readerracket/base pi.f
595 #readerracket/base`pi.f
596 `#readerracket/base pi.f
597 #readerracket/base`,pi.f
598 `#readerracket/base,pi.f
599 `,#readerracket/base pi.f
600 #readerracket/base'`,pi.f
601 '#readerracket/base`,pi.f
602 '`#readerracket/base,pi.f
603 '`,#readerracket/base pi.f
604 #readerracket/base'(*)
605 '#readerracket/base(*)
606 #readerracket/base`(*)
607 `#readerracket/base(*)
608 #readerracket/base`,(*)
609 `#readerracket/base,(*)
610 `,#readerracket/base(*)
611 #readerracket/base'`,(*)
612 '#readerracket/base`,(*)
613 '`#readerracket/base,(*)
614 '`,#readerracket/base(*)
615 (quote pi)
616 (quote (quote pi))
617 (quote (quasiquote pi))
618 (quote (quasiquote (unquote pi)))
619 (quote (unquote pi))
620 (quasiquote pi)
621 (quasiquote (quote pi))
622 (quasiquote (quasiquote pi))
623 (quasiquote (unquote pi))
624 (quasiquote (unquote (quote pi)))
625 (quasiquote (unquote (quasiquote pi)))
626 (quasiquote (unquote (quasiquote (unquote pi))))
627 (quote (+))
628 (quote (quote (+)))
629 (quote (quasiquote (+)))
630 (quote (unquote (+)))
631 (quasiquote (+))
632 (quasiquote (quote (+)))
633 (quasiquote (quasiquote (+)))
634 (quasiquote (unquote (+)))
635 (quasiquote (unquote (quote (+))))
636 (quasiquote (unquote (quasiquote (+))))
637 (quasiquote (unquote (quasiquote (unquote (+)))))
638 #reader racket/base (quote pi.f)
639 (quote #reader racket/base pi.f)
640 #reader racket/base (quasiquote pi.f)
641 (quasiquote #reader racket/base pi.f)
642 #reader racket/base (quasiquote (unquote pi.f))
643 (quasiquote #reader racket/base (unquote pi.f))
644 (quasiquote (unquote #reader racket/base pi.f))
645 #reader racket/base (quote (quasiquote (unquote pi.f)))
646 (quote #reader racket/base (quasiquote (unquote pi.f)))
647 (quote (quasiquote #reader racket/base (unquote pi.f)))
648 (quote (quasiquote (unquote #reader racket/base pi.f)))
649 #reader racket/base (quote (*))
650 (quote #reader racket/base (*))
651 #reader racket/base (quasiquote (*))
652 (quasiquote #reader racket/base (*))
653 #reader racket/base (quasiquote (unquote (*)))
654 (quasiquote #reader racket/base (unquote (*)))
655 (quasiquote (unquote #reader racket/base (*)))
656 #reader racket/base (quote (quasiquote (unquote (*))))
657 (quote #reader racket/base (quasiquote (unquote (*))))
658 (quote (quasiquote #reader racket/base (unquote (*))))
659 (quote (quasiquote (unquote #reader racket/base (*))))
660 ;; Make sure non-identifiers work with quotes
661 ' "" pi
662 ' #t pi
663 ' #() pi
664 ' #s(s) pi
665 ' #\u3BB pi
666 ' #\U000003BB pi
667 ' #\space pi
668 ' #\. pi
669 ' #"" pi
670 ' #:kw pi
671 ' #&b pi
672 ' #'(define x 1) pi
673 ' #`(define x #,pi) pi
674 ' #I0 pi
675 ' #E0 pi
676 ' #X0 pi
677 ' #O0 pi
678 ' #D0 pi
679 ' #B0 pi
680 ' #<<EOF
681EOF
682 pi
683 ' #rx"" pi
684 ' #rx#"" pi
685 ' #px"" pi
686 ' #px#"" pi
687 ' #hash() pi
688 ' #hasheq[] pi
689 ' #hasheqv{} pi
690 ' #1(v) pi
691 )
692
693;; Use the following to generate lists of built-ins and keywords.
694;; Run
695;;   (displayln (wrap-lines KEYWORDS))
696;;   (displayln (wrap-lines BUILTINS))
697;; and copy the results into RacketLexer._keywords and RacketLexer._builtins.
698
699;; (-> (listof string?) string?)
700;; Appends all the strings together, quoting them as appropriate for Python,
701;; with commas and spaces between them, wrapping at 80 characters, with an
702;; indentation of 8 spaces.
703(define (wrap-lines lst)
704  (define INDENTATION '"        ")
705  (define WIDTH '80)
706  (define (wrap-lines* lst done-lines current-line)
707    (if (null? lst)
708        (string-append (foldr string-append "" done-lines) current-line)
709        (let* ([str (first lst)]
710               [wrapped-str (if (regexp-match-exact? '#px"[[:ascii:]]+" str)
711                                (string-append "'" str "',")
712                                (string-append "u'" str "',"))]
713               [new-line (string-append current-line " " wrapped-str)])
714          (if ((string-length new-line) . >= . WIDTH)
715              (wrap-lines* (rest lst)
716                           (append done-lines
717                                   `(,(string-append current-line "\n")))
718                           (string-append INDENTATION wrapped-str))
719              (wrap-lines* (rest lst)
720                           done-lines
721                           new-line)))))
722  (wrap-lines* lst '() INDENTATION))
723
724;; (-> string? boolean?)
725;; Returns #t if str represents a syntax identifier in the current namespace,
726;; otherwise #f.
727(define (syntax-identifier? str)
728    (with-handlers ([exn? exn?])
729      (not (eval (call-with-input-string str read)))))
730
731(define RACKET-NAMESPACE
732  (parameterize ([current-namespace (make-base-namespace)])
733    (namespace-require 'racket)
734    (current-namespace)))
735
736(define BOUND-IDENTIFIERS
737  (parameterize ([current-namespace RACKET-NAMESPACE])
738    (sort (map symbol->string (namespace-mapped-symbols))
739          string<=?)))
740
741(define-values (KEYWORDS BUILTINS)
742  (parameterize ([current-namespace RACKET-NAMESPACE])
743    (partition syntax-identifier? BOUND-IDENTIFIERS)))
744