ref: 6e03c31865cf9167ec3e8743ed3700b3e7bcba2d
parent: 916167a53d09c9852020c5c75bfe2fe6744ddb0a
parent: 2acbf18832cedf7acdc3f6640d343b5f0feb1398
author: Ori Bernstein <[email protected]>
date: Wed Jun 20 07:47:02 EDT 2012
Merge branch 'master' of git+ssh://mimir.eigenstate.org/git/ori/mc2 Conflicts: 8/main.c
--- a/8/isel.c
+++ b/8/isel.c
@@ -803,7 +803,7 @@
is.curbb = is.bb[0];
prologue(&is, fn->stksz);
- for (j = 0; j < fn->cfg->nbb; j++) {
+ for (j = 0; j < fn->cfg->nbb - 1; j++) {
is.curbb = is.bb[j];
for (i = 0; i < fn->cfg->bb[j]->nnl; i++) {
/* put in a comment that says where this line comes from */
@@ -817,7 +817,5 @@
epilogue(&is);
regalloc(&is);
- if (debug)
- writeasm(stdout, &is, fn);
writeasm(fd, &is, fn);
}
--- a/8/main.c
+++ b/8/main.c
@@ -12,11 +12,12 @@
#include "parse.h"
#include "opt.h"
#include "asm.h"
+#include "platform.h"
/* FIXME: move into one place...? */
Node *file;
int debug;
-int asmonly;
+char debugopt[128];
char *outfile;
char **incpaths;
size_t nincpaths;
@@ -23,41 +24,27 @@
static void usage(char *prog)
{
- printf("%s [-h] [-o outfile] inputs\n", prog);
+ printf("%s [-h] [-o outfile] [-d[dbgopts]] inputs\n", prog);
printf("\t-h\tPrint this help\n");
printf("\t-I path\tAdd 'path' to use search path\n");
- printf("\t-d\tPrint debug dumps\n");
+ printf("\t-d\tPrint debug dumps. Recognized options: f r p i\n");
+ printf("\t\t\tno options: print most common debug information\n");
+ printf("\t\t\tf: additionally log folded trees\n");
+ printf("\t\t\tl: additionally log lowered pre-cfg trees\n");
+ printf("\t\t\tT: additionally log tree immediately\n");
+ printf("\t\t\tr: additionally log register allocation activity\n");
printf("\t-o\tOutput to outfile\n");
printf("\t-S\tGenerate assembly instead of object code\n");
}
-char *outfmt(char *buf, size_t sz, char *infile, char *outfile)
+static void assem(char *f)
{
- char *p, *suffix;
- size_t len;
+ char objfile[1024];
+ char cmd[1024];
- if (outfile) {
- snprintf(buf, sz, "%s", outfile);
- return buf;
- }
-
- if (asmonly)
- suffix = ".s";
- else
- suffix = ".o";
-
- p = strrchr(infile, '.');
- if (p)
- len = (p - infile);
- else
- len = strlen(infile);
- if (len + strlen(suffix) >= sz)
- die("Output file name too long");
- buf[0] = '\0';
- strncat(buf, infile, len);
- strcat(buf, suffix);
-
- return buf;
+ swapsuffix(objfile, 1024, f, ".s", ".o");
+ snprintf(cmd, 1024, Asmcmd, objfile, f);
+ system(cmd);
}
int main(int argc, char **argv)
@@ -67,7 +54,7 @@
Stab *globls;
char buf[1024];
- while ((opt = getopt(argc, argv, "dhSo:I:")) != -1) {
+ while ((opt = getopt(argc, argv, "d::hSo:I:")) != -1) {
switch (opt) {
case 'o':
outfile = optarg;
@@ -77,11 +64,10 @@
exit(0);
break;
case 'd':
- debug++;
+ debug = 1;
+ while (optarg && *optarg)
+ debugopt[*optarg++ & 0x7f] = 1;
break;
- case 'S':
- asmonly++;
- break;
case 'I':
lappend(&incpaths, &nincpaths, optarg);
break;
@@ -102,7 +88,7 @@
yyparse();
/* before we do anything to the parse */
- if (debug)
+ if (debugopt['T'])
dump(file, stdout);
infer(file);
/* after all processing */
@@ -109,7 +95,9 @@
if (debug)
dump(file, stdout);
- gen(file, outfmt(buf, 1024, argv[i], outfile));
+ swapsuffix(buf, 1024, argv[i], ".myr", ".s");
+ gen(file, buf);
+ assem(buf);
}
return 0;
--- a/8/platform.h
+++ b/8/platform.h
@@ -1,8 +1,9 @@
#if defined(__APPLE__) && defined(__MACH__)
/* for OSX */
+# define Asmcmd "as -arch i386 -g -o %s %s"
# define Fprefix "_"
#else
/* Default to linux */
+# define Asmcmd "as --32 -g -o %s %s"
# define Fprefix ""
#endif
-#define Assembler "as --32 -g -o %s -"
--- a/8/ra.c
+++ b/8/ra.c
@@ -539,7 +539,7 @@
size_t i, j;
int has;
- if (debug) {
+ if (debugopt['r']) {
printf("Combine ");
locprint(stdout, locmap[u]);
printf(" ==> ");
@@ -709,7 +709,7 @@
found = 0;
for (i = 0; i < K; i++) {
if (!taken[i]) {
- if (debug) {
+ if (debugopt['r']) {
locprint(stdout, n);
printf(" ==> %s\n", regnames[regmap[i][n->mode]]);
}
@@ -749,7 +749,7 @@
liveness(s);
build(s);
mkworklist(s);
- if (debug)
+ if (debugopt['r'])
dumpasm(s, stdout);
do {
if (s->nwlsimp)
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -56,6 +56,7 @@
static Node *zero;
static Node *ptrsz;
static Type *tyword;
+static Type *tyvoid;
static Type *base(Type *t)
{
@@ -204,8 +205,7 @@
return 2;
case Tyint: case Tyint32:
case Tyuint: case Tyuint32:
- case Typtr: case Tyenum:
- case Tyfunc:
+ case Typtr: case Tyfunc:
return 4;
case Tyint64: case Tylong:
@@ -347,10 +347,10 @@
n = mkname(lit->line, genlblstr(lbl, 128));
t = mkdecl(lit->line, n, lit->expr.type);
- r = mkexpr(lit->line, Ovar, t, NULL);
- t->decl.init = lit;
+ r = mkexpr(lit->line, Ovar, n, NULL);
+ r->expr.type = lit->expr.type;
r->expr.did = t->decl.did;
- r->expr.type = t->expr.type;
+ t->decl.init = lit;
htput(s->globls, t, strdup(lbl));
lappend(&s->blobs, &s->nblobs, t);
return r;
@@ -529,11 +529,27 @@
return r;
}
+static Node *visit(Simp *s, Node *n)
+{
+ size_t i;
+ Node *r;
+
+ for (i = 0; i < n->expr.nargs; i++)
+ n->expr.args[i] = rval(s, n->expr.args[i]);
+ if (ispure(n)) {
+ r = n;
+ } else {
+ r = temp(s, n);
+ append(s, store(r, n));
+ }
+ return r;
+}
+
static Node *rval(Simp *s, Node *n)
{
Node *r; /* expression result */
Node *t, *u, *v; /* temporary nodes */
- size_t i;
+ Type *ty;
Node **args;
const Op fusedmap[] = {
[Oaddeq] = Oadd,
@@ -665,15 +681,19 @@
r = store(t, u);
}
break;
- default:
- for (i = 0; i < n->expr.nargs; i++)
- n->expr.args[i] = rval(s, n->expr.args[i]);
- if (ispure(n)) {
- r = n;
- } else {
+ case Ocall:
+ if (size(n) > 4) {
r = temp(s, n);
- append(s, store(r, n));
+ ty = mktyptr(n->line, exprtype(r));
+ linsert(&args[0]->expr.args, &n->expr.nargs, 1, addr(r, ty));
+ linsert(&args[0]->expr.type->sub, &n->expr.type->nsub, 1, ty);
+ args[0]->expr.type->sub[0] = tyvoid;
+ n->expr.type = tyvoid;
}
+ r = visit(s, n);
+ break;
+ default:
+ r = visit(s, n);
}
return r;
}
@@ -683,7 +703,7 @@
assert(n->type == Ndecl);
s->stksz += size(n);
if (debug)
- printf("DECLARE %s(%ld) at %zd\n", declname(n), n->decl.did, s->stksz);
+ printf("declare %s(%ld) at %zd\n", declname(n), n->decl.did, s->stksz);
htput(s->locs, n, (void*)s->stksz);
}
@@ -691,7 +711,7 @@
{
assert(n->type == Ndecl);
if (debug)
- printf("DECLARE %s(%ld) at %zd\n", declname(n), n->decl.did, -(s->argsz + 8));
+ printf("declare %s(%ld) at %zd\n", declname(n), n->decl.did, -(s->argsz + 8));
htput(s->locs, n, (void*)-(s->argsz + 8));
s->argsz += size(n);
}
@@ -778,6 +798,8 @@
if(debug)
printf("\n\nfunction %s\n", name);
+ if (!n->decl.init)
+ return NULL;
/* set up the simp context */
/* unwrap to the function body */
n = n->expr.args[0];
@@ -790,12 +812,12 @@
for (i = 0; i < s->nstmts; i++) {
if (s->stmts[i]->type != Nexpr)
continue;
- if (debug) {
+ if (debugopt['f']) {
printf("FOLD FROM ----------\n");
dump(s->stmts[i], stdout);
}
s->stmts[i] = fold(s->stmts[i]);
- if (debug) {
+ if (debugopt['f']) {
printf("FOLD TO ------------\n");
dump(s->stmts[i], stdout);
printf("END ----------------\n");
@@ -850,11 +872,13 @@
s.nblobs = *nblob;
if (isconstfn(dcl)) {
- f = lowerfn(&s, name, dcl->decl.init);
- lappend(fn, nfn, f);
+ if (!dcl->decl.isextern) {
+ f = lowerfn(&s, name, dcl->decl.init);
+ lappend(fn, nfn, f);
+ }
} else {
if (dcl->decl.init && exprop(dcl->decl.init) == Olit)
- lappend(blob, nblob, dcl);
+ lappend(&s.blobs, &s.nblobs, dcl);
else
die("We don't lower globls with nonlit inits yet...");
}
@@ -871,10 +895,10 @@
size_t nn, nfn, nblob;
size_t i;
FILE *fd;
- char cmd[1024];
/* declare useful constants */
tyword = mkty(-1, Tyint);
+ tyvoid = mkty(-1, Tyvoid);
one = word(-1, 1);
zero = word(-1, 0);
ptrsz = word(-1, 4);
@@ -903,21 +927,19 @@
}
}
- sprintf(cmd, Assembler, out);
- if (asmonly)
- fd = fopen(out, "w");
- else
- fd = popen(cmd, "w");
+ fd = fopen(out, "w");
if (!fd)
die("Couldn't open fd %s", out);
+ if (debug) {
+ for (i = 0; i < nblob; i++)
+ genblob(stdout, blob[i], globls);
+ for (i = 0; i < nfn; i++)
+ genasm(stdout, fn[i], globls);
+ }
for (i = 0; i < nblob; i++)
genblob(fd, blob[i], globls);
for (i = 0; i < nfn; i++)
genasm(fd, fn[i], globls);
- fflush(fd);
- if (asmonly)
- fclose(fd);
- else
- pclose(fd);
+ fclose(fd);
}
--- a/mk/c.mk
+++ b/mk/c.mk
@@ -16,18 +16,14 @@
all: subdirs $(BIN) $(LIB) $(EXTRA)
install: subdirs-install install-bin install-lib install-hdr install-pc
-$(LIB): $(OBJ) libs
+$(LIB): $(OBJ) $(DEPS)
$(AR) -rcs $@ $(OBJ)
-$(BIN): $(OBJ) $(EXTRADEP) libs
+$(BIN): $(OBJ) $(EXTRADEP) $(DEPS)
$(CC) -o $@ $(OBJ) $(_LIBSRCHPATHS) $(_LIBPATHS)
-libs: $(DEPS)
- @for i in $(dir $(DEPS)); do (\
- cd $$i && \
- $(MAKE) || \
- exit 1 \
- ) || exit 1; done
+$(DEPS):
+ @cd $(dir $@) && $(MAKE)
subdirs:
@for i in $(SUB); do (\
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -18,7 +18,7 @@
int yylex(void);
static Op binop(int toktype);
Stab *curscope;
-//int n = 0;
+
%}
%token<tok> Terror
@@ -83,7 +83,6 @@
%token<tok> Tchrlit
%token<tok> Tboollit
-%token<tok> Tenum /* enum */
%token<tok> Tstruct /* struct */
%token<tok> Tunion /* union */
%token<tok> Ttyparam /* @typename */
@@ -113,7 +112,7 @@
%start module
-%type <ty> type structdef uniondef enumdef compoundtype functype funcsig
+%type <ty> type structdef uniondef compoundtype functype funcsig
%type <ty> generictype
%type <tok> asnop cmpop addop mulop shiftop
@@ -123,11 +122,11 @@
%type <node> exprln retexpr expr atomicexpr literal asnexpr lorexpr landexpr borexpr
%type <node> bandexpr cmpexpr addexpr mulexpr shiftexpr prefixexpr postfixexpr
%type <node> funclit arraylit name block blockbody stmt label use
-%type <node> decl declbody declcore structelt enumelt unionelt
+%type <node> decl declbody declcore structelt unionelt
%type <node> ifstmt forstmt whilestmt elifs optexprln
%type <node> castexpr
-%type <nodelist> arglist argdefs structbody enumbody unionbody params
+%type <nodelist> arglist argdefs structbody unionbody params
%union {
struct {
@@ -207,10 +206,11 @@
| pkgbody pkgitem
;
-pkgitem : decl {putdcl(file->file.exports, $1);}
- | tydef {puttype(file->file.exports,
- mkname($1.line, $1.name),
- $1.type);}
+pkgitem : decl
+ {putdcl(file->file.exports, $1);
+ if ($1->decl.init)
+ lappend(&file->file.stmts, &file->file.nstmts, $1);}
+ | tydef {puttype(file->file.exports, mkname($1.line, $1.name), $1.type);}
| visdef {die("Unimplemented visdef");}
| Tendln
;
@@ -248,7 +248,6 @@
type : structdef
| uniondef
- | enumdef
| compoundtype
| generictype
| Tellipsis {$$ = mkty($1->line, Tyvalist);}
@@ -283,6 +282,10 @@
$$.nn = 0; lappend(&$$.nl, &$$.nn, $1);}
| argdefs Tcomma declcore
{lappend(&$$.nl, &$$.nn, $3);}
+ | /* empty */
+ {$$.line = line;
+ $$.nl = NULL;
+ $$.nn = 0;}
;
structdef
@@ -323,24 +326,6 @@
{$$ = NULL; die("unionelt impl");}
| visdef Tendln
{$$ = NULL;}
- | Tendln
- {$$ = NULL;}
- ;
-
-enumdef : Tenum enumbody Tendblk
- {$$ = mktyenum($1->line, $2.nl, $2.nn);}
- ;
-
-enumbody: enumelt
- {$$.nl = NULL; $$.nn = 0; if ($1) lappend(&$$.nl, &$$.nn, $1);}
- | enumbody enumelt
- {if ($2) {lappend(&$$.nl, &$$.nn, $2);}}
- ;
-
-enumelt : Tident Tendln
- {$$ = NULL; die("enumelt impl");}
- | Tident Tasn exprln
- {$$ = NULL; die("enumelt impl");}
| Tendln
{$$ = NULL;}
;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -455,6 +455,9 @@
if (n->decl.init) {
inferexpr(n->decl.init, NULL, NULL);
unify(n, type(n), type(n->decl.init));
+ } else {
+ if (n->decl.isconst && !n->decl.isextern)
+ fatal(n->line, "non-extern \"%s\" has no initializer", ctxstr(n));
}
}
@@ -474,9 +477,7 @@
static void infernode(Node *n, Type *ret, int *sawret)
{
- void **k;
- size_t i, nk;
- Type *ty;
+ size_t i;
Node *d;
Node *s;
@@ -486,15 +487,7 @@
case Nfile:
pushstab(n->file.globls);
/* exports allow us to specify types later in the body, so we
- * need to patch the types in. */
- k = htkeys(file->file.exports->ty, &nk);
- for (i = 0; i < nk; i++) {
- ty = gettype(file->file.globls, k[i]);
- if (!ty)
- fatal(((Node*)k[i])->line, "Exported type %s not declared", namestr(k[i]));
- updatetype(file->file.exports, k[i], tf(ty));
- }
- free(k);
+ * need to patch the types in if they don't have a definition */
inferstab(n->file.globls);
inferstab(n->file.exports);
for (i = 0; i < n->file.nstmts; i++) {
@@ -564,21 +557,16 @@
static Type *tyfix(Node *ctx, Type *t)
{
static Type *tyint;
- static Type *tyfloat;
size_t i;
char buf[1024];
if (!tyint)
tyint = mkty(-1, Tyint);
- if (!tyfloat)
- tyfloat = mkty(-1, Tyfloat64);
t = tf(t);
if (t->type == Tyvar) {
if (hascstr(t, cstrtab[Tcint]) && cstrcheck(t, tyint))
return tyint;
- if (hascstr(t, cstrtab[Tcnum]) && cstrcheck(t, tyfloat))
- return tyfloat;
} else {
if (t->type == Tyarray)
typesub(t->asize);
@@ -728,11 +716,62 @@
}
}
+void mergeexports(Node *file)
+{
+ Stab *exports, *globls;
+ size_t i, nk;
+ void **k;
+ /* local, global version */
+ Node *nl, *ng;
+ Type *tl, *tg;
+
+ exports = file->file.exports;
+ globls = file->file.globls;
+
+ pushstab(globls);
+ k = htkeys(exports->ty, &nk);
+ for (i = 0; i < nk; i++) {
+ tl = gettype(exports, k[i]);
+ nl = k[i];
+ if (tl) {
+ tg = gettype(globls, nl);
+ if (!tg)
+ puttype(globls, nl, tl);
+ else
+ fatal(nl->line, "Exported type %s double-declared on line %d", namestr(nl), tg->line);
+ } else {
+ tg = gettype(globls, nl);
+ if (tg)
+ updatetype(exports, nl, tf(tg));
+ else
+ fatal(nl->line, "Exported type %s not declared", namestr(nl));
+ }
+ }
+ free(k);
+
+ k = htkeys(exports->dcl, &nk);
+ for (i = 0; i < nk; i++) {
+ nl = getdcl(exports, k[i]);
+ ng = getdcl(globls, k[i]);
+ /* if an export has an initializer, it shouldn't be declared in the
+ * body */
+ if (nl->decl.init && ng)
+ fatal(nl->line, "Export %s double-defined on line %d", ctxstr(nl), ng->line);
+ if (!ng)
+ putdcl(globls, nl);
+ else
+ unify(nl, type(ng), type(nl));
+ }
+ free(k);
+ popstab();
+}
+
void infer(Node *file)
{
assert(file->type == Nfile);
loaduses(file);
+ mergeexports(file);
infernode(file, NULL, NULL);
infercompn(file);
checkcast(file);
--- a/parse/node.c
+++ b/parse/node.c
@@ -279,7 +279,6 @@
switch (t->type) {
case Tystruct: return t->sdecls; break;
case Tyunion: return t->udecls; break;
- case Tyenum: return t->edecls; break;
case Tyarray: return &t->asize; break;
default: return NULL;
}
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -94,7 +94,7 @@
int resolved; /* Have we resolved the subtypes? Idempotent, but slow to repeat. */
Bitset *cstrs; /* the type constraints matched on this type */
size_t nsub; /* For compound types */
- size_t nmemb; /* for aggregate types (struct, union, enum) */
+ size_t nmemb; /* for aggregate types (struct, union) */
Type **sub; /* sub-types; shared by all composite types */
union {
Node *name; /* Tyname: unresolved name */
@@ -102,7 +102,6 @@
char *pname; /* Typaram: name of type parameter */
Node **sdecls; /* Tystruct: decls in struct */
Node **udecls; /* Tyunion: decls in union */
- Node **edecls; /* Tyenum: decls in enum */
};
};
@@ -297,7 +296,6 @@
Type *mktyfunc(int line, Node **args, size_t nargs, Type *ret);
Type *mktystruct(int line, Node **decls, size_t ndecls);
Type *mktyunion(int line, Node **decls, size_t ndecls);
-Type *mktyenum(int line, Node **decls, size_t ndecls);
Cstr *mkcstr(int line, char *name, Node **memb, size_t nmemb, Node **funcs, size_t nfuncs);
Type *tylike(Type *t, Ty ty); /* constrains tyvar t like it was builtin ty */
int istysigned(Type *t);
@@ -363,6 +361,7 @@
/* convenience funcs */
void lappend(void *l, size_t *len, void *n); /* ugly hack; nl is void* because void*** is incompatible with T*** */
+void linsert(void *l, size_t *len, size_t idx, void *n);
void *lpop(void *l, size_t *len);
void ldel(void *l, size_t *len, size_t idx);
void lfree(void *l, size_t *len);
@@ -395,8 +394,12 @@
void wrbool(FILE *fd, int val);
int rdbool(FILE *fd);
+/* suffix replacement */
+char *swapsuffix(char *buf, size_t sz, char *s, char *suf, char *swap);
+
/* Options to control the compilation */
extern int debug;
+extern char debugopt[128];
extern int asmonly;
extern char *outfile;
extern char **incpaths;
--- a/parse/pickle.c
+++ b/parse/pickle.c
@@ -152,11 +152,6 @@
for (i = 0; i < ty->nmemb; i++)
pickle(ty->udecls[i], fd);
break;
- case Tyenum:
- wrint(fd, ty->nmemb);
- for (i = 0; i < ty->nmemb; i++)
- pickle(ty->edecls[i], fd);
- break;
case Tyarray:
wrtype(fd, ty->sub[0]);
pickle(ty->asize, fd);
@@ -205,12 +200,6 @@
ty->udecls = xalloc(ty->nmemb * sizeof(Node*));
for (i = 0; i < ty->nmemb; i++)
ty->udecls[i] = unpickle(fd);
- break;
- case Tyenum:
- ty->nmemb = rdint(fd);
- ty->edecls = xalloc(ty->nmemb * sizeof(Node*));
- for (i = 0; i < ty->nmemb; i++)
- ty->edecls[i] = unpickle(fd);
break;
case Tyarray:
ty->sub[0] = rdtype(fd);
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -108,7 +108,7 @@
d = getdcl(st, s->decl.name);
if (d)
- fatal(s->line, "%s already declared (line %d", namestr(s->decl.name), d->line);
+ fatal(s->line, "%s already declared (on line %d)", namestr(s->decl.name), d->line);
if (st->name)
setns(s->decl.name, namestr(st->name));
htput(st->dcl, s->decl.name, s);
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -141,7 +141,6 @@
{"match", Tmatch},
{"default", Tdefault},
{"goto", Tgoto},
- {"enum", Tenum},
{"struct", Tstruct},
{"union", Tunion},
{"const", Tconst},
--- a/parse/type.c
+++ b/parse/type.c
@@ -162,6 +162,7 @@
Type *t;
t = mkty(line, Tystruct);
+ t->nsub = 0;
t->nmemb = ndecls;
t->sdecls = memdup(decls, ndecls*sizeof(Node *));
return t;
@@ -177,16 +178,6 @@
return t;
}
-Type *mktyenum(int line, Node **decls, size_t ndecls)
-{
- Type *t;
-
- t = mkty(line, Tyenum);
- t->nmemb = ndecls;
- t->edecls = decls;
- return t;
-}
-
int istysigned(Type *t)
{
switch (t->type) {
@@ -258,8 +249,8 @@
end = p + len;
p += snprintf(p, end - p, "struct ");
for (i = 0; i < t->nmemb; i++) {
- name = declname(t->edecls[i]);
- ty = tystr(decltype(t->edecls[i]));
+ name = declname(t->sdecls[i]);
+ ty = tystr(decltype(t->sdecls[i]));
p += snprintf(p, end - p, "%s:%s; ", name, ty);
free(ty);
}
@@ -272,19 +263,10 @@
size_t i;
*buf = 0;
for (i = 0; i < t->nmemb; i++)
- dump(t->sdecls[i], stdout);
+ dump(t->udecls[i], stdout);
return 0;
}
-static int fmtenum(char *buf, size_t len, Type *t)
-{
- size_t i;
- *buf = 0;
- for (i = 0; i < t->nmemb; i++)
- dump(t->sdecls[i], stdout);
- return 0;
-}
-
static int tybfmt(char *buf, size_t len, Type *t)
{
size_t i;
@@ -374,7 +356,6 @@
break;
case Tystruct: p += fmtstruct(p, end - p, t); break;
case Tyunion: p += fmtunion(p, end - p, t); break;
- case Tyenum: p += fmtenum(p, end - p, t); break;
case Ntypes:
die("Ntypes is not a type");
break;
@@ -432,10 +413,6 @@
tycstrs[Tyslice][0] = cstrtab[Tctest];
tycstrs[Tyslice][1] = cstrtab[Tcslice];
tycstrs[Tyslice][2] = cstrtab[Tcidx];
-
- /* enum :: tcint, tcnum */
- tycstrs[Tyenum][0] = cstrtab[Tcint];
- tycstrs[Tyenum][1] = cstrtab[Tcnum];
/* array :: tcidx, tcslice */
tycstrs[Tyarray][0] = cstrtab[Tcidx];
--- a/parse/types.def
+++ b/parse/types.def
@@ -38,5 +38,4 @@
Ty(Tyname, NULL)
Ty(Tystruct, NULL)
Ty(Tyunion, NULL)
-Ty(Tyenum, NULL)
Ty(Ntypes, NULL)
--- a/parse/use.c
+++ b/parse/use.c
@@ -118,7 +118,7 @@
k = htkeys(st->ty, &n);
for (i = 0; i < n; i++) {
- t = htget(st->ty, k[i]);
+ t = gettype(st, k[i]);
wrbyte(f, 'T');
wrstr(f, namestr(k[i]));
typickle(t, f);
--- a/parse/util.c
+++ b/parse/util.c
@@ -129,6 +129,20 @@
return v;
}
+void linsert(void *p, size_t *len, size_t idx, void *v)
+{
+ void ***pl, **l;
+ size_t i;
+
+ pl = p;
+ *pl = xrealloc(*pl, (*len + 1)*sizeof(void*));
+ l = *pl;
+ for (i = idx; i < *len; i++)
+ l[i + 1] = l[i];
+ l[idx] = v;
+ (*len)++;
+}
+
void ldel(void *l, size_t *len, size_t idx)
{
void ***pl;
@@ -322,5 +336,30 @@
int rdbool(FILE *fd)
{
return rdbyte(fd);
+}
+
+char *swapsuffix(char *buf, size_t sz, char *s, char *suf, char *swap)
+{
+ size_t slen, suflen, swaplen;
+
+ slen = strlen(s);
+ suflen = strlen(suf);
+ swaplen = strlen(swap);
+
+ if (slen < suflen)
+ return NULL;
+ if (slen + swaplen >= sz)
+ die("swapsuffix: buf too small");
+
+ buf[0] = '\0';
+ if (suflen < slen && !strcmp(suf, &s[slen - suflen])) {
+ strncat(buf, s, slen - suflen);
+ strcat(buf, swap);
+ } else {
+ strncat(buf, s, slen);
+ strcat(buf, swap);
+ }
+
+ return buf;
}
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,11 +1,12 @@
# don't build anything for 'all'
all:
+ $(MAKE) -C ..
check:
./test.sh
.PHONY: clean
clean:
- @for i in `awk '{print $$1}' tests`; do \
+ @for i in `awk '/^[A-Z]/{print $$2}' tests`; do \
echo rm -f $$i; \
rm -f $$i; \
done
--- /dev/null
+++ b/test/arraylen.myr
@@ -1,0 +1,5 @@
+const main = {
+ var a : int[12]
+
+ -> a.len
+}
--- /dev/null
+++ b/test/generic.myr
@@ -1,0 +1,13 @@
+generic max = {a:@a::tcnum, b::@a::tcnum
+ if (a > b)
+ -> a
+ else
+ -> b
+ ;;
+}
+
+const main = {
+ max('a', 'b')
+ -> max(1, 2)
+}
+
--- /dev/null
+++ b/test/hello/Makefile
@@ -1,0 +1,11 @@
+# don't build anything for 'all'
+all:
+ ./bld.sh
+.PHONY: clean
+clean:
+ @for i in `awk '{print $$1}' tests`; do \
+ echo rm -f $$i; \
+ rm -f $$i; \
+ done
+
+install:
--- /dev/null
+++ b/test/hello/bld.sh
@@ -1,0 +1,36 @@
+#!/bin/bash
+
+# We have no dependency handling yet, so this is done via
+# a shell script. Also, we want to rebuild everything for
+# testing purposes on every run as things stand.
+
+export PATH=.:$PATH
+export MC=../../8/8m
+export MU=../../util/muse
+export CC=cc
+export ASOPT="-g"
+
+function use {
+ N=`basename $1 .myr`
+
+ echo $MU $1 -o $N.use && \
+ $MU $1 -o $N.use
+}
+
+function build {
+ N=`basename $1 .myr`
+
+ echo $MC $1 && \
+ $MC $1 -I.
+}
+
+function assem {
+ $CC $ASOPT -m32 -c $1
+}
+
+assem syscall.s
+use sys.myr
+build sys.myr
+build hello.myr
+
+$CC -m32 -o hello sys.o hello.o syscall.o
--- /dev/null
+++ b/test/hello/hello.myr
@@ -1,0 +1,5 @@
+use "sys.use"
+
+const main = {
+ sys.write(1, "Hello world\n")
+}
--- /dev/null
+++ b/test/hello/sys.myr
@@ -1,0 +1,69 @@
+
+pkg sys =
+ type scno = int
+ type fdopt = int
+ type statbuf = struct
+ dev : uint
+ ino : uint
+ mode : uint16
+ nlink : uint16
+ uid : uint16
+ gid : uint16
+ rdev : uint
+ size : uint
+ blksize : uint
+ blocks : uint
+ atime : uint
+ atimens : uint
+ mtime : uint
+ mtimens : uint
+ ctime : uint
+ ctimens : uint
+ _unused1: uint
+ _unused2: uint
+ ;;
+
+ const Rdonly : fdopt = 0x0
+ const Wronly : fdopt = 0x1
+ const Rdwr : fdopt = 0x2
+ const Append : fdopt = 0x80
+ const Creat : fdopt = 0x40
+ const Nofollow : fdopt = 0x20000
+ const Ndelay : fdopt = 0x800
+ const Trunc : fdopt = 0x200
+
+ const Sysexit : scno = 1
+ const Sysread : scno = 3
+ const Syswrite : scno = 4
+ const Sysopen : scno = 5
+ const Sysclose : scno = 6
+ const Syscreat : scno = 8
+ const Syslseek : scno = 19
+ const Sysfstat : scno = 108
+ const Syskill : scno = 37
+ const Sysgetpid : scno = 20
+
+ extern const syscall : (sc:scno, count:int, args:... -> int)
+
+ const exit : (status:int -> int)
+ const getpid : ( -> int)
+ const kill : (pid:int, sig:int -> int)
+ const open : (path:char[,], opts:fdopt -> int)
+ const close : (fd:int -> int)
+ const creat : (path:char[,], mode:int -> int)
+ const read : (fd:int, buf:char[,] -> int)
+ const write : (fd:int, buf:char[,] -> int)
+ const lseek : (fd:int, off:uint, whence:int -> int)
+ const fstat : (fd:int, sb:statbuf* -> int)
+;;
+
+const exit = {status; -> syscall(Sysexit, 1);}
+const getpid = {; -> syscall(Sysgetpid, 1);}
+const kill = {pid, sig; -> syscall(Syskill, 2, pid, sig);}
+const open = {path, opts:fdopt; -> syscall(Sysopen, 2, path castto(char*), opts);}
+const close = {fd; -> syscall(Sysclose, 1, fd);}
+const creat = {path, mode; -> syscall(Syscreat, 2, path castto(char*), mode);}
+const read = {fd, buf; -> syscall(Sysread, 3, fd, buf castto(char*), buf.len);}
+const write = {fd, buf; -> syscall(Syswrite, 3, fd, buf castto(char*), buf.len);}
+const lseek = {fd, off:uint, whence;-> syscall(Syslseek, 2, fd, off, whence);}
+const fstat = {fd, sb; -> syscall(Sysfstat, 2, fd, sb);}
--- /dev/null
+++ b/test/hello/syscall.s
@@ -1,0 +1,24 @@
+.globl sys$syscall
+sys$syscall:
+ pushl %ebp
+ movl %esp,%ebp
+ movl 12(%ebp),%eax #count
+ shl $2,%eax
+ jmp *.jmptab(%eax)
+.jmptab:
+ .long .a0
+ .long .a1
+ .long .a2
+ .long .a3
+ .long .a4
+.a5: movl 32(%ebp),%edi
+.a4: movl 28(%ebp),%esi
+.a3: movl 24(%ebp),%edx
+.a2: movl 20(%ebp),%ecx
+.a1: movl 16(%ebp),%ebx
+ /* 12(%ebp) holds nargs */
+.a0: movl 8(%ebp),%eax
+ int $0x80
+ movl %ebp,%esp
+ popl %ebp
+ ret
--- /dev/null
+++ b/test/slicelen.myr
@@ -1,0 +1,7 @@
+const main = {
+ var a : int[8]
+ var s
+
+ s = a[1,6]
+ -> s.len
+}
--- /dev/null
+++ b/test/str.myr
@@ -1,0 +1,6 @@
+const main = {
+ var str
+
+ str = "asdf"
+ -> str[3]
+}
--- /dev/null
+++ b/test/structret.myr
@@ -1,0 +1,19 @@
+type pair = struct
+ a : int
+ b : int
+;;
+
+const f = {
+ var s
+
+ s.a = 12
+ s.b = 30
+ -> s
+}
+
+const main = {
+ var s : pair
+
+ s = f()
+ -> s.a + s.b
+}
--- a/test/tests
+++ b/test/tests
@@ -21,15 +21,18 @@
B bsr E 5
B struct1 E 12
B struct E 42
+B structasn E 42
+B structret E 42
B array E 7
B arraylen E 12
+B slice E 7
+B slicelen E 5
B call E 42
+B voidcall E 12
B callbig E 42
B loop E 45
B fib E 21
-B slice E 7
B float E 1
-B structasn E 42
B log-and E 0
B log-or E 1
B str E 102
--- /dev/null
+++ b/test/voidcall.myr
@@ -1,0 +1,10 @@
+const f = {
+ var a
+
+ a = a + 1
+}
+
+const main = {
+ f()
+ -> 12
+}
--- a/util/muse.c
+++ b/util/muse.c
@@ -15,6 +15,7 @@
Node *file;
char *outfile;
int debug;
+char debugopt[128];
char **incpaths;
size_t nincpaths;
@@ -32,13 +33,12 @@
{
int opt;
int i;
- Stab *s;
Stab *globls;
Node *rdback;
FILE *tmp;
FILE *f;
- while ((opt = getopt(argc, argv, "dho:")) != -1) {
+ while ((opt = getopt(argc, argv, "d::ho:I:")) != -1) {
switch (opt) {
case 'o':
outfile = optarg;
@@ -45,7 +45,9 @@
break;
case 'h':
case 'd':
- debug++;
+ debug = 1;
+ while (optarg && *optarg)
+ debugopt[*optarg++ & 0x7f] = 1;
break;
case 'I':
lappend(&incpaths, &nincpaths, optarg);
@@ -68,7 +70,7 @@
infer(file);
/* before we do anything to the parse */
- if (debug) {
+ if (debugopt['p']) {
/* test storing tree to file */
tmp = fopen("a.pkl", "w");
pickle(file, tmp);
@@ -86,9 +88,6 @@
f = fopen(outfile, "w");
writeuse(file, f);
fclose(f);
- s = mkstab();
- readuse(mkuse(-1, outfile, 1), s);
- dumpstab(s, stdout);
}
return 0;