commit 1ecd1920f1c64ae76a9d9406e17d70985dd22dc0
parent 35c64b917aeb39f9b254dc1fb3d9379f66955ef6
Author: Sebastian <sebastian@sebsite.pw>
Date: Fri, 13 May 2022 23:34:52 -0400
hare::lex: properly lex strings separated by comments
This example wasn't lexed correctly prior to this commit:
"foo"
// bar
"baz";
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
2 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/hare/lex/+test.ha b/hare/lex/+test.ha
@@ -259,6 +259,13 @@ fn loc(line: uint, col: uint) location = location {
(ltok::LIT_STR, "foo", loc(1, 35)),
];
lextest(in, expected);
+ const in = "\"foo\"\n"
+ "// bar\n"
+ "\"baz\"";
+ const expected: [_]token = [
+ (ltok::LIT_STR, "foobaz", loc(1, 1)),
+ ];
+ lextest(in, expected);
};
@test fn literals() void = {
diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha
@@ -234,20 +234,36 @@ fn lex_string(lex: *lexer, loc: location, delim: rune) (token | error) = {
strio::appendrune(&buf, r.0)?;
};
};
- match (nextw(lex)?) {
- case io::EOF => void;
+ for (true) match (nextw(lex)?) {
+ case io::EOF =>
+ break;
case let r: (rune, location) =>
- if (r.0 == '"') {
+ switch (r.0) {
+ case '"', '`' =>
const tok = lex_string(lex, loc, r.0)?;
const next = tok.1 as str;
strio::concat(&buf, next)!;
free(next);
- } else {
+ break;
+ case '/' =>
+ match (nextw(lex)?) {
+ case io::EOF =>
+ unget(lex, r);
+ case let s: (rune, location) =>
+ if (s.0 == '/') {
+ lex_comment(lex)?;
+ continue;
+ } else {
+ unget(lex, s);
+ unget(lex, r);
+ };
+ };
+ break;
+ case =>
unget(lex, r);
+ break;
};
};
- line_comment(lex)?;
-
return (ltok::LIT_STR, strio::string(&buf), loc);
};