4 # Scheme scanner for CodeRay (by closure).
5 # Thanks to murphy for putting CodeRay into public.
12 lambda let let* letrec syntax-case define-syntax let-syntax
13 letrec-syntax begin define quote if or and cond case do delay
14 quasiquote set! cons force call-with-current-continuation call/cc
17 IDENT_KIND = CaseIgnoringWordList.new(:ident).
18 add(CORE_FORMS, :reserved)
20 #IDENTIFIER_INITIAL = /[a-z!@\$%&\*\/\:<=>\?~_\^]/i
21 #IDENTIFIER_SUBSEQUENT = /#{IDENTIFIER_INITIAL}|\d|\.|\+|-/
22 #IDENTIFIER = /#{IDENTIFIER_INITIAL}#{IDENTIFIER_SUBSEQUENT}*|\+|-|\.{3}/
23 IDENTIFIER = /[a-zA-Z!@$%&*\/:<=>?~_^][\w!@$%&*\/:<=>?~^.+\-]*|[+-]|\.\.\./
36 EXP = /#{EXP_MARK}#{SIGN}#{DIGIT}+/
38 PREFIX10 = /#{RADIX10}?#{EXACTNESS}?|#{EXACTNESS}?#{RADIX10}?/
39 PREFIX16 = /#{RADIX16}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX16}/
40 PREFIX8 = /#{RADIX8}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX8}/
41 PREFIX2 = /#{RADIX2}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX2}/
42 UINT10 = /#{DIGIT10}+#*/
43 UINT16 = /#{DIGIT16}+#*/
44 UINT8 = /#{DIGIT8}+#*/
45 UINT2 = /#{DIGIT2}+#*/
46 DECIMAL = /#{DIGIT10}+#+\.#*#{SUFFIX}|#{DIGIT10}+\.#{DIGIT10}*#*#{SUFFIX}|\.#{DIGIT10}+#*#{SUFFIX}|#{UINT10}#{EXP}/
47 UREAL10 = /#{UINT10}\/#{UINT10}|#{DECIMAL}|#{UINT10}/
48 UREAL16 = /#{UINT16}\/#{UINT16}|#{UINT16}/
49 UREAL8 = /#{UINT8}\/#{UINT8}|#{UINT8}/
50 UREAL2 = /#{UINT2}\/#{UINT2}|#{UINT2}/
51 REAL10 = /#{SIGN}#{UREAL10}/
52 REAL16 = /#{SIGN}#{UREAL16}/
53 REAL8 = /#{SIGN}#{UREAL8}/
54 REAL2 = /#{SIGN}#{UREAL2}/
55 IMAG10 = /i|#{UREAL10}i/
56 IMAG16 = /i|#{UREAL16}i/
57 IMAG8 = /i|#{UREAL8}i/
58 IMAG2 = /i|#{UREAL2}i/
59 COMPLEX10 = /#{REAL10}@#{REAL10}|#{REAL10}\+#{IMAG10}|#{REAL10}-#{IMAG10}|\+#{IMAG10}|-#{IMAG10}|#{REAL10}/
60 COMPLEX16 = /#{REAL16}@#{REAL16}|#{REAL16}\+#{IMAG16}|#{REAL16}-#{IMAG16}|\+#{IMAG16}|-#{IMAG16}|#{REAL16}/
61 COMPLEX8 = /#{REAL8}@#{REAL8}|#{REAL8}\+#{IMAG8}|#{REAL8}-#{IMAG8}|\+#{IMAG8}|-#{IMAG8}|#{REAL8}/
62 COMPLEX2 = /#{REAL2}@#{REAL2}|#{REAL2}\+#{IMAG2}|#{REAL2}-#{IMAG2}|\+#{IMAG2}|-#{IMAG2}|#{REAL2}/
63 NUM10 = /#{PREFIX10}?#{COMPLEX10}/
64 NUM16 = /#{PREFIX16}#{COMPLEX16}/
65 NUM8 = /#{PREFIX8}#{COMPLEX8}/
66 NUM2 = /#{PREFIX2}#{COMPLEX2}/
67 NUM = /#{NUM10}|#{NUM16}|#{NUM8}|#{NUM2}/
70 def scan_tokens tokens,options
73 ident_kind = IDENT_KIND
80 if scan(/ \s+ | \\\n /x)
82 elsif scan(/['\(\[\)\]]|#\(/)
86 elsif scan(/#\\(?:newline|space|.?)/)
90 elsif scan(/#{IDENTIFIER}/o)
91 kind = ident_kind[matched]
95 tokens << [:open, :string]
97 tokens << ['"', :delimiter]
99 elsif scan(/#{NUM}/o) and not matched.empty?
106 if scan(/[^"\\]+/) or scan(/\\.?/)
109 tokens << ['"', :delimiter]
110 tokens << [:close, :string]
114 raise_inspect "else case \" reached; %p not handled." % peek(1),
119 raise "else case reached"
123 if $DEBUG and not kind
124 raise_inspect 'Error token %p in line %d' %
125 [[match, kind], line], tokens
127 raise_inspect 'Empty token', tokens, state unless match
129 tokens << [match, kind]
134 tokens << [:close, :string]