support nested block comments

FossilOrigin-Name: 5ec3ea233b52addff0cdd9b20b001c919a32cbf21e5b468e67fdc31cc4480051
private
alpha 2 years ago
parent dcdd0981f5
commit a4163b0e49

@ -108,7 +108,8 @@ module Lox
when state.scan(/>=/) then state.add_token(:GREATER_EQUAL)
when state.scan(/>/) then state.add_token(:GREATER)
when state.scan(/\/\/(?~\n)+/) # ignore line comment
when state.scan(/\/\*(?~\*\/)\*\//m) # ignore block comment
when state.scan(/\/\*/)
scan_block_comment(state)
when state.scan(/\//) then state.add_token(:SLASH)
when state.scan(/[ \r\t]/) # ignore whitespace
when state.scan(/\n/) then state.line += 1
@ -150,6 +151,26 @@ module Lox
end
end
end
def scan_block_comment(state)
loop do
case
when state.scan(/\/\*/)
scan_block_comment(state)
when state.scan(/\*\//)
return
when state.scan(/\n/)
state.line += 1
when state.eos?
state.errors << Error.new(line: state.line, message: "Unterminated block comment.")
return
when c = state.scan(/./)
# no-op
else
fail "unreachable!"
end
end
end
end
Token = Struct.new(:type, :lexeme, :literal, :line) do

@ -103,13 +103,16 @@ class TestScanner < Minitest::Test
def test_block_comments
tokens = @scanner.scan(<<~SRC)
foo
/* here lies a block comment */
/* 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, 3),
Lox::Token.new(:IDENTIFIER, "bar", nil, 4),
], tokens
assert_equal [], @scanner.scan("/*")
end
end

Loading…
Cancel
Save