18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
# File 'lib/fam/syntax/lexer.rb', line 18
def lexer
puts "Lexing..." if $VERBOSE
@raw << EOF unless @raw[-1] == EOF
loc = {:line => 1, :col => 1}
i = 0
while i < @raw.size
unread = @raw[i..-1]
if ["\n", ";"].include? unread[0]
loc[:line] += 1
loc[:col] = 1
@tokens << tokenize(unread[0], :TERMINATOR, loc)
i += 1
elsif unread[0] == ' '
loc[:col] += 1
i += 1
elsif unread[/\A{{/, 0] || unread[/\A!/, 0]
= unread[/\A{{/, 0] || unread[/\A!/, 0]
= loc.clone
j = 0
if == '!'
until unread[j] == "\n" || unread[j] == EOF
i += 1
j += 1
end
j -= 1
else
until unread[j..j+1] == '}}' || unread[j] == EOF
i += 1
loc[:col] += 1
if unread[j] == "\n"
loc[:line] += 1
loc[:col] = 1
end
j += 1
end
j += 1
end
@tokens << tokenize(unread[0..j], :COMMENT, )
elsif label = unread[/\A[a-zA-Z_]([a-zA-Z0-9_]+)?:/, 0]
@tokens << tokenize(label, :LABEL, loc)
loc[:col] += label.size
i += label.size
elsif numeric = unread[/\A(\-|\+)??((?=0x|0b)([0-9A-Za-z]+)|([0-9]+((e(\-|\+)?[0-9]+)?)))/, 0]
@tokens << tokenize(numeric, :NUMERIC, loc)
loc[:col] += numeric.size
i += numeric.size
elsif address = unread[/\A@[0-9]+/, 0]
@tokens << tokenize(address, :ADDRESS, loc)
loc[:col] += address.size
i += address.size
elsif register = unread[/\A&[a-zA-Z0-9]+/, 0]
@tokens << tokenize(register, :REGISTER, loc)
loc[:col] += register.size
i += register.size
elsif ident = unread[/\A[A-Za-z_]([A-Za-z0-9_]+)?/, 0]
if Tokens::OPCODES.include? ident
@tokens << tokenize(ident, :OPCODE, loc)
else
@tokens << tokenize(ident, :IDENT, loc)
end
loc[:col] += ident.size
i += ident.size
elsif op = unread[/\A[(\+)(\-)(\:)(\|)]/, 0]
@tokens << tokenize(op, :OPERATOR, loc)
loc[:col] += op.size
i += op.size
else
i += 1
loc[:col] += 1
end
end
@tokens
end
|