diff options
author | Rob Pike <r@golang.org> | 2008-06-04 14:46:07 -0700 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2008-06-04 14:46:07 -0700 |
commit | 5cf1e37b96825023b2da8de9be3a07d1987bb306 (patch) | |
tree | fda9e615c7d6ddb748cee567027fae05ba9215ae /src/old/c/const.c | |
parent | 0a2697043d69739b27b6ba872b2092a4c2bb61a8 (diff) | |
download | golang-5cf1e37b96825023b2da8de9be3a07d1987bb306.tar.gz |
move old code into 'old' directory
add src/test dir
SVN=121166
Diffstat (limited to 'src/old/c/const.c')
-rw-r--r-- | src/old/c/const.c | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/src/old/c/const.c b/src/old/c/const.c new file mode 100644 index 000000000..ff1f5221d --- /dev/null +++ b/src/old/c/const.c @@ -0,0 +1,377 @@ +// 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; +} |