-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlexer.rb
68 lines (60 loc) · 1.16 KB
/
lexer.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
module Brainfuck
class Lexer
attr_reader :column
attr_reader :line
attr_reader :source_stream
def initialize(file_path)
@source_stream = File.new(file_path, 'r')
@column = 1
@line = 1
end
def tokenize(c)
case c
when '<'
return :decr_ptr
when '>'
return :incr_ptr
when '+'
return :incr_ptd_byte
when '-'
return :decr_ptd_byte
when '['
return :begin_while
when ']'
return :end_while
when '.'
return :output_ptd_byte
when ','
return :input_ptd_byte
when nil
return :eof
else
raise "Unknown token at line #{@line} and column #{@column}"
end
end
def peek
next_char = @source_stream.getc
if next_char != nil
@source_stream.ungetc(next_char)
next_char = next_char.chr
end
return tokenize(next_char)
end
def recognize!
consume
return tokenize(@current_char)
end
protected
def consume
@current_char = @source_stream.getc
@current_char = @current_char.chr if @current_char != nil
@column += 1
if @current_char == '\n'
@column = 1
@line += 1
end
# This line should be here because of possible tail recursion optimization
consume if @current_char =~ /\r/
end
end
end