commit 2f8887f661ba204928a530cf8653aff0a4dcc2e1
parent 695fb305e3ce03c5248b3219edd7e6f55779ed0d
Author: Sebastian <sebastian@sebsite.pw>
Date: Sun, 12 Jun 2022 19:30:45 -0400
Parse labels in hare::parse instead of hare::lex
As per the change to the spec which allows whitespace characters between
the colon and name of a label, labels are now handled during parse
instead of lex. The lexer only sees a colon and a name, and the label is
constructed by the parser from this.
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
4 files changed, 17 insertions(+), 24 deletions(-)
diff --git a/hare/lex/+test.ha b/hare/lex/+test.ha
@@ -179,7 +179,8 @@ fn loc(line: uint, col: uint) location = location {
(ltok::RETURN, void, loc(1, 13)),
(ltok::VOID, void, loc(1, 20)),
(ltok::NAME, "foobar", loc(1, 25)),
- (ltok::LABEL, "foobaz", loc(1, 32)),
+ (ltok::COLON, void, loc(1, 32)),
+ (ltok::NAME, "foobaz", loc(1, 33)),
];
lextest(in, expected);
};
diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha
@@ -107,7 +107,7 @@ export fn lex(lex: *lexer) (token | error) = {
lex.require_int = false;
if (is_name(r.0, false)) {
unget(lex, r);
- return lex_name(lex, r.1, false);
+ return lex_name(lex, r.1);
};
let tok = switch (r.0) {
@@ -299,7 +299,7 @@ fn lex_rn_str(lex: *lexer) (token | error) = {
return ret;
};
-fn lex_name(lex: *lexer, loc: location, label: bool) (token | error) = {
+fn lex_name(lex: *lexer, loc: location) (token | error) = {
let buf = strio::dynamic();
match (next(lex)) {
case let r: (rune, location) =>
@@ -322,9 +322,6 @@ fn lex_name(lex: *lexer, loc: location, label: bool) (token | error) = {
line_comment(lex)?;
let n = strio::string(&buf);
- if (label) {
- return (ltok::LABEL, n, loc);
- };
match (sort::searchstrings(bmap[..ltok::LAST_KEYWORD+1], n)) {
case void =>
@@ -644,9 +641,7 @@ fn lex2(lexr: *lexer) (token | error) = {
case =>
unget(lexr, r);
line_comment(lexr)?;
- return if (is_name(r.0, false)) {
- yield lex_name(lexr, first.1, true)?;
- } else (ltok::COLON, void, first.1);
+ return (ltok::COLON, void, first.1);
};
case io::EOF =>
return (ltok::COLON, void, first.1);
diff --git a/hare/lex/token.ha b/hare/lex/token.ha
@@ -153,7 +153,6 @@ export type ltok = enum uint {
LAST_LITERAL = LIT_STR,
NAME,
- LABEL,
EOF,
};
@@ -337,9 +336,6 @@ export fn tokstr(tok: token) const str = {
return "str";
case ltok::NAME =>
return tok.1 as str;
- case ltok::LABEL =>
- // XXX: strings::concat(":", tok.1 as str)?
- return "label";
case ltok::EOF =>
return "EOF";
case =>
diff --git a/hare/parse/expr.ha b/hare/parse/expr.ha
@@ -593,9 +593,9 @@ fn constant(lexer: *lex::lexer) (ast::expr | error) = {
fn control(lexer: *lex::lexer) (ast::expr | error) = {
let tok = want(lexer, ltok::BREAK, ltok::CONTINUE, ltok::RETURN)?;
let label = if (tok.0 == ltok::BREAK || tok.0 == ltok::CONTINUE) {
- yield match (try(lexer, ltok::LABEL)?) {
- case let tok: lex::token =>
- yield tok.1 as str;
+ yield match (try(lexer, ltok::COLON)?) {
+ case lex::token =>
+ yield want(lexer, ltok::NAME)?.1 as str;
case void =>
yield "";
};
@@ -640,11 +640,12 @@ fn delete_expr(lexer: *lex::lexer, is_static: bool) (ast::expr | error) = {
fn compound_expr(lexer: *lex::lexer) (ast::expr | error) = {
let items: []*ast::expr = [];
- const start = want(lexer, ltok::LBRACE, ltok::LABEL)?;
+ const start = want(lexer, ltok::LBRACE, ltok::COLON)?;
const label = switch (start.0) {
- case ltok::LABEL =>
+ case ltok::COLON =>
+ const tok = want(lexer, ltok::NAME)?;
want(lexer, ltok::LBRACE)?;
- yield start.1 as str;
+ yield tok.1 as str;
case =>
yield "";
};
@@ -1221,7 +1222,7 @@ fn unarithm(lexer: *lex::lexer) (ast::expr | error) = {
const tok = match (try(lexer,
ltok::PLUS, ltok::MINUS, ltok::BNOT,
ltok::LNOT, ltok::TIMES, ltok::BAND,
- ltok::SWITCH, ltok::MATCH, ltok::LABEL, ltok::LBRACE)) {
+ ltok::SWITCH, ltok::MATCH, ltok::COLON, ltok::LBRACE)) {
case void =>
return builtin(lexer);
case let tok: lex::token =>
@@ -1232,7 +1233,7 @@ fn unarithm(lexer: *lex::lexer) (ast::expr | error) = {
case ltok::MATCH =>
lex::unlex(lexer, tok);
return match_expr(lexer);
- case ltok::LABEL, ltok::LBRACE =>
+ case ltok::COLON, ltok::LBRACE =>
lex::unlex(lexer, tok);
return compound_expr(lexer);
case =>
@@ -1300,15 +1301,15 @@ fn yield_expr(lexer: *lex::lexer) (ast::expr | error) = {
const start = want(lexer, ltok::YIELD)?;
let label = "";
let value: nullable *ast::expr = null;
- match (try(lexer, ltok::SEMICOLON, ltok::LABEL, ltok::EOF)?) {
+ match (try(lexer, ltok::SEMICOLON, ltok::COLON, ltok::EOF)?) {
case void =>
value = alloc(expr(lexer)?);
case let t: lex::token =>
switch (t.0) {
case ltok::SEMICOLON, ltok::EOF =>
lex::unlex(lexer, t);
- case ltok::LABEL =>
- label = t.1 as str;
+ case ltok::COLON =>
+ label = want(lexer, ltok::NAME)?.1 as str;
match (try(lexer, ltok::COMMA)?) {
case void => void;
case lex::token =>