#include <assert.h>#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <inttypes.h>#include <ctype.h>#include <string.h>#include <assert.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h> #include "util.h"#include "parse.h" typedef struct Typename Typename;typedef struct Typair Typair;Type **tytab = NULL;Type **types = NULL;size_t ntypes;Trait **traittab;size_t ntraittab;Node **impltab;size_t nimpltab;Htab *eqcache; struct Typair { uint32_t atid; uint32_t btid;}; static Htab *tydeduptab;/* Built in type constraints */static int tybfmt(char *buf, size_t len, Bitset *visted, Type *t); char stackness[] = {#define Ty(t, n, stk) stk,#include "types.def"#undef Ty}; intisstacktype(Type *t){ t = tybase(t); if (t->type == Tyunion) return !isenum(t); return stackness[t->type];} intisenum(Type *t){ size_t i; char isenum; assert(t->type == Tyunion); /* t->isenum is lazily set: * a value of 0 means that it was not computed, * a value of 1 means that the type is an enum * (i.e., it only has nullary constructors) * a value of 2 means that the type is not an enum */ if (t->isenum == 0) { /* initialize it */ isenum = 1; for (i = 0; i < t->nmemb; i++) if (t->udecls[i]->etype) { isenum = 2; break; } t->isenum = isenum; } return t->isenum == 1;} Type *tydedup(Type *ty){ Type *had; had = htget(tydeduptab, ty); if (!had) { htput(tydeduptab, ty, ty); return ty; } /* if one is emitted, both are */ ty->isemitted = ty->isemitted || had->isemitted; return had;} Type *mktype(Srcloc loc, Ty ty){ Type *t; /* the first 'n' types will be identity mapped: tytab[Tyint], eg, * will map to an instantitaion of Tyint. * * This is accomplished at program startup by calling mktype() on * each builtin type in order. As we do this, we put the type into * the table as ususal, which gives us an identity mapping. */ if (ty <= Tyvalist && ty < ntypes) return types[ty]; t = zalloc(sizeof(Type)); t->type = ty; t->tid = ntypes++; t->loc = loc; tytab = xrealloc(tytab, ntypes * sizeof(Type *)); tytab[t->tid] = NULL; types = xrealloc(types, ntypes * sizeof(Type *)); types[t->tid] = t; if (ty <= Tyvalist) /* the last builtin atomic type */ t->vis = Visbuiltin; return t;} /* * Shallowly duplicates a type, so we can frob * its internals later */Type *tydup(Type *t){ Type *r; r = mktype(t->loc, t->type); r->resolved = 0; /* re-resolving doesn't hurt */ r->fixed = 0; /* re-resolving doesn't hurt */ r->arg = memdup(t->arg, t->narg * sizeof(Type *)); r->narg = t->narg; r->inst = memdup(t->arg, t->narg * sizeof(Type *)); r->ninst = t->ninst; r->sub = memdup(t->sub, t->nsub * sizeof(Type *)); r->nsub = t->nsub; r->nmemb = t->nmemb; switch (t->type) { case Tyname: r->name = t->name; break; case Tyunres: r->name = t->name; break; case Tyarray: r->asize = t->asize; break; case Typaram: r->pname = strdup(t->pname); break; case Tystruct: r->sdecls = memdup(t->sdecls, t->nmemb * sizeof(Node *)); break; case Tyunion: r->udecls = memdup(t->udecls, t->nmemb * sizeof(Node *)); break; default: break; } return r;} /* steals memb, funcs */Trait *mktrait(Srcloc loc, Node *name, Type *param, Type **aux, size_t naux, Node **proto, size_t nproto, int isproto){ Trait *t; size_t i; t = zalloc(sizeof(Trait)); t->uid = ntraittab++; t->loc = loc; if (t->uid < Ntraits) t->vis = Visbuiltin; t->vis = Visintern; t->name = name; t->param = param; t->proto = proto; t->nproto = nproto; t->aux = aux; t->env = mkenv(); t->naux = naux; t->isproto = isproto; bindtype(t->env, param); for (i = 0; i < naux; i++) bindtype(t->env, aux[i]); for (i = 0; i < nproto; i++) if (proto[i]->decl.env) proto[i]->decl.env->super = t->env; traittab = xrealloc(traittab, ntraittab * sizeof(Trait *)); traittab[t->uid] = t; return t;} Type *mktyvar(Srcloc loc){ Type *t; t = mktype(loc, Tyvar); return t;} Type *mktyparam(Srcloc loc, char *name){ Type *t; t = mktype(loc, Typaram); t->pname = strdup(name); return t;} Type *mktyunres(Srcloc loc, Node *name, Type **arg, size_t narg){ size_t i; Type *t; /* resolve it in the type inference stage */ t = mktype(loc, Tyunres); t->name = name; t->arg = arg; t->narg = narg; t->env = mkenv(); for (i = 0; i < narg; i++) bindtype(t->env, arg[i]); return t;} Type *mktygeneric(Srcloc loc, Node *name, Type **param, size_t nparam, Type *base){ Type *t; int i; t = mktype(loc, Tygeneric); t->name = name; t->nsub = 1; t->sub = xalloc(sizeof(Type *)); t->sub[0] = base; t->gparam = param; t->ngparam = nparam; t->env = mkenv(); for (i = 0; i < nparam; i++) bindtype(t->env, param[i]); if (!base->env) base->env = t->env; return t;} Type *mktyname(Srcloc loc, Node *name, Type *base){ Type *t; t = mktype(loc, Tyname); t->name = name; t->nsub = 1; t->sub = xalloc(sizeof(Type *)); t->sub[0] = base; return t;} Type *mktyarray(Srcloc loc, Type *base, Node *sz){ Type *t; t = mktype(loc, Tyarray); t->nsub = 1; t->nmemb = 1; /* the size is a "member" */ t->sub = xalloc(sizeof(Type *)); t->sub[0] = base; t->asize = sz; return t;} Type *mktyslice(Srcloc loc, Type *base){ Type *t; t = mktype(loc, Tyslice); t->nsub = 1; t->sub = xalloc(sizeof(Type *)); t->sub[0] = base; return t;} Type *mktyptr(Srcloc loc, Type *base){ Type *t; t = mktype(loc, Typtr); t->nsub = 1; t->sub = xalloc(sizeof(Type *)); t->sub[0] = base; return t;} Type *mktytuple(Srcloc loc, Type **sub, size_t nsub){ Type *t; size_t i; t = mktype(loc, Tytuple); t->nsub = nsub; t->sub = xalloc(nsub * sizeof(Type *)); for (i = 0; i < nsub; i++) t->sub[i] = sub[i]; return t;} Type *mktyfunc(Srcloc loc, Node **args, size_t nargs, Type *ret){ Type *t; size_t i; t = mktype(loc, Tyfunc); t->nsub = nargs + 1; t->sub = xalloc((1 + nargs) * sizeof(Type *)); t->sub[0] = ret; t->env = mkenv(); for (i = 0; i < nargs; i++) t->sub[i + 1] = nodetype(args[i]); for (i = 0; i < t->nsub; i++) bindtype(t->env, t->sub[i]); return t;} Type *mktystruct(Srcloc loc, Node **decls, size_t ndecls){ Type *t; Htab *ht; int i; char *s; t = mktype(loc, Tystruct); t->nsub = 0; t->nmemb = ndecls; ht = mkht(strhash, streq); for (i = 0; i < ndecls; i++) { s = declname(decls[i]); if (hthas(ht, s)) fatal(decls[i], "duplicate struct member %s\n", declname(decls[i])); htput(ht, s, s); } htfree(ht); t->sdecls = memdup(decls, ndecls * sizeof(Node *)); return t;} Type *mktyunion(Srcloc loc, Ucon **decls, size_t ndecls){ Type *t; t = mktype(loc, Tyunion); t->nmemb = ndecls; t->udecls = decls; return t;} Ucon *finducon(Type *ty, Node *name){ size_t i; ty = tybase(ty); for (i = 0; i < ty->nmemb; i++) if (!strcmp(namestr(ty->udecls[i]->name), namestr(name))) return ty->udecls[i]; return NULL;} intistyunsigned(Type *t){ switch (tybase(t)->type) { case Tybyte: case Tyuint8: case Tyuint16: case Tyuint: case Tychar: case Tyuint32: case Tyuint64: case Tybool: return 1; default: return 0; }} intistysigned(Type *t){ switch (tybase(t)->type) { case Tyint8: case Tyint16: case Tyint: case Tyint32: case Tyint64: return 1; default: return 0; }} intistyint(Type *t){ return istysigned(t) || istyunsigned(t);} intistyfloat(Type *t){ t = tybase(t); return t->type == Tyflt32 || t->type == Tyflt64;} intistyprimitive(Type *t) { return istysigned(t) || istyunsigned(t) || istyfloat(t); } /* * Checks if a type contains any type * parameers at all (ie, if it generic). */inthasparamsrec(Type *t, Bitset *visited){ size_t i; if (bshas(visited, t->tid)) return 0; bsput(visited, t->tid); switch (t->type) { case Typaram: return 1; case Tygeneric: return 1; case Tyname: for (i = 0; i < t->narg; i++) if (hasparamsrec(t->arg[i], visited)) return 1; return hasparamsrec(t->sub[0], visited); case Tyunres: for (i = 0; i < t->narg; i++) if (hasparamsrec(t->arg[i], visited)) return 1; break; case Tystruct: for (i = 0; i < t->nmemb; i++) if (hasparamsrec(t->sdecls[i]->decl.type, visited)) return 1; break; case Tyunion: for (i = 0; i < t->nmemb; i++) if (t->udecls[i]->etype && hasparamsrec(t->udecls[i]->etype, visited)) return 1; break; default: for (i = 0; i < t->nsub; i++) if (hasparamsrec(t->sub[i], visited)) return 1; break; } return 0;} inthasparams(Type *t){ Bitset *visited; if (t->hasparams) return 1; visited = mkbs(); t->hasparams = hasparamsrec(t, visited); bsfree(visited); return t->hasparams;} Type *tybase(Type *t){ assert(t != NULL); while (t->type == Tyname || t->type == Tygeneric) t = t->sub[0]; return t;} static intnamefmt(char *buf, size_t len, Node *n){ char *p;Lines 1–500 of 1173. Load more
#include <assert.h> #include <stdlib.h> #include <stdio.h> #include <stdarg.h> #include <inttypes.h> #include <ctype.h> #include <string.h> #include <assert.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include "util.h" #include "parse.h" typedef struct Typename Typename; typedef struct Typair Typair; Type **tytab = NULL; Type **types = NULL; size_t ntypes; Trait **traittab; size_t ntraittab; Node **impltab; size_t nimpltab; Htab *eqcache; struct Typair { uint32_t atid; uint32_t btid; }; static Htab *tydeduptab; /* Built in type constraints */ static int tybfmt(char *buf, size_t len, Bitset *visted, Type *t); char stackness[] = { #define Ty(t, n, stk) stk, #include "types.def" #undef Ty }; int isstacktype(Type *t) { t = tybase(t); if (t->type == Tyunion) return !isenum(t); return stackness[t->type]; } int isenum(Type *t) { size_t i; char isenum; assert(t->type == Tyunion); /* t->isenum is lazily set: * a value of 0 means that it was not computed, * a value of 1 means that the type is an enum * (i.e., it only has nullary constructors) * a value of 2 means that the type is not an enum */ if (t->isenum == 0) { /* initialize it */ isenum = 1; for (i = 0; i < t->nmemb; i++) if (t->udecls[i]->etype) { isenum = 2; break; } t->isenum = isenum; } return t->isenum == 1; } Type * tydedup(Type *ty) { Type *had; had = htget(tydeduptab, ty); if (!had) { htput(tydeduptab, ty, ty); return ty; } /* if one is emitted, both are */ ty->isemitted = ty->isemitted || had->isemitted; return had; } Type * mktype(Srcloc loc, Ty ty) { Type *t; /* the first 'n' types will be identity mapped: tytab[Tyint], eg, * will map to an instantitaion of Tyint. * * This is accomplished at program startup by calling mktype() on * each builtin type in order. As we do this, we put the type into * the table as ususal, which gives us an identity mapping. */ if (ty <= Tyvalist && ty < ntypes) return types[ty]; t = zalloc(sizeof(Type)); t->type = ty; t->tid = ntypes++; t->loc = loc; tytab = xrealloc(tytab, ntypes * sizeof(Type *)); tytab[t->tid] = NULL; types = xrealloc(types, ntypes * sizeof(Type *)); types[t->tid] = t; if (ty <= Tyvalist) /* the last builtin atomic type */ t->vis = Visbuiltin; return t; } /* * Shallowly duplicates a type, so we can frob * its internals later */ Type * tydup(Type *t) { Type *r; r = mktype(t->loc, t->type); r->resolved = 0; /* re-resolving doesn't hurt */ r->fixed = 0; /* re-resolving doesn't hurt */ r->arg = memdup(t->arg, t->narg * sizeof(Type *)); r->narg = t->narg; r->inst = memdup(t->arg, t->narg * sizeof(Type *)); r->ninst = t->ninst; r->sub = memdup(t->sub, t->nsub * sizeof(Type *)); r->nsub = t->nsub; r->nmemb = t->nmemb; switch (t->type) { case Tyname: r->name = t->name; break; case Tyunres: r->name = t->name; break; case Tyarray: r->asize = t->asize; break; case Typaram: r->pname = strdup(t->pname); break; case Tystruct: r->sdecls = memdup(t->sdecls, t->nmemb * sizeof(Node *)); break; case Tyunion: r->udecls = memdup(t->udecls, t->nmemb * sizeof(Node *)); break; default: break; } return r; } /* steals memb, funcs */ Trait * mktrait(Srcloc loc, Node *name, Type *param, Type **aux, size_t naux, Node **proto, size_t nproto, int isproto) { Trait *t; size_t i; t = zalloc(sizeof(Trait)); t->uid = ntraittab++; t->loc = loc; if (t->uid < Ntraits) t->vis = Visbuiltin; t->vis = Visintern; t->name = name; t->param = param; t->proto = proto; t->nproto = nproto; t->aux = aux; t->env = mkenv(); t->naux = naux; t->isproto = isproto; bindtype(t->env, param); for (i = 0; i < naux; i++) bindtype(t->env, aux[i]); for (i = 0; i < nproto; i++) if (proto[i]->decl.env) proto[i]->decl.env->super = t->env; traittab = xrealloc(traittab, ntraittab * sizeof(Trait *)); traittab[t->uid] = t; return t; } Type * mktyvar(Srcloc loc) { Type *t; t = mktype(loc, Tyvar); return t; } Type * mktyparam(Srcloc loc, char *name) { Type *t; t = mktype(loc, Typaram); t->pname = strdup(name); return t; } Type * mktyunres(Srcloc loc, Node *name, Type **arg, size_t narg) { size_t i; Type *t; /* resolve it in the type inference stage */ t = mktype(loc, Tyunres); t->name = name; t->arg = arg; t->narg = narg; t->env = mkenv(); for (i = 0; i < narg; i++) bindtype(t->env, arg[i]); return t; } Type * mktygeneric(Srcloc loc, Node *name, Type **param, size_t nparam, Type *base) { Type *t; int i; t = mktype(loc, Tygeneric); t->name = name; t->nsub = 1; t->sub = xalloc(sizeof(Type *)); t->sub[0] = base; t->gparam = param; t->ngparam = nparam; t->env = mkenv(); for (i = 0; i < nparam; i++) bindtype(t->env, param[i]); if (!base->env) base->env = t->env; return t; } Type * mktyname(Srcloc loc, Node *name, Type *base) { Type *t; t = mktype(loc, Tyname); t->name = name; t->nsub = 1; t->sub = xalloc(sizeof(Type *)); t->sub[0] = base; return t; } Type * mktyarray(Srcloc loc, Type *base, Node *sz) { Type *t; t = mktype(loc, Tyarray); t->nsub = 1; t->nmemb = 1; /* the size is a "member" */ t->sub = xalloc(sizeof(Type *)); t->sub[0] = base; t->asize = sz; return t; } Type * mktyslice(Srcloc loc, Type *base) { Type *t; t = mktype(loc, Tyslice); t->nsub = 1; t->sub = xalloc(sizeof(Type *)); t->sub[0] = base; return t; } Type * mktyptr(Srcloc loc, Type *base) { Type *t; t = mktype(loc, Typtr); t->nsub = 1; t->sub = xalloc(sizeof(Type *)); t->sub[0] = base; return t; } Type * mktytuple(Srcloc loc, Type **sub, size_t nsub) { Type *t; size_t i; t = mktype(loc, Tytuple); t->nsub = nsub; t->sub = xalloc(nsub * sizeof(Type *)); for (i = 0; i < nsub; i++) t->sub[i] = sub[i]; return t; } Type * mktyfunc(Srcloc loc, Node **args, size_t nargs, Type *ret) { Type *t; size_t i; t = mktype(loc, Tyfunc); t->nsub = nargs + 1; t->sub = xalloc((1 + nargs) * sizeof(Type *)); t->sub[0] = ret; t->env = mkenv(); for (i = 0; i < nargs; i++) t->sub[i + 1] = nodetype(args[i]); for (i = 0; i < t->nsub; i++) bindtype(t->env, t->sub[i]); return t; } Type * mktystruct(Srcloc loc, Node **decls, size_t ndecls) { Type *t; Htab *ht; int i; char *s; t = mktype(loc, Tystruct); t->nsub = 0; t->nmemb = ndecls; ht = mkht(strhash, streq); for (i = 0; i < ndecls; i++) { s = declname(decls[i]); if (hthas(ht, s)) fatal(decls[i], "duplicate struct member %s\n", declname(decls[i])); htput(ht, s, s); } htfree(ht); t->sdecls = memdup(decls, ndecls * sizeof(Node *)); return t; } Type * mktyunion(Srcloc loc, Ucon **decls, size_t ndecls) { Type *t; t = mktype(loc, Tyunion); t->nmemb = ndecls; t->udecls = decls; return t; } Ucon * finducon(Type *ty, Node *name) { size_t i; ty = tybase(ty); for (i = 0; i < ty->nmemb; i++) if (!strcmp(namestr(ty->udecls[i]->name), namestr(name))) return ty->udecls[i]; return NULL; } int istyunsigned(Type *t) { switch (tybase(t)->type) { case Tybyte: case Tyuint8: case Tyuint16: case Tyuint: case Tychar: case Tyuint32: case Tyuint64: case Tybool: return 1; default: return 0; } } int istysigned(Type *t) { switch (tybase(t)->type) { case Tyint8: case Tyint16: case Tyint: case Tyint32: case Tyint64: return 1; default: return 0; } } int istyint(Type *t) { return istysigned(t) || istyunsigned(t); } int istyfloat(Type *t) { t = tybase(t); return t->type == Tyflt32 || t->type == Tyflt64; } int istyprimitive(Type *t) { return istysigned(t) || istyunsigned(t) || istyfloat(t); } /* * Checks if a type contains any type * parameers at all (ie, if it generic). */ int hasparamsrec(Type *t, Bitset *visited) { size_t i; if (bshas(visited, t->tid)) return 0; bsput(visited, t->tid); switch (t->type) { case Typaram: return 1; case Tygeneric: return 1; case Tyname: for (i = 0; i < t->narg; i++) if (hasparamsrec(t->arg[i], visited)) return 1; return hasparamsrec(t->sub[0], visited); case Tyunres: for (i = 0; i < t->narg; i++) if (hasparamsrec(t->arg[i], visited)) return 1; break; case Tystruct: for (i = 0; i < t->nmemb; i++) if (hasparamsrec(t->sdecls[i]->decl.type, visited)) return 1; break; case Tyunion: for (i = 0; i < t->nmemb; i++) if (t->udecls[i]->etype && hasparamsrec(t->udecls[i]->etype, visited)) return 1; break; default: for (i = 0; i < t->nsub; i++) if (hasparamsrec(t->sub[i], visited)) return 1; break; } return 0; } int hasparams(Type *t) { Bitset *visited; if (t->hasparams) return 1; visited = mkbs(); t->hasparams = hasparamsrec(t, visited); bsfree(visited); return t->hasparams; } Type * tybase(Type *t) { assert(t != NULL); while (t->type == Tyname || t->type == Tygeneric) t = t->sub[0]; return t; } static int namefmt(char *buf, size_t len, Node *n) { char *p;