Skip to content

Commit 4e2cb29

Browse files
committed
AVR Assembler Scanner by Andreas Schwarz
1 parent 3effca8 commit 4e2cb29

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

lib/coderay/scanners/avrasm.rb

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
module CodeRay
2+
module Scanners
3+
4+
class AVRASM < Scanner
5+
6+
register_for :avrasm
7+
8+
RESERVED_WORDS = [
9+
]
10+
11+
PREDEFINED_TYPES = [
12+
]
13+
14+
PREDEFINED_CONSTANTS = [
15+
]
16+
17+
IDENT_KIND = CaseIgnoringWordList.new(:ident).
18+
add(RESERVED_WORDS, :reserved).
19+
add(PREDEFINED_TYPES, :pre_type).
20+
add(PREDEFINED_CONSTANTS, :pre_constant)
21+
22+
ESCAPE = / [rbfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
23+
UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x
24+
25+
def scan_tokens tokens, options
26+
27+
state = :initial
28+
29+
until eos?
30+
31+
kind = nil
32+
match = nil
33+
34+
case state
35+
36+
when :initial
37+
38+
if scan(/ \s+ | \\\n /x)
39+
kind = :space
40+
41+
elsif scan(/;.*/x)
42+
kind = :comment
43+
44+
elsif scan(/\.(\w*)/x)
45+
kind = :preprocessor
46+
state = :include_expected if self[1] == 'include'
47+
48+
elsif scan(/@[0-9]+/)
49+
kind = :preprocessor
50+
51+
elsif scan(/ [-+*\/=<>?:;,!&^|()\[\]{}~%]+ | \.(?!\d) /x)
52+
kind = :operator
53+
54+
elsif scan(/r[0-9]+/i)
55+
# register R0-R31
56+
kind = :pre_constant
57+
58+
elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
59+
kind = IDENT_KIND[match]
60+
if kind == :ident and check(/:(?!:)/)
61+
match << scan(/:/)
62+
kind = :label
63+
end
64+
65+
elsif match = scan(/"/)
66+
tokens << [:open, :string]
67+
state = :string
68+
kind = :delimiter
69+
70+
elsif scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
71+
kind = :char
72+
73+
elsif scan(/0[xX][0-9A-Fa-f]+/)
74+
kind = :integer
75+
76+
elsif scan(/(?:0[0-7]+)(?![89.eEfF])/)
77+
kind = :integer
78+
79+
elsif scan(/0[bB][0-9A-Fa-f]+/)
80+
kind = :integer
81+
82+
elsif scan(/(?:\d+)(?![.eEfF])/)
83+
kind = :integer
84+
85+
elsif scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
86+
kind = :float
87+
88+
else
89+
getch
90+
kind = :error
91+
92+
end
93+
94+
when :string
95+
if scan(/[^\\\n"]+/)
96+
kind = :content
97+
elsif scan(/"/)
98+
tokens << ['"', :delimiter]
99+
tokens << [:close, :string]
100+
state = :initial
101+
next
102+
elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
103+
kind = :char
104+
elsif scan(/ \\ | $ /x)
105+
tokens << [:close, :string]
106+
kind = :error
107+
state = :initial
108+
else
109+
raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
110+
end
111+
112+
when :include_expected
113+
if scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/)
114+
kind = :include
115+
state = :initial
116+
117+
elsif match = scan(/\s+/)
118+
kind = :space
119+
state = :initial if match.index ?\n
120+
121+
else
122+
getch
123+
kind = :error
124+
125+
end
126+
127+
else
128+
raise_inspect 'Unknown state', tokens
129+
130+
end
131+
132+
match ||= matched
133+
if $DEBUG and not kind
134+
raise_inspect 'Error token %p in line %d' %
135+
[[match, kind], line], tokens
136+
end
137+
raise_inspect 'Empty token', tokens unless match
138+
139+
tokens << [match, kind]
140+
141+
end
142+
143+
if state == :string
144+
tokens << [:close, :string]
145+
end
146+
147+
tokens
148+
end
149+
150+
end
151+
152+
end
153+
end

0 commit comments

Comments
 (0)