// 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;
}
