From efd99ae6b29f3e0ec0a75e5969b7f9775552502d Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Thu, 24 Apr 2014 02:29:55 -0700 Subject: [PATCH] refactor IntegerExp --- src/cast.c | 78 +++++++++++------------------ src/ctfeexpr.c | 45 +++++++++-------- src/e2ir.c | 2 +- src/expression.c | 127 ++++++++++++++++++----------------------------- src/expression.h | 8 ++- src/interpret.c | 14 +++--- src/statement.c | 4 +- src/template.c | 2 +- src/todt.c | 5 +- 9 files changed, 120 insertions(+), 165 deletions(-) diff --git a/src/cast.c b/src/cast.c index 254e937945d1..0a2a80446e79 100644 --- a/src/cast.c +++ b/src/cast.c @@ -300,39 +300,16 @@ MATCH implicitConvTo(Expression *e, Type *t) switch (ty) { case Tbool: - e->value &= 1; - ty = Tint32; - break; - case Tint8: - e->value = (signed char)e->value; - ty = Tint32; - break; - case Tchar: case Tuns8: - e->value &= 0xFF; - ty = Tint32; - break; - case Tint16: - e->value = (short)e->value; - ty = Tint32; - break; - case Tuns16: case Twchar: - e->value &= 0xFFFF; ty = Tint32; break; - case Tint32: - e->value = (int)e->value; - break; - - case Tuns32: case Tdchar: - e->value &= 0xFFFFFFFF; ty = Tuns32; break; @@ -341,41 +318,42 @@ MATCH implicitConvTo(Expression *e, Type *t) } // Only allow conversion if no change in value + dinteger_t value = e->toInteger(); switch (toty) { case Tbool: - if ((e->value & 1) != e->value) + if ((value & 1) != value) return; break; case Tint8: - if (ty == Tuns64 && e->value & ~0x7FUL) + if (ty == Tuns64 && value & ~0x7FUL) return; - else if ((signed char)e->value != e->value) + else if ((signed char)value != value) return; break; case Tchar: - if ((oldty == Twchar || oldty == Tdchar) && e->value > 0x7F) + if ((oldty == Twchar || oldty == Tdchar) && value > 0x7F) return; case Tuns8: - //printf("value = %llu %llu\n", (dinteger_t)(unsigned char)e->value, e->value); - if ((unsigned char)e->value != e->value) + //printf("value = %llu %llu\n", (dinteger_t)(unsigned char)value, value); + if ((unsigned char)value != value) return; break; case Tint16: - if (ty == Tuns64 && e->value & ~0x7FFFUL) + if (ty == Tuns64 && value & ~0x7FFFUL) return; - else if ((short)e->value != e->value) + else if ((short)value != value) return; break; case Twchar: - if (oldty == Tdchar && e->value > 0xD7FF && e->value < 0xE000) + if (oldty == Tdchar && value > 0xD7FF && value < 0xE000) return; case Tuns16: - if ((unsigned short)e->value != e->value) + if ((unsigned short)value != value) return; break; @@ -383,9 +361,9 @@ MATCH implicitConvTo(Expression *e, Type *t) if (ty == Tuns32) { } - else if (ty == Tuns64 && e->value & ~0x7FFFFFFFUL) + else if (ty == Tuns64 && value & ~0x7FFFFFFFUL) return; - else if ((int)e->value != e->value) + else if ((int)value != value) return; break; @@ -393,12 +371,12 @@ MATCH implicitConvTo(Expression *e, Type *t) if (ty == Tint32) { } - else if ((unsigned)e->value != e->value) + else if ((unsigned)value != value) return; break; case Tdchar: - if (e->value > 0x10FFFFUL) + if (value > 0x10FFFFUL) return; break; @@ -407,14 +385,14 @@ MATCH implicitConvTo(Expression *e, Type *t) volatile float f; if (e->type->isunsigned()) { - f = (float)e->value; - if (f != e->value) + f = (float)value; + if (f != value) return; } else { - f = (float)(sinteger_t)e->value; - if (f != (sinteger_t)e->value) + f = (float)(sinteger_t)value; + if (f != (sinteger_t)value) return; } break; @@ -425,14 +403,14 @@ MATCH implicitConvTo(Expression *e, Type *t) volatile double f; if (e->type->isunsigned()) { - f = (double)e->value; - if (f != e->value) + f = (double)value; + if (f != value) return; } else { - f = (double)(sinteger_t)e->value; - if (f != (sinteger_t)e->value) + f = (double)(sinteger_t)value; + if (f != (sinteger_t)value) return; } break; @@ -443,14 +421,14 @@ MATCH implicitConvTo(Expression *e, Type *t) volatile_longdouble f; if (e->type->isunsigned()) { - f = ldouble(e->value); - if (f != e->value) // isn't this a noop, because the compiler prefers ld + f = ldouble(value); + if (f != value) // isn't this a noop, because the compiler prefers ld return; } else { - f = ldouble((sinteger_t)e->value); - if (f != (sinteger_t)e->value) + f = ldouble((sinteger_t)value); + if (f != (sinteger_t)value) return; } break; @@ -3237,7 +3215,7 @@ IntRange getIntRange(Expression *e) void visit(IntegerExp *e) { - range = IntRange(SignExtendedNumber(e->value)).cast(e->type); + range = IntRange(SignExtendedNumber(e->getInteger())).cast(e->type); } void visit(CastExp *e) diff --git a/src/ctfeexpr.c b/src/ctfeexpr.c index b24dcba4c041..bba459d80185 100644 --- a/src/ctfeexpr.c +++ b/src/ctfeexpr.c @@ -873,10 +873,10 @@ void intUnary(TOK op, IntegerExp *e) switch (op) { case TOKneg: - e->value = -e->value; + e->setInteger(-e->getInteger()); break; case TOKtilde: - e->value = ~e->value; + e->setInteger(~e->getInteger()); break; default: assert(0); @@ -892,26 +892,27 @@ void intBinary(TOK op, IntegerExp *dest, Type *type, IntegerExp *e1, IntegerExp switch (op) { case TOKand: - result = e1->value & e2->value; + result = e1->getInteger() & e2->getInteger(); break; case TOKor: - result = e1->value | e2->value; + result = e1->getInteger() | e2->getInteger(); break; case TOKxor: - result = e1->value ^ e2->value; + result = e1->getInteger() ^ e2->getInteger(); break; case TOKadd: - result = e1->value + e2->value; + result = e1->getInteger() + e2->getInteger(); break; case TOKmin: - result = e1->value - e2->value; + result = e1->getInteger() - e2->getInteger(); break; case TOKmul: - result = e1->value * e2->value; + result = e1->getInteger() * e2->getInteger(); break; case TOKdiv: - { sinteger_t n1 = e1->value; - sinteger_t n2 = e2->value; + { + sinteger_t n1 = e1->getInteger(); + sinteger_t n2 = e2->getInteger(); if (n2 == 0) { e2->error("divide by 0"); @@ -924,8 +925,8 @@ void intBinary(TOK op, IntegerExp *dest, Type *type, IntegerExp *e1, IntegerExp } break; case TOKmod: - { sinteger_t n1 = e1->value; - sinteger_t n2 = e2->value; + { sinteger_t n1 = e1->getInteger(); + sinteger_t n2 = e2->getInteger(); if (n2 == 0) { e2->error("divide by 0"); @@ -951,13 +952,13 @@ void intBinary(TOK op, IntegerExp *dest, Type *type, IntegerExp *e1, IntegerExp } break; case TOKpow: - { dinteger_t n = e2->value; + { dinteger_t n = e2->getInteger(); if (!e2->type->isunsigned() && (sinteger_t)n < 0) { e2->error("integer ^^ -integer: total loss of precision"); n = 1; } - uinteger_t r = e1->value; + uinteger_t r = e1->getInteger(); result = 1; while (n != 0) { @@ -969,11 +970,11 @@ void intBinary(TOK op, IntegerExp *dest, Type *type, IntegerExp *e1, IntegerExp } break; case TOKshl: - result = e1->value << e2->value; + result = e1->getInteger() << e2->getInteger(); break; case TOKshr: - { dinteger_t value = e1->value; - dinteger_t dcount = e2->value; + { dinteger_t value = e1->getInteger(); + dinteger_t dcount = e2->getInteger(); assert(dcount <= 0xFFFFFFFF); unsigned count = (unsigned)dcount; switch (e1->type->toBasetype()->ty) @@ -1018,8 +1019,8 @@ void intBinary(TOK op, IntegerExp *dest, Type *type, IntegerExp *e1, IntegerExp } break; case TOKushr: - { dinteger_t value = e1->value; - dinteger_t dcount = e2->value; + { dinteger_t value = e1->getInteger(); + dinteger_t dcount = e2->getInteger(); assert(dcount <= 0xFFFFFFFF); unsigned count = (unsigned)dcount; switch (e1->type->toBasetype()->ty) @@ -1056,16 +1057,16 @@ void intBinary(TOK op, IntegerExp *dest, Type *type, IntegerExp *e1, IntegerExp break; case TOKequal: case TOKidentity: - result = (e1->value == e2->value); + result = (e1->getInteger() == e2->getInteger()); break; case TOKnotequal: case TOKnotidentity: - result = (e1->value != e2->value); + result = (e1->getInteger() != e2->getInteger()); break; default: assert(0); } - dest->value = result; + dest->setInteger(result); dest->type = type; } diff --git a/src/e2ir.c b/src/e2ir.c index 2f34ee9ead8f..d6cf3a448ec4 100644 --- a/src/e2ir.c +++ b/src/e2ir.c @@ -1101,7 +1101,7 @@ elem *toElem(Expression *e, IRState *irs) void visit(IntegerExp *ie) { - elem *e = el_long(totym(ie->type), ie->value); + elem *e = el_long(totym(ie->type), ie->getInteger()); el_setLoc(e,ie->loc); result = e; } diff --git a/src/expression.c b/src/expression.c index 11801191c3de..87d5230bda52 100644 --- a/src/expression.c +++ b/src/expression.c @@ -2612,7 +2612,8 @@ IntegerExp::IntegerExp(Loc loc, dinteger_t value, Type *type) : Expression(loc, TOKint64, sizeof(IntegerExp)) { //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : ""); - if (type && !type->isscalar()) + assert(type); + if (!type->isscalar()) { //printf("%s, loc = %d\n", toChars(), loc.linnum); if (type->ty != Terror) @@ -2620,14 +2621,14 @@ IntegerExp::IntegerExp(Loc loc, dinteger_t value, Type *type) type = Type::terror; } this->type = type; - this->value = value; + setInteger(value); } IntegerExp::IntegerExp(dinteger_t value) : Expression(Loc(), TOKint64, sizeof(IntegerExp)) { this->type = Type::tint32; - this->value = value; + this->value = (d_int32) value; } bool IntegerExp::equals(RootObject *o) @@ -2651,72 +2652,53 @@ char *IntegerExp::toChars() return Expression::toChars(); } -dinteger_t IntegerExp::toInteger() -{ Type *t; - - t = type; - while (t) - { - switch (t->ty) - { - case Tbool: value = (value != 0); break; - case Tint8: value = (d_int8) value; break; - case Tchar: - case Tuns8: value = (d_uns8) value; break; - case Tint16: value = (d_int16) value; break; - case Twchar: - case Tuns16: value = (d_uns16) value; break; - case Tint32: value = (d_int32) value; break; - case Tdchar: - case Tuns32: value = (d_uns32) value; break; - case Tint64: value = (d_int64) value; break; - case Tuns64: value = (d_uns64) value; break; - case Tpointer: - if (Target::ptrsize == 4) - value = (d_uns32) value; - else if (Target::ptrsize == 8) - value = (d_uns64) value; - else - assert(0); - break; - - case Tenum: - { - TypeEnum *te = (TypeEnum *)t; - t = te->sym->memtype; - continue; - } - - case Ttypedef: - { - TypeTypedef *tt = (TypeTypedef *)t; - t = tt->sym->basetype; - continue; - } +void IntegerExp::setInteger(dinteger_t value) +{ + this->value = value; + normalize(); +} - default: - /* This can happen if errors, such as - * the type is painted on like in fromConstInitializer(). - */ - if (!global.errors) - { - printf("e = %p, ty = %d\n", this, type->ty); - type->print(); - assert(0); - } - break; - } - break; +void IntegerExp::normalize() +{ + /* 'Normalize' the value of the integer to be in range of the type + */ + switch (type->toBasetype()->ty) + { + case Tbool: value = (value != 0); break; + case Tint8: value = (d_int8) value; break; + case Tchar: + case Tuns8: value = (d_uns8) value; break; + case Tint16: value = (d_int16) value; break; + case Twchar: + case Tuns16: value = (d_uns16) value; break; + case Tint32: value = (d_int32) value; break; + case Tdchar: + case Tuns32: value = (d_uns32) value; break; + case Tint64: value = (d_int64) value; break; + case Tuns64: value = (d_uns64) value; break; + case Tpointer: + if (Target::ptrsize == 4) + value = (d_uns32) value; + else if (Target::ptrsize == 8) + value = (d_uns64) value; + else + assert(0); + break; + default: + break; } +} + +dinteger_t IntegerExp::toInteger() +{ + normalize(); // necessary until we fix all the paints of 'type' return value; } real_t IntegerExp::toReal() { - Type *t; - - toInteger(); - t = type->toBasetype(); + normalize(); // necessary until we fix all the paints of 'type' + Type *t = type->toBasetype(); if (t->ty == Tuns64) return ldouble((d_uns64)value); else @@ -2741,23 +2723,10 @@ int IntegerExp::isBool(int result) Expression *IntegerExp::semantic(Scope *sc) { - if (!type) - { - // Determine what the type of this number is - dinteger_t number = value; - - if (number & 0x8000000000000000LL) - type = Type::tuns64; - else if (number & 0xFFFFFFFF80000000LL) - type = Type::tint64; - else - type = Type::tint32; - } - else - { - if (!type->deco) - type = type->semantic(loc, sc); - } + assert(type && type->deco); + if (type->ty == Terror) + return new ErrorExp(); + normalize(); return this; } diff --git a/src/expression.h b/src/expression.h index 1e05cf8b8129..ac3ffdf3c507 100644 --- a/src/expression.h +++ b/src/expression.h @@ -245,9 +245,10 @@ class Expression : public RootObject class IntegerExp : public Expression { -public: +private: dinteger_t value; +public: IntegerExp(Loc loc, dinteger_t value, Type *type); IntegerExp(dinteger_t value); bool equals(RootObject *o); @@ -261,6 +262,11 @@ class IntegerExp : public Expression void toMangleBuffer(OutBuffer *buf); Expression *toLvalue(Scope *sc, Expression *e); void accept(Visitor *v) { v->visit(this); } + dinteger_t getInteger() { return value; } + void setInteger(dinteger_t value); + +private: + void normalize(); }; class ErrorExp : public Expression diff --git a/src/interpret.c b/src/interpret.c index 17b0b853f165..226ef5bd2630 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -6677,7 +6677,7 @@ Expression *interpret_aaApply(InterState *istate, Expression *aa, Expression *de return eresult; assert(eresult->op == TOKint64); - if (((IntegerExp *)eresult)->value != 0) + if (((IntegerExp *)eresult)->getInteger() != 0) return eresult; } return eresult; @@ -6770,7 +6770,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del { Expression * r = (*ale->elements)[indx]; assert(r->op == TOKint64); - utf8_t x = (utf8_t)(((IntegerExp *)r)->value); + utf8_t x = (utf8_t)(((IntegerExp *)r)->getInteger()); if ( (x & 0xC0) != 0x80) break; ++buflen; @@ -6782,7 +6782,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del { Expression * r = (*ale->elements)[indx + i]; assert(r->op == TOKint64); - utf8buf[i] = (utf8_t)(((IntegerExp *)r)->value); + utf8buf[i] = (utf8_t)(((IntegerExp *)r)->getInteger()); } n = 0; errmsg = utf_decodeChar(&utf8buf[0], buflen, &n, &rawvalue); @@ -6794,7 +6794,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del buflen = 1; Expression * r = (*ale->elements)[indx]; assert(r->op == TOKint64); - unsigned short x = (unsigned short)(((IntegerExp *)r)->value); + unsigned short x = (unsigned short)(((IntegerExp *)r)->getInteger()); if (indx > 0 && x >= 0xDC00 && x <= 0xDFFF) { --indx; @@ -6807,7 +6807,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del { Expression * r = (*ale->elements)[indx + i]; assert(r->op == TOKint64); - utf16buf[i] = (unsigned short)(((IntegerExp *)r)->value); + utf16buf[i] = (unsigned short)(((IntegerExp *)r)->getInteger()); } n = 0; errmsg = utf_decodeWchar(&utf16buf[0], buflen, &n, &rawvalue); @@ -6819,7 +6819,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del Expression * r = (*ale->elements)[indx]; assert(r->op == TOKint64); - rawvalue = (dchar_t)((IntegerExp *)r)->value; + rawvalue = (dchar_t)((IntegerExp *)r)->getInteger(); n = 1; } break; @@ -6931,7 +6931,7 @@ Expression *foreachApplyUtf(InterState *istate, Expression *str, Expression *del if (exceptionOrCantInterpret(eresult)) return eresult; assert(eresult->op == TOKint64); - if (((IntegerExp *)eresult)->value != 0) + if (((IntegerExp *)eresult)->getInteger() != 0) return eresult; } } diff --git a/src/statement.c b/src/statement.c index cafd7b761c12..46c0bfa31121 100644 --- a/src/statement.c +++ b/src/statement.c @@ -1921,7 +1921,7 @@ Statement *ForeachStatement::semantic(Scope *sc) if (op == TOKforeach_reverse) key->init = new ExpInitializer(loc, tmp_length); else - key->init = new ExpInitializer(loc, new IntegerExp(loc, 0, NULL)); + key->init = new ExpInitializer(loc, new IntegerExp(loc, 0, key->type)); Statements *cs = new Statements(); cs->push(new ExpStatement(loc, tmp)); @@ -1943,7 +1943,7 @@ Statement *ForeachStatement::semantic(Scope *sc) Expression *increment = NULL; if (op == TOKforeach) // key += 1 - increment = new AddAssignExp(loc, new VarExp(loc, key), new IntegerExp(loc, 1, NULL)); + increment = new AddAssignExp(loc, new VarExp(loc, key), new IntegerExp(loc, 1, key->type)); // T value = tmp[key]; value->init = new ExpInitializer(loc, new IndexExp(loc, new VarExp(loc, tmp), new VarExp(loc, key))); diff --git a/src/template.c b/src/template.c index 6ee7cd157999..539c53f7a6dc 100644 --- a/src/template.c +++ b/src/template.c @@ -380,7 +380,7 @@ hash_t arrayObjectHash(Objects *oa1) if (e1->op == TOKint64) { IntegerExp *ne = (IntegerExp *)e1; - hash += (size_t)ne->value; + hash += (size_t)ne->getInteger(); } } else if (s1) diff --git a/src/todt.c b/src/todt.c index 377730c12bf5..ca89670138fb 100644 --- a/src/todt.c +++ b/src/todt.c @@ -260,10 +260,11 @@ dt_t **Expression_toDt(Expression *e, dt_t **pdt) { //printf("IntegerExp::toDt() %d\n", e->op); unsigned sz = e->type->size(); - if (e->value == 0) + dinteger_t value = e->getInteger(); + if (value == 0) pdt = dtnzeros(pdt, sz); else - pdt = dtnbytes(pdt, sz, (char *)&e->value); + pdt = dtnbytes(pdt, sz, (char *)&value); } void visit(RealExp *e)