diff options
| author | 2022-08-11 20:27:48 +0200 | |
|---|---|---|
| committer | 2022-08-11 20:27:48 +0200 | |
| commit | 19f1093f0929b989a06cdee2e7d175e6db15559c (patch) | |
| tree | acf82e3cb1b8e81ff132978b7656c178249c5f15 /bootstrap | |
| parent | c7961d732e5d67e8ea1b0be05e979bf24361f794 (diff) | |
things
Diffstat (limited to 'bootstrap')
| -rw-r--r-- | bootstrap/cgen.c | 11 | ||||
| -rw-r--r-- | bootstrap/env.c | 2 | ||||
| -rw-r--r-- | bootstrap/parse.c | 58 |
3 files changed, 51 insertions, 20 deletions
diff --git a/bootstrap/cgen.c b/bootstrap/cgen.c index f79e112..1629151 100644 --- a/bootstrap/cgen.c +++ b/bootstrap/cgen.c @@ -338,7 +338,7 @@ genstmt(struct stmt *stmt) { pri("if (%e) ", &stmt->ifelse.test); genblock(stmt->ifelse.t); if (stmt->ifelse.f) { - pri("else "); + pri("else\n"); genstmt(stmt->ifelse.f); } break; @@ -389,7 +389,7 @@ genstmt(struct stmt *stmt) { struct euswitchcase c = stmt->euswitch.cs.d[i]; pri("case /* %s */ %d: ", c.fld->name, c.vval); if (c.capt) - pri("{ %t %s_%d__ = __stmp.u.%s;\n", c.fld->ty, c.capt, c.captid, c.fld->name); + pri("{ %t %s_%d__ = __stmp.u.%s_;\n", c.fld->ty, c.capt, c.captid, c.fld->name); genblock(c.t); if (c.capt) pri("}\n"); @@ -618,7 +618,7 @@ genfn(bool externp, const char *cname, struct fn *fn) { pri("static "); pri("%t %s(", fn->retty, cname); for (int i = 0; i < fn->params.n; ++i) { - pri("%t %s", fn->params.d[i].ty, fn->params.d[i].name); + pri("%t %s", fn->params.d[i].ty, fn->params.d[i].name ? fn->params.d[i].name : ""); if (i < fn->params.n - 1 || fn->variadic) pri(", "); } @@ -752,6 +752,11 @@ defctype(const struct type *ty, void *_) { *cname = (char *)unconstify(ty)->_cname; break; } + for (int i = 0; i < ty->agg.flds.n; ++i) { + struct aggfield *fld = &ty->agg.flds.d[i]; + if (fld->ty) + defctype(fld->ty, NULL); + } *cname = xasprintf("__ty%s%d", ty->agg.name ? ty->agg.name : "", id++); pri("typedef struct %s %s;\n", *cname, *cname); if (!ty->agg.fwd) { diff --git a/bootstrap/env.c b/bootstrap/env.c index 773550a..ff2929f 100644 --- a/bootstrap/env.c +++ b/bootstrap/env.c @@ -35,6 +35,8 @@ envput(struct env *env, const struct decl *decl) { // modify existing forward declarations? if (decl == d0 || !memcmp(d0, decl, sizeof *d0)) return d0; + if (d0->t == Ddef && decl->t == Ddef && !memcmp(&d0->var, &decl->var, sizeof d0->var)) + return d0; if (d0->t == Dmacro && !memcmp(&decl->macro, &d0->macro, sizeof decl->macro)) return d0; if (d0->t == Dtepl && !memcmp(&decl->tepl, &d0->tepl, sizeof decl->tepl)) 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; } |