Mercurial > projects > ldc
diff dmd/expression.c @ 510:6aee82889553
Merged DMD 1.034, array operations are not yet implemented ;)
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Thu, 14 Aug 2008 06:55:41 +0200 |
parents | a34078905d01 |
children | f79bbd1d0b27 |
line wrap: on
line diff
--- a/dmd/expression.c Thu Aug 14 03:09:26 2008 +0200 +++ b/dmd/expression.c Thu Aug 14 06:55:41 2008 +0200 @@ -368,6 +368,7 @@ { e->error("expression has no value"); } + } return e; } @@ -389,6 +390,26 @@ } } + +/****************************** + * Perform canThrow() on an array of Expressions. + */ + +#if DMDV2 +int arrayExpressionCanThrow(Expressions *exps) +{ + if (exps) + { + for (size_t i = 0; i < exps->dim; i++) + { Expression *e = (Expression *)exps->data[i]; + if (e && e->canThrow()) + return 1; + } + } + return 0; +} +#endif + /**************************************** * Expand tuples. */ @@ -503,10 +524,10 @@ /**************************************** * Now that we know the exact type of the function we're calling, * the arguments[] need to be adjusted: - * 1) implicitly convert argument to the corresponding parameter type - * 2) add default arguments for any missing arguments - * 3) do default promotions on arguments corresponding to ... - * 4) add hidden _arguments[] argument + * 1. implicitly convert argument to the corresponding parameter type + * 2. add default arguments for any missing arguments + * 3. do default promotions on arguments corresponding to ... + * 4. add hidden _arguments[] argument */ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *arguments) @@ -802,6 +823,7 @@ Expression::Expression(Loc loc, enum TOK op, int size) : loc(loc) { + //printf("Expression::Expression(op = %d) this = %p\n", op, this); this->loc = loc; this->op = op; this->size = size; @@ -832,6 +854,7 @@ assert(0); } e = (Expression *)mem.malloc(size); + //printf("Expression::copy(op = %d) e = %p\n", op, e); return (Expression *)memcpy(e, this, size); } @@ -965,6 +988,8 @@ Expression *Expression::modifiableLvalue(Scope *sc, Expression *e) { + //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars()); + // See if this expression is a modifiable lvalue (i.e. not const) return toLvalue(sc, e); } @@ -1300,7 +1325,8 @@ type = Type::tint32; } else - { type = type->semantic(loc, sc); + { if (!type->deco) + type = type->semantic(loc, sc); } return this; } @@ -1785,7 +1811,8 @@ { Expression *e; WithScopeSymbol *withsym; - // See if it was a with class + /* See if the symbol was a member of an enclosing 'with' + */ withsym = scopesym->isWithScopeSymbol(); if (withsym) { @@ -1800,7 +1827,7 @@ else { Type *t = withsym->withstate->wthis->type; if (t->ty == Tpointer) - t = t->next; + t = ((TypePointer *)t)->next; e = new TypeDotIdExp(loc, t, ident); } } @@ -2161,8 +2188,8 @@ return this; Lerr: - error("'this' is only allowed in non-static member functions, not %s", sc->parent->toChars()); - type = Type::tint32; + error("'this' is only defined in non-static member functions, not %s", sc->parent->toChars()); + type = Type::terror; return this; } @@ -2695,7 +2722,7 @@ // Convert any static arrays to dynamic arrays if (t0->ty == Tsarray) { - t0 = t0->next->arrayOf(); + t0 = ((TypeSArray *)t0)->next->arrayOf(); e = e->implicitCastTo(sc, t0); } } @@ -2906,6 +2933,8 @@ #if LOGSEMANTIC printf("StructLiteralExp::semantic('%s')\n", toChars()); #endif + if (type) + return this; // Run semantic() on each element for (size_t i = 0; i < elements->dim; i++) @@ -2986,11 +3015,17 @@ */ Expression *StructLiteralExp::getField(Type *type, unsigned offset) -{ Expression *e = NULL; +{ + //printf("StructLiteralExp::getField(this = %s, type = %s, offset = %u)\n", +// /*toChars()*/"", type->toChars(), offset); + Expression *e = NULL; int i = getFieldIndex(type, offset); if (i != -1) - { e = (Expression *)elements->data[i]; + { + //printf("\ti = %d\n", i); + assert(i < elements->dim); + e = (Expression *)elements->data[i]; if (e) { e = e->copy(); @@ -3330,7 +3365,7 @@ Dsymbol *s = cd->toParent2(); ClassDeclaration *cdn = s->isClassDeclaration(); - //printf("isNested, cdn = %s\n", cdn ? cdn->toChars() : "null"); + //printf("cd isNested, cdn = %s\n", cdn ? cdn->toChars() : "null"); if (cdn) { if (!cdthis) @@ -3485,7 +3520,7 @@ if (arg->op == TOKint64 && (long long)arg->toInteger() < 0) error("negative array index %s", arg->toChars()); arguments->data[i] = (void *) arg; - tb = tb->next->toBasetype(); + tb = ((TypeDArray *)tb)->next->toBasetype(); } } else if (tb->isscalar()) @@ -3822,6 +3857,29 @@ } +/******************************** OverExp **************************/ + +#if DMDV2 +OverExp::OverExp(OverloadSet *s) + : Expression(loc, TOKoverloadset, sizeof(OverExp)) +{ + //printf("OverExp(this = %p, '%s')\n", this, var->toChars()); + vars = s; + type = Type::tvoid; +} + +int OverExp::isLvalue() +{ + return 1; +} + +Expression *OverExp::toLvalue(Scope *sc, Expression *e) +{ + return this; +} +#endif + + /******************************** TupleExp **************************/ TupleExp::TupleExp(Loc loc, Expressions *exps) @@ -4158,6 +4216,43 @@ buf->writeByte(')'); } +/************************ TraitsExp ************************************/ +#if DMDV2 +/* + * __traits(identifier, args...) + */ + +TraitsExp::TraitsExp(Loc loc, Identifier *ident, Objects *args) + : Expression(loc, TOKtraits, sizeof(TraitsExp)) +{ + this->ident = ident; + this->args = args; +} + + +Expression *TraitsExp::syntaxCopy() +{ + return new TraitsExp(loc, ident, TemplateInstance::arraySyntaxCopy(args)); +} + + +void TraitsExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + buf->writestring("__traits("); + buf->writestring(ident->toChars()); + if (args) + { + for (int i = 0; i < args->dim; i++) + { + buf->writeByte(','); + Object *oarg = (Object *)args->data[i]; + ObjectToCBuffer(buf, hgs, oarg); + } + } + buf->writeByte(')'); +} +#endif + /************************************************************/ HaltExp::HaltExp(Loc loc) @@ -4210,7 +4305,11 @@ Expression *IsExp::semantic(Scope *sc) { Type *tded; - //printf("IsExp::semantic()\n"); + /* is(targ id tok tspec) + * is(targ id == tok2) + */ + + //printf("IsExp::semantic(%s)\n", toChars()); if (id && !(sc->flags & SCOPEstaticif)) error("can only declare type aliases within static if conditionals"); @@ -4267,6 +4366,19 @@ goto Lno; tded = targ; break; +#if DMDV2 + case TOKconst: + if (!targ->isConst()) + goto Lno; + tded = targ; + break; + + case TOKinvariant: + if (!targ->isInvariant()) + goto Lno; + tded = targ; + break; +#endif case TOKsuper: // If class or interface, get the base class and interfaces @@ -4293,11 +4405,12 @@ case TOKdelegate: if (targ->ty != Tdelegate) goto Lno; - tded = targ->next; // the underlying function type + tded = ((TypeDelegate *)targ)->next; // the underlying function type break; case TOKfunction: - { if (targ->ty != Tfunction) + { + if (targ->ty != Tfunction) goto Lno; tded = targ; @@ -4321,7 +4434,7 @@ * delegate, or pointer to function. */ if (targ->ty == Tfunction) - tded = targ->next; + tded = ((TypeFunction *)targ)->next; else if (targ->ty == Tdelegate) tded = targ->next->next; else if (targ->ty == Tpointer && targ->next->ty == Tfunction) @@ -4537,6 +4650,13 @@ if (e) return e; + if (e1->op == TOKslice) + { // T[] op= ... + typeCombine(sc); + type = e1->type; + return arrayOp(sc); + } + e1 = e1->modifiableLvalue(sc, e1); e1->checkScalar(); type = e1->type; @@ -4568,6 +4688,13 @@ if (e) return e; + if (e1->op == TOKslice) + { // T[] op= ... + typeCombine(sc); + type = e1->type; + return arrayOp(sc); + } + e1 = e1->modifiableLvalue(sc, e1); e1->checkScalar(); type = e1->type; @@ -4888,6 +5015,24 @@ eleft = NULL; eright = e1; } +#if DMDV2 + if (e1->op == TOKtuple && ident == Id::offsetof) + { /* 'distribute' the .offsetof to each of the tuple elements. + */ + TupleExp *te = (TupleExp *)e1; + Expressions *exps = new Expressions(); + exps->setDim(te->exps->dim); + for (int i = 0; i < exps->dim; i++) + { Expression *e = (Expression *)te->exps->data[i]; + e = e->semantic(sc); + e = new DotIdExp(e->loc, e, Id::offsetof); + exps->data[i] = (void *)e; + } + e = new TupleExp(loc, exps); + e = e->semantic(sc); + return e; + } +#endif if (e1->op == TOKtuple && ident == Id::length) { @@ -5048,7 +5193,7 @@ ident != Id::mangleof && ident != Id::stringof) { e = new PtrExp(loc, e1); - e->type = e1->type->next; + e->type = ((TypePointer *)e1->type)->next; return e->type->dotExp(sc, e, ident); } else @@ -5176,7 +5321,11 @@ Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e) { - //printf("DotVarExp::modifiableLvalue(%s)\n", toChars()); +#if 0 + printf("DotVarExp::modifiableLvalue(%s)\n", toChars()); + printf("e1->type = %s\n", e1->type->toChars()); + printf("var->type = %s\n", var->type->toChars()); +#endif if (var->isCtorinit()) { // It's only modifiable if inside the right constructor @@ -5265,6 +5414,12 @@ if (t1) t1 = t1->toBasetype(); //t1->print(); + + /* Extract the following from e1: + * s: the symbol which ti should be a member of + * eleft: if not NULL, it is the 'this' pointer for ti + */ + if (e1->op == TOKdotexp) { DotExp *de = (DotExp *)e1; eleft = de->e1; @@ -5295,7 +5450,7 @@ } else if (t1 && t1->ty == Tpointer) { - t1 = t1->next->toBasetype(); + t1 = ((TypePointer *)t1)->next->toBasetype(); if (t1->ty != Tstruct) goto L1; s = t1->toDsymbol(sc); @@ -5471,6 +5626,7 @@ int i; Type *t1; int istemp; + Objects *targsi = NULL; // initial list of template arguments #if LOGSEMANTIC printf("CallExp::semantic() %s\n", toChars()); @@ -5534,8 +5690,66 @@ } } +#if DMDV2 + /* This recognizes: + * foo!(tiargs)(funcargs) + */ + if (e1->op == TOKimport && !e1->type) + { ScopeExp *se = (ScopeExp *)e1; + TemplateInstance *ti = se->sds->isTemplateInstance(); + if (ti && !ti->semanticdone) + { + /* Attempt to instantiate ti. If that works, go with it. + * If not, go with partial explicit specialization. + */ + ti->semanticTiargs(sc); + unsigned errors = global.errors; + global.gag++; + ti->semantic(sc); + global.gag--; + if (errors != global.errors) + { + /* Didn't work, go with partial explicit specialization + */ + global.errors = errors; + targsi = ti->tiargs; + e1 = new IdentifierExp(loc, ti->name); + } + } + } + + /* This recognizes: + * expr.foo!(tiargs)(funcargs) + */ + if (e1->op == TOKdotti && !e1->type) + { DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1; + TemplateInstance *ti = se->ti; + if (!ti->semanticdone) + { + /* Attempt to instantiate ti. If that works, go with it. + * If not, go with partial explicit specialization. + */ + ti->semanticTiargs(sc); + Expression *etmp; + unsigned errors = global.errors; + global.gag++; + etmp = e1->semantic(sc); + global.gag--; + if (errors != global.errors) + { + global.errors = errors; + targsi = ti->tiargs; + e1 = new DotIdExp(loc, se->e1, ti->name); + } + else + e1 = etmp; + } + } +#endif + istemp = 0; Lagain: + //printf("Lagain: %s\n", toChars()); f = NULL; if (e1->op == TOKthis || e1->op == TOKsuper) { @@ -5804,16 +6018,16 @@ else if (t1->ty != Tfunction) { if (t1->ty == Tdelegate) - { - assert(t1->next->ty == Tfunction); - tf = (TypeFunction *)(t1->next); + { TypeDelegate *td = (TypeDelegate *)t1; + assert(td->next->ty == Tfunction); + tf = (TypeFunction *)(td->next); goto Lcheckargs; } - else if (t1->ty == Tpointer && t1->next->ty == Tfunction) + else if (t1->ty == Tpointer && ((TypePointer *)t1)->next->ty == Tfunction) { Expression *e; e = new PtrExp(loc, e1); - t1 = t1->next; + t1 = ((TypePointer *)t1)->next; e->type = t1; e1 = e; } @@ -5909,10 +6123,11 @@ { Type *t = type; int offset = 0; - - if (f->tintro->next->isBaseOf(t, &offset) && offset) - { - type = f->tintro->next; + TypeFunction *tf = (TypeFunction *)f->tintro; + + if (tf->next->isBaseOf(t, &offset) && offset) + { + type = tf->next; return castTo(sc, t); } } @@ -5974,9 +6189,7 @@ FuncDeclaration *f = dve->var->isFuncDeclaration(); if (f) - { Expression *e; - - e = new DelegateExp(loc, dve->e1, f); + { Expression *e = new DelegateExp(loc, dve->e1, f); e = e->semantic(sc); return e; } @@ -6018,7 +6231,7 @@ : UnaExp(loc, TOKstar, sizeof(PtrExp), e) { if (e->type) - type = e->type->next; + type = ((TypePointer *)e->type)->next; } PtrExp::PtrExp(Loc loc, Expression *e, Type *t) @@ -6108,7 +6321,8 @@ return e; e1->checkNoBool(); - e1->checkArithmetic(); + if (e1->op != TOKslice) + e1->checkArithmetic(); type = e1->type; } return this; @@ -6157,7 +6371,8 @@ return e; e1->checkNoBool(); - e1 = e1->checkIntegral(); + if (e1->op != TOKslice) + e1 = e1->checkIntegral(); type = e1->type; } return this; @@ -6238,7 +6453,7 @@ break; } case Tpointer: - tb = tb->next->toBasetype(); + tb = ((TypePointer *)tb)->next->toBasetype(); if (tb->ty == Tstruct) { TypeStruct *ts = (TypeStruct *)tb; @@ -6569,7 +6784,7 @@ return e; } - type = t->next->arrayOf(); + type = t->nextOf()->arrayOf(); return e; Lerror: @@ -6878,7 +7093,7 @@ index, length); } #endif - e->type = t1->next; + e->type = t1->nextOf(); break; } @@ -7199,6 +7414,20 @@ { e2 = e2->implicitCastTo(sc, e1->type); } + + /* Look for array operations + */ + if (e1->op == TOKslice && !ismemset && + (e2->op == TOKadd || e2->op == TOKmin || + e2->op == TOKmul || e2->op == TOKdiv || + e2->op == TOKmod || e2->op == TOKxor || + e2->op == TOKand || e2->op == TOKor || + e2->op == TOKtilde || e2->op == TOKneg)) + { + type = e1->type; + return arrayOp(sc); + } + type = e1->type; assert(type); return this; @@ -7234,14 +7463,23 @@ if (e) return e; - e1 = e1->modifiableLvalue(sc, e1); - Type *tb1 = e1->type->toBasetype(); Type *tb2 = e2->type->toBasetype(); + if (e1->op == TOKslice) + { + typeCombine(sc); + type = e1->type; + return arrayOp(sc); + } + else + { + e1 = e1->modifiableLvalue(sc, e1); + } + if ((tb1->ty == Tarray || tb1->ty == Tsarray) && (tb2->ty == Tarray || tb2->ty == Tsarray) && - tb1->next->equals(tb2->next) + tb1->nextOf()->equals(tb2->nextOf()) ) { type = e1->type; @@ -7263,11 +7501,7 @@ Expression *ea; Expression *ex; - char name[6+6+1]; - Identifier *id; - static int idn; - sprintf(name, "__name%d", ++idn); - id = Lexer::idPool(name); + Identifier *id = Lexer::uniqueId("__name"); v = new VarDeclaration(loc, tb1->pointerTo(), id, NULL); v->semantic(sc); @@ -7334,6 +7568,13 @@ if (e) return e; + if (e1->op == TOKslice) + { // T[] -= ... + typeCombine(sc); + type = e1->type; + return arrayOp(sc); + } + e1 = e1->modifiableLvalue(sc, e1); e1->checkScalar(); e1->checkNoBool(); @@ -7397,10 +7638,10 @@ e = this; } else if ((tb1->ty == Tarray) && - e2->implicitConvTo(tb1->next) + e2->implicitConvTo(tb1->nextOf()) ) { // Append element - e2 = e2->castTo(sc, tb1->next); + e2 = e2->castTo(sc, tb1->nextOf()); type = e1->type; e = this; } @@ -7430,6 +7671,13 @@ if (e) return e; + if (e1->op == TOKslice) + { // T[] -= ... + typeCombine(sc); + type = e1->type; + return arrayOp(sc); + } + e1 = e1->modifiableLvalue(sc, e1); e1->checkScalar(); e1->checkNoBool(); @@ -7486,6 +7734,13 @@ if (e) return e; + if (e1->op == TOKslice) + { // T[] -= ... + typeCombine(sc); + type = e1->type; + return arrayOp(sc); + } + e1 = e1->modifiableLvalue(sc, e1); e1->checkScalar(); e1->checkNoBool(); @@ -7690,7 +7945,7 @@ if ((tb1->ty == Tarray || tb1->ty == Tsarray) && (tb2->ty == Tarray || tb2->ty == Tsarray) && - tb1->next->equals(tb2->next) + tb1->nextOf()->equals(tb2->nextOf()) ) { type = e1->type; @@ -7776,17 +8031,22 @@ typeCombine(sc); // make sure pointer types are compatible type = Type::tptrdiff_t; - stride = t2->next->size(); - if (!stride) - return new IntegerExp(0, 0, Type::tptrdiff_t); - e = new DivExp(loc, this, new IntegerExp(0, stride, Type::tptrdiff_t)); - e->type = Type::tptrdiff_t; + stride = t2->nextOf()->size(); + if (stride == 0) + { + e = new IntegerExp(loc, 0, Type::tptrdiff_t); + } + else + { + e = new DivExp(loc, this, new IntegerExp(0, stride, Type::tptrdiff_t)); + e->type = Type::tptrdiff_t; + } return e; } else if (t2->isintegral()) e = scaleFactor(sc); else - { error("incompatible types for -"); + { error("incompatible types for minus"); return new IntegerExp(0); } } @@ -7864,7 +8124,7 @@ if ((tb1->ty == Tsarray || tb1->ty == Tarray) && e2->type->equals(tb1->next)) { - type = tb1->next->arrayOf(); + type = tb1->nextOf()->arrayOf(); if (tb2->ty == Tarray) { // Make e2 into [e2] e2 = new ArrayLiteralExp(e2->loc, e2); @@ -7875,7 +8135,7 @@ else if ((tb2->ty == Tsarray || tb2->ty == Tarray) && e1->type->equals(tb2->next)) { - type = tb2->next->arrayOf(); + type = tb2->nextOf()->arrayOf(); if (tb1->ty == Tarray) { // Make e1 into [e1] e1 = new ArrayLiteralExp(e1->loc, e1); @@ -7904,6 +8164,7 @@ } else { + //printf("(%s) ~ (%s)\n", e1->toChars(), e2->toChars()); error("Can only concatenate arrays, not (%s ~ %s)", e1->type->toChars(), e2->type->toChars()); type = Type::tint32; @@ -7939,8 +8200,10 @@ return e; typeCombine(sc); - e1->checkArithmetic(); - e2->checkArithmetic(); + if (e1->op != TOKslice && e2->op != TOKslice) + { e1->checkArithmetic(); + e2->checkArithmetic(); + } if (type->isfloating()) { Type *t1 = e1->type; Type *t2 = e2->type; @@ -8003,8 +8266,10 @@ return e; typeCombine(sc); - e1->checkArithmetic(); - e2->checkArithmetic(); + if (e1->op != TOKslice && e2->op != TOKslice) + { e1->checkArithmetic(); + e2->checkArithmetic(); + } if (type->isfloating()) { Type *t1 = e1->type; Type *t2 = e2->type; @@ -8068,8 +8333,10 @@ return e; typeCombine(sc); - e1->checkArithmetic(); - e2->checkArithmetic(); + if (e1->op != TOKslice && e2->op != TOKslice) + { e1->checkArithmetic(); + e2->checkArithmetic(); + } if (type->isfloating()) { type = e1->type; if (e2->type->iscomplex()) @@ -8180,8 +8447,10 @@ else { typeCombine(sc); - e1->checkIntegral(); - e2->checkIntegral(); + if (e1->op != TOKslice && e2->op != TOKslice) + { e1->checkIntegral(); + e2->checkIntegral(); + } } } return this; @@ -8211,8 +8480,10 @@ else { typeCombine(sc); - e1->checkIntegral(); - e2->checkIntegral(); + if (e1->op != TOKslice && e2->op != TOKslice) + { e1->checkIntegral(); + e2->checkIntegral(); + } } } return this; @@ -8242,8 +8513,10 @@ else { typeCombine(sc); - e1->checkIntegral(); - e2->checkIntegral(); + if (e1->op != TOKslice && e2->op != TOKslice) + { e1->checkIntegral(); + e2->checkIntegral(); + } } } return this; @@ -8414,7 +8687,7 @@ e1 = e1->implicitCastTo(sc, ta->index); // Return type is pointer to value - type = ta->next->pointerTo(); + type = ta->nextOf()->pointerTo(); } return this; } @@ -8501,6 +8774,7 @@ #endif else e = this; + //printf("CmpExp: %s\n", e->toChars()); return e; }