summaryrefslogtreecommitdiff
path: root/src/old/c/const.c
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2008-06-04 14:46:07 -0700
committerRob Pike <r@golang.org>2008-06-04 14:46:07 -0700
commit5cf1e37b96825023b2da8de9be3a07d1987bb306 (patch)
treefda9e615c7d6ddb748cee567027fae05ba9215ae /src/old/c/const.c
parent0a2697043d69739b27b6ba872b2092a4c2bb61a8 (diff)
downloadgolang-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.c377
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;
+}