2008-06-04 15:37:38 -06:00
|
|
|
// 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))
|
|
|
|
|
2008-12-02 18:03:47 -07:00
|
|
|
void
|
|
|
|
truncfltlit(Mpflt *fv, Type *t)
|
|
|
|
{
|
|
|
|
double d;
|
|
|
|
float f;
|
|
|
|
|
|
|
|
if(t == T)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// convert large precision literal floating
|
|
|
|
// into limited precision (float64 or float32)
|
|
|
|
// botch -- this assumes that compiler fp
|
|
|
|
// has same precision as runtime fp
|
|
|
|
switch(t->etype) {
|
|
|
|
case TFLOAT64:
|
|
|
|
d = mpgetflt(fv);
|
|
|
|
mpmovecflt(fv, d);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TFLOAT32:
|
|
|
|
d = mpgetflt(fv);
|
|
|
|
f = d;
|
|
|
|
d = f;
|
|
|
|
mpmovecflt(fv, d);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
void
|
2008-12-12 14:10:36 -07:00
|
|
|
convlit1(Node *n, Type *t, int conv)
|
2008-06-04 15:37:38 -06:00
|
|
|
{
|
2008-10-16 16:59:31 -06:00
|
|
|
int et, wt;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-08-29 14:24:53 -06:00
|
|
|
if(n == N || t == T)
|
2008-06-04 15:37:38 -06:00
|
|
|
return;
|
2008-10-29 21:25:34 -06:00
|
|
|
|
2008-08-29 14:24:53 -06:00
|
|
|
switch(n->op) {
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
case OLITERAL:
|
|
|
|
break;
|
|
|
|
case OLSH:
|
|
|
|
case ORSH:
|
|
|
|
convlit(n->left, t);
|
|
|
|
n->type = n->left->type;
|
|
|
|
return;
|
|
|
|
}
|
2008-09-04 13:21:10 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
et = t->etype;
|
2008-10-16 16:59:31 -06:00
|
|
|
wt = whatis(n);
|
|
|
|
|
|
|
|
switch(wt) {
|
2008-06-17 19:01:05 -06:00
|
|
|
default:
|
|
|
|
goto bad1;
|
|
|
|
|
|
|
|
case Wlitnil:
|
2008-09-04 18:15:15 -06:00
|
|
|
if(isptrto(t, TSTRING))
|
|
|
|
goto bad1;
|
2008-10-15 18:08:10 -06:00
|
|
|
if(isptr[et])
|
|
|
|
break;
|
|
|
|
if(et == TINTER)
|
|
|
|
break;
|
2008-12-09 18:52:41 -07:00
|
|
|
goto bad1;
|
2008-06-17 23:33:32 -06:00
|
|
|
|
|
|
|
case Wlitstr:
|
2008-10-15 18:08:10 -06:00
|
|
|
if(isnilinter(t)) {
|
|
|
|
defaultlit(n);
|
|
|
|
return;
|
|
|
|
}
|
2008-06-17 23:33:32 -06:00
|
|
|
if(isptrto(t, TSTRING))
|
|
|
|
break;
|
|
|
|
goto bad1;
|
|
|
|
|
|
|
|
case Wlitbool:
|
2008-10-15 18:08:10 -06:00
|
|
|
if(isnilinter(t)) {
|
|
|
|
defaultlit(n);
|
|
|
|
return;
|
|
|
|
}
|
2008-06-17 23:33:32 -06:00
|
|
|
if(et == TBOOL)
|
2008-06-17 19:01:05 -06:00
|
|
|
break;
|
|
|
|
goto bad1;
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
case Wlitint:
|
2008-10-15 18:08:10 -06:00
|
|
|
if(isnilinter(t)) {
|
|
|
|
defaultlit(n);
|
|
|
|
return;
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
if(isint[et]) {
|
2008-08-08 18:13:31 -06:00
|
|
|
// int to int
|
|
|
|
if(mpcmpfixfix(n->val.u.xval, minintval[et]) < 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto bad2;
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfixfix(n->val.u.xval, maxintval[et]) > 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto bad2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(isfloat[et]) {
|
2008-10-15 18:08:10 -06:00
|
|
|
// int to float
|
2008-08-12 15:04:03 -06:00
|
|
|
Mpint *xv;
|
2008-12-02 18:03:47 -07:00
|
|
|
Mpflt *fv;
|
2008-08-12 15:04:03 -06:00
|
|
|
|
|
|
|
xv = n->val.u.xval;
|
|
|
|
if(mpcmpfixflt(xv, minfltval[et]) < 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto bad2;
|
2008-08-12 15:04:03 -06:00
|
|
|
if(mpcmpfixflt(xv, maxfltval[et]) > 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto bad2;
|
2008-12-02 18:03:47 -07:00
|
|
|
fv = mal(sizeof(*n->val.u.fval));
|
|
|
|
n->val.u.fval = fv;
|
|
|
|
mpmovefixflt(fv, xv);
|
2008-06-04 15:37:38 -06:00
|
|
|
n->val.ctype = CTFLT;
|
2008-12-02 18:03:47 -07:00
|
|
|
truncfltlit(fv, t);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
}
|
2008-12-12 14:10:36 -07:00
|
|
|
if(!conv)
|
|
|
|
goto bad1;
|
|
|
|
|
|
|
|
// only done as string(CONST)
|
|
|
|
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;
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
goto bad1;
|
|
|
|
|
|
|
|
case Wlitfloat:
|
2008-10-15 18:08:10 -06:00
|
|
|
if(isnilinter(t)) {
|
|
|
|
defaultlit(n);
|
|
|
|
return;
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
if(isint[et]) {
|
2008-10-15 18:08:10 -06:00
|
|
|
// float to int
|
2008-08-12 15:04:03 -06:00
|
|
|
Mpflt *fv;
|
|
|
|
|
|
|
|
fv = n->val.u.fval;
|
|
|
|
if(mpcmpfltfix(fv, minintval[et]) < 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto bad2;
|
2008-08-12 15:04:03 -06:00
|
|
|
if(mpcmpfltfix(fv, maxintval[et]) > 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto bad2;
|
2008-10-16 16:59:31 -06:00
|
|
|
if(floor(mpgetflt(fv)) != mpgetflt(fv))
|
|
|
|
goto bad3;
|
2008-08-12 15:04:03 -06:00
|
|
|
n->val.u.xval = mal(sizeof(*n->val.u.xval));
|
|
|
|
mpmovefltfix(n->val.u.xval, fv);
|
2008-06-04 15:37:38 -06:00
|
|
|
n->val.ctype = CTINT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(isfloat[et]) {
|
2008-08-08 18:13:31 -06:00
|
|
|
// float to float
|
2008-12-01 18:22:05 -07:00
|
|
|
Mpflt *fv;
|
|
|
|
|
|
|
|
fv = n->val.u.fval;
|
|
|
|
if(mpcmpfltflt(fv, minfltval[et]) < 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto bad2;
|
2008-12-01 18:22:05 -07:00
|
|
|
if(mpcmpfltflt(fv, maxfltval[et]) > 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto bad2;
|
2008-12-02 18:03:47 -07:00
|
|
|
truncfltlit(fv, t);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
goto bad1;
|
|
|
|
}
|
2008-06-15 21:24:30 -06:00
|
|
|
n->type = t;
|
2008-12-02 18:03:47 -07:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
return;
|
|
|
|
|
|
|
|
bad1:
|
2008-10-16 16:59:31 -06:00
|
|
|
yyerror("illegal conversion of %W to %T", wt, t);
|
2008-06-04 15:37:38 -06:00
|
|
|
return;
|
|
|
|
|
|
|
|
bad2:
|
|
|
|
yyerror("overflow converting constant to %T", t);
|
|
|
|
return;
|
2008-10-16 16:59:31 -06:00
|
|
|
|
|
|
|
bad3:
|
|
|
|
yyerror("cannot convert non-integer constant to %T", t);
|
|
|
|
return;
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2008-12-12 14:10:36 -07:00
|
|
|
void
|
|
|
|
convlit(Node *n, Type *t)
|
|
|
|
{
|
|
|
|
convlit1(n, t, 0);
|
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
void
|
|
|
|
evconst(Node *n)
|
|
|
|
{
|
|
|
|
Node *nl, *nr;
|
2008-08-03 18:25:15 -06:00
|
|
|
int32 len;
|
2008-06-04 15:37:38 -06:00
|
|
|
String *str;
|
|
|
|
int wl, wr;
|
2008-08-08 18:13:31 -06:00
|
|
|
Mpint *xval;
|
|
|
|
Mpflt *fval;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
2008-10-06 14:52:23 -06:00
|
|
|
xval = nil;
|
|
|
|
fval = nil;
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
nl = n->left;
|
|
|
|
if(nl == N)
|
|
|
|
return;
|
|
|
|
|
|
|
|
wl = whatis(nl);
|
|
|
|
switch(wl) {
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
|
|
|
|
case Wlitint:
|
|
|
|
case Wlitfloat:
|
|
|
|
case Wlitbool:
|
|
|
|
case Wlitstr:
|
2008-12-09 18:52:41 -07:00
|
|
|
case Wlitnil:
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
nr = n->right;
|
|
|
|
if(nr == N)
|
|
|
|
goto unary;
|
|
|
|
|
|
|
|
wr = whatis(nr);
|
|
|
|
switch(wr) {
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
|
|
|
|
case Wlitint:
|
|
|
|
case Wlitfloat:
|
|
|
|
case Wlitbool:
|
|
|
|
case Wlitstr:
|
2008-12-09 18:52:41 -07:00
|
|
|
case Wlitnil:
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
}
|
2008-06-15 21:24:30 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
if(wl != wr) {
|
2008-07-05 18:43:25 -06:00
|
|
|
if(wl == Wlitfloat && wr == Wlitint) {
|
2008-08-08 18:13:31 -06:00
|
|
|
xval = nr->val.u.xval;
|
|
|
|
nr->val.u.fval = mal(sizeof(*nr->val.u.fval));
|
|
|
|
mpmovefixflt(nr->val.u.fval, xval);
|
2008-07-05 18:43:25 -06:00
|
|
|
nr->val.ctype = CTFLT;
|
|
|
|
wr = whatis(nr);
|
|
|
|
} else
|
|
|
|
if(wl == Wlitint && wr == Wlitfloat) {
|
2008-08-08 18:13:31 -06:00
|
|
|
xval = nl->val.u.xval;
|
|
|
|
nl->val.u.fval = mal(sizeof(*nl->val.u.fval));
|
|
|
|
mpmovefixflt(nl->val.u.fval, xval);
|
2008-07-05 18:43:25 -06:00
|
|
|
nl->val.ctype = CTFLT;
|
|
|
|
wl = whatis(nl);
|
|
|
|
} else {
|
2008-12-09 18:52:41 -07:00
|
|
|
yyerror("illegal combination of literals %O %W, %W", n->op, wl, wr);
|
2008-06-15 21:24:30 -06:00
|
|
|
return;
|
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
2008-08-08 18:13:31 -06:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
switch(TUP(n->op, wl)) {
|
|
|
|
default:
|
2008-12-09 18:52:41 -07:00
|
|
|
yyerror("illegal literal %O %W", n->op, wl);
|
2008-06-04 15:37:38 -06:00
|
|
|
return;
|
|
|
|
|
|
|
|
case TUP(OADD, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
mpaddfixfix(xval, nr->val.u.xval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case TUP(OSUB, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
mpsubfixfix(xval, nr->val.u.xval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case TUP(OMUL, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
mpmulfixfix(xval, nr->val.u.xval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case TUP(ODIV, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
mpdivfixfix(xval, nr->val.u.xval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case TUP(OMOD, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
mpmodfixfix(xval, nr->val.u.xval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
2008-08-08 18:13:31 -06:00
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
case TUP(OLSH, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
mplshfixfix(xval, nr->val.u.xval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case TUP(ORSH, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
mprshfixfix(xval, nr->val.u.xval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case TUP(OOR, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
mporfixfix(xval, nr->val.u.xval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case TUP(OAND, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
mpandfixfix(xval, nr->val.u.xval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
2008-07-27 14:09:15 -06:00
|
|
|
case TUP(OXOR, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
mpxorfixfix(xval, nr->val.u.xval);
|
2008-07-27 14:09:15 -06:00
|
|
|
break;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
case TUP(OADD, Wlitfloat):
|
2008-08-08 18:13:31 -06:00
|
|
|
mpaddfltflt(fval, nr->val.u.fval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case TUP(OSUB, Wlitfloat):
|
2008-08-08 18:13:31 -06:00
|
|
|
mpsubfltflt(fval, nr->val.u.fval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case TUP(OMUL, Wlitfloat):
|
2008-08-08 18:13:31 -06:00
|
|
|
mpmulfltflt(fval, nr->val.u.fval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case TUP(ODIV, Wlitfloat):
|
2008-08-08 18:13:31 -06:00
|
|
|
mpdivfltflt(fval, nr->val.u.fval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
|
2008-12-09 18:52:41 -07:00
|
|
|
case TUP(OEQ, Wlitnil):
|
|
|
|
goto settrue;
|
|
|
|
case TUP(ONE, Wlitnil):
|
|
|
|
goto setfalse;
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
case TUP(OEQ, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfixfix(xval, nr->val.u.xval) == 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
case TUP(ONE, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfixfix(xval, nr->val.u.xval) != 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
case TUP(OLT, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfixfix(xval, nr->val.u.xval) < 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
case TUP(OLE, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfixfix(xval, nr->val.u.xval) <= 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
case TUP(OGE, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfixfix(xval, nr->val.u.xval) >= 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
case TUP(OGT, Wlitint):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfixfix(xval, nr->val.u.xval) > 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
|
|
|
|
case TUP(OEQ, Wlitfloat):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfltflt(fval, nr->val.u.fval) == 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
case TUP(ONE, Wlitfloat):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfltflt(fval, nr->val.u.fval) != 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
case TUP(OLT, Wlitfloat):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfltflt(fval, nr->val.u.fval) < 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
case TUP(OLE, Wlitfloat):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfltflt(fval, nr->val.u.fval) <= 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
case TUP(OGE, Wlitfloat):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfltflt(fval, nr->val.u.fval) >= 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
case TUP(OGT, Wlitfloat):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(mpcmpfltflt(fval, nr->val.u.fval) > 0)
|
2008-06-04 15:37:38 -06:00
|
|
|
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):
|
2008-08-08 18:13:31 -06:00
|
|
|
len = nl->val.u.sval->len + nr->val.u.sval->len;
|
2008-06-04 15:37:38 -06:00
|
|
|
str = mal(sizeof(*str) + len);
|
|
|
|
str->len = len;
|
2008-08-08 18:13:31 -06:00
|
|
|
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);
|
2008-06-04 15:37:38 -06:00
|
|
|
str->len = len;
|
2008-08-08 18:13:31 -06:00
|
|
|
nl->val.u.sval = str;
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
|
|
|
|
case TUP(OOROR, Wlitbool):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(nl->val.u.bval || nr->val.u.bval)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
case TUP(OANDAND, Wlitbool):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(nl->val.u.bval && nr->val.u.bval)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
}
|
2008-08-09 18:29:26 -06:00
|
|
|
goto ret;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
settrue:
|
|
|
|
*n = *booltrue;
|
|
|
|
return;
|
|
|
|
|
|
|
|
setfalse:
|
|
|
|
*n = *boolfalse;
|
|
|
|
return;
|
|
|
|
|
|
|
|
unary:
|
2008-08-09 18:29:26 -06:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2008-06-04 15:37:38 -06:00
|
|
|
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):
|
2008-08-09 18:29:26 -06:00
|
|
|
mpnegfix(xval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case TUP(OCOM, Wlitint):
|
2008-08-09 18:29:26 -06:00
|
|
|
mpcomfix(xval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
|
|
|
|
case TUP(OPLUS, Wlitfloat):
|
|
|
|
break;
|
|
|
|
case TUP(OMINUS, Wlitfloat):
|
2008-08-09 18:29:26 -06:00
|
|
|
mpnegflt(fval);
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
|
|
|
|
case TUP(ONOT, Wlitbool):
|
2008-08-08 18:13:31 -06:00
|
|
|
if(nl->val.u.bval)
|
2008-06-04 15:37:38 -06:00
|
|
|
goto settrue;
|
|
|
|
goto setfalse;
|
|
|
|
}
|
2008-08-09 18:29:26 -06:00
|
|
|
|
|
|
|
ret:
|
2008-06-04 15:37:38 -06:00
|
|
|
*n = *nl;
|
2008-08-09 18:29:26 -06:00
|
|
|
|
|
|
|
// second half of dance
|
|
|
|
if(wl == Wlitint) {
|
|
|
|
n->val.u.xval = xval;
|
|
|
|
} else
|
|
|
|
if(wl == Wlitfloat) {
|
|
|
|
n->val.u.fval = fval;
|
2008-12-02 18:03:47 -07:00
|
|
|
truncfltlit(fval, n->type);
|
2008-08-09 18:29:26 -06:00
|
|
|
}
|
2008-06-04 15:37:38 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
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:
|
2008-10-29 13:46:44 -06:00
|
|
|
n->type = types[TINT];
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case CTFLT:
|
2008-10-29 13:46:44 -06:00
|
|
|
n->type = types[TFLOAT];
|
2008-06-04 15:37:38 -06:00
|
|
|
break;
|
|
|
|
case CTBOOL:
|
|
|
|
n->type = types[TBOOL];
|
|
|
|
break;
|
|
|
|
case CTSTR:
|
|
|
|
n->type = types[TSTRING];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
cmpslit(Node *l, Node *r)
|
|
|
|
{
|
2008-08-03 18:25:15 -06:00
|
|
|
int32 l1, l2, i, m;
|
2008-06-04 15:37:38 -06:00
|
|
|
char *s1, *s2;
|
|
|
|
|
2008-08-08 18:13:31 -06:00
|
|
|
l1 = l->val.u.sval->len;
|
|
|
|
l2 = r->val.u.sval->len;
|
|
|
|
s1 = l->val.u.sval->s;
|
|
|
|
s2 = r->val.u.sval->s;
|
2008-06-04 15:37:38 -06:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2008-12-14 19:45:00 -07:00
|
|
|
|
|
|
|
int
|
|
|
|
smallintconst(Node *n)
|
|
|
|
{
|
|
|
|
if(n->op == OLITERAL)
|
|
|
|
switch(simtype[n->type->etype]) {
|
|
|
|
case TINT8:
|
|
|
|
case TUINT8:
|
|
|
|
case TINT16:
|
|
|
|
case TUINT16:
|
|
|
|
case TINT32:
|
|
|
|
case TUINT32:
|
|
|
|
case TBOOL:
|
|
|
|
case TPTR32:
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|