diff options
| author | 2022-08-07 17:12:05 +0200 | |
|---|---|---|
| committer | 2022-08-07 17:12:05 +0200 | |
| commit | b348c470ff065400ff149da6ccefa8fd8f22e9be (patch) | |
| tree | dfe9f618910139c8a7e544d6d060a608aef0bf48 /bootstrap | |
| parent | 4991e71b33a41440c50bf1b14abd857d459f2b52 (diff) | |
uniinitialized variables
Diffstat (limited to 'bootstrap')
| -rw-r--r-- | bootstrap/parse.c | 61 | ||||
| -rw-r--r-- | bootstrap/test2.cff | 2 |
2 files changed, 52 insertions, 11 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c index e7f4a39..912a346 100644 --- a/bootstrap/parse.c +++ b/bootstrap/parse.c @@ -87,6 +87,8 @@ aissep(char c) { case '*': case '/': case '&': case '|': case '^': case '~': case '=': case '\'': case '"': case '<': case '>': case ':': + case '$': case '@': case '#': case '\\': + case '`': return 1; return 0; } @@ -119,6 +121,32 @@ readtilsep(struct parser *P, char *buf, int n, bool dot) { return i; } +static bool +aishsep(char c) { + if (aisspace(c)) + return 1; + switch (c) + case '(': case ')': case '[': case ']': + case '{': case '}': case '.': case ',': + case ';': case '"': case '\'': + return 1; + return 0; +} + +static int +readtilhsep(struct parser *P, char *buf, int n, bool dot) { + int i = 0; + u8 c; + while (!aishsep((c = chrpeek(P))) || (dot && c == '.')) { + chr(P); + if (i >= n - 1) + return -1; + buf[i++] = c; + } + buf[i++] = 0; + return i; +} + const char *keyword2str[] = { #define KWSTR(kw) #kw, LIST_KEYWORDS(KWSTR) @@ -311,7 +339,7 @@ lex(struct parser *P) { fatal(P, P->tokspan, "invalid number literal %q", s); tok.span = P->tokspan; return tok; - } else if (aisalpha(c) || c == '_' || c == '#' || c == '$') { + } else if (aisalpha(c) || c == '_' || c == '$') { char s[100]; int t; @@ -319,7 +347,20 @@ lex(struct parser *P) { fatal(P, P->tokspan, "identifier too long"); if ((t = str2keyword(s)) >= 0) { tok.t = t; - } else if (!strcmp(s, "#")) { + } else if (c == '$') { + tok.t = TKgensym; + tok.str = xstrdup(s + 1); + } else { + tok.t = TKident; + tok.str = xstrdup(s); + } + return tok; + } else if (c == '#') { + char s[100]; + + if (readtilhsep(P, s, sizeof s, 0) < 0) + fatal(P, P->tokspan, "invalid #keyword"); + else if (!strcmp(s, "#")) { tok.t = '#'; } else if (!strcmp(s, "#t") || !strcmp(s, "#f")) { tok.t = TKboolit; @@ -330,15 +371,11 @@ lex(struct parser *P) { tok.t = '##'; } else if (!strcmp(s, "#len")) { tok.t = '#len'; - } else if (c == '#') { - fatal(P, P->tokspan, "identifier cannot start with '#'"); - } else if (c == '$') { - tok.t = TKgensym; - tok.str = xstrdup(s + 1); - } else { - tok.t = TKident; - tok.str = xstrdup(s); - } + } else if (!strcmp(s, "#?")) { + tok.t = '#?'; + } else { + fatal(P, P->tokspan, "invalid #keyword"); + } return tok; } else if (c == '\'' || c == '"') { u8 delim = c; @@ -1679,6 +1716,8 @@ parsevardecl(decl_yielder_t yield, void *yarg, struct parser *P, bool let, bool if (lexmatch(P, NULL, '=')) { P->targty = ty; ini = exprdup(parseexpr(P)); + } else if (let && lexmatch(P, NULL, '#?')) { + ini = NULL; } else if (decl.t == Dlet) { fatal(P, tok.span, "variable %T must be initialized", tok); } diff --git a/bootstrap/test2.cff b/bootstrap/test2.cff index 6fbb8fa..7a61f28 100644 --- a/bootstrap/test2.cff +++ b/bootstrap/test2.cff @@ -16,6 +16,8 @@ extern fn main() void { let n Node<int> = {#null, 0}; let n Node<int> = {&n, 1}; + let x int #?; + printf("n %d\n", n.value); printf("n link %d\n", n.link.value); |