1
0
mirror of https://github.com/golang/go synced 2024-10-04 11:11:21 -06:00
go/src/cmd/gc/const.c
Russ Cox 45f4e38506 silence gcc warnings
R=ken
OCL=16449
CL=16466
2008-10-03 16:23:02 -07:00

469 lines
8.5 KiB
C

// 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, Type *t)
{
int et;
if(n == N || t == T)
return;
switch(n->op) {
default:
return;
case OLITERAL:
break;
case OLSH:
case ORSH:
convlit(n->left, t);
n->type = n->left->type;
return;
}
et = t->etype;
switch(et) {
case TARRAY:
case TFUNC:
case TCHAN:
case TMAP:
// case TPTR32:
// case TPTR64:
return;
}
switch(whatis(n)) {
default:
goto bad1;
case Wlitnil:
if(!isptr[et] && et != TINTER)
goto bad1;
if(isptrto(t, TSTRING))
goto bad1;
break;
case Wlitstr:
if(isptrto(t, TSTRING))
break;
goto bad1;
case Wlitbool:
if(et == TBOOL)
break;
goto bad1;
case Wlitint:
if(isptrto(t, TSTRING)) {
Rune rune;
int l;
String *s;
rune = mpgetfix(n->val.u.xval);
l = runelen(rune);
s = mal(sizeof(*s)+l);
s->len = l;
runetochar((char*)(s->s), &rune);
n->val.u.sval = s;
n->val.ctype = CTSTR;
break;
}
if(isint[et]) {
// int to int
if(mpcmpfixfix(n->val.u.xval, minintval[et]) < 0)
goto bad2;
if(mpcmpfixfix(n->val.u.xval, maxintval[et]) > 0)
goto bad2;
break;
}
if(isfloat[et]) {
Mpint *xv;
// int to float
xv = n->val.u.xval;
if(mpcmpfixflt(xv, minfltval[et]) < 0)
goto bad2;
if(mpcmpfixflt(xv, maxfltval[et]) > 0)
goto bad2;
n->val.u.fval = mal(sizeof(*n->val.u.fval));
mpmovefixflt(n->val.u.fval, xv);
n->val.ctype = CTFLT;
break;
}
goto bad1;
case Wlitfloat:
if(isint[et]) {
Mpflt *fv;
// float to int
fv = n->val.u.fval;
if(mpcmpfltfix(fv, minintval[et]) < 0)
goto bad2;
if(mpcmpfltfix(fv, maxintval[et]) > 0)
goto bad2;
n->val.u.xval = mal(sizeof(*n->val.u.xval));
mpmovefltfix(n->val.u.xval, fv);
n->val.ctype = CTINT;
break;
}
if(isfloat[et]) {
// float to float
if(mpcmpfltflt(n->val.u.fval, minfltval[et]) < 0)
goto bad2;
if(mpcmpfltflt(n->val.u.fval, maxfltval[et]) > 0)
goto bad2;
break;
}
goto bad1;
}
n->type = t;
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 *nl, *nr;
int32 len;
String *str;
int wl, wr;
Mpint *xval;
Mpflt *fval;
nl = n->left;
if(nl == N)
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) {
if(wl == Wlitfloat && wr == Wlitint) {
xval = nr->val.u.xval;
nr->val.u.fval = mal(sizeof(*nr->val.u.fval));
mpmovefixflt(nr->val.u.fval, xval);
nr->val.ctype = CTFLT;
wr = whatis(nr);
} else
if(wl == Wlitint && wr == Wlitfloat) {
xval = nl->val.u.xval;
nl->val.u.fval = mal(sizeof(*nl->val.u.fval));
mpmovefixflt(nl->val.u.fval, xval);
nl->val.ctype = CTFLT;
wl = whatis(nl);
} else {
yyerror("illegal combination of literals %E %E", nl->etype, nr->etype);
return;
}
}
// dance to not modify left side
// this is because iota will reuse it
if(wl == Wlitint) {
xval = mal(sizeof(*xval));
mpmovefixfix(xval, nl->val.u.xval);
} else
if(wl == Wlitfloat) {
fval = mal(sizeof(*fval));
mpmovefltflt(fval, nl->val.u.fval);
}
switch(TUP(n->op, wl)) {
default:
yyerror("illegal combination of literals %O %E", n->op, nl->etype);
return;
case TUP(OADD, Wlitint):
mpaddfixfix(xval, nr->val.u.xval);
break;
case TUP(OSUB, Wlitint):
mpsubfixfix(xval, nr->val.u.xval);
break;
case TUP(OMUL, Wlitint):
mpmulfixfix(xval, nr->val.u.xval);
break;
case TUP(ODIV, Wlitint):
mpdivfixfix(xval, nr->val.u.xval);
break;
case TUP(OMOD, Wlitint):
mpmodfixfix(xval, nr->val.u.xval);
break;
case TUP(OLSH, Wlitint):
mplshfixfix(xval, nr->val.u.xval);
break;
case TUP(ORSH, Wlitint):
mprshfixfix(xval, nr->val.u.xval);
break;
case TUP(OOR, Wlitint):
mporfixfix(xval, nr->val.u.xval);
break;
case TUP(OAND, Wlitint):
mpandfixfix(xval, nr->val.u.xval);
break;
case TUP(OXOR, Wlitint):
mpxorfixfix(xval, nr->val.u.xval);
break;
case TUP(OADD, Wlitfloat):
mpaddfltflt(fval, nr->val.u.fval);
break;
case TUP(OSUB, Wlitfloat):
mpsubfltflt(fval, nr->val.u.fval);
break;
case TUP(OMUL, Wlitfloat):
mpmulfltflt(fval, nr->val.u.fval);
break;
case TUP(ODIV, Wlitfloat):
mpdivfltflt(fval, nr->val.u.fval);
break;
case TUP(OEQ, Wlitint):
if(mpcmpfixfix(xval, nr->val.u.xval) == 0)
goto settrue;
goto setfalse;
case TUP(ONE, Wlitint):
if(mpcmpfixfix(xval, nr->val.u.xval) != 0)
goto settrue;
goto setfalse;
case TUP(OLT, Wlitint):
if(mpcmpfixfix(xval, nr->val.u.xval) < 0)
goto settrue;
goto setfalse;
case TUP(OLE, Wlitint):
if(mpcmpfixfix(xval, nr->val.u.xval) <= 0)
goto settrue;
goto setfalse;
case TUP(OGE, Wlitint):
if(mpcmpfixfix(xval, nr->val.u.xval) >= 0)
goto settrue;
goto setfalse;
case TUP(OGT, Wlitint):
if(mpcmpfixfix(xval, nr->val.u.xval) > 0)
goto settrue;
goto setfalse;
case TUP(OEQ, Wlitfloat):
if(mpcmpfltflt(fval, nr->val.u.fval) == 0)
goto settrue;
goto setfalse;
case TUP(ONE, Wlitfloat):
if(mpcmpfltflt(fval, nr->val.u.fval) != 0)
goto settrue;
goto setfalse;
case TUP(OLT, Wlitfloat):
if(mpcmpfltflt(fval, nr->val.u.fval) < 0)
goto settrue;
goto setfalse;
case TUP(OLE, Wlitfloat):
if(mpcmpfltflt(fval, nr->val.u.fval) <= 0)
goto settrue;
goto setfalse;
case TUP(OGE, Wlitfloat):
if(mpcmpfltflt(fval, nr->val.u.fval) >= 0)
goto settrue;
goto setfalse;
case TUP(OGT, Wlitfloat):
if(mpcmpfltflt(fval, nr->val.u.fval) > 0)
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.u.sval->len + nr->val.u.sval->len;
str = mal(sizeof(*str) + len);
str->len = len;
memcpy(str->s, nl->val.u.sval->s, nl->val.u.sval->len);
memcpy(str->s+nl->val.u.sval->len, nr->val.u.sval->s, nr->val.u.sval->len);
str->len = len;
nl->val.u.sval = str;
break;
case TUP(OOROR, Wlitbool):
if(nl->val.u.bval || nr->val.u.bval)
goto settrue;
goto setfalse;
case TUP(OANDAND, Wlitbool):
if(nl->val.u.bval && nr->val.u.bval)
goto settrue;
goto setfalse;
}
goto ret;
settrue:
*n = *booltrue;
return;
setfalse:
*n = *boolfalse;
return;
unary:
if(wl == Wlitint) {
xval = mal(sizeof(*xval));
mpmovefixfix(xval, nl->val.u.xval);
} else
if(wl == Wlitfloat) {
fval = mal(sizeof(*fval));
mpmovefltflt(fval, nl->val.u.fval);
}
switch(TUP(n->op, wl)) {
default:
yyerror("illegal combination of literals %O %d", n->op, wl);
return;
case TUP(OPLUS, Wlitint):
break;
case TUP(OMINUS, Wlitint):
mpnegfix(xval);
break;
case TUP(OCOM, Wlitint):
mpcomfix(xval);
break;
case TUP(OPLUS, Wlitfloat):
break;
case TUP(OMINUS, Wlitfloat):
mpnegflt(fval);
break;
case TUP(ONOT, Wlitbool):
if(nl->val.u.bval)
goto settrue;
goto setfalse;
}
ret:
*n = *nl;
// second half of dance
if(wl == Wlitint) {
n->val.u.xval = xval;
} else
if(wl == Wlitfloat) {
n->val.u.fval = fval;
}
}
void
defaultlit(Node *n)
{
if(n == N)
return;
if(n->type != T)
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)
{
int32 l1, l2, i, m;
char *s1, *s2;
l1 = l->val.u.sval->len;
l2 = r->val.u.sval->len;
s1 = l->val.u.sval->s;
s2 = r->val.u.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;
}