//printf("Expression::isConst(): %s\n", e.toChars());
switch (e.op)
{
- case TOK.int64:
- case TOK.float64:
- case TOK.complex80:
+ case EXP.int64:
+ case EXP.float64:
+ case EXP.complex80:
return 1;
- case TOK.null_:
+ case EXP.null_:
return 0;
- case TOK.symbolOffset:
+ case EXP.symbolOffset:
return 2;
default:
return 0;
}
/**********************************
- * Initialize a TOK.cantExpression Expression.
+ * Initialize a EXP.cantExpression Expression.
* Params:
* ue = where to write it
*/
void cantExp(out UnionExp ue)
{
- emplaceExp!(CTFEExp)(&ue, TOK.cantExpression);
+ emplaceExp!(CTFEExp)(&ue, EXP.cantExpression);
}
/* =============================== constFold() ============================== */
{
UnionExp ue = void;
Loc loc = e1.loc;
- emplaceExp!(IntegerExp)(&ue, loc, e1.isBool(false) ? 1 : 0, type);
+ emplaceExp!(IntegerExp)(&ue, loc, e1.toBool().hasValue(false) ? 1 : 0, type);
return ue;
}
{
UnionExp ue = void;
Loc loc = e1.loc;
- emplaceExp!(IntegerExp)(&ue, loc, e1.isBool(true) ? 1 : 0, type);
+ emplaceExp!(IntegerExp)(&ue, loc, e1.toBool().hasValue(true) ? 1 : 0, type);
return ue;
}
}
emplaceExp!(ComplexExp)(&ue, loc, v, type);
}
- else if (e1.op == TOK.symbolOffset)
+ else if (e1.op == EXP.symbolOffset)
{
SymOffExp soe = cast(SymOffExp)e1;
emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset + e2.toInteger());
ue.exp().type = type;
}
- else if (e2.op == TOK.symbolOffset)
+ else if (e2.op == EXP.symbolOffset)
{
SymOffExp soe = cast(SymOffExp)e2;
emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset + e1.toInteger());
}
emplaceExp!(ComplexExp)(&ue, loc, v, type);
}
- else if (e1.op == TOK.symbolOffset)
+ else if (e1.op == EXP.symbolOffset)
{
SymOffExp soe = cast(SymOffExp)e1;
emplaceExp!(SymOffExp)(&ue, loc, soe.var, soe.offset - e2.toInteger());
return ue;
}
-/* Also returns TOK.cantExpression if cannot be computed.
+/* Also returns EXP.cantExpression if cannot be computed.
*/
-UnionExp Equal(TOK op, const ref Loc loc, Type type, Expression e1, Expression e2)
+UnionExp Equal(EXP op, const ref Loc loc, Type type, Expression e1, Expression e2)
{
UnionExp ue = void;
int cmp = 0;
real_t r1 = CTFloat.zero;
real_t r2 = CTFloat.zero;
//printf("Equal(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars());
- assert(op == TOK.equal || op == TOK.notEqual);
- if (e1.op == TOK.null_)
+ assert(op == EXP.equal || op == EXP.notEqual);
+ if (e1.op == EXP.null_)
{
- if (e2.op == TOK.null_)
+ if (e2.op == EXP.null_)
cmp = 1;
- else if (e2.op == TOK.string_)
+ else if (e2.op == EXP.string_)
{
StringExp es2 = cast(StringExp)e2;
cmp = (0 == es2.len);
}
- else if (e2.op == TOK.arrayLiteral)
+ else if (e2.op == EXP.arrayLiteral)
{
ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2;
cmp = !es2.elements || (0 == es2.elements.dim);
return ue;
}
}
- else if (e2.op == TOK.null_)
+ else if (e2.op == EXP.null_)
{
- if (e1.op == TOK.string_)
+ if (e1.op == EXP.string_)
{
StringExp es1 = cast(StringExp)e1;
cmp = (0 == es1.len);
}
- else if (e1.op == TOK.arrayLiteral)
+ else if (e1.op == EXP.arrayLiteral)
{
ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1;
cmp = !es1.elements || (0 == es1.elements.dim);
return ue;
}
}
- else if (e1.op == TOK.string_ && e2.op == TOK.string_)
+ else if (e1.op == EXP.string_ && e2.op == EXP.string_)
{
StringExp es1 = cast(StringExp)e1;
StringExp es2 = cast(StringExp)e2;
else
cmp = 0;
}
- else if (e1.op == TOK.arrayLiteral && e2.op == TOK.arrayLiteral)
+ else if (e1.op == EXP.arrayLiteral && e2.op == EXP.arrayLiteral)
{
ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1;
ArrayLiteralExp es2 = cast(ArrayLiteralExp)e2;
{
auto ee1 = es1[i];
auto ee2 = es2[i];
- ue = Equal(TOK.equal, loc, Type.tint32, ee1, ee2);
+ ue = Equal(EXP.equal, loc, Type.tint32, ee1, ee2);
if (CTFEExp.isCantExp(ue.exp()))
return ue;
cmp = cast(int)ue.exp().toInteger();
}
}
}
- else if (e1.op == TOK.arrayLiteral && e2.op == TOK.string_)
+ else if (e1.op == EXP.arrayLiteral && e2.op == EXP.string_)
{
// Swap operands and use common code
Expression etmp = e1;
e2 = etmp;
goto Lsa;
}
- else if (e1.op == TOK.string_ && e2.op == TOK.arrayLiteral)
+ else if (e1.op == EXP.string_ && e2.op == EXP.arrayLiteral)
{
Lsa:
StringExp es1 = cast(StringExp)e1;
}
}
}
- else if (e1.op == TOK.structLiteral && e2.op == TOK.structLiteral)
+ else if (e1.op == EXP.structLiteral && e2.op == EXP.structLiteral)
{
StructLiteralExp es1 = cast(StructLiteralExp)e1;
StructLiteralExp es2 = cast(StructLiteralExp)e2;
cmp = 0;
break;
}
- ue = Equal(TOK.equal, loc, Type.tint32, ee1, ee2);
- if (ue.exp().op == TOK.cantExpression)
+ ue = Equal(EXP.equal, loc, Type.tint32, ee1, ee2);
+ if (ue.exp().op == EXP.cantExpression)
return ue;
cmp = cast(int)ue.exp().toInteger();
if (cmp == 0)
cantExp(ue);
return ue;
}
- if (op == TOK.notEqual)
+ if (op == EXP.notEqual)
cmp ^= 1;
emplaceExp!(IntegerExp)(&ue, loc, cmp, type);
return ue;
}
-UnionExp Identity(TOK op, const ref Loc loc, Type type, Expression e1, Expression e2)
+UnionExp Identity(EXP op, const ref Loc loc, Type type, Expression e1, Expression e2)
{
UnionExp ue = void;
int cmp;
- if (e1.op == TOK.null_)
+ if (e1.op == EXP.null_)
{
- cmp = (e2.op == TOK.null_);
+ cmp = (e2.op == EXP.null_);
}
- else if (e2.op == TOK.null_)
+ else if (e2.op == EXP.null_)
{
cmp = 0;
}
- else if (e1.op == TOK.symbolOffset && e2.op == TOK.symbolOffset)
+ else if (e1.op == EXP.symbolOffset && e2.op == EXP.symbolOffset)
{
SymOffExp es1 = cast(SymOffExp)e1;
SymOffExp es2 = cast(SymOffExp)e2;
}
else
{
- ue = Equal((op == TOK.identity) ? TOK.equal : TOK.notEqual, loc, type, e1, e2);
+ ue = Equal((op == EXP.identity) ? EXP.equal : EXP.notEqual, loc, type, e1, e2);
return ue;
}
}
- if (op == TOK.notIdentity)
+ if (op == EXP.notIdentity)
cmp ^= 1;
emplaceExp!(IntegerExp)(&ue, loc, cmp, type);
return ue;
}
-UnionExp Cmp(TOK op, const ref Loc loc, Type type, Expression e1, Expression e2)
+UnionExp Cmp(EXP op, const ref Loc loc, Type type, Expression e1, Expression e2)
{
UnionExp ue = void;
dinteger_t n;
real_t r1 = CTFloat.zero;
real_t r2 = CTFloat.zero;
//printf("Cmp(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars());
- if (e1.op == TOK.string_ && e2.op == TOK.string_)
+ if (e1.op == EXP.string_ && e2.op == EXP.string_)
{
StringExp es1 = cast(StringExp)e1;
StringExp es2 = cast(StringExp)e2;
return ue;
}
-/* Also returns TOK.cantExpression if cannot be computed.
+/* Also returns EXP.cantExpression if cannot be computed.
* to: type to cast to
* type: type to paint the result
*/
emplaceExp!(UnionExp)(&ue, e1);
return ue;
}
- if (e1.op == TOK.vector && (cast(TypeVector)e1.type).basetype.equals(type) && type.equals(to))
+ if (e1.op == EXP.vector && (cast(TypeVector)e1.type).basetype.equals(type) && type.equals(to))
{
Expression ex = (cast(VectorExp)e1).e1;
emplaceExp!(UnionExp)(&ue, ex);
}
/* Allow casting from one string type to another
*/
- if (e1.op == TOK.string_)
+ if (e1.op == EXP.string_)
{
if (tb.ty == Tarray && typeb.ty == Tarray && tb.nextOf().size() == typeb.nextOf().size())
{
goto L1;
}
}
- if (e1.op == TOK.arrayLiteral && typeb == tb)
+ if (e1.op == EXP.arrayLiteral && typeb == tb)
{
L1:
Expression ex = expType(to, e1);
{
cantExp(ue);
}
- else if (tb.ty == Tstruct && e1.op == TOK.int64)
+ else if (tb.ty == Tstruct && e1.op == EXP.int64)
{
// Struct = 0;
StructDeclaration sd = tb.toDsymbol(null).isStructDeclaration();
UnionExp zero;
emplaceExp!(IntegerExp)(&zero, 0);
ue = Cast(loc, v.type, v.type, zero.exp());
- if (ue.exp().op == TOK.cantExpression)
+ if (ue.exp().op == EXP.cantExpression)
return ue;
elements.push(ue.exp().copy());
}
{
UnionExp ue = void;
Loc loc = e1.loc;
- if (e1.op == TOK.string_)
+ if (e1.op == EXP.string_)
{
StringExp es1 = cast(StringExp)e1;
emplaceExp!(IntegerExp)(&ue, loc, es1.len, type);
}
- else if (e1.op == TOK.arrayLiteral)
+ else if (e1.op == EXP.arrayLiteral)
{
ArrayLiteralExp ale = cast(ArrayLiteralExp)e1;
size_t dim = ale.elements ? ale.elements.dim : 0;
emplaceExp!(IntegerExp)(&ue, loc, dim, type);
}
- else if (e1.op == TOK.assocArrayLiteral)
+ else if (e1.op == EXP.assocArrayLiteral)
{
AssocArrayLiteralExp ale = cast(AssocArrayLiteralExp)e1;
size_t dim = ale.keys.dim;
return ue;
}
-/* Also return TOK.cantExpression if this fails
+/* Also return EXP.cantExpression if this fails
*/
UnionExp Index(Type type, Expression e1, Expression e2)
{
Loc loc = e1.loc;
//printf("Index(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars());
assert(e1.type);
- if (e1.op == TOK.string_ && e2.op == TOK.int64)
+ if (e1.op == EXP.string_ && e2.op == EXP.int64)
{
StringExp es1 = cast(StringExp)e1;
uinteger_t i = e2.toInteger();
emplaceExp!(IntegerExp)(&ue, loc, es1.charAt(i), type);
}
}
- else if (e1.type.toBasetype().ty == Tsarray && e2.op == TOK.int64)
+ else if (e1.type.toBasetype().ty == Tsarray && e2.op == EXP.int64)
{
TypeSArray tsa = cast(TypeSArray)e1.type.toBasetype();
uinteger_t length = tsa.dim.toInteger();
e1.error("array index %llu is out of bounds `%s[0 .. %llu]`", i, e1.toChars(), length);
emplaceExp!(ErrorExp)(&ue);
}
- else if (e1.op == TOK.arrayLiteral)
+ else if (e1.op == EXP.arrayLiteral)
{
ArrayLiteralExp ale = cast(ArrayLiteralExp)e1;
auto e = ale[cast(size_t)i];
else
cantExp(ue);
}
- else if (e1.type.toBasetype().ty == Tarray && e2.op == TOK.int64)
+ else if (e1.type.toBasetype().ty == Tarray && e2.op == EXP.int64)
{
uinteger_t i = e2.toInteger();
- if (e1.op == TOK.arrayLiteral)
+ if (e1.op == EXP.arrayLiteral)
{
ArrayLiteralExp ale = cast(ArrayLiteralExp)e1;
if (i >= ale.elements.dim)
else
cantExp(ue);
}
- else if (e1.op == TOK.assocArrayLiteral)
+ else if (e1.op == EXP.assocArrayLiteral)
{
AssocArrayLiteralExp ae = cast(AssocArrayLiteralExp)e1;
/* Search the keys backwards, in case there are duplicate keys
{
i--;
Expression ekey = (*ae.keys)[i];
- ue = Equal(TOK.equal, loc, Type.tbool, ekey, e2);
+ ue = Equal(EXP.equal, loc, Type.tbool, ekey, e2);
if (CTFEExp.isCantExp(ue.exp()))
return ue;
- if (ue.exp().isBool(true))
+ if (ue.exp().toBool().hasValue(true))
{
Expression e = (*ae.values)[i];
e.type = type;
return ue;
}
-/* Also return TOK.cantExpression if this fails
+/* Also return EXP.cantExpression if this fails
*/
UnionExp Slice(Type type, Expression e1, Expression lwr, Expression upr)
{
newupr <= upr);
}
- if (e1.op == TOK.string_ && lwr.op == TOK.int64 && upr.op == TOK.int64)
+ if (e1.op == EXP.string_ && lwr.op == EXP.int64 && upr.op == EXP.int64)
{
StringExp es1 = cast(StringExp)e1;
const uinteger_t ilwr = lwr.toInteger();
es.type = type;
}
}
- else if (e1.op == TOK.arrayLiteral && lwr.op == TOK.int64 && upr.op == TOK.int64 && !hasSideEffect(e1))
+ else if (e1.op == EXP.arrayLiteral && lwr.op == EXP.int64 && upr.op == EXP.int64 && !hasSideEffect(e1))
{
ArrayLiteralExp es1 = cast(ArrayLiteralExp)e1;
const uinteger_t ilwr = lwr.toInteger();
}
}
- if (e1.op == TOK.arrayLiteral)
+ if (e1.op == EXP.arrayLiteral)
append(cast(ArrayLiteralExp)e1);
else
elems.push(e1);
if (e2)
{
- if (e2.op == TOK.arrayLiteral)
+ if (e2.op == EXP.arrayLiteral)
append(cast(ArrayLiteralExp)e2);
else
elems.push(e2);
return elems;
}
-/* Also return TOK.cantExpression if this fails
+/* Also return EXP.cantExpression if this fails
*/
UnionExp Cat(const ref Loc loc, Type type, Expression e1, Expression e2)
{
Type t2 = e2.type.toBasetype();
//printf("Cat(e1 = %s, e2 = %s)\n", e1.toChars(), e2.toChars());
//printf("\tt1 = %s, t2 = %s, type = %s\n", t1.toChars(), t2.toChars(), type.toChars());
- if (e1.op == TOK.null_ && (e2.op == TOK.int64 || e2.op == TOK.structLiteral))
+ if (e1.op == EXP.null_ && (e2.op == EXP.int64 || e2.op == EXP.structLiteral))
{
e = e2;
t = t1;
goto L2;
}
- else if ((e1.op == TOK.int64 || e1.op == TOK.structLiteral) && e2.op == TOK.null_)
+ else if ((e1.op == EXP.int64 || e1.op == EXP.structLiteral) && e2.op == EXP.null_)
{
e = e1;
t = t2;
assert(ue.exp().type);
return ue;
}
- else if (e1.op == TOK.null_ && e2.op == TOK.null_)
+ else if (e1.op == EXP.null_ && e2.op == EXP.null_)
{
if (type == e1.type)
{
assert(ue.exp().type);
return ue;
}
- else if (e1.op == TOK.string_ && e2.op == TOK.string_)
+ else if (e1.op == EXP.string_ && e2.op == EXP.string_)
{
// Concatenate the strings
StringExp es1 = cast(StringExp)e1;
assert(ue.exp().type);
return ue;
}
- else if (e2.op == TOK.string_ && e1.op == TOK.arrayLiteral && t1.nextOf().isintegral())
+ else if (e2.op == EXP.string_ && e1.op == EXP.arrayLiteral && t1.nextOf().isintegral())
{
// [chars] ~ string --> [chars]
StringExp es = cast(StringExp)e2;
assert(ue.exp().type);
return ue;
}
- else if (e1.op == TOK.string_ && e2.op == TOK.arrayLiteral && t2.nextOf().isintegral())
+ else if (e1.op == EXP.string_ && e2.op == EXP.arrayLiteral && t2.nextOf().isintegral())
{
// string ~ [chars] --> [chars]
StringExp es = cast(StringExp)e1;
assert(ue.exp().type);
return ue;
}
- else if (e1.op == TOK.string_ && e2.op == TOK.int64)
+ else if (e1.op == EXP.string_ && e2.op == EXP.int64)
{
// string ~ char --> string
StringExp es1 = cast(StringExp)e1;
assert(ue.exp().type);
return ue;
}
- else if (e1.op == TOK.int64 && e2.op == TOK.string_)
+ else if (e1.op == EXP.int64 && e2.op == EXP.string_)
{
// [w|d]?char ~ string --> string
// We assume that we only ever prepend one char of the same type
assert(ue.exp().type);
return ue;
}
- else if (e1.op == TOK.arrayLiteral && e2.op == TOK.arrayLiteral && t1.nextOf().equals(t2.nextOf()))
+ else if (e1.op == EXP.arrayLiteral && e2.op == EXP.arrayLiteral && t1.nextOf().equals(t2.nextOf()))
{
// Concatenate the arrays
auto elems = copyElements(e1, e2);
assert(ue.exp().type);
return ue;
}
- else if (e1.op == TOK.arrayLiteral && e2.op == TOK.null_ && t1.nextOf().equals(t2.nextOf()))
+ else if (e1.op == EXP.arrayLiteral && e2.op == EXP.null_ && t1.nextOf().equals(t2.nextOf()))
{
e = e1;
goto L3;
}
- else if (e1.op == TOK.null_ && e2.op == TOK.arrayLiteral && t1.nextOf().equals(t2.nextOf()))
+ else if (e1.op == EXP.null_ && e2.op == EXP.arrayLiteral && t1.nextOf().equals(t2.nextOf()))
{
e = e2;
L3:
assert(ue.exp().type);
return ue;
}
- else if ((e1.op == TOK.arrayLiteral || e1.op == TOK.null_) && e1.type.toBasetype().nextOf() && e1.type.toBasetype().nextOf().equals(e2.type))
+ else if ((e1.op == EXP.arrayLiteral || e1.op == EXP.null_) && e1.type.toBasetype().nextOf() && e1.type.toBasetype().nextOf().equals(e2.type))
{
- auto elems = (e1.op == TOK.arrayLiteral)
+ auto elems = (e1.op == EXP.arrayLiteral)
? copyElements(e1) : new Expressions();
elems.push(e2);
assert(ue.exp().type);
return ue;
}
- else if (e2.op == TOK.arrayLiteral && e2.type.toBasetype().nextOf().equals(e1.type))
+ else if (e2.op == EXP.arrayLiteral && e2.type.toBasetype().nextOf().equals(e1.type))
{
auto elems = copyElements(e1, e2);
assert(ue.exp().type);
return ue;
}
- else if (e1.op == TOK.null_ && e2.op == TOK.string_)
+ else if (e1.op == EXP.null_ && e2.op == EXP.string_)
{
t = e1.type;
e = e2;
goto L1;
}
- else if (e1.op == TOK.string_ && e2.op == TOK.null_)
+ else if (e1.op == EXP.string_ && e2.op == EXP.null_)
{
e = e1;
t = e2.type;
{
//printf("Ptr(e1 = %s)\n", e1.toChars());
UnionExp ue = void;
- if (e1.op == TOK.add)
+ if (e1.op == EXP.add)
{
AddExp ae = cast(AddExp)e1;
- if (ae.e1.op == TOK.address && ae.e2.op == TOK.int64)
+ if (ae.e1.op == EXP.address && ae.e2.op == EXP.int64)
{
AddrExp ade = cast(AddrExp)ae.e1;
- if (ade.e1.op == TOK.structLiteral)
+ if (ade.e1.op == EXP.structLiteral)
{
StructLiteralExp se = cast(StructLiteralExp)ade.e1;
uint offset = cast(uint)ae.e2.toInteger();