aboutsummaryrefslogtreecommitdiff
path: root/bootstrap
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-07 17:12:05 +0200
committerlemon <lsof@mailbox.org>2022-08-07 17:12:05 +0200
commitb348c470ff065400ff149da6ccefa8fd8f22e9be (patch)
treedfe9f618910139c8a7e544d6d060a608aef0bf48 /bootstrap
parent4991e71b33a41440c50bf1b14abd857d459f2b52 (diff)
uniinitialized variables
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/parse.c61
-rw-r--r--bootstrap/test2.cff2
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);