diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/prc/posix.c | 4 | ||||
| -rw-r--r-- | src/prc1/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/prc1/arg.c | 19 | ||||
| -rw-r--r-- | src/prc1/arg.h | 4 | ||||
| -rw-r--r-- | src/prc1/cgen.c | 5 | ||||
| -rw-r--r-- | src/prc1/cgen/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/prc1/cgen/from.c | 8 | ||||
| -rw-r--r-- | src/prc1/cgen/prv.h | 2 | ||||
| -rw-r--r-- | src/prc1/cgen/qbe/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/prc1/cgen/qbe/from.c | 134 | ||||
| -rw-r--r-- | src/prc1/cgen/qbe/qbe.c | 1 | ||||
| -rw-r--r-- | src/prc1/cgen/qbe/qbe.h | 2 | ||||
| -rw-r--r-- | src/prc1/div.c | 10 | ||||
| -rw-r--r-- | src/prc1/from.c | 150 | ||||
| -rw-r--r-- | src/prc1/from.h | 1 | ||||
| -rw-r--r-- | src/prc1/kw.c | 6 | ||||
| -rw-r--r-- | src/prc1/lk.c | 2 | ||||
| -rw-r--r-- | src/prc1/prc1.c | 7 | ||||
| -rw-r--r-- | src/prc1/prv.h | 2 | ||||
| -rw-r--r-- | src/prc1/sym.c | 6 | ||||
| -rw-r--r-- | src/prc1/td.c | 18 | ||||
| -rw-r--r-- | src/prc1/tmp.c | 15 | ||||
| -rw-r--r-- | src/prc1/triplet.c | 40 | ||||
| -rw-r--r-- | src/prc1/triplet.h | 9 | ||||
| -rw-r--r-- | src/prc1/triplet/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/prc1/triplet/prv.h | 3 | ||||
| -rw-r--r-- | src/prc1/triplet/x86_64-linux-gnu.c | 18 | ||||
| -rw-r--r-- | src/prc1/type.c | 57 | ||||
| -rw-r--r-- | src/prc1/type.h | 4 | ||||
| -rw-r--r-- | src/prc1/ws.c | 2 |
30 files changed, 310 insertions, 226 deletions
diff --git a/src/prc/posix.c b/src/prc/posix.c index bce793e..d73050b 100644 --- a/src/prc/posix.c +++ b/src/prc/posix.c @@ -37,8 +37,8 @@ int spawn_wait(struct spawn *s) return -1; else if (WIFSIGNALED(stat)) { - fprintf(stderr, "%s terminated by signal %d\n", s->path, - WTERMSIG(stat)); + fprintf(stderr, "%s terminated by signal %d (%s)\n", s->path, + WTERMSIG(stat), strsignal(stat)); return -1; } else if (WIFSTOPPED(stat)) diff --git a/src/prc1/CMakeLists.txt b/src/prc1/CMakeLists.txt index 82d670d..e738343 100644 --- a/src/prc1/CMakeLists.txt +++ b/src/prc1/CMakeLists.txt @@ -30,6 +30,7 @@ add_executable(prc1 storage.c td.c tmp.c + triplet.c type.c warn.c ws.c @@ -42,5 +43,6 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") target_compile_options(prc1 PRIVATE -Og) endif() add_subdirectory(cgen) +add_subdirectory(triplet) include(GNUInstallDirs) install(TARGETS prc1 DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}) diff --git a/src/prc1/arg.c b/src/prc1/arg.c index f55d322..e844aee 100644 --- a/src/prc1/arg.c +++ b/src/prc1/arg.c @@ -26,11 +26,19 @@ static int debug(struct args *a, const char *arg) static int target(struct args *a, const char *arg) { + fprintf(stderr, "%s: TODO, arg=%s\n", __func__, arg); + return -1; +} + +static int backend(struct args *a, const char *arg) +{ if (!strcmp(arg, "qbe")) - a->tgt = QBE; + a->backend = QBE; + else if (!strcmp(arg, "c99")) + a->backend = C99; else { - fprintf(stderr, "invalid or unsupported target \"%s\"", arg); + fprintf(stderr, "invalid or unsupported backend \"%s\"", arg); return -1; } @@ -90,7 +98,8 @@ int arg(struct args *a, const char *value) static const struct arg args[] = { {"-d", debug}, - {"-t", target}, + {"-t", target, SPACEVAL}, + {"-b", backend, SPACEVAL}, {"-I", inc, SPACEVAL | JOINVAL} }; @@ -124,7 +133,9 @@ int arg(struct args *a, const char *value) void arg_defaults(struct args *a) { - a->tgt = QBE; + a->backend = QBE; + /* TODO: replace */ + a->triplet = "x86_64-linux-gnu"; } static void free_input(struct arg_input *i) diff --git a/src/prc1/arg.h b/src/prc1/arg.h index 0e9a7ab..438639a 100644 --- a/src/prc1/arg.h +++ b/src/prc1/arg.h @@ -11,8 +11,8 @@ struct arg_input struct args { - enum target {QBE} tgt; - const char *name, *src; + enum {QBE, C99} backend; + const char *name, *src, *triplet; const struct arg *arg; struct arg_input incs; }; diff --git a/src/prc1/cgen.c b/src/prc1/cgen.c index c394f44..63396ed 100644 --- a/src/prc1/cgen.c +++ b/src/prc1/cgen.c @@ -5,10 +5,13 @@ int cgen(const struct ast *ast, struct cgen *c) { const struct args *args = ast->args; - switch (args->tgt) + switch (args->backend) { case QBE: return cgen_qbe(ast, c); + case C99: + fprintf(stderr, "%s: C99 backend TODO\n", __func__); + return -1; } fprintf(stderr, "%s: unreachable\n", __func__); diff --git a/src/prc1/cgen/CMakeLists.txt b/src/prc1/cgen/CMakeLists.txt index 77aa786..d788d2f 100644 --- a/src/prc1/cgen/CMakeLists.txt +++ b/src/prc1/cgen/CMakeLists.txt @@ -3,6 +3,7 @@ target_sources(prc1 PRIVATE call.c fn.c free.c + from.c gl.c global.c param.c diff --git a/src/prc1/cgen/from.c b/src/prc1/cgen/from.c new file mode 100644 index 0000000..be018ef --- /dev/null +++ b/src/prc1/cgen/from.c @@ -0,0 +1,8 @@ +#include "cgen.h" +#include "cgen/prv.h" +#include "from.h" + +int from_cgen(const struct from *f, struct cgen *c) +{ + return c->drv->from(f, c); +} diff --git a/src/prc1/cgen/prv.h b/src/prc1/cgen/prv.h index dc99404..32601f0 100644 --- a/src/prc1/cgen/prv.h +++ b/src/prc1/cgen/prv.h @@ -3,6 +3,7 @@ #include "cgen.h" #include "call.h" +#include "from.h" #include "print.h" #include "set.h" #include "storage.h" @@ -13,6 +14,7 @@ struct cgen_drv int (*gl)(const struct storage *, struct cgen *); int (*ws)(const struct storage *, struct cgen *); int (*call)(const struct call *, struct cgen *); + int (*from)(const struct from *, struct cgen *); int (*set)(const struct set *, struct cgen *); int (*fn)(const struct fn *, struct cgen *); void (*free)(struct cgen_prv *); diff --git a/src/prc1/cgen/qbe/CMakeLists.txt b/src/prc1/cgen/qbe/CMakeLists.txt index 5d0bd63..a9e7155 100644 --- a/src/prc1/cgen/qbe/CMakeLists.txt +++ b/src/prc1/cgen/qbe/CMakeLists.txt @@ -1,6 +1,7 @@ target_sources(prc1 PRIVATE call.c free.c + from.c fn.c gl.c print.c diff --git a/src/prc1/cgen/qbe/from.c b/src/prc1/cgen/qbe/from.c new file mode 100644 index 0000000..40b2724 --- /dev/null +++ b/src/prc1/cgen/qbe/from.c @@ -0,0 +1,134 @@ +#include "from.h" +#include "stmt.h" +#include "cgen.h" +#include "qbe.h" +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +static int loadvar(const struct from_it *st, struct cgen *c) +{ + const struct stentry *e = st->u.e; + size_t sz = e->t->sz; + const char *tmp = cgen_tmp(sz); + + printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(e->t)); + cgen_printvar(c->fn, e); + putchar('\n'); + return 0; +} + +/* TODO: de-duplicate function */ +static unsigned long long tonum(const char *s) +{ + unsigned long long v; + char *end; + + errno = 0; + v = strtoull(s, &end, 0); + + if (*s == '-' || errno || *end) + return strtoll(s, NULL, 0); + + return v; +} + +static int loadval(const struct from *fr, struct cgen *c) +{ + const struct stentry *dst = fr->var; + const struct from_it *st = &fr->start; + unsigned long long v = tonum(st->u.tk->s); + + printf("store%s %llu, ", cgen_sz(dst->t->sz), v); + cgen_printvar(c->fn, dst); + putchar('\n'); + return 0; +} + +static int endvar(const struct from *fr, struct cgen *c) +{ + fprintf(stderr, "%s: TODO\n", __func__); + return -1; +} + +static int endval(const struct from *fr, struct cgen *c) +{ + const struct stentry *src = fr->var; + size_t sz = src->t->sz; + const char *tmp = cgen_tmp(sz); + const struct from_it *end = &fr->end; + const struct tk *tk = end->u.tk; + int neg = *tk->s == '-'; + size_t bl = fr->block_i; + + printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(src->t)); + cgen_printvar(c->fn, src); + putchar('\n'); + printf("%%%s =%s c", tmp, cgen_sz(sz)); + fputs(neg ? "sge" : "uge", stdout); + printf("%s ", cgen_sz(sz)); + printf("%%%s, %s\n", tmp, tk->s); + printf("jnz %%%s, @__end%zu, @__blockbody%zu\n", tmp, bl, bl); + printf("@__blockbody%zu\n", bl); + return 0; +} + +static int from_var(const struct from *fr, struct cgen *c) +{ + const struct from_it *st = &fr->start; + + switch (st->type) + { + case FR_VAR: + if (loadvar(st, c)) + return -1; + break; + + case FR_VAL: + if (loadval(fr, c)) + return -1; + break; + } + + printf("@__block%zu\n", fr->block_i); + + switch (fr->end.type) + { + case FR_VAR: + if (endvar(fr, c)) + return -1; + break; + + case FR_VAL: + if (endval(fr, c)) + return -1; + break; + } + + return 0; +} + +int from_end(const struct stmt *s, struct cgen *c) +{ + const struct from *fr = &s->u.from; + const struct stentry *src = fr->var; + const struct type *t = src->t; + size_t sz = t->sz; + const char *tmp = cgen_tmp(sz); + const struct fn *fn = c->fn; + + printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(t)); + cgen_printvar(fn, src); + putchar('\n'); + printf("%%%s =%s add %%%s, 1\n", tmp, cgen_sz(sz), tmp); + printf("store%s %%%s, ", cgen_sz(sz), tmp); + cgen_printvar(fn, src); + putchar('\n'); + printf("jmp @__block%zu\n", fr->block_i); + return 0; +} + +int qbe_from(const struct from *fr, struct cgen *c) +{ + return from_var(fr, c); +} diff --git a/src/prc1/cgen/qbe/qbe.c b/src/prc1/cgen/qbe/qbe.c index c27bad6..d727bc0 100644 --- a/src/prc1/cgen/qbe/qbe.c +++ b/src/prc1/cgen/qbe/qbe.c @@ -154,6 +154,7 @@ int cgen_qbe(const struct ast *ast, struct cgen *c) .print = qbe_print, .call = qbe_call, .free = qbe_free, + .from = qbe_from, .set = qbe_set, .gl = qbe_gl, .ws = qbe_ws, diff --git a/src/prc1/cgen/qbe/qbe.h b/src/prc1/cgen/qbe/qbe.h index b0e66f1..206cf32 100644 --- a/src/prc1/cgen/qbe/qbe.h +++ b/src/prc1/cgen/qbe/qbe.h @@ -3,6 +3,7 @@ #include "call.h" #include "cgen.h" +#include "from.h" #include "print.h" #include "set.h" #include "storage.h" @@ -20,6 +21,7 @@ int qbe_call(const struct call *m, struct cgen *c); int qbe_set(const struct set *m, struct cgen *c); int qbe_gl(const struct storage *gl, struct cgen *c); int qbe_ws(const struct storage *s, struct cgen *c); +int qbe_from(const struct from *fn, struct cgen *c); int qbe_fn(const struct fn *fn, struct cgen *c); void qbe_free(struct cgen_prv *p); diff --git a/src/prc1/div.c b/src/prc1/div.c index 7236a71..5c6422f 100644 --- a/src/prc1/div.c +++ b/src/prc1/div.c @@ -8,25 +8,25 @@ #include "ws.h" static const struct seq - linkage = {(struct step[]){{ID, "linkage"}, {0}}, .fn = lk}, + externals = {(struct step[]){{ID, "externals"}, {0}}, .fn = lk}, types = {(struct step[]){{ID, "types"}, {0}}, .fn = td}, imports = {(struct step[]){{ID, "imports"}, {0}}, .fn = im}, procedure = {(struct step[]){{ID, "procedure"}, {0}}, .fn = pr}; static const struct seq fnseq[] = { - linkage, + externals, types, imports, procedure, - {(struct step[]){{ID, "storage"}, {0}}, .fn = ws}, + {(struct step[]){{ID, "locals"}, {0}}, .fn = ws}, {(struct step[]){{ID, "globals"}, {0}}, .fn = gl}, {0} }; static const struct seq imseq[] = { - linkage, + externals, types, imports, {0} @@ -34,7 +34,7 @@ static const struct seq imseq[] = static const struct seq pseq[] = { - linkage, + externals, procedure, {0} }; diff --git a/src/prc1/from.c b/src/prc1/from.c index 83f9b71..8561b8f 100644 --- a/src/prc1/from.c +++ b/src/prc1/from.c @@ -1,11 +1,11 @@ #include "from.h" -#include "cgen.h" #include "dbg.h" #include "fn.h" #include "errloc.h" #include "stmt.h" #include "storage.h" #include "tmp.h" +#include "triplet.h" #include "type.h" #include <errno.h> #include <stddef.h> @@ -17,133 +17,6 @@ void from_free(struct from *fr) { } -static int loadvar(const struct from_it *st, struct cgen *c) -{ - const struct stentry *e = st->u.e; - size_t sz = e->t->sz; - const char *tmp = cgen_tmp(sz); - - printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(e->t)); - cgen_printvar(c->fn, e); - putchar('\n'); - return 0; -} - -/* TODO: de-duplicate function */ -static unsigned long long tonum(const char *s) -{ - unsigned long long v; - char *end; - - errno = 0; - v = strtoull(s, &end, 0); - - if (*s == '-' || errno || *end) - return strtoll(s, NULL, 0); - - return v; -} - -static int loadval(const struct from *fr, struct cgen *c) -{ - const struct stentry *dst = fr->var; - const struct from_it *st = &fr->start; - unsigned long long v = tonum(st->u.tk->s); - - printf("store%s %llu, ", cgen_sz(dst->t->sz), v); - cgen_printvar(c->fn, dst); - putchar('\n'); - return 0; -} - -static int endvar(const struct from *fr, struct cgen *c) -{ - fprintf(stderr, "%s: TODO\n", __func__); - return -1; -} - -static int endval(const struct from *fr, struct cgen *c) -{ - const struct stentry *src = fr->var; - size_t sz = src->t->sz; - const char *tmp = cgen_tmp(sz); - const struct from_it *end = &fr->end; - const struct tk *tk = end->u.tk; - int neg = *tk->s == '-'; - size_t bl = fr->block_i; - - printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(src->t)); - cgen_printvar(c->fn, src); - putchar('\n'); - printf("%%%s =%s c", tmp, cgen_sz(sz)); - fputs(neg ? "sge" : "uge", stdout); - printf("%s ", cgen_sz(sz)); - printf("%%%s, %s\n", tmp, tk->s); - printf("jnz %%%s, @__end%zu, @__blockbody%zu\n", tmp, bl, bl); - printf("@__blockbody%zu\n", bl); - return 0; -} - -static int from_var(const struct from *fr, struct cgen *c) -{ - const struct from_it *st = &fr->start; - - switch (st->type) - { - case FR_VAR: - if (loadvar(st, c)) - return -1; - break; - - case FR_VAL: - if (loadval(fr, c)) - return -1; - break; - } - - printf("@__block%zu\n", fr->block_i); - - switch (fr->end.type) - { - case FR_VAR: - if (endvar(fr, c)) - return -1; - break; - - case FR_VAL: - if (endval(fr, c)) - return -1; - break; - } - - return 0; -} - -int from_cgen(const struct from *fr, struct cgen *c) -{ - return from_var(fr, c); -} - -static int from_end(const struct stmt *s, struct cgen *c) -{ - const struct from *fr = &s->u.from; - const struct stentry *src = fr->var; - const struct type *t = src->t; - size_t sz = t->sz; - const char *tmp = cgen_tmp(sz); - const struct fn *fn = c->fn; - - printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(t)); - cgen_printvar(fn, src); - putchar('\n'); - printf("%%%s =%s add %%%s, 1\n", tmp, cgen_sz(sz), tmp); - printf("store%s %%%s, ", cgen_sz(sz), tmp); - cgen_printvar(fn, src); - putchar('\n'); - printf("jmp @__block%zu\n", fr->block_i); - return 0; -} - static int checksym(const struct fn *fn, const struct tk *tk, struct from_it *fr) { @@ -241,7 +114,8 @@ static int finalize(struct prv *p, struct fn *fn, struct from *fr) return 0; } -static const struct type *valtype(const struct fn *fn, const struct tk *tk) +static const struct type *valtype(const struct fn *fn, const char *tr, + const struct tk *tk) { char *end; @@ -254,20 +128,21 @@ static const struct type *valtype(const struct fn *fn, const struct tk *tk) strtoll(tk->s, &end, 0); if (errno || *end) - return type_find(fn, "ulong"); + return type_find(fn, tr, "ulong"); - return type_find(fn, "long"); + return type_find(fn, tr, "long"); } - return type_find(fn, "word"); + return type_find(fn, tr, "word"); } -static const struct type *ittype(const struct fn *fn, const struct from_it *it) +static const struct type *ittype(const struct fn *fn, const char *tr, + const struct from_it *it) { switch (it->type) { case FR_VAL: - return valtype(fn, it->u.tk); + return valtype(fn, tr, it->u.tk); case FR_VAR: return it->u.e->t; } @@ -277,9 +152,9 @@ static const struct type *ittype(const struct fn *fn, const struct from_it *it) } static const struct type *gettype(const struct fn *fn, - const struct from_it *a, const struct from_it *b) + const char *tr, const struct from_it *a, const struct from_it *b) { - const struct type *ta = ittype(fn, a), *tb = ittype(fn, b); + const struct type *ta = ittype(fn, tr, a), *tb = ittype(fn, tr, b); return ta->sz > tb->sz ? ta : tb; } @@ -287,13 +162,14 @@ static const struct type *gettype(const struct fn *fn, int from(const struct lex *l, struct prv *p) { const struct tk *start = p->stk + 1, *end = p->stk + 3; + const char *tr = triplet(p); struct fn *fn = fn_cur(p); struct from fr = {0}; const struct type *t; if (check(fn, start, &fr.start) || check(fn, end, &fr.end) - || !(t = gettype(fn, &fr.start, &fr.end)) + || !(t = gettype(fn, tr, &fr.start, &fr.end)) || !(fr.var = tmp_create(fn, t))) return -1; diff --git a/src/prc1/from.h b/src/prc1/from.h index 8a77629..89b2f04 100644 --- a/src/prc1/from.h +++ b/src/prc1/from.h @@ -29,6 +29,7 @@ int from_id(const struct lex *l, struct prv *p); int from_by(const struct lex *l, struct prv *p); int from_idby(const struct lex *l, struct prv *p); int from_cgen(const struct from *m, struct cgen *c); +int from_end(const struct stmt *s, struct cgen *c); void from_free(struct from *fr); #endif diff --git a/src/prc1/kw.c b/src/prc1/kw.c index 0f4ca9f..8531c52 100644 --- a/src/prc1/kw.c +++ b/src/prc1/kw.c @@ -7,7 +7,7 @@ static const char *kws[] = /* headers */ "public", "function", /* sections */ - "types", "storage", "linkage", "procedure", "locals", "globals", "imports", + "types", "externals", "procedure", "locals", "globals", "imports", /* types */ "union", "struct", "constant", "alias", "prototype", /* operators */ @@ -26,9 +26,9 @@ static const char *kws[] = /* comparators */ "is", "not", "equal", "greater", "smaller", "and", "or", /* built-in types */ - "void", "array", "pointer", + "void", "char", "array", "pointer", /* built-in signed types */ - "char", "schar", "short", "int", "long", "longlong", + "schar", "short", "int", "long", "longlong", /* built-in unsigned types */ "uchar", "ushort", "uint", "ulong", "ulonglong" }; diff --git a/src/prc1/lk.c b/src/prc1/lk.c index 8bfb738..488529d 100644 --- a/src/prc1/lk.c +++ b/src/prc1/lk.c @@ -8,5 +8,5 @@ int lk(const struct lex *l, struct prv *p) { struct fn *fn = fn_cur(p); - return storage(l, p, "linkage section", 1, &fn->lk); + return storage(l, p, "externals section", 1, &fn->lk); } diff --git a/src/prc1/prc1.c b/src/prc1/prc1.c index 634608b..bd481c1 100644 --- a/src/prc1/prc1.c +++ b/src/prc1/prc1.c @@ -41,13 +41,8 @@ int main(int argc, char *argv[]) fname = args.src; } - if (!(l.loc.f = malloc(strlen(fname) + 1))) - { - perror("malloc(3)"); + if (!(l.loc.f = sdup(fname))) goto end; - } - else - strcpy(l.loc.f, fname); l.args = a.args = &args; diff --git a/src/prc1/prv.h b/src/prc1/prv.h index e3658bc..945c7be 100644 --- a/src/prc1/prv.h +++ b/src/prc1/prv.h @@ -43,10 +43,10 @@ struct seq }; int kw(const char *s); -int prev(const struct prv *p); int push(const struct pos *pos, struct prv *p); int pop(const struct lex *l, struct prv *p); void reset(struct prv *p); char *sdup(const char *s); +const char *triplet(const struct prv *p); #endif diff --git a/src/prc1/sym.c b/src/prc1/sym.c index fb67f14..69d3bca 100644 --- a/src/prc1/sym.c +++ b/src/prc1/sym.c @@ -363,7 +363,8 @@ static int invalid(const struct tk *tk, const struct type *a, static const struct type *genlittype(struct prv *p) { const struct fn *fn = fn_cur(p); - const struct type *byte = type_find(fn, "char"); + const char *tr = triplet(p); + const struct type *byte = type_find(fn, tr, "char"); struct type *bytedup = NULL, *t = NULL; if (!byte) @@ -420,9 +421,10 @@ const struct type *sym_type(struct prv *p, const struct sym *s) case SYM_ID: { const struct stentry *e = fn_var(fn, tk); + const char *tr = triplet(p); const struct type *t; - if (!e && !(t = type_ufind(fn, tk->s))) + if (!e && !(t = type_ufind(fn, tr, tk->s))) return NULL; else if (e) t = e->t; diff --git a/src/prc1/td.c b/src/prc1/td.c index af88af8..4f894af 100644 --- a/src/prc1/td.c +++ b/src/prc1/td.c @@ -98,9 +98,10 @@ static void insert(struct td *td, struct type *t) static int cid(const struct lex *l, struct prv *p) { const struct fn *fn = fn_cur(p); + const char *tr = triplet(p); const struct tk *id = p->stk, *v = p->stk + 3; const struct stentry *e; - const struct type *t = type_find(fn, id->s); + const struct type *t = type_find(fn, tr, id->s); struct tdconstant *tdc = p->tdc; struct td *td = fn->td; struct type *nt; @@ -127,7 +128,7 @@ static int cid(const struct lex *l, struct prv *p) v->s, loc->f, loc->line, loc->col); return -1; } - else if (!(t = type_find(fn, v->s))) + else if (!(t = type_find(fn, tr, v->s))) { errloc(id, "undefined reference to value \"%s\"", v->s); return -1; @@ -173,12 +174,12 @@ static int cnum(const struct lex *l, struct prv *p) { const struct fn *fn = fn_cur(p); const struct tk *id = p->stk, *num = p->stk + 3; - const char *name = id->s; + const char *name = id->s, *tr = triplet(p); const struct stentry *e; struct td *td = fn->td; struct type *nt; struct tdconstant *tdc = p->tdc; - const struct type *t = type_find(fn, name); + const struct type *t = type_find(fn, tr, name); int sign = *num->s == '-'; unsigned long long uv = 0; const struct loc *loc; @@ -247,8 +248,9 @@ static int c(const struct lex *l, struct prv *p) { const struct fn *fn = fn_cur(p); const struct tk *id = p->stk; + const char *tr = triplet(p); const struct stentry *e; - const struct type *t = type_find(fn, id->s); + const struct type *t = type_find(fn, tr, id->s); struct td *td = fn->td; struct type *nt; const struct tdconstant *tdc = p->tdc; @@ -426,10 +428,11 @@ static int end(const struct lex *l, struct prv *p) static int s(const struct lex *l, struct prv *p) { const struct tk *id = p->stk; + const char *tr = triplet(p); struct fn *fn = fn_cur(p); struct td *td = fn->td; struct type *nt; - const struct type *t = type_find(fn, id->s); + const struct type *t = type_find(fn, tr, id->s); if (t) { @@ -467,8 +470,9 @@ static int tt(const struct lex *l, struct prv *p, const struct type *t) { int ret = -1; const struct fn *fn = fn_cur(p); + const char *tr = triplet(p); const struct tk *id = p->id; - const struct type *tp = type_ufind(fn, id->s); + const struct type *tp = type_ufind(fn, tr, id->s); const struct loc *loc = &id->loc; struct td *td = fn->td; struct type *nt; diff --git a/src/prc1/tmp.c b/src/prc1/tmp.c index 96b2208..c990216 100644 --- a/src/prc1/tmp.c +++ b/src/prc1/tmp.c @@ -1,6 +1,7 @@ #include "tmp.h" #include "dbg.h" #include "type.h" +#include "prv.h" #include <stddef.h> #include <stdio.h> #include <stdlib.h> @@ -11,7 +12,7 @@ const struct stentry *tmp_create(struct fn *fn, const struct type *t) static const char fmt[] = "__tmp%zu", path[] = "(temporary)"; int r = snprintf(NULL, 0, fmt, fn->ntmps); char *s = NULL, *tname = NULL, *pathdup = NULL; - struct tmp *tmp; + struct tmp *tmp = NULL; if (!(tname = type_name(t))) goto failure; @@ -21,20 +22,15 @@ const struct stentry *tmp_create(struct fn *fn, const struct type *t) goto failure; } else if (!(s = malloc(r + 1)) - || !(pathdup = malloc(strlen(path) + 1))) + || !(tmp = malloc(sizeof *tmp))) { perror("malloc(3)"); goto failure; } + else if (!(pathdup = sdup(path + 1))) + goto failure; snprintf(s, r + 1, fmt, fn->ntmps++); - strcpy(pathdup, path); - - if (!(tmp = malloc(sizeof *tmp))) - { - perror("realloc(3)"); - goto failure; - } *tmp = (struct tmp) { @@ -68,6 +64,7 @@ const struct stentry *tmp_create(struct fn *fn, const struct type *t) failure: free(s); + free(tmp); free(tname); free(pathdup); return NULL; diff --git a/src/prc1/triplet.c b/src/prc1/triplet.c new file mode 100644 index 0000000..37d6e10 --- /dev/null +++ b/src/prc1/triplet.c @@ -0,0 +1,40 @@ +#include "prv.h" +#include "arg.h" +#include "parse.h" +#include "triplet/prv.h" +#include <stddef.h> +#include <string.h> + +const char *triplet(const struct prv *p) +{ + const struct args *args = p->ast->args; + + return args->triplet; +} + +static const struct type *find(const char *s, const struct type (*v)[12]) +{ + for (size_t i = 0; i < sizeof *v / sizeof **v; i++) + if (!strcmp(s, (*v)[i].u.b.name)) + return &(*v)[i]; + + return NULL; +} + +const struct type *triplet_type(const char *tr, const char *s) +{ + static const struct + { + const char *s; + const struct type (*v)[12]; + } m[] = + { + {"x86_64-linux-gnu", &x86_64_linux_gnu} + }; + + for (size_t i = 0; i < sizeof m / sizeof *m; i++) + if (!strcmp(tr, m[i].s)) + return find(s, m[i].v); + + return NULL; +} diff --git a/src/prc1/triplet.h b/src/prc1/triplet.h new file mode 100644 index 0000000..cccca0c --- /dev/null +++ b/src/prc1/triplet.h @@ -0,0 +1,9 @@ +#ifndef TRIPLET_H +#define TRIPLET_H + +#include "prv.h" + +const char *triplet(const struct prv *p); +const struct type *triplet_type(const char *tr, const char *s); + +#endif diff --git a/src/prc1/triplet/CMakeLists.txt b/src/prc1/triplet/CMakeLists.txt new file mode 100644 index 0000000..49b17ee --- /dev/null +++ b/src/prc1/triplet/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(prc1 PRIVATE + x86_64-linux-gnu.c +) diff --git a/src/prc1/triplet/prv.h b/src/prc1/triplet/prv.h new file mode 100644 index 0000000..342036c --- /dev/null +++ b/src/prc1/triplet/prv.h @@ -0,0 +1,3 @@ +#include "parse.h" + +extern const struct type x86_64_linux_gnu[12]; diff --git a/src/prc1/triplet/x86_64-linux-gnu.c b/src/prc1/triplet/x86_64-linux-gnu.c new file mode 100644 index 0000000..c22bc93 --- /dev/null +++ b/src/prc1/triplet/x86_64-linux-gnu.c @@ -0,0 +1,18 @@ +#include "triplet/prv.h" +#include "parse.h" + +const struct type x86_64_linux_gnu[] = +{ + {.type = BUILTIN, .u.b = {"void"}}, + {.type = BUILTIN, .u.b = {"char"}, .sz = 1, .sign = 1, .align = 1}, + {.type = BUILTIN, .u.b = {"schar"}, .sz = 1, .sign = 1, .align = 1}, + {.type = BUILTIN, .u.b = {"short"}, .sz = 2, .sign = 1, .align = 2}, + {.type = BUILTIN, .u.b = {"int"}, .sz = 4, .sign = 1, .align = 4}, + {.type = BUILTIN, .u.b = {"long"}, .sz = 8, .sign = 1, .align = 8}, + {.type = BUILTIN, .u.b = {"longlong"}, .sz = 8, .sign = 1, .align = 8}, + {.type = BUILTIN, .u.b = {"uchar"}, .sz = 1, .align = 1}, + {.type = BUILTIN, .u.b = {"ushort"}, .sz = 2, .align = 2}, + {.type = BUILTIN, .u.b = {"uint"}, .sz = 4, .align = 4}, + {.type = BUILTIN, .u.b = {"ulong"}, .sz = 8, .align = 8}, + {.type = BUILTIN, .u.b = {"ulonglong"}, .sz = 8, .align = 8} +}; diff --git a/src/prc1/type.c b/src/prc1/type.c index 92cc53f..cdd8f72 100644 --- a/src/prc1/type.c +++ b/src/prc1/type.c @@ -4,6 +4,7 @@ #include "lex.h" #include "parse.h" #include "prv.h" +#include "triplet.h" #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -159,61 +160,31 @@ char *type_name(const struct type *t) return ret; } -const struct type *type_ufind(const struct fn *fn, const char *s) +const struct type *type_ufind(const struct fn *fn, const char *tr, + const char *s) { - static const struct type builtins[] = - { - {.type = BUILTIN, .u.b = {"void"}}, - {.type = BUILTIN, .u.b = {"char"}, .sz = 1, .sign = 1, .align = 1}, - {.type = BUILTIN, .u.b = {"schar"}, .sz = 1, .sign = 1, .align = 1}, - {.type = BUILTIN, .u.b = {"short"}, .sz = 2, .sign = 1, .align = 2}, - {.type = BUILTIN, .u.b = {"int"}, .sz = 4, .sign = 1, .align = 4}, - {.type = BUILTIN, .u.b = {"long"}, .sz = 8, .sign = 1, .align = 8}, - {.type = BUILTIN, .u.b = {"longlong"}, .sz = 8, .sign = 1, .align = 8}, - {.type = BUILTIN, .u.b = {"uchar"}, .sz = 1, .align = 1}, - {.type = BUILTIN, .u.b = {"ushort"}, .sz = 2, .align = 2}, - {.type = BUILTIN, .u.b = {"uint"}, .sz = 4, .align = 4}, - {.type = BUILTIN, .u.b = {"ulong"}, .sz = 8, .align = 8}, - {.type = BUILTIN, .u.b = {"ulonglong"}, .sz = 8, .align = 8} - }; - const struct td *td = fn->td; + const struct type *t; - if (fn->parent) - { - const struct type *t = type_find(fn->parent, s); - - if (t) - return t; - } - - for (size_t i = 0; i < sizeof builtins / sizeof *builtins; i++) - { - const struct type *t = &builtins[i]; - - if (!strcmp(t->u.b.name, s)) - return t; - } - - if (td) + if (fn->parent && (t = type_find(fn->parent, tr, s))) + return t; + else if ((t = triplet_type(tr, s))) + return t; + else if (td) for (const struct type *t = td->types; t; t = t->next) if (!strcmp(t->tk->s, s)) return t; for (size_t i = 0; i < fn->nimps; i++) - { - const struct type *t = type_ufind(fn->imps[i].ast.fns, s); - - if (t) + if ((t = type_ufind(fn->imps[i].ast.fns, tr, s))) return t; - } return NULL; } -const struct type *type_find(const struct fn *fn, const char *s) +const struct type *type_find(const struct fn *fn, const char *tr, const char *s) { - const struct type *t = type_ufind(fn, s); + const struct type *t = type_ufind(fn, tr, s); if (t && t->type == T) return t->u.t.alias; @@ -270,7 +241,7 @@ static int aetc(const struct lex *l, struct prv *p) static int aid(const struct lex *l, struct prv *p) { const struct tk *qty = p->stk + 2; - const struct type *ct = type_find(fn_cur(p), qty->s); + const struct type *ct = type_find(fn_cur(p), triplet(p), qty->s); struct type *t; unsigned long long v; @@ -410,7 +381,7 @@ static int t(const struct lex *l, struct prv *p) { const struct fn *fn = fn_cur(p); const struct tk *tk = p->stk; - const struct type *t = type_find(fn, tk->s); + const struct type *t = type_find(fn, triplet(p), tk->s); struct type *tt = p->t; if (!t) diff --git a/src/prc1/type.h b/src/prc1/type.h index 455f243..ae53b34 100644 --- a/src/prc1/type.h +++ b/src/prc1/type.h @@ -5,8 +5,8 @@ #include "prv.h" #include "parse.h" -const struct type *type_ufind(const struct fn *fn, const char *s); -const struct type *type_find(const struct fn *fn, const char *s); +const struct type *type_ufind(const struct fn *fn, const char *t, const char *s); +const struct type *type_find(const struct fn *fn, const char *t, const char *s); const struct type *type_insert(struct prv *p, struct type *a); char *type_name(const struct type *t); int type(const struct lex *l, struct prv *p, diff --git a/src/prc1/ws.c b/src/prc1/ws.c index 94014ce..c553f6e 100644 --- a/src/prc1/ws.c +++ b/src/prc1/ws.c @@ -8,5 +8,5 @@ int ws(const struct lex *l, struct prv *p) { struct fn *fn = fn_cur(p); - return storage(l, p, "storage section", 1, &fn->ws); + return storage(l, p, "locals section", 1, &fn->ws); } |
