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
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
106
107
108
require_relative "../test_helper"
require "lox/scanner"
class TestScanner < Lox::Test
def setup
@scanner = Lox::Scanner.new
end
def test_basic_tokens
%w[( LEFT_PAREN
) RIGHT_PAREN
{ LEFT_BRACE
} RIGHT_BRACE
, COMMA
. DOT
- MINUS
+ PLUS
; SEMICOLON
* STAR
!= BANG_EQUAL
! BANG
== EQUAL_EQUAL
= EQUAL
<= LESS_EQUAL
< LESS
>= GREATER_EQUAL
> GREATER
/ SLASH].each_slice(2).to_h.transform_values(&:to_sym).each do |str, token_type|
assert_equal token_type.to_sym, @scanner.scan(str)[0].type
end
end
def test_comments_and_whitespace
tokens = @scanner.scan(<<~SRC)
(\t) // here lies a comment
. //
SRC
assert_equal %i[LEFT_PAREN RIGHT_PAREN DOT EOF], tokens.map(&:type)
end
def test_line_numbers
tokens = @scanner.scan(<<~SRC)
(
)
SRC
assert_equal [1, 2, 3], tokens.map(&:line)
end
def test_strings
assert_equal [
Lox::Token.new(:STRING, '""', "", 1),
Lox::Token.new(:EOF, "", nil, 1),
], @scanner.scan('""')
assert_raises do
@scanner.scan('"')
end
assert_equal [
Lox::Token.new(:STRING, '"foo"', "foo", 1),
Lox::Token.new(:EOF, "", nil, 1),
], @scanner.scan('"foo"')
assert_equal [
Lox::Token.new(:STRING, "\"foo\nbar\"", "foo\nbar", 2),
Lox::Token.new(:EOF, "", nil, 2),
], @scanner.scan("\"foo\nbar\"")
end
def test_numbers
assert_equal [
Lox::Token.new(:NUMBER, "123", 123.0, 1),
Lox::Token.new(:NUMBER, "123.4", 123.4, 1),
Lox::Token.new(:EOF, "", nil, 1),
], @scanner.scan("123 123.4")
end
def test_identifiers
assert_equal [
Lox::Token.new(:OR, "or", nil, 1),
Lox::Token.new(:IDENTIFIER, "orchid", nil, 1),
Lox::Token.new(:IDENTIFIER, "o", nil, 1),
Lox::Token.new(:EOF, "", nil, 1),
], @scanner.scan("or orchid o")
end
def test_block_comments
tokens = @scanner.scan(<<~SRC)
foo
/* here lies a /* nested */ block comment
with newlines */
bar
SRC
assert_equal [
Lox::Token.new(:IDENTIFIER, "foo", nil, 1),
Lox::Token.new(:IDENTIFIER, "bar", nil, 4),
Lox::Token.new(:EOF, "", nil, 5),
], tokens
assert_raises do
@scanner.scan("/*")
end
end
end