diff options
Diffstat (limited to 'src/old/c/subr.c')
-rw-r--r-- | src/old/c/subr.c | 1522 |
1 files changed, 0 insertions, 1522 deletions
diff --git a/src/old/c/subr.c b/src/old/c/subr.c deleted file mode 100644 index 1bb6ac520..000000000 --- a/src/old/c/subr.c +++ /dev/null @@ -1,1522 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "go.h" -#include "y.tab.h" - -void -errorexit(void) -{ - if(outfile) - remove(outfile); - myexit(1); -} - -void -myexit(int x) -{ - if(x) - exits("error"); - exits(nil); -} - -void -yyerror(char *fmt, ...) -{ - va_list arg; - long lno; - - lno = dynlineno; - if(lno == 0) - lno = curio.lineno; - - print("%s:%ld: ", curio.infile, lno); - va_start(arg, fmt); - vfprint(1, fmt, arg); - va_end(arg); - print("\n"); - if(debug['h']) - *(int*)0 = 0; - - nerrors++; - if(nerrors >= 10) - fatal("too many errors"); -} - -void -warn(char *fmt, ...) -{ - va_list arg; - long lno; - - lno = dynlineno; - if(lno == 0) - lno = curio.lineno; - - print("%s:%ld: ", curio.infile, lno); - va_start(arg, fmt); - vfprint(1, fmt, arg); - va_end(arg); - print("\n"); - if(debug['h']) - *(int*)0 = 0; -} - -void -fatal(char *fmt, ...) -{ - va_list arg; - long lno; - - lno = dynlineno; - if(lno == 0) - lno = curio.lineno; - - print("%s:%ld: fatal error: ", curio.infile, lno); - va_start(arg, fmt); - vfprint(1, fmt, arg); - va_end(arg); - print("\n"); - if(debug['h']) - *(int*)0 = 0; - myexit(1); -} - -ulong -stringhash(char *p) -{ - long h; - int c; - - h = 0; - for(;;) { - c = *p++; - if(c == 0) - break; - h = h*PRIME1 + c; - } - - if(h < 0) { - h = -h; - if(h < 0) - h = 0; - } - return h; -} - -Sym* -lookup(char *p) -{ - Sym *s; - ulong h; - int c; - - h = stringhash(p) % NHASH; - c = p[0]; - - for(s = hash[h]; s != S; s = s->link) { - if(s->name[0] != c) - continue; - if(strcmp(s->name, p) == 0) - if(strcmp(s->package, package) == 0) - return s; - } - - s = mal(sizeof(*s)); - s->lexical = LNAME; - s->name = mal(strlen(p)+1); - s->opackage = package; - s->package = package; - - strcpy(s->name, p); - - s->link = hash[h]; - hash[h] = s; - - return s; -} - -Sym* -pkglookup(char *p, char *k) -{ - Sym *s; - ulong h; - int c; - - h = stringhash(p) % NHASH; - c = p[0]; - for(s = hash[h]; s != S; s = s->link) { - if(s->name[0] != c) - continue; - if(strcmp(s->name, p) == 0) - if(strcmp(s->package, k) == 0) - return s; - } - - s = mal(sizeof(*s)); - s->lexical = LNAME; - s->name = mal(strlen(p)+1); - strcpy(s->name, p); - - s->package = mal(strlen(k)+1); - s->opackage = s->package; - strcpy(s->package, k); - - s->link = hash[h]; - hash[h] = s; - - return s; -} - -void -gethunk(void) -{ - char *h; - long nh; - - nh = NHUNK; - if(thunk >= 10L*NHUNK) - nh = 10L*NHUNK; - h = (char*)malloc(nh); - if(h == (char*)-1) { - yyerror("out of memory"); - errorexit(); - } - hunk = h; - nhunk = nh; - thunk += nh; -} - -void* -mal(long n) -{ - void *p; - - while((ulong)hunk & MAXALIGN) { - hunk++; - nhunk--; - } - while(nhunk < n) - gethunk(); - - p = hunk; - nhunk -= n; - hunk += n; - memset(p, 0, n); - return p; -} - -void* -remal(void *p, long on, long n) -{ - void *q; - - q = (uchar*)p + on; - if(q != hunk || nhunk < n) { - while(nhunk < on+n) - gethunk(); - memmove(hunk, p, on); - p = hunk; - hunk += on; - nhunk -= on; - } - hunk += n; - nhunk -= n; - return p; -} - -Dcl* -dcl(void) -{ - Dcl *d; - - d = mal(sizeof(*d)); - d->lineno = dynlineno; - return d; -} - -Node* -nod(int op, Node *nleft, Node *nright) -{ - Node *n; - - n = mal(sizeof(*n)); - n->op = op; - n->left = nleft; - n->right = nright; - n->lineno = dynlineno; - if(dynlineno == 0) - n->lineno = curio.lineno; - return n; -} - -Node* -dobad(void) -{ - return nod(OBAD, N, N); -} - -Node* -rev(Node *na) -{ - Node *i, *n; - - /* - * since yacc wants to build lists - * stacked down on the left - - * this routine converts them to - * stack down on the right - - * in memory without recursion - */ - - if(na == N || na->op != OLIST) - return na; - i = na; - for(n = na->left; n != N; n = n->left) { - if(n->op != OLIST) - break; - i->left = n->right; - n->right = i; - i = n; - } - i->left = n; - return i; -} - -Node* -unrev(Node *na) -{ - Node *i, *n; - - /* - * this restores a reverse list - */ - if(na == N || na->op != OLIST) - return na; - i = na; - for(n = na->right; n != N; n = n->right) { - if(n->op != OLIST) - break; - i->right = n->left; - n->left = i; - i = n; - } - i->right = n; - return i; -} - -Node* -aindex(Node *b, Node *t) -{ - Node *r; - - r = nod(OTYPE, N, N); - r->type = t; - r->etype = TARRAY; - - if(t->etype == TDARRAY) - yyerror("dynamic array type cannot be a dynamic array"); - - walktype(b, 0); - switch(whatis(b)) { - default: - yyerror("array bound must be a constant integer expression"); - break; - - case Wnil: // default zero lb - r->bound = 0; - break; - - case Wlitint: // fixed lb - r->bound = b->val.vval; - break; - } - return r; -} - -void -indent(int dep) -{ - int i; - - for(i=0; i<dep; i++) - print(". "); -} - -void -dodump(Node *n, int dep) -{ - -loop: - if(n == N) - return; - - switch(n->op) { - case OLIST: - if(n->left != N && n->left->op == OLIST) - dodump(n->left, dep+1); - else - dodump(n->left, dep); - n = n->right; - goto loop; - - case ODCLFUNC: - dodump(n->nname, dep); - if(n->this) { - indent(dep); - print("%O-this\n", n->op); - dodump(n->this, dep+1); - } - if(n->argout) { - indent(dep); - print("%O-outarg\n", n->op); - dodump(n->argout, dep+1); - } - if(n->argin) { - indent(dep); - print("%O-inarg\n", n->op); - dodump(n->argin, dep+1); - } - n = n->nbody; - goto loop; - - case OIF: - case OSWITCH: - case OFOR: - dodump(n->ninit, dep); - break; - } - - indent(dep); - if(dep > 10) { - print("...\n"); - return; - } - - switch(n->op) { - default: - print("%N\n", n); - break; - - case OTYPE: - print("%O-%E %lT\n", n->op, n->etype, n); - break; - - case OIF: - print("%O%J\n", n->op, n); - dodump(n->ntest, dep+1); - if(n->nbody != N) { - indent(dep); - print("%O-then\n", n->op); - dodump(n->nbody, dep+1); - } - if(n->nelse != N) { - indent(dep); - print("%O-else\n", n->op); - dodump(n->nelse, dep+1); - } - return; - - case OSWITCH: - case OFOR: - print("%O%J\n", n->op, n); - dodump(n->ntest, dep+1); - - if(n->nbody != N) { - indent(dep); - print("%O-body\n", n->op); - dodump(n->nbody, dep+1); - } - - if(n->nincr != N) { - indent(dep); - print("%O-incr\n", n->op); - dodump(n->nincr, dep+1); - } - return; - - case OCASE: - // the right side points to the next case - print("%O%J\n", n->op, n); - dodump(n->left, dep+1); - return; - } - - dodump(n->left, dep+1); - n = n->right; - dep++; - goto loop; -} - -void -dump(char *s, Node *n) -{ - print("%s\n", s); - dodump(n, 1); -} - -int -whatis(Node *n) -{ - Node *t; - - if(n == N) - return Wnil; - - if(n->op == OLITERAL) { - switch(n->val.ctype) { - default: - break; - case CTINT: - case CTSINT: - case CTUINT: - return Wlitint; - case CTFLT: - return Wlitfloat; - case CTBOOL: - return Wlitbool; - case CTSTR: - return Wlitstr; - } - return Wtunkn; - } - - t = n->type; - if(t == N) - return Wtnil; - - switch(t->etype) { - case TINT8: - case TINT16: - case TINT32: - case TINT64: - case TUINT8: - case TUINT16: - case TUINT32: - case TUINT64: - return Wtint; - case TFLOAT32: - case TFLOAT64: - case TFLOAT80: - return Wtfloat; - case TBOOL: - return Wtbool; - - case TPTR: - if(isptrto(t, TSTRING)) - return Wtstr; - break; - } - return Wtunkn; -} - -/* -s%,%,\n%g -s%\n+%\n%g -s%^[ ]*O%%g -s%,.*%%g -s%.+% [O&] = "&",%g -s%^ ........*\]%&~%g -s%~ %%g -*/ - -static char* -opnames[] = -{ - [OADDR] = "ADDR", - [OADD] = "ADD", - [OANDAND] = "ANDAND", - [OAND] = "AND", - [OARRAY] = "ARRAY", - [OASOP] = "ASOP", - [OAS] = "AS", - [OBAD] = "BAD", - [OBREAK] = "BREAK", - [OCALL] = "CALL", - [OCALLPTR] = "CALLPTR", - [OCALLMETH] = "CALLMETH", - [OCALLINTER] = "CALLINTER", - [OCAT] = "CAT", - [OCASE] = "CASE", - [OXCASE] = "XCASE", - [OFALL] = "FALL", - [OCONV] = "CONV", - [OCOM] = "COM", - [OCONST] = "CONST", - [OCONTINUE] = "CONTINUE", - [ODCLARG] = "DCLARG", - [ODCLFIELD] = "DCLFIELD", - [ODCLFUNC] = "DCLFUNC", - [ODIV] = "DIV", - [ODOT] = "DOT", - [ODOTPTR] = "DOTPTR", - [ODOTMETH] = "DOTMETH", - [ODOTINTER] = "DOTINTER", - [OEMPTY] = "EMPTY", - [OEND] = "END", - [OEQ] = "EQ", - [OFOR] = "FOR", - [OFUNC] = "FUNC", - [OGE] = "GE", - [OPROC] = "PROC", - [OGOTO] = "GOTO", - [OGT] = "GT", - [OIF] = "IF", - [OINDEX] = "INDEX", - [OINDEXPTR] = "INDEXPTR", - [OINDEXSTR] = "INDEXSTR", - [OINDEXPTRSTR] = "INDEXPTRSTR", - [OINDEXMAP] = "INDEXMAP", - [OINDEXPTRMAP] = "INDEXPTRMAP", - [OIND] = "IND", - [OLABEL] = "LABEL", - [OLE] = "LE", - [OLEN] = "LEN", - [OLIST] = "LIST", - [OLITERAL] = "LITERAL", - [OLSH] = "LSH", - [OLT] = "LT", - [OMINUS] = "MINUS", - [OMOD] = "MOD", - [OMUL] = "MUL", - [ONAME] = "NAME", - [ONE] = "NE", - [ONOT] = "NOT", - [OOROR] = "OROR", - [OOR] = "OR", - [OPLUS] = "PLUS", - [ODEC] = "DEC", - [OINC] = "INC", - [OSEND] = "SEND", - [ORECV] = "RECV", - [OPTR] = "PTR", - [ORETURN] = "RETURN", - [ORSH] = "RSH", - [OSLICE] = "SLICE", - [OSLICESTR] = "SLICESTR", - [OSLICEPTRSTR] = "SLICEPTRSTR", - [OSUB] = "SUB", - [OSWITCH] = "SWITCH", - [OTYPE] = "TYPE", - [OVAR] = "VAR", - [OEXPORT] = "EXPORT", - [OIMPORT] = "IMPORT", - [OXOR] = "XOR", - [ONEW] = "NEW", - [OFALL] = "FALL", - [OXFALL] = "XFALL", - [OPANIC] = "PANIC", - [OPRINT] = "PRINT", - [OXXX] = "XXX", -}; - -int -Oconv(Fmt *fp) -{ - char buf[500]; - int o; - - o = va_arg(fp->args, int); - if(o < 0 || o >= nelem(opnames) || opnames[o] == nil) { - snprint(buf, sizeof(buf), "O-%d", o); - return fmtstrcpy(fp, buf); - } - return fmtstrcpy(fp, opnames[o]); -} - -/* -s%,%,\n%g -s%\n+%\n%g -s%^[ ]*T%%g -s%,.*%%g -s%.+% [T&] = "&",%g -s%^ ........*\]%&~%g -s%~ %%g -*/ - -static char* -etnames[] = -{ - [TINT8] = "INT8", - [TUINT8] = "UINT8", - [TINT16] = "INT16", - [TUINT16] = "UINT16", - [TINT32] = "INT32", - [TUINT32] = "UINT32", - [TINT64] = "INT64", - [TUINT64] = "UINT64", - [TFLOAT32] = "FLOAT32", - [TFLOAT64] = "FLOAT64", - [TFLOAT80] = "FLOAT80", - [TBOOL] = "BOOL", - [TPTR] = "PTR", - [TFUNC] = "FUNC", - [TARRAY] = "ARRAY", - [TDARRAY] = "DARRAY", - [TSTRUCT] = "STRUCT", - [TCHAN] = "CHAN", - [TMAP] = "MAP", - [TINTER] = "INTER", - [TFORW] = "FORW", - [TFIELD] = "FIELD", - [TSTRING] = "STRING", - [TCHAN] = "CHAN", -}; - -int -Econv(Fmt *fp) -{ - char buf[500]; - int et; - - et = va_arg(fp->args, int); - if(et < 0 || et >= nelem(etnames) || etnames[et] == nil) { - snprint(buf, sizeof(buf), "E-%d", et); - return fmtstrcpy(fp, buf); - } - return fmtstrcpy(fp, etnames[et]); -} - -int -Jconv(Fmt *fp) -{ - char buf[500], buf1[100]; - Node *n; - - n = va_arg(fp->args, Node*); - strcpy(buf, ""); - - if(n->ullman != 0) { - snprint(buf1, sizeof(buf1), " u(%d)", n->ullman); - strncat(buf, buf1, sizeof(buf)); - } - - if(n->addable != 0) { - snprint(buf1, sizeof(buf1), " a(%d)", n->addable); - strncat(buf, buf1, sizeof(buf)); - } - - if(n->vargen != 0) { - snprint(buf1, sizeof(buf1), " g(%ld)", n->vargen); - strncat(buf, buf1, sizeof(buf)); - } - - if(n->lineno != 0) { - snprint(buf1, sizeof(buf1), " l(%ld)", n->lineno); - strncat(buf, buf1, sizeof(buf)); - } - - return fmtstrcpy(fp, buf); -} - -int -Gconv(Fmt *fp) -{ - char buf[100]; - Node *t; - - t = va_arg(fp->args, Node*); - - if(t->etype == TFUNC) { - if(t->vargen != 0) { - snprint(buf, sizeof(buf), "-%d%d%d g(%ld)", - t->thistuple, t->outtuple, t->intuple, t->vargen); - goto out; - } - snprint(buf, sizeof(buf), "-%d%d%d", - t->thistuple, t->outtuple, t->intuple); - goto out; - } - if(t->vargen != 0) { - snprint(buf, sizeof(buf), " g(%ld)", t->vargen); - goto out; - } - strcpy(buf, ""); - -out: - return fmtstrcpy(fp, buf); -} - -int -Sconv(Fmt *fp) -{ - char buf[500]; - Sym *s; - char *opk, *pkg, *nam; - - s = va_arg(fp->args, Sym*); - if(s == S) { - snprint(buf, sizeof(buf), "<S>"); - goto out; - } - - pkg = "<nil>"; - nam = pkg; - opk = pkg; - - if(s->opackage != nil) - opk = s->opackage; - if(s->package != nil) - pkg = s->package; - if(s->name != nil) - nam = s->name; - - if(strcmp(pkg, package) || strcmp(opk, package) || (fp->flags & FmtLong)) { - if(strcmp(opk, pkg) == 0) { - snprint(buf, sizeof(buf), "%s.%s", pkg, nam); - goto out; - } - snprint(buf, sizeof(buf), "(%s)%s.%s", opk, pkg, nam); - goto out; - } - snprint(buf, sizeof(buf), "%s", nam); - -out: - return fmtstrcpy(fp, buf); -} - -int -Tconv(Fmt *fp) -{ - char buf[500], buf1[500]; - Node *t, *t1; - int et; - - t = va_arg(fp->args, Node*); - if(t == N) - return fmtstrcpy(fp, "<T>"); - - t->trecur++; - if(t->op != OTYPE) { - snprint(buf, sizeof(buf), "T-%O", t->op); - goto out; - } - et = t->etype; - - strcpy(buf, ""); - if(t->sym != S) { - snprint(buf, sizeof(buf), "<%S>", t->sym); - } - if(t->trecur > 5) { - strncat(buf, "...", sizeof(buf)); - goto out; - } - - switch(et) { - default: - snprint(buf1, sizeof(buf1), "%E", et); - strncat(buf, buf1, sizeof(buf)); - if(t->type != N) { - snprint(buf1, sizeof(buf1), " %T", t->type); - strncat(buf, buf1, sizeof(buf)); - } - break; - - case TFIELD: - snprint(buf1, sizeof(buf1), "%T", t->type); - strncat(buf, buf1, sizeof(buf)); - break; - - case TFUNC: - snprint(buf1, sizeof(buf1), "%d%d%d(%lT,%lT,%lT)", - t->thistuple, t->outtuple, t->intuple, - t->type, t->type->down, t->type->down->down); - strncat(buf, buf1, sizeof(buf)); - break; - - case TINTER: - strncat(buf, "I{", sizeof(buf)); - if(fp->flags & FmtLong) { - for(t1=t->type; t1!=N; t1=t1->down) { - snprint(buf1, sizeof(buf1), "%T;", t1); - strncat(buf, buf1, sizeof(buf)); - } - } - strncat(buf, "}", sizeof(buf)); - break; - - case TSTRUCT: - strncat(buf, "{", sizeof(buf)); - if(fp->flags & FmtLong) { - for(t1=t->type; t1!=N; t1=t1->down) { - snprint(buf1, sizeof(buf1), "%T;", t1); - strncat(buf, buf1, sizeof(buf)); - } - } - strncat(buf, "}", sizeof(buf)); - break; - - case TMAP: - snprint(buf, sizeof(buf), "[%T]%T", t->down, t->type); - break; - - case TARRAY: - snprint(buf1, sizeof(buf1), "[%ld]%T", t->bound, t->type); - strncat(buf, buf1, sizeof(buf)); - break; - - case TDARRAY: - snprint(buf1, sizeof(buf1), "[]%T", t->type); - strncat(buf, buf1, sizeof(buf)); - break; - - case TPTR: - snprint(buf1, sizeof(buf1), "*%T", t->type); - strncat(buf, buf1, sizeof(buf)); - break; - } - -out: - t->trecur--; - return fmtstrcpy(fp, buf); -} - -int -Nconv(Fmt *fp) -{ - char buf[500], buf1[500]; - Node *n; - - n = va_arg(fp->args, Node*); - if(n == N) { - snprint(buf, sizeof(buf), "<N>"); - goto out; - } - - switch(n->op) { - default: - snprint(buf, sizeof(buf), "%O%J", n->op, n); - break; - - case ONAME: - if(n->sym == S) { - snprint(buf, sizeof(buf), "%O%J", n->op, n); - break; - } - snprint(buf, sizeof(buf), "%O-%S G%ld%J", n->op, - n->sym, n->sym->vargen, n); - goto ptyp; - - case OLITERAL: - switch(n->val.ctype) { - default: - snprint(buf1, sizeof(buf1), "LITERAL-%d", n->val.ctype); - break; - case CTINT: - snprint(buf1, sizeof(buf1), "I%lld", n->val.vval); - break; - case CTSINT: - snprint(buf1, sizeof(buf1), "S%lld", n->val.vval); - break; - case CTUINT: - snprint(buf1, sizeof(buf1), "U%lld", n->val.vval); - break; - case CTFLT: - snprint(buf1, sizeof(buf1), "F%g", n->val.dval); - break; - case CTSTR: - snprint(buf1, sizeof(buf1), "S\"%Z\"", n->val.sval); - break; - case CTBOOL: - snprint(buf1, sizeof(buf1), "B%lld", n->val.vval); - break; - case CTNIL: - snprint(buf1, sizeof(buf1), "N"); - break; - } - snprint(buf, sizeof(buf1), "%O-%s%J", n->op, buf1, n); - break; - - case OASOP: - snprint(buf, sizeof(buf), "%O-%O%J", n->op, n->kaka, n); - break; - - case OTYPE: - snprint(buf, sizeof(buf), "%O-%E%J", n->op, n->etype, n); - break; - } - if(n->sym != S) { - snprint(buf1, sizeof(buf1), " %S G%ld", n->sym, n->sym->vargen); - strncat(buf, buf1, sizeof(buf)); - } - -ptyp: - if(n->type != N) { - snprint(buf1, sizeof(buf1), " %T", n->type); - strncat(buf, buf1, sizeof(buf)); - } - -out: - return fmtstrcpy(fp, buf); -} - -int -Zconv(Fmt *fp) -{ - uchar *s, *se; - char *p; - char buf[500]; - int c; - String *sp; - - sp = va_arg(fp->args, String*); - if(sp == nil) { - snprint(buf, sizeof(buf), "<nil>"); - goto out; - } - s = sp->s; - se = s + sp->len; - - p = buf; - -loop: - c = *s++; - if(s > se) - c = 0; - switch(c) { - default: - *p++ = c; - break; - case 0: - *p = 0; - goto out; - case '\t': - *p++ = '\\'; - *p++ = 't'; - break; - case '\n': - *p++ = '\\'; - *p++ = 'n'; - break; - } - goto loop; - -out: - return fmtstrcpy(fp, buf); -} - -int -isnil(Node *n) -{ - if(n == N) - return 0; - if(n->op != OLITERAL) - return 0; - if(n->val.ctype != CTNIL) - return 0; - return 1; -} - -int -isptrto(Node *t, int et) -{ - if(t == N) - return 0; - if(t->etype != TPTR) - return 0; - t = t->type; - if(t == N) - return 0; - if(t->etype != et) - return 0; - return 1; -} - -int -isinter(Node *t) -{ - if(t != N && t->etype == TINTER) - return 1; - return 0; -} - -int -isbytearray(Node *t) -{ - if(t == N) - return 0; - if(t->etype == TPTR) { - t = t->type; - if(t == N) - return 0; - } - if(t->etype != TARRAY) - return 0; - return t->bound+1; -} - -int -eqtype(Node *t1, Node *t2, int d) -{ - if(d >= 10) - return 1; - - if(t1 == t2) - return 1; - if(t1 == N || t2 == N) - return 0; - if(t1->op != OTYPE || t2->op != OTYPE) - fatal("eqtype: oops %O %O", t1->op, t2->op); - - if(t1->etype != t2->etype) - return 0; - - switch(t1->etype) { - case TINTER: - case TSTRUCT: - t1 = t1->type; - t2 = t2->type; - for(;;) { - if(!eqtype(t1, t2, 0)) - return 0; - if(t1 == N) - return 1; - if(t1->nname != N && t1->nname->sym != S) { - if(t2->nname == N || t2->nname->sym == S) - return 0; - if(strcmp(t1->nname->sym->name, t2->nname->sym->name) != 0) { - // assigned names dont count - if(t1->nname->sym->name[0] != '_' || - t2->nname->sym->name[0] != '_') - return 0; - } - } - t1 = t1->down; - t2 = t2->down; - } - return 1; - - case TFUNC: - t1 = t1->type; - t2 = t2->type; - for(;;) { - if(t1 == t2) - break; - if(t1 == N || t2 == N) - return 0; - if(t1->etype != TSTRUCT || t2->etype != TSTRUCT) - return 0; - - if(!eqtype(t1->type, t2->type, 0)) - return 0; - - t1 = t1->down; - t2 = t2->down; - } - return 1; - } - return eqtype(t1->type, t2->type, d+1); -} - -/* - * are the arg names of two - * functions the same. we know - * that eqtype has been called - * and has returned true. - */ -int -eqargs(Node *t1, Node *t2) -{ - if(t1 == t2) - return 1; - if(t1 == N || t2 == N) - return 0; - if(t1->op != OTYPE || t2->op != OTYPE) - fatal("eqargs: oops %O %O", t1->op, t2->op); - - if(t1->etype != t2->etype) - return 0; - - if(t1->etype != TFUNC) - fatal("eqargs: oops %E", t1->etype); - - t1 = t1->type; - t2 = t2->type; - for(;;) { - if(t1 == t2) - break; - if(!eqtype(t1, t2, 0)) - return 0; - t1 = t1->down; - t2 = t2->down; - } - return 1; -} - -ulong -typehash(Node *at, int d) -{ - ulong h; - Node *t; - - if(at == N) - return PRIME2; - if(d >= 5) - return PRIME3; - - if(at->op != OTYPE) - fatal("typehash: oops %O", at->op); - - if(at->recur) - return 0; - at->recur = 1; - - h = at->etype*PRIME4; - - switch(at->etype) { - default: - h += PRIME5 * typehash(at->type, d+1); - break; - - case TINTER: - // botch -- should be sorted? - for(t=at->type; t!=N; t=t->down) - h += PRIME6 * typehash(t, d+1); - break; - - case TSTRUCT: - for(t=at->type; t!=N; t=t->down) - h += PRIME7 * typehash(t, d+1); - break; - - case TFUNC: - t = at->type; - // skip this argument - if(t != N) - t = t->down; - for(; t!=N; t=t->down) - h += PRIME7 * typehash(t, d+1); - break; - } - - at->recur = 0; - return h; -} - -Node* -ptrto(Node *t) -{ - Node *p; - - p = nod(OTYPE, N, N); - p->etype = TPTR; - p->type = t; - return p; -} - -Node* -literal(long v) -{ - Node *n; - - n = nod(OLITERAL, N, N); - n->val.ctype = CTINT; - n->val.vval = v; - return n; -} - -void -frame(int context) -{ - char *p; - Dcl *d; - int flag; - - p = "stack"; - d = autodcl; - if(context) { - p = "external"; - d = externdcl; - } - - flag = 1; - for(; d!=D; d=d->forw) { - switch(d->op) { - case ONAME: - if(flag) - print("--- %s frame ---\n", p); - print("%O %S G%ld T\n", d->op, d->dsym, d->dnode->vargen, d->dnode->type); - flag = 0; - break; - - case OTYPE: - if(flag) - print("--- %s frame ---\n", p); - print("%O %lT\n", d->op, d->dnode); - flag = 0; - break; - } - } -} - -/* - * calculate sethi/ullman number - * roughly how many registers needed to - * compile a node. used to compile the - * hardest side first to minimize registers. - */ -void -ullmancalc(Node *n) -{ - int ul, ur; - - if(n == N) - return; - - switch(n->op) { - case OLITERAL: - case ONAME: - ul = 0; - goto out; - case OCALL: - ul = UINF; - goto out; - } - ul = 0; - if(n->left != N) - ul = n->left->ullman; - ur = 0; - if(n->right != N) - ur = n->right->ullman; - if(ul == ur) - ul += 1; - if(ur > ul) - ul = ur; - -out: - n->ullman = ul; -} - -void -badtype(int o, Node *tl, Node *tr) -{ - yyerror("illegal types for operand"); - if(tl != N) - print(" (%T)", tl); - print(" %O ", o); - if(tr != N) - print("(%T)", tr); - print("\n"); -} - -/* - * this routine gets the parsing of - * a parameter list that can have - * name, type and name-type. - * it must distribute lone names - * with trailing types to give every - * name a type. (a,b,c int) comes out - * (a int, b int, c int). - */ -Node* -cleanidlist(Node *r) -{ - Node *t, *l, *n, *nn; - - t = N; // untyped name - nn = r; // next node to take - -loop: - n = nn; - if(n == N) { - if(t != N) { - yyerror("syntax error in parameter list"); - l = types[TINT32]; - goto distrib; - } - return r; - } - - l = n; - nn = N; - if(l->op == OLIST) { - nn = l->right; - l = l->left; - } - - if(l->op != ODCLFIELD) - fatal("cleanformal: %O", n->op); - - if(l->type == N) { - if(t == N) - t = n; - goto loop; - } - - if(t == N) - goto loop; - - l = l->type; // type to be distributed - -distrib: - while(t != n) { - if(t->op != OLIST) { - if(t->type == N) - t->type = l; - break; - } - if(t->left->type == N) - t->left->type = l; - t = t->right; - } - - t = N; - goto loop; -} - -/* - * iterator to walk a structure declaration - */ -Node* -structfirst(Iter *s, Node **nn) -{ - Node *r, *n; - - n = *nn; - if(n == N || n->op != OTYPE) - goto bad; - - switch(n->etype) { - default: - goto bad; - - case TSTRUCT: - case TINTER: - case TFUNC: - break; - } - - r = n->type; - if(r == N) - goto rnil; - - if(r->op != OTYPE || r->etype != TFIELD) - fatal("structfirst: not field %N", r); - - s->n = r; - return r; - -bad: - fatal("structfirst: not struct %N", n); - -rnil: - return N; -} - -Node* -structnext(Iter *s) -{ - Node *n, *r; - - n = s->n; - r = n->down; - if(r == N) - goto rnil; - - if(r->op != OTYPE || r->etype != TFIELD) - goto bad; - - s->n = r; - return r; - -bad: - fatal("structnext: not struct %N", n); - -rnil: - return N; -} - -/* - * iterator to walk a list - */ -Node* -listfirst(Iter *s, Node **nn) -{ - Node *n; - - n = *nn; - if(n == N) { - s->done = 1; - s->an = &s->n; - s->n = N; - return N; - } - - if(n->op == OLIST) { - s->done = 0; - s->n = n; - s->an = &n->left; - return n->left; - } - - s->done = 1; - s->an = nn; - return n; -} - -Node* -listnext(Iter *s) -{ - Node *n, *r; - - if(s->done) { - s->an = &s->n; - s->n = N; - return N; - } - - n = s->n; - r = n->right; - if(r->op == OLIST) { - s->n = r; - s->an = &r->left; - return r->left; - } - - s->done = 1; - s->an = &n->right; - return n->right; -} - -Node** -getthis(Node *t) -{ - if(t->etype != TFUNC) - fatal("getthis: not a func %N", t); - return &t->type; -} - -Node** -getoutarg(Node *t) -{ - if(t->etype != TFUNC) - fatal("getoutarg: not a func %N", t); - return &t->type->down; -} - -Node** -getinarg(Node *t) -{ - if(t->etype != TFUNC) - fatal("getinarg: not a func %N", t); - return &t->type->down->down; -} - -Node* -getthisx(Node *t) -{ - return *getthis(t); -} - -Node* -getoutargx(Node *t) -{ - return *getoutarg(t); -} - -Node* -getinargx(Node *t) -{ - return *getinarg(t); -} |