aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/parse.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-11 20:27:48 +0200
committerlemon <lsof@mailbox.org>2022-08-11 20:27:48 +0200
commit19f1093f0929b989a06cdee2e7d175e6db15559c (patch)
treeacf82e3cb1b8e81ff132978b7656c178249c5f15 /bootstrap/parse.c
parentc7961d732e5d67e8ea1b0be05e979bf24361f794 (diff)
things
Diffstat (limited to 'bootstrap/parse.c')
-rw-r--r--bootstrap/parse.c58
1 files changed, 41 insertions, 17 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c
index cff303f..d0bea8e 100644
--- a/bootstrap/parse.c
+++ b/bootstrap/parse.c
@@ -266,6 +266,7 @@ readstrlit(struct parser *P, u8 delim, char *s, size_t n) {
fatal(P, P->tokspan, "unterminated %s literal",
delim == '"' ? "string" : "character");
case '\'': s[i++] = '\''; break;
+ case '\\': s[i++] = '\\'; break;
case '"': s[i++] = '"'; break;
case 'n': s[i++] = '\n'; break;
case 'r': s[i++] = '\r'; break;
@@ -576,6 +577,8 @@ finddecl(struct parser *P, const char *name) {
static struct expr parseexpr(struct parser *P);
+
+static const struct type *xident2type(struct parser *P, struct tok tok);
static const struct type *parsetype(struct parser *P);
static const struct type *
@@ -589,9 +592,13 @@ parsefntype(struct parser *P) {
if (lexmatch(P, &tok, '...')) {
ty.fn.variadic = 1;
} else {
- const struct type *param;
- tok = lexexpects(P, TKident, "parameter name");
- param = parsetype(P);
+ const struct type *param ;
+ if (lexmatch(P, &tok, TKident)) {
+ if (lexpeek(P).t == ',' || lexpeek(P).t == ')')
+ param = xident2type(P, tok);
+ } else {
+ param = parsetype(P);
+ }
if (!completetype(param))
fatal(P, tok.span, "parameter type is incomplete (%t)",
param);
@@ -728,6 +735,19 @@ parseexpandtepl(struct parser *P, struct tepl *tepl) {
}
static const struct type *
+xident2type(struct parser *P, struct tok tok) {
+ const struct decl *decl = finddecl(P, tok.str);
+ if (!decl)
+ fatal(P, P->tokspan, "%T is not defined", tok);
+ if (decl->t == Dtype) {
+ return decl->ty;
+ } else if (decl->t == Dtepl && decl->tepl.t == Dtype) {
+ return parseexpandtepl(P, (struct tepl *)&decl->tepl);
+ } else
+ fatal(P, P->tokspan, "%T is not a type", tok);
+}
+
+static const struct type *
parsetype(struct parser *P) {
struct tok tok;
if (lexmatch(P, &tok, '*')) {
@@ -790,15 +810,7 @@ parsetype(struct parser *P) {
} while (!lexmatch(P, &tok, ')'));
return ty;
} else if (lexmatch(P, &tok, TKident)) {
- const struct decl *decl = finddecl(P, tok.str);
- if (!decl)
- fatal(P, P->tokspan, "%T is not defined", tok);
- if (decl->t == Dtype) {
- return decl->ty;
- } else if (decl->t == Dtepl && decl->tepl.t == Dtype) {
- return parseexpandtepl(P, (struct tepl *)&decl->tepl);
- } else
- fatal(P, P->tokspan, "%T is not a type", tok);
+ return xident2type(P, tok);
} else if (lexmatch(P, &tok, TKkw_fn)) {
return parsefntype(P);
} else if (lexmatch(P, &tok, TKtype)) {
@@ -1817,6 +1829,7 @@ parsevardecl(decl_yielder_t yield, void *yarg, struct parser *P, bool let, bool
}
ty2.size = ty->child->size * ty2.length;
ty2.align = ty->child->align;
+ uninterntype(ty);
ty = interntype(ty2);
}
@@ -2409,8 +2422,16 @@ parsefn(struct decl *decl, struct parser *P) {
if (lexmatch(P, &tok, '...')) {
fn->variadic = 1;
} else {
- param.name = (tok = lexexpects(P, TKident, "parameter name")).str;
- param.ty = parsetype(P);
+ if (lexmatch(P, &tok, TKident)) {
+ if (lexpeek(P).t == ',' || lexpeek(P).t == ')') {
+ param.ty = xident2type(P, tok);
+ } else {
+ param.name = tok.str;
+ param.ty = parsetype(P);
+ }
+ } else {
+ param.ty = parsetype(P);
+ }
if (!completetype(param.ty))
fatal(P, tok.span, "parameter type is incomplete (%t)",
param.ty);
@@ -2442,6 +2463,8 @@ parsefn(struct decl *decl, struct parser *P) {
Dfn, fn->name, .fn = *fn, ._cname = decl->_cname
});
for (int i = 0; i < params.length; ++i) {
+ if (!params.data[i].name)
+ continue;
struct decl decl = {
Dlet, params.data[i].name, .var = {
.ty = params.data[i].ty,
@@ -2824,13 +2847,14 @@ doimport(struct parser *P, const char *path) {
for (int i = 0; i < seen.length; ++i)
if (!strcmp(seen.data[i].s, rpath))
return seen.data[i].cf;
- rpath = xstrdup(rpath);
+ rpath = xstrdup(rpath);
// P2.primenv = P->primenv;
- initparser(&P2, xstrdup(path2));
+ initparser(&P2, rpath);
P2.is_header = 1;
- parse(&cf, &P2);
vec_push(&seen, ((struct entry) { rpath, cf }));
+ parse(&cf, &P2);
+ seen.data[seen.length - 1].cf = cf;
return cf;
}