aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2026-10-11 01:26:41 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2026-10-20 01:03:47 +0200
commitcab0135f57ca1c7e448e11f866b0adb8a1328d48 (patch)
treefcc24dc0b2d350524c33f07dc8b71f491431e832
parent4ce39e4fc1de9536de7dedfe91b6dee38dec76ae (diff)
downloadprc-master.tar.gz
WIP tripletHEADmaster
-rw-r--r--examples/hello.prs2
-rw-r--r--src/prc/posix.c4
-rw-r--r--src/prc1/CMakeLists.txt2
-rw-r--r--src/prc1/arg.c19
-rw-r--r--src/prc1/arg.h4
-rw-r--r--src/prc1/cgen.c5
-rw-r--r--src/prc1/cgen/CMakeLists.txt1
-rw-r--r--src/prc1/cgen/from.c8
-rw-r--r--src/prc1/cgen/prv.h2
-rw-r--r--src/prc1/cgen/qbe/CMakeLists.txt1
-rw-r--r--src/prc1/cgen/qbe/from.c134
-rw-r--r--src/prc1/cgen/qbe/qbe.c1
-rw-r--r--src/prc1/cgen/qbe/qbe.h2
-rw-r--r--src/prc1/div.c10
-rw-r--r--src/prc1/from.c150
-rw-r--r--src/prc1/from.h1
-rw-r--r--src/prc1/kw.c6
-rw-r--r--src/prc1/lk.c2
-rw-r--r--src/prc1/prc1.c7
-rw-r--r--src/prc1/prv.h2
-rw-r--r--src/prc1/sym.c6
-rw-r--r--src/prc1/td.c18
-rw-r--r--src/prc1/tmp.c15
-rw-r--r--src/prc1/triplet.c40
-rw-r--r--src/prc1/triplet.h9
-rw-r--r--src/prc1/triplet/CMakeLists.txt3
-rw-r--r--src/prc1/triplet/prv.h3
-rw-r--r--src/prc1/triplet/x86_64-linux-gnu.c18
-rw-r--r--src/prc1/type.c57
-rw-r--r--src/prc1/type.h4
-rw-r--r--src/prc1/ws.c2
31 files changed, 311 insertions, 227 deletions
diff --git a/examples/hello.prs b/examples/hello.prs
index 4ba371a..ae1693d 100644
--- a/examples/hello.prs
+++ b/examples/hello.prs
@@ -5,7 +5,7 @@ public function main
myptr pointer to int
types
socket prototype
- linkage
+ externals
fd int
procedure returning fd
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);
}