aboutsummaryrefslogtreecommitdiff
path: root/bootstrap
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-14 11:16:03 +0200
committerlemon <lsof@mailbox.org>2022-08-14 11:16:03 +0200
commit0d1e125832d0fd8ca31c5f782e7c3db774ae5a02 (patch)
treee4622f75a8307d8ee1970f8bd6cc92766582f0ba /bootstrap
parentc129f77ad724aa940b53a125de0e1e4de0ca7240 (diff)
woa
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/ack.cff15
-rw-r--r--bootstrap/all.h1
-rw-r--r--bootstrap/cgen.c8
-rw-r--r--bootstrap/env.c4
-rw-r--r--bootstrap/parse.c17
5 files changed, 24 insertions, 21 deletions
diff --git a/bootstrap/ack.cff b/bootstrap/ack.cff
deleted file mode 100644
index 233abc2..0000000
--- a/bootstrap/ack.cff
+++ /dev/null
@@ -1,15 +0,0 @@
-import "libc.hff";
-
-fn ack(m uint, n uint) uint {
- if m == 0 { return n + 1; }
- if n == 0 { return ack(m - 1, 1); }
- return ack(m - 1, ack(m, n - 1));
-}
-
-extern fn main() void {
- for let m = 0; m <= 4; ++m {
- for let n = 0; n < 6 - m; ++n {
- printf("A(%u,%u) = %u\n", m, n, ack(m, n));
- }
- }
-}
diff --git a/bootstrap/all.h b/bootstrap/all.h
index 9bbab37..bb0711a 100644
--- a/bootstrap/all.h
+++ b/bootstrap/all.h
@@ -290,6 +290,7 @@ struct decl {
int loopid;
};
int age;
+ bool _gen;
};
struct teplparam {
diff --git a/bootstrap/cgen.c b/bootstrap/cgen.c
index 5c64a30..39cbba0 100644
--- a/bootstrap/cgen.c
+++ b/bootstrap/cgen.c
@@ -50,7 +50,11 @@ pristring(const char *s, u64 n) {
extern int isprint(int);
pri("\"");
for (int i = 0; i < n; ++i) {
- if (isprint(s[i]))
+ if (s[i] == '"')
+ pri("\\\"");
+ else if (s[i] == '\\')
+ pri("\\\\");
+ else if (isprint(s[i]))
pri("%c", s[i]);
else
fprintf(outfp, "\\%.3o", s[i]);
@@ -699,6 +703,7 @@ genstatic(bool externp, const char *cname, struct var *var) {
static void
gendecl(struct decl *decl, bool toplevel) {
const char *p = fileid2path(decl->span.fileid);
+ if (decl->_gen) return;
switch (decl->t) {
case Dfn:
pri("#line %d %S\n", decl->span.line, p, (u64)strlen(p));
@@ -718,6 +723,7 @@ gendecl(struct decl *decl, bool toplevel) {
case Dtype: case Ddef: case Dtepl: case Dmacro: case Dlabel:
break;
}
+ decl->_gen = 1;
}
static void
diff --git a/bootstrap/env.c b/bootstrap/env.c
index 40392b9..21d9580 100644
--- a/bootstrap/env.c
+++ b/bootstrap/env.c
@@ -42,6 +42,10 @@ envput(struct env *env, const struct decl *decl) {
return d0;
if (d0->t == Dmacro && !memcmp(&decl->macro, &d0->macro, sizeof decl->macro))
return d0;
+ if (d0->t == Dtype && d0->ty == decl->ty)
+ return d0;
+ if (d0->t == Dfn && !memcmp(&decl->fn, &d0->fn, sizeof decl->fn))
+ return d0;
if (d0->t == Dtepl && !memcmp(&decl->tepl, &d0->tepl, sizeof decl->tepl))
return d0;
for (int kind = TYstruct; kind <= TYeunion; ++kind) {
diff --git a/bootstrap/parse.c b/bootstrap/parse.c
index 4a1721d..0c619fc 100644
--- a/bootstrap/parse.c
+++ b/bootstrap/parse.c
@@ -2925,7 +2925,7 @@ getbasedir(const char *path) {
static struct comfile
doimport(struct parser *P, const char *path) {
- static vec_t(struct entry { const char *s; struct comfile cf; }) seen;
+ static vec_t(struct entry { const char *s; struct comfile cf; bool wip; }) seen;
char path2[PATH_MAX], _rpath[PATH_MAX], *rpath;
struct comfile cf = {0};
struct parser P2;
@@ -2934,16 +2934,23 @@ doimport(struct parser *P, const char *path) {
if (!(rpath = realpath(path2, _rpath)))
fatal(P, P->tokspan, "import %q: %s", path, strerror(errno));
- for (int i = 0; i < seen.length; ++i)
- if (!strcmp(seen.data[i].s, rpath))
- return seen.data[i].cf;
+ for (int i = 0; i < seen.length; ++i) {
+ if (!strcmp(seen.data[i].s, rpath)) {
+ if (seen.data[i].wip) {
+ epri("warning: \"%s\": circular import detected: \"%s\" being processed\n",
+ P->curfile, path);
+ }
+ return seen.data[i].cf;
+ }
+ }
rpath = xstrdup(rpath);
// P2.primenv = P->primenv;
initparser(&P2, rpath);
P2.is_header = 1;
- vec_push(&seen, ((struct entry) { rpath, cf }));
+ vec_push(&seen, ((struct entry) { rpath, cf, 1 }));
parse(&cf, &P2);
+ seen.data[seen.length - 1].wip = 0;
seen.data[seen.length - 1].cf = cf;
return cf;
}