Mercurial > hg > soundsoftware-site
comparison vendor/plugins/coderay-0.9.2/lib/coderay/scanners/scheme.rb @ 0:513646585e45
* Import Redmine trunk SVN rev 3859
author | Chris Cannam |
---|---|
date | Fri, 23 Jul 2010 15:52:44 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:513646585e45 |
---|---|
1 module CodeRay | |
2 module Scanners | |
3 | |
4 # Scheme scanner for CodeRay (by closure). | |
5 # Thanks to murphy for putting CodeRay into public. | |
6 class Scheme < Scanner | |
7 | |
8 # TODO: function defs | |
9 # TODO: built-in functions | |
10 | |
11 register_for :scheme | |
12 file_extension 'scm' | |
13 | |
14 CORE_FORMS = %w[ | |
15 lambda let let* letrec syntax-case define-syntax let-syntax | |
16 letrec-syntax begin define quote if or and cond case do delay | |
17 quasiquote set! cons force call-with-current-continuation call/cc | |
18 ] | |
19 | |
20 IDENT_KIND = CaseIgnoringWordList.new(:ident). | |
21 add(CORE_FORMS, :reserved) | |
22 | |
23 #IDENTIFIER_INITIAL = /[a-z!@\$%&\*\/\:<=>\?~_\^]/i | |
24 #IDENTIFIER_SUBSEQUENT = /#{IDENTIFIER_INITIAL}|\d|\.|\+|-/ | |
25 #IDENTIFIER = /#{IDENTIFIER_INITIAL}#{IDENTIFIER_SUBSEQUENT}*|\+|-|\.{3}/ | |
26 IDENTIFIER = /[a-zA-Z!@$%&*\/:<=>?~_^][\w!@$%&*\/:<=>?~^.+\-]*|[+-]|\.\.\./ | |
27 DIGIT = /\d/ | |
28 DIGIT10 = DIGIT | |
29 DIGIT16 = /[0-9a-f]/i | |
30 DIGIT8 = /[0-7]/ | |
31 DIGIT2 = /[01]/ | |
32 RADIX16 = /\#x/i | |
33 RADIX8 = /\#o/i | |
34 RADIX2 = /\#b/i | |
35 RADIX10 = /\#d/i | |
36 EXACTNESS = /#i|#e/i | |
37 SIGN = /[\+-]?/ | |
38 EXP_MARK = /[esfdl]/i | |
39 EXP = /#{EXP_MARK}#{SIGN}#{DIGIT}+/ | |
40 SUFFIX = /#{EXP}?/ | |
41 PREFIX10 = /#{RADIX10}?#{EXACTNESS}?|#{EXACTNESS}?#{RADIX10}?/ | |
42 PREFIX16 = /#{RADIX16}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX16}/ | |
43 PREFIX8 = /#{RADIX8}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX8}/ | |
44 PREFIX2 = /#{RADIX2}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX2}/ | |
45 UINT10 = /#{DIGIT10}+#*/ | |
46 UINT16 = /#{DIGIT16}+#*/ | |
47 UINT8 = /#{DIGIT8}+#*/ | |
48 UINT2 = /#{DIGIT2}+#*/ | |
49 DECIMAL = /#{DIGIT10}+#+\.#*#{SUFFIX}|#{DIGIT10}+\.#{DIGIT10}*#*#{SUFFIX}|\.#{DIGIT10}+#*#{SUFFIX}|#{UINT10}#{EXP}/ | |
50 UREAL10 = /#{UINT10}\/#{UINT10}|#{DECIMAL}|#{UINT10}/ | |
51 UREAL16 = /#{UINT16}\/#{UINT16}|#{UINT16}/ | |
52 UREAL8 = /#{UINT8}\/#{UINT8}|#{UINT8}/ | |
53 UREAL2 = /#{UINT2}\/#{UINT2}|#{UINT2}/ | |
54 REAL10 = /#{SIGN}#{UREAL10}/ | |
55 REAL16 = /#{SIGN}#{UREAL16}/ | |
56 REAL8 = /#{SIGN}#{UREAL8}/ | |
57 REAL2 = /#{SIGN}#{UREAL2}/ | |
58 IMAG10 = /i|#{UREAL10}i/ | |
59 IMAG16 = /i|#{UREAL16}i/ | |
60 IMAG8 = /i|#{UREAL8}i/ | |
61 IMAG2 = /i|#{UREAL2}i/ | |
62 COMPLEX10 = /#{REAL10}@#{REAL10}|#{REAL10}\+#{IMAG10}|#{REAL10}-#{IMAG10}|\+#{IMAG10}|-#{IMAG10}|#{REAL10}/ | |
63 COMPLEX16 = /#{REAL16}@#{REAL16}|#{REAL16}\+#{IMAG16}|#{REAL16}-#{IMAG16}|\+#{IMAG16}|-#{IMAG16}|#{REAL16}/ | |
64 COMPLEX8 = /#{REAL8}@#{REAL8}|#{REAL8}\+#{IMAG8}|#{REAL8}-#{IMAG8}|\+#{IMAG8}|-#{IMAG8}|#{REAL8}/ | |
65 COMPLEX2 = /#{REAL2}@#{REAL2}|#{REAL2}\+#{IMAG2}|#{REAL2}-#{IMAG2}|\+#{IMAG2}|-#{IMAG2}|#{REAL2}/ | |
66 NUM10 = /#{PREFIX10}?#{COMPLEX10}/ | |
67 NUM16 = /#{PREFIX16}#{COMPLEX16}/ | |
68 NUM8 = /#{PREFIX8}#{COMPLEX8}/ | |
69 NUM2 = /#{PREFIX2}#{COMPLEX2}/ | |
70 NUM = /#{NUM10}|#{NUM16}|#{NUM8}|#{NUM2}/ | |
71 | |
72 private | |
73 def scan_tokens tokens,options | |
74 | |
75 state = :initial | |
76 ident_kind = IDENT_KIND | |
77 | |
78 until eos? | |
79 kind = match = nil | |
80 | |
81 case state | |
82 when :initial | |
83 if scan(/ \s+ | \\\n /x) | |
84 kind = :space | |
85 elsif scan(/['\(\[\)\]]|#\(/) | |
86 kind = :operator_fat | |
87 elsif scan(/;.*/) | |
88 kind = :comment | |
89 elsif scan(/#\\(?:newline|space|.?)/) | |
90 kind = :char | |
91 elsif scan(/#[ft]/) | |
92 kind = :pre_constant | |
93 elsif scan(/#{IDENTIFIER}/o) | |
94 kind = ident_kind[matched] | |
95 elsif scan(/\./) | |
96 kind = :operator | |
97 elsif scan(/"/) | |
98 tokens << [:open, :string] | |
99 state = :string | |
100 tokens << ['"', :delimiter] | |
101 next | |
102 elsif scan(/#{NUM}/o) and not matched.empty? | |
103 kind = :integer | |
104 elsif getch | |
105 kind = :error | |
106 end | |
107 | |
108 when :string | |
109 if scan(/[^"\\]+/) or scan(/\\.?/) | |
110 kind = :content | |
111 elsif scan(/"/) | |
112 tokens << ['"', :delimiter] | |
113 tokens << [:close, :string] | |
114 state = :initial | |
115 next | |
116 else | |
117 raise_inspect "else case \" reached; %p not handled." % peek(1), | |
118 tokens, state | |
119 end | |
120 | |
121 else | |
122 raise "else case reached" | |
123 end | |
124 | |
125 match ||= matched | |
126 if $CODERAY_DEBUG and not kind | |
127 raise_inspect 'Error token %p in line %d' % | |
128 [[match, kind], line], tokens | |
129 end | |
130 raise_inspect 'Empty token', tokens, state unless match | |
131 | |
132 tokens << [match, kind] | |
133 | |
134 end # until eos | |
135 | |
136 if state == :string | |
137 tokens << [:close, :string] | |
138 end | |
139 | |
140 tokens | |
141 | |
142 end #scan_tokens | |
143 end #class | |
144 end #module scanners | |
145 end #module coderay |