# HG changeset patch # User korDen # Date 1271070780 -14400 # Node ID 832f71e6f96cb2e4bd5403f8b418b746cfe512ad # Parent 3356c90e9aacd4c97e8afb03651a8391a4e6b90d *Exp and *AssignExp arrayOp implementation added (might be a bit incomplete) Some unittest-specific functions implemented diff -r 3356c90e9aac -r 832f71e6f96c dmd/AddAssignExp.d --- a/dmd/AddAssignExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/AddAssignExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -5,6 +5,8 @@ import dmd.Expression; import dmd.Scope; import dmd.InterState; +import dmd.Argument; +import dmd.STC; import dmd.OutBuffer; import dmd.ArrayTypes; import dmd.Identifier; @@ -143,12 +145,19 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + AssignExp_buildArrayIdent(buf, arguments, "Add"); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + /* Evaluate assign expressions right to left + */ + Expression ex2 = e2.buildArrayLoop(fparams); + Expression ex1 = e1.buildArrayLoop(fparams); + Argument param = cast(Argument)fparams.data[0]; + param.storageClass = STCundefined; + Expression e = new AddAssignExp(Loc(0), ex1, ex2); + return e; } Identifier opId() /* For operator overloading */ diff -r 3356c90e9aac -r 832f71e6f96c dmd/AddExp.d --- a/dmd/AddExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/AddExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -118,12 +118,17 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + Exp_buildArrayIdent(buf, arguments, "Add"); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new AddExp(Loc(0), ex1, ex2); + return e; } bool isCommutative() diff -r 3356c90e9aac -r 832f71e6f96c dmd/AndAssignExp.d --- a/dmd/AndAssignExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/AndAssignExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -34,7 +34,7 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + AssignExp_buildArrayIdent(buf, arguments, "And"); } Expression buildArrayLoop(Arguments fparams) diff -r 3356c90e9aac -r 832f71e6f96c dmd/AndExp.d --- a/dmd/AndExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/AndExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -80,12 +80,17 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + Exp_buildArrayIdent(buf, arguments, "And"); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new AndExp(Loc(0), ex1, ex2); + return e; } IntRange getIntRange() diff -r 3356c90e9aac -r 832f71e6f96c dmd/AssignExp.d --- a/dmd/AssignExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/AssignExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -4,8 +4,10 @@ import dmd.Identifier; import dmd.backend.elem; import dmd.InterState; +import dmd.Argument; import dmd.IndexExp; import dmd.CallExp; +import dmd.CastExp; import dmd.TypeSArray; import dmd.StructLiteralExp; import dmd.ArrayLengthExp; @@ -379,12 +381,31 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + /* Evaluate assign expressions right to left + */ + e2.buildArrayIdent(buf, arguments); + e1.buildArrayIdent(buf, arguments); + buf.writestring("Assign"); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + /* Evaluate assign expressions right to left + */ + Expression ex2 = e2.buildArrayLoop(fparams); + version (DMDV2) { + /* Need the cast because: + * b = c + p[i]; + * where b is a byte fails because (c + p[i]) is an int + * which cannot be implicitly cast to byte. + */ + ex2 = new CastExp(Loc(0), ex2, e1.type.nextOf()); + } + Expression ex1 = e1.buildArrayLoop(fparams); + Argument param = cast(Argument)fparams.data[0]; + param.storageClass = STCundefined; + Expression e = new AssignExp(Loc(0), ex1, ex2); + return e; } elem* toElem(IRState* irs) diff -r 3356c90e9aac -r 832f71e6f96c dmd/BinExp.d --- a/dmd/BinExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/BinExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -31,12 +31,32 @@ import dmd.MulExp; import dmd.Token; import dmd.PREC; +import dmd.StringValue; +import dmd.StringTable; +import dmd.Argument; +import dmd.Statement; +import dmd.ForeachRangeStatement; +import dmd.ArrayLengthExp; +import dmd.IdentifierExp; +import dmd.ExpStatement; +import dmd.CompoundStatement; +import dmd.TypeFunction; +import dmd.LINK; +import dmd.Lexer; +import dmd.ReturnStatement; +import dmd.Id; +import dmd.STC; +import dmd.PROT; +import dmd.VarExp; +import dmd.CallExp; import dmd.expression.Util; import dmd.backend.elem; import dmd.backend.Util; +import dmd.backend.iasm : binary; + import std.stdio : writef; /************************************** @@ -50,6 +70,12 @@ * 0 failed */ +/************************************** + * Hash table of array op functions already generated or known about. + */ + +__gshared StringTable arrayfuncs; + int typeMerge(Scope sc, Expression e, Type* pt, Expression* pe1, Expression* pe2) { //printf("typeMerge() %s op %s\n", (*pe1).toChars(), (*pe2).toChars()); @@ -620,9 +646,283 @@ return e1.canThrow() || e2.canThrow(); } + /*********************************** + * Construct the array operation expression. + */ Expression arrayOp(Scope sc) { - assert(false); + //printf("BinExp.arrayOp() %s\n", toChars()); + Expressions arguments = new Expressions(); + + /* The expression to generate an array operation for is mangled + * into a name to use as the array operation function name. + * Mangle in the operands and operators in RPN order, and type. + */ + scope OutBuffer buf = new OutBuffer(); + buf.writestring("_array"); + buildArrayIdent(buf, arguments); + buf.writeByte('_'); + + /* Append deco of array element type + */ +version (DMDV2) { + buf.writestring(type.toBasetype().nextOf().toBasetype().mutableOf().deco); +} else { + buf.writestring(type.toBasetype().nextOf().toBasetype().deco); +} + + size_t namelen = buf.offset; + buf.writeByte(0); + immutable(char)* name = cast(immutable(char)*)buf.extractData(); + + /* Look up name in hash table + */ + if (arrayfuncs is null) arrayfuncs = new StringTable(); /// HACK! + + StringValue* sv = arrayfuncs.update(name[0..namelen]); + FuncDeclaration fd = cast(FuncDeclaration)sv.ptrvalue; + if (!fd) + { + /* Some of the array op functions are written as library functions, + * presumably to optimize them with special CPU vector instructions. + * List those library functions here, in alpha order. + */ + static const(char)*[] libArrayopFuncs = + [ + "_arrayExpSliceAddass_a", + "_arrayExpSliceAddass_d", // T[]+=T + "_arrayExpSliceAddass_f", // T[]+=T + "_arrayExpSliceAddass_g", + "_arrayExpSliceAddass_h", + "_arrayExpSliceAddass_i", + "_arrayExpSliceAddass_k", + "_arrayExpSliceAddass_s", + "_arrayExpSliceAddass_t", + "_arrayExpSliceAddass_u", + "_arrayExpSliceAddass_w", + + "_arrayExpSliceDivass_d", // T[]/=T + "_arrayExpSliceDivass_f", // T[]/=T + + "_arrayExpSliceMinSliceAssign_a", + "_arrayExpSliceMinSliceAssign_d", // T[]=T-T[] + "_arrayExpSliceMinSliceAssign_f", // T[]=T-T[] + "_arrayExpSliceMinSliceAssign_g", + "_arrayExpSliceMinSliceAssign_h", + "_arrayExpSliceMinSliceAssign_i", + "_arrayExpSliceMinSliceAssign_k", + "_arrayExpSliceMinSliceAssign_s", + "_arrayExpSliceMinSliceAssign_t", + "_arrayExpSliceMinSliceAssign_u", + "_arrayExpSliceMinSliceAssign_w", + + "_arrayExpSliceMinass_a", + "_arrayExpSliceMinass_d", // T[]-=T + "_arrayExpSliceMinass_f", // T[]-=T + "_arrayExpSliceMinass_g", + "_arrayExpSliceMinass_h", + "_arrayExpSliceMinass_i", + "_arrayExpSliceMinass_k", + "_arrayExpSliceMinass_s", + "_arrayExpSliceMinass_t", + "_arrayExpSliceMinass_u", + "_arrayExpSliceMinass_w", + + "_arrayExpSliceMulass_d", // T[]*=T + "_arrayExpSliceMulass_f", // T[]*=T + "_arrayExpSliceMulass_i", + "_arrayExpSliceMulass_k", + "_arrayExpSliceMulass_s", + "_arrayExpSliceMulass_t", + "_arrayExpSliceMulass_u", + "_arrayExpSliceMulass_w", + + "_arraySliceExpAddSliceAssign_a", + "_arraySliceExpAddSliceAssign_d", // T[]=T[]+T + "_arraySliceExpAddSliceAssign_f", // T[]=T[]+T + "_arraySliceExpAddSliceAssign_g", + "_arraySliceExpAddSliceAssign_h", + "_arraySliceExpAddSliceAssign_i", + "_arraySliceExpAddSliceAssign_k", + "_arraySliceExpAddSliceAssign_s", + "_arraySliceExpAddSliceAssign_t", + "_arraySliceExpAddSliceAssign_u", + "_arraySliceExpAddSliceAssign_w", + + "_arraySliceExpDivSliceAssign_d", // T[]=T[]/T + "_arraySliceExpDivSliceAssign_f", // T[]=T[]/T + + "_arraySliceExpMinSliceAssign_a", + "_arraySliceExpMinSliceAssign_d", // T[]=T[]-T + "_arraySliceExpMinSliceAssign_f", // T[]=T[]-T + "_arraySliceExpMinSliceAssign_g", + "_arraySliceExpMinSliceAssign_h", + "_arraySliceExpMinSliceAssign_i", + "_arraySliceExpMinSliceAssign_k", + "_arraySliceExpMinSliceAssign_s", + "_arraySliceExpMinSliceAssign_t", + "_arraySliceExpMinSliceAssign_u", + "_arraySliceExpMinSliceAssign_w", + + "_arraySliceExpMulSliceAddass_d", // T[] += T[]*T + "_arraySliceExpMulSliceAddass_f", + "_arraySliceExpMulSliceAddass_r", + + "_arraySliceExpMulSliceAssign_d", // T[]=T[]*T + "_arraySliceExpMulSliceAssign_f", // T[]=T[]*T + "_arraySliceExpMulSliceAssign_i", + "_arraySliceExpMulSliceAssign_k", + "_arraySliceExpMulSliceAssign_s", + "_arraySliceExpMulSliceAssign_t", + "_arraySliceExpMulSliceAssign_u", + "_arraySliceExpMulSliceAssign_w", + + "_arraySliceExpMulSliceMinass_d", // T[] -= T[]*T + "_arraySliceExpMulSliceMinass_f", + "_arraySliceExpMulSliceMinass_r", + + "_arraySliceSliceAddSliceAssign_a", + "_arraySliceSliceAddSliceAssign_d", // T[]=T[]+T[] + "_arraySliceSliceAddSliceAssign_f", // T[]=T[]+T[] + "_arraySliceSliceAddSliceAssign_g", + "_arraySliceSliceAddSliceAssign_h", + "_arraySliceSliceAddSliceAssign_i", + "_arraySliceSliceAddSliceAssign_k", + "_arraySliceSliceAddSliceAssign_r", // T[]=T[]+T[] + "_arraySliceSliceAddSliceAssign_s", + "_arraySliceSliceAddSliceAssign_t", + "_arraySliceSliceAddSliceAssign_u", + "_arraySliceSliceAddSliceAssign_w", + + "_arraySliceSliceAddass_a", + "_arraySliceSliceAddass_d", // T[]+=T[] + "_arraySliceSliceAddass_f", // T[]+=T[] + "_arraySliceSliceAddass_g", + "_arraySliceSliceAddass_h", + "_arraySliceSliceAddass_i", + "_arraySliceSliceAddass_k", + "_arraySliceSliceAddass_s", + "_arraySliceSliceAddass_t", + "_arraySliceSliceAddass_u", + "_arraySliceSliceAddass_w", + + "_arraySliceSliceMinSliceAssign_a", + "_arraySliceSliceMinSliceAssign_d", // T[]=T[]-T[] + "_arraySliceSliceMinSliceAssign_f", // T[]=T[]-T[] + "_arraySliceSliceMinSliceAssign_g", + "_arraySliceSliceMinSliceAssign_h", + "_arraySliceSliceMinSliceAssign_i", + "_arraySliceSliceMinSliceAssign_k", + "_arraySliceSliceMinSliceAssign_r", // T[]=T[]-T[] + "_arraySliceSliceMinSliceAssign_s", + "_arraySliceSliceMinSliceAssign_t", + "_arraySliceSliceMinSliceAssign_u", + "_arraySliceSliceMinSliceAssign_w", + + "_arraySliceSliceMinass_a", + "_arraySliceSliceMinass_d", // T[]-=T[] + "_arraySliceSliceMinass_f", // T[]-=T[] + "_arraySliceSliceMinass_g", + "_arraySliceSliceMinass_h", + "_arraySliceSliceMinass_i", + "_arraySliceSliceMinass_k", + "_arraySliceSliceMinass_s", + "_arraySliceSliceMinass_t", + "_arraySliceSliceMinass_u", + "_arraySliceSliceMinass_w", + + "_arraySliceSliceMulSliceAssign_d", // T[]=T[]*T[] + "_arraySliceSliceMulSliceAssign_f", // T[]=T[]*T[] + "_arraySliceSliceMulSliceAssign_i", + "_arraySliceSliceMulSliceAssign_k", + "_arraySliceSliceMulSliceAssign_s", + "_arraySliceSliceMulSliceAssign_t", + "_arraySliceSliceMulSliceAssign_u", + "_arraySliceSliceMulSliceAssign_w", + + "_arraySliceSliceMulass_d", // T[]*=T[] + "_arraySliceSliceMulass_f", // T[]*=T[] + "_arraySliceSliceMulass_i", + "_arraySliceSliceMulass_k", + "_arraySliceSliceMulass_s", + "_arraySliceSliceMulass_t", + "_arraySliceSliceMulass_u", + "_arraySliceSliceMulass_w", + ]; + + int i = binary(name, libArrayopFuncs.ptr, libArrayopFuncs.length); + if (i == -1) + { +debug { // Make sure our array is alphabetized + for (i = 0; i < libArrayopFuncs.length; i++) + { + if (strcmp(name, libArrayopFuncs[i]) == 0) + assert(false); + } +} + /* Not in library, so generate it. + * Construct the function body: + * foreach (i; 0 .. p.length) for (size_t i = 0; i < p.length; i++) + * loopbody; + * return p; + */ + + Arguments fparams = new Arguments(); + Expression loopbody = buildArrayLoop(fparams); + Argument p = cast(Argument)fparams.data[0 /*fparams.dim - 1*/]; +version (DMDV1) { + // for (size_t i = 0; i < p.length; i++) + Initializer init = new ExpInitializer(0, new IntegerExp(0, 0, Type.tsize_t)); + Dsymbol d = new VarDeclaration(0, Type.tsize_t, Id.p, init); + Statement s1 = new ForStatement(0, + new DeclarationStatement(0, d), + new CmpExp(TOKlt, 0, new IdentifierExp(0, Id.p), new ArrayLengthExp(0, new IdentifierExp(0, p.ident))), + new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id.p)), + new ExpStatement(0, loopbody)); +} else { + // foreach (i; 0 .. p.length) + Statement s1 = new ForeachRangeStatement(Loc(0), TOKforeach, + new Argument(STC.STCundefined, null, Id.p, null), + new IntegerExp(Loc(0), 0, Type.tint32), + new ArrayLengthExp(Loc(0), new IdentifierExp(Loc(0), p.ident)), + new ExpStatement(Loc(0), loopbody)); +} + Statement s2 = new ReturnStatement(Loc(0), new IdentifierExp(Loc(0), p.ident)); + //printf("s2: %s\n", s2.toChars()); + Statement fbody = new CompoundStatement(Loc(0), s1, s2); + + /* Construct the function + */ + TypeFunction ftype = new TypeFunction(fparams, type, 0, LINKc); + //printf("ftype: %s\n", ftype.toChars()); + fd = new FuncDeclaration(Loc(0), Loc(0), Lexer.idPool(name[0..namelen]), STCundefined, ftype); + fd.fbody = fbody; + fd.protection = PROT.PROTpublic; + fd.linkage = LINKc; + + sc.module_.importedFrom.members.push(cast(void*)fd); + + sc = sc.push(); + sc.parent = sc.module_.importedFrom; + sc.stc = STCundefined; + sc.linkage = LINKc; + fd.semantic(sc); + sc.pop(); + } + else + { /* In library, refer to it. + */ + fd = FuncDeclaration.genCfunc(type, name[0..namelen]); + } + sv.ptrvalue = cast(void*)fd; // cache symbol in hash table + } + + /* Call the function fd(arguments) + */ + Expression ec = new VarExp(Loc(0), fd); + Expression e = new CallExp(loc, ec, arguments); + e.type = type; + return e; } int inlineCost(InlineCostState* ics) @@ -917,4 +1217,23 @@ return e; } + + final void Exp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str) + { + /* Evaluate assign expressions left to right + */ + e1.buildArrayIdent(buf, arguments); + e2.buildArrayIdent(buf, arguments); + buf.writestring(Str); + } + + final void AssignExp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str) + { + /* Evaluate assign expressions right to left + */ + e2.buildArrayIdent(buf, arguments); + e1.buildArrayIdent(buf, arguments); + buf.writestring(Str); + buf.writestring("ass"); + } } \ No newline at end of file diff -r 3356c90e9aac -r 832f71e6f96c dmd/CastExp.d --- a/dmd/CastExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/CastExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -378,12 +378,24 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + Type tb = type.toBasetype(); + if (tb.ty == Tarray || tb.ty == Tsarray) + { + e1.buildArrayIdent(buf, arguments); + } + else + Expression.buildArrayIdent(buf, arguments); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + Type tb = type.toBasetype(); + if (tb.ty == Tarray || tb.ty == Tsarray) + { + return e1.buildArrayLoop(fparams); + } + else + return Expression.buildArrayLoop(fparams); } static int X(int fty, int tty) { diff -r 3356c90e9aac -r 832f71e6f96c dmd/DivAssignExp.d --- a/dmd/DivAssignExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/DivAssignExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -98,7 +98,7 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + AssignExp_buildArrayIdent(buf, arguments, "Div"); } Expression buildArrayLoop(Arguments fparams) diff -r 3356c90e9aac -r 832f71e6f96c dmd/DivExp.d --- a/dmd/DivExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/DivExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -112,12 +112,17 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + Exp_buildArrayIdent(buf, arguments, "Div"); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new DivExp(Loc(0), ex1, ex2); + return e; } IntRange getIntRange() diff -r 3356c90e9aac -r 832f71e6f96c dmd/Expression.d --- a/dmd/Expression.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/Expression.d Mon Apr 12 15:13:00 2010 +0400 @@ -2,6 +2,8 @@ import dmd.Loc; import dmd.TOK; +import dmd.Argument; +import dmd.IdentifierExp; import dmd.Type; import dmd.WANT; import dmd.Scope; @@ -886,14 +888,23 @@ } // For array ops + /****************************************** + * Construct the identifier for the array operation function, + * and build the argument list to pass to it. + */ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + buf.writestring("Exp"); + arguments.shift(cast(void*)this); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + Identifier id = Identifier.generateId("c", fparams.dim); + Argument param = new Argument(STC.STCundefined, type, id, null); + fparams.shift(cast(void*)param); + Expression e = new IdentifierExp(Loc(0), id); + return e; } // Back end diff -r 3356c90e9aac -r 832f71e6f96c dmd/ForeachStatement.d --- a/dmd/ForeachStatement.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/ForeachStatement.d Mon Apr 12 15:13:00 2010 +0400 @@ -654,7 +654,7 @@ case TY.Tdchar: flag += 2; break; } string r = (op == TOK.TOKforeach_reverse) ? "R" : ""; - int j = sprintf(fdname.ptr, "_aApply%*.s%.*s%ld".ptr, r, 2, fntab[flag].ptr, dim); + int j = sprintf(fdname.ptr, "_aApply%.*s%.*s%ld".ptr, r, 2, fntab[flag].ptr, dim); assert(j < fdname.sizeof); fdapply = FuncDeclaration.genCfunc(Type.tindex, fdname[0..j].idup); diff -r 3356c90e9aac -r 832f71e6f96c dmd/MinAssignExp.d --- a/dmd/MinAssignExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/MinAssignExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -73,7 +73,7 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + AssignExp_buildArrayIdent(buf, arguments, "Min"); } Expression buildArrayLoop(Arguments fparams) diff -r 3356c90e9aac -r 832f71e6f96c dmd/MinExp.d --- a/dmd/MinExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/MinExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -144,12 +144,17 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + Exp_buildArrayIdent(buf, arguments, "Min"); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new MinExp(Loc(0), ex1, ex2); + return e; } Identifier opId() diff -r 3356c90e9aac -r 832f71e6f96c dmd/ModExp.d --- a/dmd/ModExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/ModExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -79,12 +79,17 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + Exp_buildArrayIdent(buf, arguments, "Mod"); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new ModExp(Loc(0), ex1, ex2); + return e; } Identifier opId() diff -r 3356c90e9aac -r 832f71e6f96c dmd/MulAssignExp.d --- a/dmd/MulAssignExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/MulAssignExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -90,7 +90,7 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + AssignExp_buildArrayIdent(buf, arguments, "Mul"); } Expression buildArrayLoop(Arguments fparams) diff -r 3356c90e9aac -r 832f71e6f96c dmd/MulExp.d --- a/dmd/MulExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/MulExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -117,12 +117,17 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + Exp_buildArrayIdent(buf, arguments, "Mul"); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new MulExp(Loc(0), ex1, ex2); + return e; } bool isCommutative() diff -r 3356c90e9aac -r 832f71e6f96c dmd/OutBuffer.d --- a/dmd/OutBuffer.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/OutBuffer.d Mon Apr 12 15:13:00 2010 +0400 @@ -195,7 +195,9 @@ final void write4(uint w) { - assert(false); + reserve(4); + *cast(uint*)(this.data + offset) = w; + offset += 4; } final void write(OutBuffer buf) diff -r 3356c90e9aac -r 832f71e6f96c dmd/SliceExp.d --- a/dmd/SliceExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/SliceExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -3,6 +3,10 @@ import dmd.Expression; import dmd.backend.elem; import dmd.UnaExp; +import dmd.Identifier; +import dmd.IdentifierExp; +import dmd.ArrayExp; +import dmd.STC; import dmd.InterState; import dmd.ScopeDsymbol; import dmd.WANT; @@ -444,12 +448,21 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + buf.writestring("Slice"); + arguments.shift(cast(void*)this); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + Identifier id = Identifier.generateId("p", fparams.dim); + Argument param = new Argument(STCconst, type, id, null); + fparams.shift(cast(void*)param); + Expression e = new IdentifierExp(Loc(0), id); + Expressions arguments = new Expressions(); + Expression index = new IdentifierExp(Loc(0), Id.p); + arguments.push(cast(void*)index); + e = new ArrayExp(Loc(0), e, arguments); + return e; } int inlineCost(InlineCostState* ics) diff -r 3356c90e9aac -r 832f71e6f96c dmd/Type.d --- a/dmd/Type.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/Type.d Mon Apr 12 15:13:00 2010 +0400 @@ -894,7 +894,7 @@ return false; } - int isString() + bool isString() { return false; } diff -r 3356c90e9aac -r 832f71e6f96c dmd/TypeDArray.d --- a/dmd/TypeDArray.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/TypeDArray.d Mon Apr 12 15:13:00 2010 +0400 @@ -158,9 +158,10 @@ return e; } - int isString() + bool isString() { - assert(false); + TY nty = next.toBasetype().ty; + return nty == Tchar || nty == Twchar || nty == Tdchar; } bool isZeroInit(Loc loc) diff -r 3356c90e9aac -r 832f71e6f96c dmd/TypeSArray.d --- a/dmd/TypeSArray.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/TypeSArray.d Mon Apr 12 15:13:00 2010 +0400 @@ -258,7 +258,7 @@ return e; } - int isString() + bool isString() { assert(false); } diff -r 3356c90e9aac -r 832f71e6f96c dmd/UnitTestDeclaration.d --- a/dmd/UnitTestDeclaration.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/UnitTestDeclaration.d Mon Apr 12 15:13:00 2010 +0400 @@ -65,22 +65,22 @@ AggregateDeclaration isThis() { - assert(false); + return null; } bool isVirtual() { - assert(false); + return false; } bool addPreInvariant() { - assert(false); + return false; } bool addPostInvariant() { - assert(false); + return false; } void toCBuffer(OutBuffer buf, HdrGenState* hgs) diff -r 3356c90e9aac -r 832f71e6f96c dmd/VarDeclaration.d --- a/dmd/VarDeclaration.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/VarDeclaration.d Mon Apr 12 15:13:00 2010 +0400 @@ -757,9 +757,38 @@ return true; } - int needsAutoDtor() + /****************************************** + * Return TRUE if variable needs to call the destructor. + */ + bool needsAutoDtor() { - assert(false); + //printf("VarDeclaration.needsAutoDtor() %s\n", toChars()); + + if (noauto || storage_class & STCnodtor) + return false; + + // Destructors for structs and arrays of structs + Type tv = type.toBasetype(); + while (tv.ty == Tsarray) + { + TypeSArray ta = cast(TypeSArray)tv; + tv = tv.nextOf().toBasetype(); + } + if (tv.ty == Tstruct) + { + TypeStruct ts = cast(TypeStruct)tv; + StructDeclaration sd = ts.sym; + if (sd.dtor) + return true; + } + + // Destructors for classes + if (storage_class & (STCauto | STCscope)) + { + if (type.isClassHandle()) + return true; + } + return false; } } diff -r 3356c90e9aac -r 832f71e6f96c dmd/XorAssignExp.d --- a/dmd/XorAssignExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/XorAssignExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -33,7 +33,7 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + AssignExp_buildArrayIdent(buf, arguments, "Xor"); } Expression buildArrayLoop(Arguments fparams) diff -r 3356c90e9aac -r 832f71e6f96c dmd/XorExp.d --- a/dmd/XorExp.d Wed Mar 31 16:29:36 2010 +0400 +++ b/dmd/XorExp.d Mon Apr 12 15:13:00 2010 +0400 @@ -77,12 +77,17 @@ void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + Exp_buildArrayIdent(buf, arguments, "Xor"); } Expression buildArrayLoop(Arguments fparams) { - assert(false); + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new XorExp(Loc(0), ex1, ex2); + return e; } MATCH implicitConvTo(Type t)