Commit 173ca5e7 authored by Rob Pike's avatar Rob Pike

delete old, c-output compiler. won't be open-sourced anyway

R=rsc
OCL=33407
CL=33409
parent 83c9d97a
// 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"
#define TUP(x,y) (((x)<<16)|(y))
void
convlit(Node *n, Node *t)
{
int et;
if(n->op != OLITERAL)
return;
if(t == N)
return;
n->type = t;
et = t->etype;
switch(whatis(n)) {
case Wlitint:
if(isptrto(t, TSTRING)) {
Rune rune;
int l;
String *s;
rune = n->val.vval;
l = runelen(rune);
s = mal(sizeof(*s)+l);
s->len = l;
runetochar((char*)(s->s), &rune);
n->val.sval = s;
n->val.ctype = CTSTR;
break;
}
if(isint[et]) {
if(n->val.vval < minintval[et])
goto bad2;
if(n->val.vval > maxintval[et])
goto bad2;
break;
}
if(isfloat[et]) {
if(n->val.vval < minfloatval[et])
goto bad2;
if(n->val.vval > maxfloatval[et])
goto bad2;
n->val.dval = n->val.vval;
n->val.ctype = CTFLT;
break;
}
goto bad1;
case Wlitfloat:
if(isint[et]) {
if(n->val.dval < minintval[et])
goto bad2;
if(n->val.dval > maxintval[et])
goto bad2;
n->val.vval = n->val.dval;
n->val.ctype = CTINT;
break;
}
if(isfloat[et]) {
if(n->val.dval < minfloatval[et])
goto bad2;
if(n->val.dval > maxfloatval[et])
goto bad2;
break;
}
goto bad1;
}
return;
bad1:
yyerror("illegal conversion of constant to %T", t);
return;
bad2:
yyerror("overflow converting constant to %T", t);
return;
}
void
evconst(Node *n)
{
Node *t, *nl, *nr;
long len;
String *str;
int wl, wr;
nl = n->left;
if(nl == N)
return;
switch(n->op) {
case OCONV:
t = n->type;
*n = *nl;
n->type = t;
return;
}
wl = whatis(nl);
switch(wl) {
default:
return;
case Wlitint:
case Wlitfloat:
case Wlitbool:
case Wlitstr:
break;
}
nr = n->right;
if(nr == N)
goto unary;
wr = whatis(nr);
switch(wr) {
default:
return;
case Wlitint:
case Wlitfloat:
case Wlitbool:
case Wlitstr:
break;
}
if(wl != wr) {
yyerror("illegal combination of literals %d %d", nl->etype, nr->etype);
return;
}
switch(TUP(n->op, wl)) {
default:
yyerror("illegal combination of literals %O %d", n->op, wl);
return;
case TUP(OADD, Wlitint):
nl->val.vval += nr->val.vval;
break;
case TUP(OSUB, Wlitint):
nl->val.vval -= nr->val.vval;
break;
case TUP(OMUL, Wlitint):
nl->val.vval *= nr->val.vval;
break;
case TUP(ODIV, Wlitint):
nl->val.vval /= nr->val.vval;
break;
case TUP(OMOD, Wlitint):
nl->val.vval %= nr->val.vval;
break;
case TUP(OLSH, Wlitint):
nl->val.vval <<= nr->val.vval;
break;
case TUP(ORSH, Wlitint):
nl->val.vval >>= nr->val.vval;
break;
case TUP(OOR, Wlitint):
nl->val.vval |= nr->val.vval;
break;
case TUP(OAND, Wlitint):
nl->val.vval &= nr->val.vval;
break;
case TUP(OADD, Wlitfloat):
nl->val.dval += nr->val.dval;
break;
case TUP(OSUB, Wlitfloat):
nl->val.dval -= nr->val.dval;
break;
case TUP(OMUL, Wlitfloat):
nl->val.dval *= nr->val.dval;
break;
case TUP(ODIV, Wlitfloat):
nl->val.dval /= nr->val.dval;
break;
case TUP(OEQ, Wlitint):
if(nl->val.vval == nr->val.vval)
goto settrue;
goto setfalse;
case TUP(ONE, Wlitint):
if(nl->val.vval != nr->val.vval)
goto settrue;
goto setfalse;
case TUP(OLT, Wlitint):
if(nl->val.vval < nr->val.vval)
goto settrue;
goto setfalse;
case TUP(OLE, Wlitint):
if(nl->val.vval <= nr->val.vval)
goto settrue;
goto setfalse;
case TUP(OGE, Wlitint):
if(nl->val.vval >= nr->val.vval)
goto settrue;
goto setfalse;
case TUP(OGT, Wlitint):
if(nl->val.vval > nr->val.vval)
goto settrue;
goto setfalse;
case TUP(OEQ, Wlitfloat):
if(nl->val.dval == nr->val.dval)
goto settrue;
goto setfalse;
case TUP(ONE, Wlitfloat):
if(nl->val.dval != nr->val.dval)
goto settrue;
goto setfalse;
case TUP(OLT, Wlitfloat):
if(nl->val.dval < nr->val.dval)
goto settrue;
goto setfalse;
case TUP(OLE, Wlitfloat):
if(nl->val.dval <= nr->val.dval)
goto settrue;
goto setfalse;
case TUP(OGE, Wlitfloat):
if(nl->val.dval >= nr->val.dval)
goto settrue;
goto setfalse;
case TUP(OGT, Wlitfloat):
if(nl->val.dval > nr->val.dval)
goto settrue;
goto setfalse;
case TUP(OEQ, Wlitstr):
if(cmpslit(nl, nr) == 0)
goto settrue;
goto setfalse;
case TUP(ONE, Wlitstr):
if(cmpslit(nl, nr) != 0)
goto settrue;
goto setfalse;
case TUP(OLT, Wlitstr):
if(cmpslit(nl, nr) < 0)
goto settrue;
goto setfalse;
case TUP(OLE, Wlitstr):
if(cmpslit(nl, nr) <= 0)
goto settrue;
goto setfalse;
case TUP(OGE, Wlitstr):
if(cmpslit(nl, nr) >= 0l)
goto settrue;
goto setfalse;
case TUP(OGT, Wlitstr):
if(cmpslit(nl, nr) > 0)
goto settrue;
goto setfalse;
case TUP(OADD, Wlitstr):
len = nl->val.sval->len + nr->val.sval->len;
str = mal(sizeof(*str) + len);
str->len = len;
memcpy(str->s, nl->val.sval->s, nl->val.sval->len);
memcpy(str->s+nl->val.sval->len, nr->val.sval->s, nr->val.sval->len);
str->len = len;
nl->val.sval = str;
break;
case TUP(OOROR, Wlitbool):
if(nl->val.vval || nr->val.vval)
goto settrue;
goto setfalse;
case TUP(OANDAND, Wlitbool):
if(nl->val.vval && nr->val.vval)
goto settrue;
goto setfalse;
}
*n = *nl;
return;
settrue:
*n = *booltrue;
return;
setfalse:
*n = *boolfalse;
return;
unary:
switch(TUP(n->op, wl)) {
default:
yyerror("illegal combination of literals %O %d", n->op, wl);
return;
case TUP(OPLUS, Wlitint):
nl->val.vval = +nl->val.vval;
break;
case TUP(OMINUS, Wlitint):
nl->val.vval = -nl->val.vval;
break;
case TUP(OCOM, Wlitint):
nl->val.vval = ~nl->val.vval;
break;
case TUP(OPLUS, Wlitfloat):
nl->val.dval = +nl->val.dval;
break;
case TUP(OMINUS, Wlitfloat):
nl->val.dval = -nl->val.dval;
break;
case TUP(ONOT, Wlitbool):
if(nl->val.vval)
goto settrue;
goto setfalse;
}
*n = *nl;
}
void
defaultlit(Node *n)
{
if(n == N)
return;
if(n->type != N)
return;
if(n->op != OLITERAL)
return;
switch(n->val.ctype) {
default:
yyerror("defaultlit: unknown literal: %N", n);
break;
case CTINT:
case CTSINT:
case CTUINT:
n->type = types[TINT32];
break;
case CTFLT:
n->type = types[TFLOAT64];
break;
case CTBOOL:
n->type = types[TBOOL];
break;
case CTSTR:
n->type = types[TSTRING];
break;
}
}
int
cmpslit(Node *l, Node *r)
{
long l1, l2, i, m;
uchar *s1, *s2;
l1 = l->val.sval->len;
l2 = r->val.sval->len;
s1 = l->val.sval->s;
s2 = r->val.sval->s;
m = l1;
if(l2 < m)
m = l2;
for(i=0; i<m; i++) {
if(s1[i] == s2[i])
continue;
if(s1[i] > s2[i])
return +1;
return -1;
}
if(l1 == l2)
return 0;
if(l1 > l2)
return +1;
return -1;
}
This diff is collapsed.
// 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
markexport(Node *n)
{
Sym *s;
Dcl *d, *r;
loop:
if(n == N)
return;
if(n->op == OLIST) {
markexport(n->left);
n = n->right;
goto loop;
}
if(n->op != OEXPORT)
fatal("markexport: op no OEXPORT: %O", n->op);
s = n->sym;
if(n->psym != S)
s = pkglookup(n->sym->name, n->psym->name);
if(s->export != 0)
return;
s->export = 1;
d = mal(sizeof(*d));
d->dsym = s;
d->dnode = N;
d->lineno = curio.lineno;
r = exportlist;
d->back = r->back;
r->back->forw = d;
r->back = d;
}
void
reexport(Node *t)
{
Sym *s;
if(t == N)
fatal("reexport: type nil\n");
s = t->sym;
if(s == S/* || s->name[0] == '_'*/) {
exportgen++;
snprint(namebuf, sizeof(namebuf), "_e%.3ld", exportgen);
s = lookup(namebuf);
s->lexical = LATYPE;
s->otype = t;
t->sym = s;
}
dumpexporttype(s);
}
void
dumpexportconst(Sym *s)
{
Node *n, *t;
if(s->exported != 0)
return;
s->exported = 1;
n = s->oconst;
if(n == N || n->op != OLITERAL)
fatal("dumpexportconst: oconst nil: %S\n", s);
t = n->type; // may or may not be specified
if(t != N)
reexport(t);
Bprint(bout, "\tconst ");
if(s->export != 0)
Bprint(bout, "!");
Bprint(bout, "%lS ", s);
if(t != N)
Bprint(bout, "%lS ", t->sym);
switch(n->val.ctype) {
default:
fatal("dumpexportconst: unknown ctype: %S\n", s);
case CTINT:
case CTSINT:
case CTUINT:
case CTBOOL:
Bprint(bout, "0x%llux\n", n->val.vval);
break;
case CTFLT:
Bprint(bout, "%.17e\n", n->val.dval);
break;
case CTSTR:
Bprint(bout, "\"%Z\"\n", n->val.sval);
break;
}
}
void
dumpexportvar(Sym *s)
{
Node *n, *t;
if(s->exported != 0)
return;
s->exported = 1;
n = s->oname;
if(n == N || n->type == N)
fatal("dumpexportvar: oname nil: %S\n", s);
t = n->type;
reexport(t);
Bprint(bout, "\tvar ");
if(s->export != 0)
Bprint(bout, "!");
Bprint(bout, "%lS %lS\n", s, t->sym);
}
void
dumpexporttype(Sym *s)
{
Node *t, *f;
Sym *ts;
int et;
if(s->exported != 0)
return;
s->exported = 1;
t = s->otype;
if(t == N || t->op != OTYPE)
fatal("dumpexporttype: otype nil: %S\n", s);
if(t->sym != s)
fatal("dumpexporttype: cross reference: %S\n", s);
et = t->etype;
switch(et) {
default:
if(et < 0 || et >= nelem(types) || types[et] == N)
fatal("dumpexporttype: basic type: %E\n", et);
/* type 5 */
Bprint(bout, "\ttype %lS %d\n", s, et);
break;
case TARRAY:
reexport(t->type);
/* type 2 */
Bprint(bout, "\ttype ");
if(s->export != 0)
Bprint(bout, "!");
Bprint(bout, "%lS [%lud] %lS\n", s, t->bound, t->type->sym);
break;
case TPTR:
reexport(t->type);
/* type 6 */
Bprint(bout, "\ttype ");
if(s->export != 0)
Bprint(bout, "!");
Bprint(bout, "%lS *%lS\n", s, t->type->sym);
break;
case TFUNC:
for(f=t->type; f!=N; f=f->down) {
if(f->op != OTYPE || f->etype != TSTRUCT)
fatal("dumpexporttype: funct not field: %O/%E\n",
f->op, f->etype);
reexport(f);
}
/* type 3 */
Bprint(bout, "\ttype ");
if(s->export != 0)
Bprint(bout, "!");
Bprint(bout, "%lS (", s);
for(f=t->type; f!=N; f=f->down) {
if(f != t->type)
Bprint(bout, " ");
Bprint(bout, "%lS", f->sym);
}
Bprint(bout, ")\n");
break;
case TSTRUCT:
case TINTER:
for(f=t->type; f!=N; f=f->down) {
if(f->op != OTYPE || f->etype != TFIELD)
fatal("dumpexporttype: funct not field: %O/%E\n",
f->op, f->etype);
reexport(f->type);
}
/* type 4 */
Bprint(bout, "\ttype ");
if(s->export)
Bprint(bout, "!");
Bprint(bout, "%lS %c", s, (et==TSTRUCT)? '{': '<');
for(f=t->type; f!=N; f=f->down) {
ts = f->type->sym;
if(f != t->type)
Bprint(bout, " ");
Bprint(bout, "%s %lS", f->sym->name, ts);
}
Bprint(bout, "%c\n", (et==TSTRUCT)? '}': '>');
break;
}
}
void
dumpe(Sym *s)
{
switch(s->lexical) {
default:
yyerror("unknown export symbol: %S\n", s, s->lexical);
break;
case LPACK:
yyerror("package export symbol: %S\n", s);
break;
case LATYPE:
case LBASETYPE:
dumpexporttype(s);
break;
case LNAME:
dumpexportvar(s);
break;
case LACONST:
dumpexportconst(s);
break;
}
}
void
dumpexport(void)
{
Dcl *d;
long lno;
lno = dynlineno;
Bprint(bout, " import\n");
Bprint(bout, " ((\n");
// print it depth first
for(d=exportlist->forw; d!=D; d=d->forw) {
dynlineno = d->lineno;
dumpe(d->dsym);
}
Bprint(bout, " ))\n");
dynlineno = lno;
}
/*
* ******* import *******
*/
Node*
importlooktype(Node *n)
{
Sym *s;
if(n->op != OIMPORT)
fatal("importlooktype: oops1 %N\n", n);
s = pkglookup(n->sym->name, n->psym->name);
if(s->otype == N)
fatal("importlooktype: oops2 %S\n", s);
return s->otype;
}
Node**
importstotype(Node *n, Node **t, Node *uber)
{
Node *f;
Iter save;
n = listfirst(&save, &n);
loop:
if(n == N) {
*t = N;
return t;
}
f = nod(OTYPE, N, N);
f->etype = TFIELD;
f->type = importlooktype(n);
f->uberstruct = uber;
if(n->fsym != S) {
f->nname = newname(n->fsym);
} else {
vargen++;
snprint(namebuf, sizeof(namebuf), "_m%.3ld", vargen);
f->nname = newname(lookup(namebuf));
}
f->sym = f->nname->sym;
f->nname->uberstruct = uber;
*t = f;
t = &f->down;
n = listnext(&save);
goto loop;
}
int
importcount(Node *t)
{
int i;
Node *f;
if(t == N || t->op != OTYPE || t->etype != TSTRUCT)
fatal("importcount: not a struct: %N", t);
i = 0;
for(f=t->type; f!=N; f=f->down)
i = i+1;
return i;
}
void
importfuncnam(Node *t)
{
Node *n, *n1;
if(t->etype != TFUNC)
fatal("importfuncnam: not func %T\n", t);
if(t->thistuple > 0) {
n1 = t->type;
if(n1->sym == S)
fatal("importfuncnam: no this");
n = newname(n1->sym);
vargen++;
n->vargen = vargen;
n1->nname = n;
}
if(t->outtuple > 0) {
n1 = t->type->down;
if(n1->sym == S)
fatal("importfuncnam: no output");
n = newname(n1->sym);
vargen++;
n->vargen = vargen;
n1->nname = n;
}
if(t->intuple > 0) {
n1 = t->type->down->down;
if(n1->sym == S)
fatal("importfuncnam: no input");
n = newname(n1->sym);
vargen++;
n->vargen = vargen;
n1->nname = n;
}
}
Sym*
getimportsym(Node *ss)
{
char *pkg;
Sym *s;
pkg = ss->psym->name;
if(ss->kaka) {
pkg = package;
if(pkgmyname != S)
pkg = pkgmyname->name;
}
s = pkglookup(ss->sym->name, pkg);
/* botch - need some diagnostic checking for the following assignment */
s->opackage = ss->osym->name;
return s;
}
void
importaddtyp(Node *ss, Node *t)
{
Sym *s;
s = getimportsym(ss);
if(s->otype == N || !eqtype(t, s->otype, 0)) {
addtyp(newtype(s), t, PEXTERN);
}
}
/*
* LCONST importsym LITERAL
* untyped constant
*/
void
doimportc1(Node *ss, Val *v)
{
Node *n;
Sym *s;
n = nod(OLITERAL, N, N);
n->val = *v;
s = getimportsym(ss);
if(s->oconst == N) {
// botch sould ask if already declared the same
dodclconst(newname(s), n);
}
}
/*
* LCONST importsym importsym LITERAL
* typed constant
*/
void
doimportc2(Node *ss, Node *st, Val *v)
{
Node *n, *t;
Sym *s;
n = nod(OLITERAL, N, N);
n->val = *v;
t = importlooktype(st);
n->type = t;
s = getimportsym(ss);
if(s->oconst == N) {
// botch sould ask if already declared the same
dodclconst(newname(s), n);
}
}
/*
* LVAR importsym importsym
* variable
*/
void
doimportv1(Node *ss, Node *st)
{
Node *t;
Sym *s;
t = importlooktype(st);
s = getimportsym(ss);
if(s->oname == N || !eqtype(t, s->oname->type, 0)) {
addvar(newname(s), t, dclcontext);
}
}
/*
* LTYPE importsym [ importsym ] importsym
* array type
*/
void
doimport1(Node *ss, Node *ss1, Node *s)
{
fatal("doimport1");
}
/*
* LTYPE importsym [ LLITERAL ] importsym
* array type
*/
void
doimport2(Node *ss, Val *b, Node *st)
{
Node *t;
Sym *s;
t = nod(OTYPE, N, N);
t->etype = TARRAY;
t->bound = b->vval;
s = pkglookup(st->sym->name, st->psym->name);
t->type = s->otype;
importaddtyp(ss, t);
}
/*
* LTYPE importsym '(' importsym_list ')'
* function/method type
*/
void
doimport3(Node *ss, Node *n)
{
Node *t;
t = nod(OTYPE, N, N);
t->etype = TFUNC;
t->type = importlooktype(n->left);
t->type->down = importlooktype(n->right->left);
t->type->down->down = importlooktype(n->right->right);
t->thistuple = importcount(t->type);
t->outtuple = importcount(t->type->down);
t->intuple = importcount(t->type->down->down);
importfuncnam(t);
importaddtyp(ss, t);
}
/*
* LTYPE importsym '{' importsym_list '}'
* structure type
*/
void
doimport4(Node *ss, Node *n)
{
Node *t;
t = nod(OTYPE, N, N);
t->etype = TSTRUCT;
importstotype(n, &t->type, t);
importaddtyp(ss, t);
}
/*
* LTYPE importsym LLITERAL
* basic type
*/
void
doimport5(Node *ss, Val *v)
{
int et;
Node *t;
et = v->vval;
if(et <= 0 || et >= nelem(types) || types[et] == N)
fatal("doimport5: bad type index: %E\n", et);
t = nod(OTYPE, 0, 0);
t->etype = et;
t->sym = S;
importaddtyp(ss, t);
}
/*
* LTYPE importsym * importsym
* pointer type
*/
void
doimport6(Node *ss, Node *st)
{
Node *t;
Sym *s;
s = pkglookup(st->sym->name, st->psym->name);
t = s->otype;
if(t == N)
t = forwdcl(s);
else
t = ptrto(t);
importaddtyp(ss, t);
}
/*
* LTYPE importsym '<' importsym '>'
* interface type
*/
void
doimport7(Node *ss, Node *n)
{
Node *t;
t = nod(OTYPE, N, N);
t->etype = TINTER;
importstotype(n, &t->type, t);
importaddtyp(ss, t);
}
This diff is collapsed.
// 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.
#ifndef EXTERN
#define EXTERN extern
#endif
typedef struct Prog Prog;
typedef struct Addr Addr;
struct Addr
{
int type;
Node* node;
Prog* branch;
};
enum
{
AXXX = 0,
ANONE,
ANODE,
ABRANCH,
};
struct Prog
{
int op; // opcode
int pt;
int pt1;
int param;
long lineno; // source line
long loc; // program counter for print
int mark;
Addr addr; // operand
Prog* link;
};
#define P ((Prog*)0)
typedef struct Plist Plist;
struct Plist
{
Node* name;
Dcl* locals;
Prog* firstpc;
int recur;
Plist* link;
};
typedef struct Sig Sig;
struct Sig
{
char* fun;
ulong hash;
int offset;
Sig* link;
};
enum
{
PTxxx,
PTINT8 = TINT8,
PTUINT8 = TUINT8,
PTINT16 = TINT16,
PTUINT16 = TUINT16,
PTINT32 = TINT32,
PTUINT32 = TUINT32,
PTINT64 = TINT64,
PTUINT64 = TUINT64,
PTFLOAT32 = TFLOAT32,
PTFLOAT64 = TFLOAT64,
PTFLOAT80 = TFLOAT80,
PTBOOL = TBOOL,
PTPTR = TPTR,
PTSTRUCT = TSTRUCT,
PTINTER = TINTER,
PTARRAY = TARRAY,
PTSTRING = TSTRING,
PTCHAN = TCHAN,
PTMAP = TMAP,
PTNIL = NTYPE,
PTADDR,
PTERROR,
NPTYPE,
};
enum
{
PXXX = 0,
PERROR, PPANIC, PPRINT, PGOTO, PGOTOX,
PCMP, PTEST, PNEW, PLEN,
PCALL1, PCALL2, PCALLI2, PCALLM2, PCALLF2, PCALL3, PRETURN,
PBEQ, PBNE,
PBLT, PBLE, PBGE, PBGT,
PBTRUE, PBFALSE,
PLOAD, PLOADI,
PSTORE, PSTOREI,
PSTOREZ, PSTOREZI,
PCONV, PADDR, PADDO, PINDEX, PINDEXZ,
PSLICE,
PADD, PSUB, PMUL, PDIV, PLSH, PRSH, PMOD,
PAND, POR, PXOR, PCAT,
PMINUS, PCOM,
PEND,
};
typedef struct Case Case;
struct Case
{
Prog* sprog;
Node* scase;
Case* slink;
};
#define C ((Case*)0)
EXTERN Prog* continpc;
EXTERN Prog* breakpc;
EXTERN Prog* pc;
EXTERN Prog* firstpc;
EXTERN Plist* plist;
EXTERN Plist* plast;
EXTERN Biobuf* bout;
EXTERN long dynloc;
/*
* gen.c
*/
void compile(Node*);
void proglist(void);
void gen(Node*);
void cgen(Node*);
void agen(Node*);
void bgen(Node*, int, Prog*);
void swgen(Node*);
Node* lookdot(Node*, Node*, int);
int usesptr(Node*);
void inarggen(void);
void cgen_as(Node*, Node*, int, int);
void cgen_asop(Node*, Node*, int);
void cgen_ret(Node*);
void cgen_call(Node*, int);
void cgen_callret(Node*, Node*);
void genprint(Node*);
int needconvert(Node*, Node*);
void genconv(Node*, Node*);
void genindex(Node*);
/*
* gsubr.c
*/
int Aconv(Fmt*);
int Pconv(Fmt*);
void proglist(void);
Prog* gbranch(int, Node*);
void patch(Prog*, Prog*);
Prog* prog(int);
Node* tempname(Node*);
Prog* gopcode(int, int, Node*);
Prog* gopcodet(int, Node*, Node*);
void gaddoffset(Node*);
void gconv(int, int);
int conv2pt(Node*);
void belexinit(int);
vlong convvtox(vlong, int);
int brcom(int);
int brrev(int);
void fnparam(Node*, int, int);
Sig* lsort(Sig*, int(*)(Sig*, Sig*));
/*
* obj.c
*/
void dumpobj(void);
void litrl(Prog*);
void obj(Prog*);
void follow(Prog*);
Prog* gotochain(Prog*);
int Xconv(Fmt*);
int Rconv(Fmt*);
int Qconv(Fmt*);
int Dconv(Fmt*);
int Cconv(Fmt*);
void dumpexterns(void);
void dumpfunct(Plist*);
void dumpsignatures(void);
void doframe(Dcl*, char*);
void docall1(Prog*);
void docall2(Prog*);
void docalli2(Prog*);
void docallm2(Prog*);
void docallf2(Prog*);
void docall3(Prog*);
void doconv(Prog*);
char* getfmt(int);
void dumpmethods(void);
// 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.
/*
todo:
1. dyn arrays
2. multi
3. block 0
tothinkabout:
1. alias name name.name.name
2. argument in import
*/
#include <u.h>
#include <libc.h>
#include <bio.h>
#ifndef EXTERN
#define EXTERN extern
#endif
enum
{
NHUNK = 50000,
BUFSIZ = 8192,
NSYMB = 500,
NHASH = 1024,
STRINGSZ = 200,
YYMAXDEPTH = 500,
MAXALIGN = 7,
UINF = 100,
PRIME1 = 3,
PRIME2 = 10007,
PRIME3 = 10009,
PRIME4 = 10037,
PRIME5 = 10039,
PRIME6 = 10061,
PRIME7 = 10067,
PRIME8 = 10079,
PRIME9 = 10091,
};
/* note this is the representation
* of the compilers string literals,
* it happens to also be the runtime
* representation, but that may change */
typedef struct String String;
struct String
{
long len;
uchar s[3]; // variable
};
typedef struct Val Val;
struct Val
{
int ctype;
double dval;
vlong vval;
String* sval;
};
typedef struct Sym Sym;
typedef struct Node Node;
struct Node
{
int op;
// most nodes
Node* left;
Node* right;
Node* type;
// for-body
Node* ninit;
Node* ntest;
Node* nincr;
Node* nbody;
// if-body
Node* nelse;
// OTYPE-TFIELD
Node* down; // also used in TMAP
Node* uberstruct;
// cases
Node* ncase;
// OTYPE-TPTR
Node* nforw;
// OTYPE-TFUNCT
Node* this;
Node* argout;
Node* argin;
Node* nname;
int thistuple;
int outtuple;
int intuple;
// OTYPE-TARRAY
long bound;
// OLITERAL
Val val;
Sym* osym; // import
Sym* fsym; // import
Sym* psym; // import
Sym* sym; // various
uchar ullman; // sethi/ullman number
uchar addable; // type of addressability - 0 is not addressable
uchar recur; // to detect loops
uchar trecur; // to detect loops
uchar etype; // is an op for OASOP, is etype for OTYPE
uchar chan;
uchar kaka;
uchar multi; // type of assignment or call
long vargen; // unique name for OTYPE/ONAME
long lineno;
};
#define N ((Node*)0)
struct Sym
{
char* opackage; // original package name
char* package; // package name
char* name; // variable name
Node* oname; // ONAME node if a var
Node* otype; // OTYPE node if a type
Node* oconst; // OLITERAL node if a const
Node* forwtype; // OTYPE/TPTR iff foreward declared
void* label; // pointer to Prog* of label
long lexical;
long vargen; // unique variable number
uchar undef; // a diagnostic has been generated
uchar export; // marked as export
uchar exported; // has been exported
Sym* link;
};
#define S ((Sym*)0)
typedef struct Dcl Dcl;
struct Dcl
{
int op; // ONAME for var, OTYPE for type, Oxxx for const
Sym* dsym; // for printing only
Node* dnode; // otype or oname
long lineno;
Dcl* forw;
Dcl* back; // sentinel has pointer to last
};
#define D ((Dcl*)0)
typedef struct Iter Iter;
struct Iter
{
int done;
Node** an;
Node* n;
};
enum
{
OXXX,
OTYPE, OCONST, OVAR, OEXPORT, OIMPORT,
ONAME,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER,
ODCLFUNC, ODCLFIELD, ODCLARG,
OLIST,
OPTR, OARRAY,
ORETURN, OFOR, OIF, OSWITCH,
OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL,
OGOTO, OPROC, ONEW, OPANIC, OPRINT, OEMPTY,
OOROR,
OANDAND,
OEQ, ONE, OLT, OLE, OGE, OGT,
OADD, OSUB, OOR, OXOR, OCAT,
OMUL, ODIV, OMOD, OLSH, ORSH, OAND,
ODEC, OINC,
OLEN,
OFUNC,
OLABEL,
OBREAK,
OCONTINUE,
OADDR,
OIND,
OCALL, OCALLPTR, OCALLMETH, OCALLINTER,
OINDEX, OINDEXSTR, OINDEXMAP,
OINDEXPTR, OINDEXPTRSTR, OINDEXPTRMAP,
OSLICE, OSLICESTR, OSLICEPTRSTR,
ONOT, OCOM, OPLUS, OMINUS, OSEND, ORECV,
OLITERAL,
OCONV,
OBAD,
OEND,
};
enum
{
Txxx,
TINT8, TUINT8,
TINT16, TUINT16,
TINT32, TUINT32,
TINT64, TUINT64,
TFLOAT32,
TFLOAT64,
TFLOAT80,
TBOOL,
TPTR,
TFUNC,
TARRAY,
TDARRAY,
TSTRUCT,
TCHAN,
TMAP,
TINTER,
TFORW,
TFIELD,
TANY,
TSTRING,
NTYPE,
};
enum
{
CTxxx,
CTINT,
CTSINT,
CTUINT,
CTFLT,
CTSTR,
CTBOOL,
CTNIL,
};
enum
{
/* indications for whatis() */
Wnil = 0,
Wtnil,
Wtfloat,
Wtint,
Wtbool,
Wtstr,
Wlitfloat,
Wlitint,
Wlitbool,
Wlitstr,
Wtunkn,
};
enum
{
/* types of channel */
Cxxx,
Cboth,
Crecv,
Csend,
};
enum
{
Pxxx,
PEXTERN, // declaration context
PAUTO,
PCALL_NIL, // no return value
PCALL_SINGLE, // single return value
PCALL_MULTI, // multiple return values
PAS_SINGLE, // top level walk->gen hints for OAS
PAS_MULTI, // multiple values
PAS_CALLM, // multiple values from a call
PAS_STRUCT, // structure assignment
};
typedef struct Io Io;
struct Io
{
char* infile;
Biobuf* bin;
long lineno;
int peekc;
};
EXTERN Io curio;
EXTERN Io pushedio;
EXTERN char* outfile;
EXTERN char* package;
EXTERN Biobuf* bout;
EXTERN int nerrors;
EXTERN char namebuf[NSYMB];
EXTERN char debug[256];
EXTERN long dynlineno;
EXTERN Sym* hash[NHASH];
EXTERN Sym* dclstack;
EXTERN Sym* b0stack;
EXTERN Sym* pkgmyname; // my name for package
EXTERN Node* types[NTYPE];
EXTERN uchar isint[NTYPE];
EXTERN uchar isfloat[NTYPE];
EXTERN uchar okforeq[NTYPE];
EXTERN uchar okforadd[NTYPE];
EXTERN uchar okforand[NTYPE];
EXTERN double minfloatval[NTYPE];
EXTERN double maxfloatval[NTYPE];
EXTERN vlong minintval[NTYPE];
EXTERN vlong maxintval[NTYPE];
EXTERN Dcl* autodcl;
EXTERN Dcl* externdcl;
EXTERN Dcl* exportlist;
EXTERN int dclcontext; // PEXTERN/PAUTO
EXTERN int importflag;
EXTERN Node* booltrue;
EXTERN Node* boolfalse;
EXTERN ulong iota;
EXTERN long vargen;
EXTERN long exportgen;
EXTERN Node* retnil;
EXTERN Node* fskel;
EXTERN char* context;
EXTERN int thechar;
EXTERN char* thestring;
EXTERN char* hunk;
EXTERN long nhunk;
EXTERN long thunk;
/*
* y.tab.c
*/
int yyparse(void);
/*
* lex.c
*/
int main(int, char*[]);
void importfile(Val*);
void unimportfile();
long yylex(void);
void lexinit(void);
char* lexname(int);
long getr(void);
int getnsc(void);
long escchar(long, int*);
int getc(void);
void ungetc(int);
void mkpackage(char*);
/*
* mpatof.c
*/
int mpatof(char*, double*);
int mpatov(char*, vlong*);
/*
* subr.c
*/
void myexit(int);
void* mal(long);
void* remal(void*, long, long);
void errorexit(void);
ulong stringhash(char*);
Sym* lookup(char*);
Sym* pkglookup(char*, char*);
void yyerror(char*, ...);
void warn(char*, ...);
void fatal(char*, ...);
Node* nod(int, Node*, Node*);
Dcl* dcl(void);
Node* rev(Node*);
Node* unrev(Node*);
void dodump(Node*, int);
void dump(char*, Node*);
Node* aindex(Node*, Node*);
int isnil(Node*);
int isptrto(Node*, int);
int isinter(Node*);
int isbytearray(Node*);
int eqtype(Node*, Node*, int);
int eqargs(Node*, Node*);
ulong typehash(Node*, int);
void frame(int);
Node* literal(long);
Node* dobad(void);
void ullmancalc(Node*);
void badtype(int, Node*, Node*);
Node* ptrto(Node*);
Node* cleanidlist(Node*);
Node** getthis(Node*);
Node** getoutarg(Node*);
Node** getinarg(Node*);
Node* getthisx(Node*);
Node* getoutargx(Node*);
Node* getinargx(Node*);
Node* listfirst(Iter*, Node**);
Node* listnext(Iter*);
Node* structfirst(Iter*, Node**);
Node* structnext(Iter*);
int Econv(Fmt*);
int Jconv(Fmt*);
int Oconv(Fmt*);
int Sconv(Fmt*);
int Tconv(Fmt*);
int Nconv(Fmt*);
int Zconv(Fmt*);
/*
* dcl.c
*/
void dodclvar(Node*, Node*);
void dodcltype(Node*, Node*);
void dodclconst(Node*, Node*);
void defaultlit(Node*);
int listcount(Node*);
Node* functype(Node*, Node*, Node*);
char* thistypenam(Node*);
void funcnam(Node*, char*);
void funchdr(Node*);
void funcargs(Node*);
void funcbody(Node*);
Node* dostruct(Node*, int);
Node** stotype(Node*, Node**, Node*);
Node* sortinter(Node*);
void markdcl(char*);
void popdcl(char*);
void poptodcl(void);
void markdclstack(void);
void testdclstack(void);
Sym* pushdcl(Sym*);
void addvar(Node*, Node*, int);
void addtyp(Node*, Node*, int);
Node* newname(Sym*);
Node* oldname(Sym*);
Node* newtype(Sym*);
Node* oldtype(Sym*);
Node* forwdcl(Sym*);
/*
* export.c
*/
void markexport(Node*);
void dumpe(Sym*);
void dumpexport(void);
void dumpexporttype(Sym*);
void dumpexportvar(Sym*);
void dumpexportconst(Sym*);
void doimportv1(Node*, Node*);
void doimportc1(Node*, Val*);
void doimportc2(Node*, Node*, Val*);
void doimport1(Node*, Node*, Node*);
void doimport2(Node*, Val*, Node*);
void doimport3(Node*, Node*);
void doimport4(Node*, Node*);
void doimport5(Node*, Val*);
void doimport6(Node*, Node*);
void doimport7(Node*, Node*);
/*
* walk.c
*/
void walk(Node*);
void walktype(Node*, int);
Node* walkswitch(Node*, Node*, Node*(*)(Node*, Node*));
int casebody(Node*);
int whatis(Node*);
void walkdot(Node*);
void walkslice(Node*);
void ascompatee(int, Node**, Node**);
void ascompatet(int, Node**, Node**);
void ascompatte(int, Node**, Node**);
void ascompattt(int, Node**, Node**);
int ascompat(Node*, Node*);
void prcompat(Node**);
/*
* const.c
*/
void convlit(Node*, Node*);
void evconst(Node*);
int cmpslit(Node *l, Node *r);
/*
* gen.c/gsubr.c/obj.c
*/
void belexinit(int);
vlong convvtox(vlong, int);
void compile(Node*);
void proglist(void);
void dumpobj(void);
int optopop(int);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment