diff -uNr dmd-1.011/dmd/src/dmd/arraytypes.h dmd-1.012/dmd/src/dmd/arraytypes.h --- dmd-1.011/dmd/src/dmd/arraytypes.h 2007-04-10 14:38:56.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/arraytypes.h 2007-04-11 02:37:52.000000000 +0200 @@ -23,6 +23,8 @@ struct BaseClass; struct TemplateParameter; struct FuncDeclaration; +struct Identifier; +struct Initializer; struct TemplateParameters : Array { }; @@ -42,4 +44,8 @@ struct Arguments : Array { }; +struct Identifiers : Array { }; + +struct Initializers : Array { }; + #endif diff -uNr dmd-1.011/dmd/src/dmd/declaration.c dmd-1.012/dmd/src/dmd/declaration.c --- dmd-1.011/dmd/src/dmd/declaration.c 2007-04-10 18:20:50.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/declaration.c 2007-04-11 17:54:46.000000000 +0200 @@ -690,7 +690,7 @@ // Initialize by constructor only storage_class = (storage_class & ~STCconst) | STCctorinit; - if (isConst() || isFinal()) + if (isConst()) { } else if (isStatic()) diff -uNr dmd-1.011/dmd/src/dmd/delegatize.c dmd-1.012/dmd/src/dmd/delegatize.c --- dmd-1.011/dmd/src/dmd/delegatize.c 2007-04-10 14:38:58.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/delegatize.c 2007-04-11 16:14:42.000000000 +0200 @@ -177,6 +177,13 @@ } +void AssocArrayLiteralExp::scanForNestedRef(Scope *sc) +{ + arrayExpressionScanForNestedRef(sc, keys); + arrayExpressionScanForNestedRef(sc, values); +} + + void TupleExp::scanForNestedRef(Scope *sc) { arrayExpressionScanForNestedRef(sc, exps); diff -uNr dmd-1.011/dmd/src/dmd/expression.c dmd-1.012/dmd/src/dmd/expression.c --- dmd-1.011/dmd/src/dmd/expression.c 2007-04-10 18:21:32.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/expression.c 2007-04-11 17:46:38.000000000 +0200 @@ -2505,6 +2505,136 @@ } } +/************************ AssocArrayLiteralExp ************************************/ + +// [ key0 : value0, key1 : value1, ... ] + +AssocArrayLiteralExp::AssocArrayLiteralExp(Loc loc, + Expressions *keys, Expressions *values) + : Expression(loc, TOKassocarrayliteral, sizeof(AssocArrayLiteralExp)) +{ + assert(keys->dim == values->dim); + this->keys = keys; + this->values = values; +} + +Expression *AssocArrayLiteralExp::syntaxCopy() +{ + return new AssocArrayLiteralExp(loc, + arraySyntaxCopy(keys), arraySyntaxCopy(values)); +} + +Expression *AssocArrayLiteralExp::semantic(Scope *sc) +{ Expression *e; + Type *tkey = NULL; + Type *tvalue = NULL; + +#if LOGSEMANTIC + printf("AssocArrayLiteralExp::semantic('%s')\n", toChars()); +#endif + + // Run semantic() on each element + for (size_t i = 0; i < keys->dim; i++) + { Expression *key = (Expression *)keys->data[i]; + Expression *value = (Expression *)values->data[i]; + + key = key->semantic(sc); + value = value->semantic(sc); + + keys->data[i] = (void *)key; + values->data[i] = (void *)value; + } + expandTuples(keys); + expandTuples(values); + if (keys->dim != values->dim) + { + error("number of keys is %u, must match number of values %u", keys->dim, values->dim); + keys->setDim(0); + values->setDim(0); + } + for (size_t i = 0; i < keys->dim; i++) + { Expression *key = (Expression *)keys->data[i]; + Expression *value = (Expression *)values->data[i]; + + if (!key->type) + error("%s has no value", key->toChars()); + if (!value->type) + error("%s has no value", value->toChars()); + key = resolveProperties(sc, key); + value = resolveProperties(sc, value); + + if (!tkey) + tkey = key->type; + else + key = key->implicitCastTo(sc, tkey); + keys->data[i] = (void *)key; + + if (!tvalue) + tvalue = value->type; + else + value = value->implicitCastTo(sc, tvalue); + values->data[i] = (void *)value; + } + + if (!tkey) + tkey = Type::tvoid; + if (!tvalue) + tvalue = Type::tvoid; + type = new TypeAArray(tvalue, tkey); + type = type->semantic(loc, sc); + return this; +} + +int AssocArrayLiteralExp::checkSideEffect(int flag) +{ int f = 0; + + for (size_t i = 0; i < keys->dim; i++) + { Expression *key = (Expression *)keys->data[i]; + Expression *value = (Expression *)values->data[i]; + + f |= key->checkSideEffect(2); + f |= value->checkSideEffect(2); + } + if (flag == 0 && f == 0) + Expression::checkSideEffect(0); + return f; +} + +int AssocArrayLiteralExp::isBool(int result) +{ + size_t dim = keys->dim; + return result ? (dim != 0) : (dim == 0); +} + +void AssocArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + buf->writeByte('['); + for (size_t i = 0; i < keys->dim; i++) + { Expression *key = (Expression *)keys->data[i]; + Expression *value = (Expression *)values->data[i]; + + if (i) + buf->writeByte(','); + expToCBuffer(buf, hgs, key, PREC_assign); + buf->writeByte(':'); + expToCBuffer(buf, hgs, value, PREC_assign); + } + buf->writeByte(']'); +} + +void AssocArrayLiteralExp::toMangleBuffer(OutBuffer *buf) +{ + size_t dim = keys->dim; + buf->printf("A%u", dim); + for (size_t i = 0; i < dim; i++) + { Expression *key = (Expression *)keys->data[i]; + Expression *value = (Expression *)values->data[i]; + + key->toMangleBuffer(buf); + value->toMangleBuffer(buf); + } +} + /************************ TypeDotIdExp ************************************/ /* Things like: @@ -3198,7 +3328,8 @@ error("cannot change reference to static array '%s'", var->toChars()); VarDeclaration *v = var->isVarDeclaration(); - if (v && v->canassign == 0 && (var->isConst() || var->isFinal())) + if (v && v->canassign == 0 && + (var->isConst() || (global.params.Dversion > 1 && var->isFinal()))) error("cannot modify final variable '%s'", var->toChars()); if (var->isCtorinit()) diff -uNr dmd-1.011/dmd/src/dmd/expression.h dmd-1.012/dmd/src/dmd/expression.h --- dmd-1.011/dmd/src/dmd/expression.h 2007-04-10 14:38:58.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/expression.h 2007-04-11 16:16:16.000000000 +0200 @@ -367,6 +367,29 @@ Expression *inlineScan(InlineScanState *iss); }; +struct AssocArrayLiteralExp : Expression +{ + Expressions *keys; + Expressions *values; + + AssocArrayLiteralExp(Loc loc, Expressions *keys, Expressions *values); + + Expression *syntaxCopy(); + Expression *semantic(Scope *sc); + int isBool(int result); + elem *toElem(IRState *irs); + int checkSideEffect(int flag); + void toCBuffer(OutBuffer *buf, HdrGenState *hgs); + void toMangleBuffer(OutBuffer *buf); + void scanForNestedRef(Scope *sc); + Expression *optimize(int result); + Expression *interpret(InterState *istate); + + int inlineCost(InlineCostState *ics); + Expression *doInline(InlineDoState *ids); + Expression *inlineScan(InlineScanState *iss); +}; + struct TypeDotIdExp : Expression { Identifier *ident; diff -uNr dmd-1.011/dmd/src/dmd/init.c dmd-1.012/dmd/src/dmd/init.c --- dmd-1.011/dmd/src/dmd/init.c 2007-04-10 23:46:24.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/init.c 2007-04-11 02:37:50.000000000 +0200 @@ -45,12 +45,12 @@ return Type::terror; } -Array *Initializer::arraySyntaxCopy(Array *ai) -{ Array *a = NULL; +Initializers *Initializer::arraySyntaxCopy(Initializers *ai) +{ Initializers *a = NULL; if (ai) { - a = new Array(); + a = new Initializers(); a->setDim(ai->dim); for (int i = 0; i < a->dim; i++) { Initializer *e = (Initializer *)ai->data[i]; diff -uNr dmd-1.011/dmd/src/dmd/init.h dmd-1.012/dmd/src/dmd/init.h --- dmd-1.011/dmd/src/dmd/init.h 2007-04-10 14:38:58.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/init.h 2007-04-11 02:37:52.000000000 +0200 @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2006 by Digital Mars +// Copyright (c) 1999-2007 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -14,6 +14,7 @@ #include "root.h" #include "mars.h" +#include "arraytypes.h" struct Identifier; struct Expression; @@ -39,7 +40,7 @@ virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0; char *toChars(); - static Array *arraySyntaxCopy(Array *ai); + static Initializers *arraySyntaxCopy(Initializers *ai); virtual dt_t *toDt(); @@ -64,8 +65,8 @@ struct StructInitializer : Initializer { - Array field; // of Identifier *'s - Array value; // parallel array of Initializer *'s + Identifiers field; // of Identifier *'s + Initializers value; // parallel array of Initializer *'s Array vars; // parallel array of VarDeclaration *'s AggregateDeclaration *ad; // which aggregate this is for @@ -82,8 +83,8 @@ struct ArrayInitializer : Initializer { - Array index; // of Expression *'s - Array value; // of Initializer *'s + Expressions index; // indices + Initializers value; // of Initializer *'s unsigned dim; // length of array being initialized Type *type; // type that array will be used to initialize int sem; // !=0 if semantic() is run diff -uNr dmd-1.011/dmd/src/dmd/inline.c dmd-1.012/dmd/src/dmd/inline.c --- dmd-1.011/dmd/src/dmd/inline.c 2007-04-10 14:39:00.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/inline.c 2007-04-11 15:48:56.000000000 +0200 @@ -183,6 +183,11 @@ return 1 + arrayInlineCost(ics, elements); } +int AssocArrayLiteralExp::inlineCost(InlineCostState *ics) +{ + return 1 + arrayInlineCost(ics, keys) + arrayInlineCost(ics, values); +} + int FuncExp::inlineCost(InlineCostState *ics) { // Right now, this makes the function be output to the .obj file twice. @@ -699,6 +704,17 @@ } +Expression *AssocArrayLiteralExp::doInline(InlineDoState *ids) +{ + AssocArrayLiteralExp *ce; + + ce = (AssocArrayLiteralExp *)copy(); + ce->keys = arrayExpressiondoInline(keys, ids); + ce->values = arrayExpressiondoInline(values, ids); + return ce; +} + + Expression *ArrayExp::doInline(InlineDoState *ids) { ArrayExp *ce; @@ -1093,6 +1109,17 @@ } +Expression *AssocArrayLiteralExp::inlineScan(InlineScanState *iss) +{ Expression *e = this; + + //printf("AssocArrayLiteralExp::inlineScan()\n"); + arrayInlineScan(iss, keys); + arrayInlineScan(iss, values); + + return e; +} + + Expression *ArrayExp::inlineScan(InlineScanState *iss) { Expression *e = this; diff -uNr dmd-1.011/dmd/src/dmd/interpret.c dmd-1.012/dmd/src/dmd/interpret.c --- dmd-1.011/dmd/src/dmd/interpret.c 2007-04-10 18:46:42.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/interpret.c 2007-04-11 16:53:34.000000000 +0200 @@ -990,6 +990,82 @@ return this; } +Expression *AssocArrayLiteralExp::interpret(InterState *istate) +{ Expressions *keysx = NULL; + Expressions *valuesx = NULL; + +#if LOG + printf("AssocArrayLiteralExp::interpret() %s\n", toChars()); +#endif + for (size_t i = 0; i < keys->dim; i++) + { Expression *ekey = (Expression *)keys->data[i]; + Expression *evalue = (Expression *)values->data[i]; + Expression *ex; + + ex = ekey->interpret(istate); + if (ex == EXP_CANT_INTERPRET) + { delete keysx; + delete valuesx; + return EXP_CANT_INTERPRET; + } + + /* If any changes, do Copy On Write + */ + if (ex != ekey) + { + if (!keysx) + { keysx = new Expressions(); + keysx->setDim(keys->dim); + for (size_t j = 0; j < i; j++) + { + keysx->data[j] = keys->data[j]; + } + } + keysx->data[i] = (void *)ex; + } + + ex = evalue->interpret(istate); + if (ex == EXP_CANT_INTERPRET) + { delete keysx; + delete valuesx; + return EXP_CANT_INTERPRET; + } + + /* If any changes, do Copy On Write + */ + if (ex != evalue) + { + if (!valuesx) + { valuesx = new Expressions(); + valuesx->setDim(values->dim); + for (size_t j = 0; j < i; j++) + { + valuesx->data[j] = values->data[j]; + } + } + valuesx->data[i] = (void *)ex; + } + } + if (keysx || valuesx) + { + if (keysx) + expandTuples(keysx); + if (valuesx) + expandTuples(valuesx); + if ((keysx && keysx->dim != keys->dim) || + (valuesx && valuesx->dim != values->dim)) + { delete keysx; + delete valuesx; + return EXP_CANT_INTERPRET; + } + AssocArrayLiteralExp *ae = new AssocArrayLiteralExp(loc, + keysx ? keysx : keys, valuesx ? valuesx : values); + ae->type = type; + return ae; + } + return this; +} + Expression *UnaExp::interpretCommon(InterState *istate, Expression *(*fp)(Type *, Expression *)) { Expression *e; Expression *e1; diff -uNr dmd-1.011/dmd/src/dmd/lexer.c dmd-1.012/dmd/src/dmd/lexer.c --- dmd-1.011/dmd/src/dmd/lexer.c 2007-04-10 21:35:40.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/lexer.c 2007-04-11 16:57:48.000000000 +0200 @@ -2729,6 +2729,7 @@ Token::tochars[TOKtypedot] = "typedot"; Token::tochars[TOKarraylength] = "arraylength"; Token::tochars[TOKarrayliteral] = "arrayliteral"; + Token::tochars[TOKassocarrayliteral] = "assocarrayliteral"; Token::tochars[TOKstring] = "string"; Token::tochars[TOKdsymbol] = "symbol"; Token::tochars[TOKtuple] = "tuple"; diff -uNr dmd-1.011/dmd/src/dmd/lexer.h dmd-1.012/dmd/src/dmd/lexer.h --- dmd-1.011/dmd/src/dmd/lexer.h 2007-04-10 14:38:58.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/lexer.h 2007-04-11 02:41:14.000000000 +0200 @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2006 by Digital Mars +// Copyright (c) 1999-2007 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -66,7 +66,7 @@ TOKtypeid, TOKuadd, TOKremove, TOKnewanonclass, TOKcomment, - TOKarrayliteral, + TOKarrayliteral, TOKassocarrayliteral, // Operators TOKlt, TOKgt, diff -uNr dmd-1.011/dmd/src/dmd/mangle.c dmd-1.012/dmd/src/dmd/mangle.c --- dmd-1.011/dmd/src/dmd/mangle.c 2007-04-10 14:39:00.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/mangle.c 2007-04-12 02:40:44.000000000 +0200 @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2006 by Digital Mars +// Copyright (c) 1999-2007 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -125,6 +125,7 @@ buf.writestring(p); p = buf.toChars(); buf.data = NULL; + //printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d) = %s\n", this, toChars(), parent ? parent->toChars() : "null", linkage, p); return p; } @@ -192,8 +193,28 @@ char *TemplateInstance::mangle() { - //printf("TemplateInstance::mangle() '%s'\n", toChars()); - return Dsymbol::mangle(); + OutBuffer buf; + char *id; + +#if 0 + printf("TemplateInstance::mangle() %s", toChars()); + if (parent) + printf(" parent = %s %s", parent->kind(), parent->toChars()); + printf("\n"); +#endif + id = ident ? ident->toChars() : toChars(); + if (tempdecl->parent) + { + char *p = tempdecl->parent->mangle(); + if (p[0] == '_' && p[1] == 'D') + p += 2; + buf.writestring(p); + } + buf.printf("%zu%s", strlen(id), id); + id = buf.toChars(); + buf.data = NULL; + //printf("TemplateInstance::mangle() %s = %s\n", toChars(), id); + return id; } @@ -203,11 +224,15 @@ OutBuffer buf; char *id; - //printf("Dsymbol::mangle() '%s'\n", toChars()); +#if 0 + printf("Dsymbol::mangle() '%s'", toChars()); + if (parent) + printf(" parent = %s %s", parent->kind(), parent->toChars()); + printf("\n"); +#endif id = ident ? ident->toChars() : toChars(); if (parent) { - //printf(" parent = '%s', kind = '%s'\n", parent->mangle(), parent->kind()); char *p = parent->mangle(); if (p[0] == '_' && p[1] == 'D') p += 2; @@ -216,6 +241,7 @@ buf.printf("%zu%s", strlen(id), id); id = buf.toChars(); buf.data = NULL; + //printf("Dsymbol::mangle() %s = %s\n", toChars(), id); return id; } diff -uNr dmd-1.011/dmd/src/dmd/mars.c dmd-1.012/dmd/src/dmd/mars.c --- dmd-1.011/dmd/src/dmd/mars.c 2007-04-10 18:26:18.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/mars.c 2007-04-11 16:57:26.000000000 +0200 @@ -60,7 +60,7 @@ copyright = "Copyright (c) 1999-2007 by Digital Mars"; written = "written by Walter Bright"; - version = "v1.011"; + version = "v1.012"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); @@ -221,14 +221,6 @@ goto Largs; } - // Initialization - Type::init(); - Id::initialize(); - Module::init(); - initPrecedence(); - - backend_init(); - #if __DMC__ // DMC unique support for response files if (response_expand(&argc,&argv)) // expand response files error("can't open response file"); @@ -569,6 +561,13 @@ if (global.params.cov) VersionCondition::addPredefinedGlobalIdent("D_Coverage"); + // Initialization + Type::init(); + Id::initialize(); + Module::init(); + initPrecedence(); + + backend_init(); //printf("%d source files\n",files.dim); diff -uNr dmd-1.011/dmd/src/dmd/optimize.c dmd-1.012/dmd/src/dmd/optimize.c --- dmd-1.011/dmd/src/dmd/optimize.c 2007-04-10 18:19:42.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/optimize.c 2007-04-11 15:50:42.000000000 +0200 @@ -87,6 +87,22 @@ return this; } +Expression *AssocArrayLiteralExp::optimize(int result) +{ + assert(keys->dim == values->dim); + for (size_t i = 0; i < keys->dim; i++) + { Expression *e = (Expression *)keys->data[i]; + + e = e->optimize(WANTvalue | (result & WANTinterpret)); + keys->data[i] = (void *)e; + + e = (Expression *)values->data[i]; + e = e->optimize(WANTvalue | (result & WANTinterpret)); + values->data[i] = (void *)e; + } + return this; +} + Expression *TypeExp::optimize(int result) { return this; diff -uNr dmd-1.011/dmd/src/dmd/template.c dmd-1.012/dmd/src/dmd/template.c --- dmd-1.011/dmd/src/dmd/template.c 2007-04-10 23:11:26.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/template.c 2007-04-12 02:49:16.000000000 +0200 @@ -2420,7 +2420,7 @@ this->withsym = NULL; this->nest = 0; this->havetempdecl = 0; - this->isnested = 0; + this->isnested = NULL; this->errors = 0; } @@ -2442,7 +2442,7 @@ this->withsym = NULL; this->nest = 0; this->havetempdecl = 1; - this->isnested = 0; + this->isnested = NULL; this->errors = 0; assert((size_t)tempdecl->scope > 0x10000); @@ -2553,9 +2553,10 @@ // Nesting must match if (isnested != ti->isnested) continue; +#if 0 if (isnested && sc->parent != ti->parent) continue; - +#endif for (size_t j = 0; j < tdtypes.dim; j++) { Object *o1 = (Object *)tdtypes.data[j]; Object *o2 = (Object *)ti->tdtypes.data[j]; @@ -2589,8 +2590,10 @@ ident = genIdent(); // need an identifier for name mangling purposes. +#if 1 if (isnested) - parent = sc->parent; + parent = isnested; +#endif //printf("parent = '%s'\n", parent->kind()); // Add 'this' to the enclosing scope's members[] so the semantic routines @@ -3084,7 +3087,7 @@ */ int TemplateInstance::isNested(Objects *args) -{ +{ int nested = 0; //printf("TemplateInstance::isNested('%s')\n", tempdecl->ident->toChars()); /* A nested instance happens when an argument references a local @@ -3118,8 +3121,11 @@ { // if module level template if (tempdecl->toParent()->isModule()) - { isnested = 1; - return 1; + { + if (isnested && isnested != d->toParent()) + error("inconsistent nesting levels %s and %s", isnested->toChars(), d->toParent()->toChars()); + isnested = d->toParent(); + nested |= 1; } else error("cannot use local '%s' as template parameter", d->toChars()); @@ -3127,11 +3133,10 @@ } else if (va) { - if (isNested(&va->objects)) - return 1; + nested |= isNested(&va->objects); } } - return 0; + return nested; } /**************************************** diff -uNr dmd-1.011/dmd/src/dmd/template.h dmd-1.012/dmd/src/dmd/template.h --- dmd-1.011/dmd/src/dmd/template.h 2007-04-10 14:38:58.000000000 +0200 +++ dmd-1.012/dmd/src/dmd/template.h 2007-04-12 02:36:34.000000000 +0200 @@ -248,7 +248,7 @@ int semanticdone; // has semantic() been done? int nest; // for recursion detection int havetempdecl; // 1 if used second constructor - int isnested; // if referencing local symbols + Dsymbol *isnested; // if referencing local symbols, this is the context int errors; // 1 if compiled with errors #ifdef IN_GCC /* On some targets, it is necessary to know whether a symbol diff -uNr dmd-1.011/dmd/src/phobos/internal/object.d dmd-1.012/dmd/src/phobos/internal/object.d --- dmd-1.011/dmd/src/phobos/internal/object.d 2007-04-11 00:38:08.000000000 +0200 +++ dmd-1.012/dmd/src/phobos/internal/object.d 2007-04-12 13:18:50.000000000 +0200 @@ -469,7 +469,12 @@ int compare(void *p1, void *p2) { - return *cast(void* *)p1 - *cast(void* *)p2; + if (*cast(void* *)p1 < *cast(void* *)p2) + return -1; + else if (*cast(void* *)p1 > *cast(void* *)p2) + return 1; + else + return 0; } size_t tsize()