summaryrefslogtreecommitdiff
path: root/src/old/c/subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/old/c/subr.c')
-rw-r--r--src/old/c/subr.c1522
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);
-}