Mercurial > projects > ddmd
diff dmd/expression/Equal.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | cab4c37afb89 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/expression/Equal.d Sat Oct 24 08:42:06 2009 +0400 @@ -0,0 +1,209 @@ +module dmd.expression.Equal; + +import dmd.Expression; +import dmd.Type; +import dmd.TOK; +import dmd.Loc; +import dmd.StringExp; +import dmd.GlobalExpressions; +import dmd.ArrayLiteralExp; +import dmd.StructLiteralExp; +import dmd.Global; +import dmd.IntegerExp; + +import core.stdc.string; + +/* Also returns EXP_CANT_INTERPRET if cannot be computed. + */ +Expression Equal(TOK op, Type type, Expression e1, Expression e2) +{ + Expression e; + Loc loc = e1.loc; + bool cmp; + real r1; + real r2; + + //printf("Equal(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars()); + + assert(op == TOK.TOKequal || op == TOK.TOKnotequal); + + if (e1.op == TOK.TOKnull) + { + if (e2.op == TOK.TOKnull) + cmp = true; + else if (e2.op == TOK.TOKstring) + { StringExp es2 = cast(StringExp)e2; + cmp = (0 == es2.len); + } + else if (e2.op == TOK.TOKarrayliteral) + { + ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2; + cmp = !es2.elements || (0 == es2.elements.dim); + } + else + return EXP_CANT_INTERPRET; + } + else if (e2.op == TOK.TOKnull) + { + if (e1.op == TOK.TOKstring) + { + StringExp es1 = cast(StringExp)e1; + cmp = (0 == es1.len); + } + else if (e1.op == TOK.TOKarrayliteral) + { + ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1; + cmp = !es1.elements || (0 == es1.elements.dim); + } + else + return EXP_CANT_INTERPRET; + } + else if (e1.op == TOK.TOKstring && e2.op == TOK.TOKstring) + { + StringExp es1 = cast(StringExp)e1; + StringExp es2 = cast(StringExp)e2; + + if (es1.sz != es2.sz) + { + assert(global.errors); + return EXP_CANT_INTERPRET; + } + if (es1.len == es2.len && memcmp(es1.string_, es2.string_, es1.sz * es1.len) == 0) + cmp = true; + else + cmp = false; + } + else if (e1.op == TOK.TOKarrayliteral && e2.op == TOK.TOKarrayliteral) + { + ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1; + ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2; + + if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim)) + cmp = true; // both arrays are empty + else if (!es1.elements || !es2.elements) + cmp = false; + else if (es1.elements.dim != es2.elements.dim) + cmp = false; + else + { + for (size_t i = 0; i < es1.elements.dim; i++) + { + Expression ee1 = cast(Expression)es1.elements.data[i]; + Expression ee2 = cast(Expression)es2.elements.data[i]; + + Expression v = Equal(TOK.TOKequal, Type.tint32, ee1, ee2); + if (v == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; + long tmp = v.toInteger(); + cmp = (tmp != 0); + if (!cmp) + break; + } + } + } + else if (e1.op == TOK.TOKarrayliteral && e2.op == TOK.TOKstring) + { + // Swap operands and use common code + Expression ee = e1; + e1 = e2; + e2 = ee; + goto Lsa; + } + else if (e1.op == TOK.TOKstring && e2.op == TOK.TOKarrayliteral) + { + Lsa: + StringExp es1 = cast(StringExp)e1; + ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2; + size_t dim1 = es1.len; + size_t dim2 = es2.elements ? es2.elements.dim : 0; + if (dim1 != dim2) + cmp = false; + else + { + for (size_t i = 0; i < dim1; i++) + { + ulong c = es1.charAt(i); + Expression ee2 = cast(Expression)es2.elements.data[i]; + if (ee2.isConst() != 1) + return EXP_CANT_INTERPRET; + cmp = (c == ee2.toInteger()); + if (!cmp) + break; + } + } + } + else if (e1.op == TOK.TOKstructliteral && e2.op == TOK.TOKstructliteral) + { + StructLiteralExp es1 = cast(StructLiteralExp)e1; + StructLiteralExp es2 = cast(StructLiteralExp)e2; + + if (es1.sd != es2.sd) + cmp = false; + else if ((!es1.elements || !es1.elements.dim) && (!es2.elements || !es2.elements.dim)) + cmp = true; // both arrays are empty + else if (!es1.elements || !es2.elements) + cmp = false; + else if (es1.elements.dim != es2.elements.dim) + cmp = false; + else + { + cmp = true; + for (size_t i = 0; i < es1.elements.dim; i++) + { + Expression ee1 = cast(Expression)es1.elements.data[i]; + Expression ee2 = cast(Expression)es2.elements.data[i]; + + if (ee1 == ee2) + continue; + if (!ee1 || !ee2) + { + cmp = false; + break; + } + Expression v = Equal(TOK.TOKequal, Type.tint32, ee1, ee2); + if (v == EXP_CANT_INTERPRET) + return EXP_CANT_INTERPRET; + long tmp = v.toInteger(); + cmp = (tmp != 0); + if (!cmp) + break; + } + } + } +///static if (false) { +/// else if (e1.op == TOKarrayliteral && e2.op == TOKstring) +/// { +/// } +///} + else if (e1.isConst() != 1 || e2.isConst() != 1) + return EXP_CANT_INTERPRET; + else if (e1.type.isreal()) + { + r1 = e1.toReal(); + r2 = e2.toReal(); + goto L1; + } + else if (e1.type.isimaginary()) + { + r1 = e1.toImaginary(); + r2 = e2.toImaginary(); + L1: + cmp = (r1 == r2); + } + else if (e1.type.iscomplex()) + { + cmp = (e1.toComplex() == e2.toComplex()); + } + else if (e1.type.isintegral()) + { + cmp = (e1.toInteger() == e2.toInteger()); + } + else + return EXP_CANT_INTERPRET; + if (op == TOK.TOKnotequal) + cmp = !cmp; + + e = new IntegerExp(loc, cmp, type); + + return e; +} \ No newline at end of file