From 58af6dcf569c7f83b317d30f8dd85d96d314d785 Mon Sep 17 00:00:00 2001 From: lemon Date: Sat, 13 Aug 2022 07:11:23 +0200 Subject: cond switch --- src/parse.cff | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'src/parse.cff') diff --git a/src/parse.cff b/src/parse.cff index bcb5763..07158fb 100644 --- a/src/parse.cff +++ b/src/parse.cff @@ -84,6 +84,18 @@ fn issep(c u8) bool { return #f; } +fn ishsep(c u8) bool { + if isspace(c) { + return #t; + } + switch (c) { + case '(', ')', '[', ']', '{', + '}', '.', ',', ';', '"'; + return #t; + } + return #f; +} + fn readtilsep(P *Parser, buf [#]u8, dot bool) int { let i = 0, c u8 #?; @@ -98,6 +110,24 @@ fn readtilsep(P *Parser, buf [#]u8, dot bool) int { return i; } +fn readtilhsep(P *Parser, buf [#]u8, dot bool) int { + let i = 0, + c u8 #?, + pred = &ishsep; + while (not pred(c = chrpeek(P))) or (dot and c == '.') { + chr(P); + if not issep(c) { + pred = &issep; + } + if i >= buf.#len - 1 { + return -1; + } + buf[i++] = c; + } + buf[i++] = 0; + return i; +} + fn eatspaces(P *Parser) void { for ;;chr(P) { if not isspace(chrpeek(P)) { @@ -226,6 +256,18 @@ fn lex(P *Parser) Tok { } return tok; } + if c == '#' { + let s [100]u8 = {}; + if readtilhsep(P, s[0::], #f) < 0 { + fatal(P, P.tokloc, "invalid #keyword"); + } + switch { + case streq(s, "#"); + tok.t = '#'; + case else + fatal(P, P.tokloc, "invalid #keyword"); + } + } if c == '"' or c == '\'' { chr(P); let delim = c; @@ -255,8 +297,21 @@ fn lex(P *Parser) Tok { } } - tok.t = :str; - tok.u.str = str->compact(); + if delim == '"' { + tok.t = :str; + tok.u.str = str->compact(); + } else { + tok.t = :chr; + if str.len == 0 { + fatal(P, P.tokloc, "empty char literal"); + } else if str.len > 8 { + fatal(P, P.tokloc, "too long multichar literal %qs", str.dat); + } + tok.u.uint = 0; + vec_each(c0, i, str, + tok.u.uint = (tok.u.uint << 8) | c0; + ) + } return tok; } switch c = chr(P) { -- cgit v1.2.3