# HG changeset patch # User korDen # Date 1283532418 -14400 # Node ID 9e39c7de84388962c43c0022c4956350b4630ad4 # Parent c77e9f4f1793d9b7cea189929bdf00b60acbfaf0 Make dmd test suite compile diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/AddAssignExp.d --- a/dmd/AddAssignExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/AddAssignExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -153,14 +153,7 @@ override Expression buildArrayLoop(Arguments fparams) { - /* 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; + return AssignExp_buildArrayLoop!(typeof(this))(fparams); } override Identifier opId() /* For operator overloading */ diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/AddExp.d --- a/dmd/AddExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/AddExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -124,12 +124,7 @@ override Expression buildArrayLoop(Arguments fparams) { - /* 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; + return Exp_buildArrayLoop!(typeof(this))(fparams); } override bool isCommutative() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/AndAssignExp.d --- a/dmd/AndAssignExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/AndAssignExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -41,7 +41,7 @@ override Expression buildArrayLoop(Arguments fparams) { - assert(false); + return AssignExp_buildArrayLoop!(typeof(this))(fparams); } override Identifier opId() /* For operator overloading */ diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/AndExp.d --- a/dmd/AndExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/AndExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -85,12 +85,7 @@ override Expression buildArrayLoop(Arguments fparams) { - /* 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; + return Exp_buildArrayLoop!(typeof(this))(fparams); } override IntRange getIntRange() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/ArrayLiteralExp.d --- a/dmd/ArrayLiteralExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/ArrayLiteralExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -16,6 +16,7 @@ import dmd.HdrGenState; import dmd.backend.dt_t; import dmd.InlineScanState; +import dmd.GlobalExpressions; import dmd.Array; import dmd.ArrayTypes; import dmd.TOK; @@ -238,7 +239,56 @@ override Expression interpret(InterState istate) { - assert(false); + Expressions expsx = null; + +version (LOG) { + printf("ArrayLiteralExp.interpret() %.*s\n", toChars()); +} + if (elements) + { + foreach (size_t i, Expression e; elements) + { + Expression ex; + + ex = e.interpret(istate); + if (ex is EXP_CANT_INTERPRET) + { + delete expsx; + return EXP_CANT_INTERPRET; + } + + /* If any changes, do Copy On Write + */ + if (ex != e) + { + if (!expsx) + { + expsx = new Expressions(); + expsx.setDim(elements.dim); + for (size_t j = 0; j < elements.dim; j++) + { + expsx[j] = elements[j]; + } + } + expsx[i] = ex; + } + } + } + if (elements && expsx) + { + expandTuples(expsx); + if (expsx.dim != elements.dim) + { + delete expsx; + return EXP_CANT_INTERPRET; + } + + ArrayLiteralExp ae = new ArrayLiteralExp(loc, expsx); + ae.type = type; + + return ae; + } + return this; } override MATCH implicitConvTo(Type t) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/BinExp.d --- a/dmd/BinExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/BinExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -672,7 +672,8 @@ void scanForNestedRef(Scope sc) { - assert(false); + e1.scanForNestedRef(sc); + e2.scanForNestedRef(sc); } Expression interpretCommon(InterState istate, Expression function(Type, Expression, Expression) fp) @@ -1959,6 +1960,8 @@ case TOK.TOKleg: case TOK.TOKue: break; + default: + break; /// } return e; @@ -2008,6 +2011,15 @@ return e; } + 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"); + } final void Exp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str) { @@ -2018,13 +2030,25 @@ 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"); + final Expression AssignExp_buildArrayLoop(AssignExpType)(Arguments fparams)// if (is (AssignExpType : AssignExp)) + { + /* 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 AssignExpType(Loc(0), ex1, ex2); + return e; } -} + + final Expression Exp_buildArrayLoop(ExpType)(Arguments fparams) if (is (ExpType : BinExp)) + { + /* Evaluate assign expressions left to right + */ + Expression ex1 = e1.buildArrayLoop(fparams); + Expression ex2 = e2.buildArrayLoop(fparams); + Expression e = new ExpType(Loc(0), ex1, ex2); + return e; + } +} \ No newline at end of file diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/CastExp.d --- a/dmd/CastExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/CastExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -370,7 +370,14 @@ override bool checkSideEffect(int flag) { - assert(false); + /* if not: + * cast(void) + * cast(classtype)func() + */ + if (!to.equals(Type.tvoid) && !(to.ty == Tclass && e1.op == TOKcall && e1.type.ty == Tclass)) + return Expression.checkSideEffect(flag); + + return true; } override void checkEscape() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/ComExp.d --- a/dmd/ComExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/ComExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -13,6 +13,7 @@ import dmd.ArrayTypes; import dmd.TOK; import dmd.TY; +import dmd.Id; import dmd.backend.Util; import dmd.backend.OPER; @@ -69,17 +70,20 @@ override void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + e1.buildArrayIdent(buf, arguments); + buf.writestring("Com"); } override Expression buildArrayLoop(Arguments fparams) { - assert(false); + Expression ex1 = e1.buildArrayLoop(fparams); + Expression e = new ComExp(Loc(0), ex1); + return e; } override Identifier opId() { - assert(false); + return Id.com; } override elem* toElem(IRState* irs) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/Complex.d --- a/dmd/Complex.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/Complex.d Fri Sep 03 20:46:58 2010 +0400 @@ -4,4 +4,6 @@ { T re; T im; + + public static const Complex zero = Complex(0, 0); } \ No newline at end of file diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/ComplexExp.d --- a/dmd/ComplexExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/ComplexExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -105,7 +105,10 @@ override bool isBool(bool result) { - assert(false); + if (result) + return value != Complex!(real).zero; + else + return value == Complex!(real).zero; } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/CompoundStatement.d --- a/dmd/CompoundStatement.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/CompoundStatement.d Fri Sep 03 20:46:58 2010 +0400 @@ -207,7 +207,13 @@ override bool usesEH() { - assert(false); + foreach (Statement s; statements) + { + if (s && s.usesEH()) + return true; + } + + return false; } override BE blockExit() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/CondExp.d --- a/dmd/CondExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/CondExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -3,6 +3,7 @@ import dmd.common; import dmd.BinExp; import dmd.Loc; +import dmd.PtrExp; import dmd.MATCH; import dmd.Expression; import dmd.Scope; @@ -171,22 +172,39 @@ override int isLvalue() { - assert(false); + return e1.isLvalue() && e2.isLvalue(); } - override Expression toLvalue(Scope sc, Expression e) + override Expression toLvalue(Scope sc, Expression ex) { - assert(false); + PtrExp e; + + // convert (econd ? e1 : e2) to *(econd ? &e1 : &e2) + e = new PtrExp(loc, this, type); + + e1 = e1.addressOf(sc); + //e1 = e1.toLvalue(sc, null); + + e2 = e2.addressOf(sc); + //e2 = e2.toLvalue(sc, null); + + typeCombine(sc); + + type = e2.type; + return e; } override Expression modifiableLvalue(Scope sc, Expression e) { - assert(false); + error("conditional expression %s is not a modifiable lvalue", toChars()); + return this; } override Expression checkToBoolean() { - assert(false); + e1 = e1.checkToBoolean(); + e2 = e2.checkToBoolean(); + return this; } override bool checkSideEffect(int flag) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/DeclarationExp.d --- a/dmd/DeclarationExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/DeclarationExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -198,7 +198,8 @@ override void scanForNestedRef(Scope sc) { - assert(false); + //printf("DeclarationExp.scanForNestedRef() %s\n", toChars()); + declaration.parent = sc.parent; } version (DMDV2) { diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/DeleteDeclaration.d --- a/dmd/DeleteDeclaration.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/DeleteDeclaration.d Fri Sep 03 20:46:58 2010 +0400 @@ -9,6 +9,13 @@ import dmd.OutBuffer; import dmd.HdrGenState; import dmd.STC; +import dmd.Id; +import dmd.Argument; +import dmd.ClassDeclaration; +import dmd.TypeFunction; +import dmd.Type; +import dmd.LINK; +import dmd.TY; class DeleteDeclaration : FuncDeclaration { @@ -16,48 +23,87 @@ this(Loc loc, Loc endloc, Arguments arguments) { - assert(false); - super(loc, endloc, null, STC.init, null); + super(loc, endloc, Id.classDelete, STCstatic, null); + this.arguments = arguments; } override Dsymbol syntaxCopy(Dsymbol) { - assert(false); + DeleteDeclaration f; + + f = new DeleteDeclaration(loc, endloc, null); + + FuncDeclaration.syntaxCopy(f); + + f.arguments = Argument.arraySyntaxCopy(arguments); + + return f; } override void semantic(Scope sc) { - assert(false); + ClassDeclaration cd; + + //printf("DeleteDeclaration.semantic()\n"); + + parent = sc.parent; + Dsymbol parent = toParent(); + cd = parent.isClassDeclaration(); + if (!cd && !parent.isStructDeclaration()) + { + error("new allocators only are for class or struct definitions"); + } + type = new TypeFunction(arguments, Type.tvoid, 0, LINKd); + + type = type.semantic(loc, sc); + assert(type.ty == Tfunction); + + // Check that there is only one argument of type void* + TypeFunction tf = cast(TypeFunction)type; + if (Argument.dim(tf.parameters) != 1) + { + error("one argument of type void* expected"); + } + else + { + Argument a = Argument.getNth(tf.parameters, 0); + if (!a.type.equals(Type.tvoid.pointerTo())) + error("one argument of type void* expected, not %s", a.type.toChars()); + } + + FuncDeclaration.semantic(sc); } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - assert(false); + buf.writestring("delete"); + Argument.argsToCBuffer(buf, hgs, arguments, 0); + bodyToCBuffer(buf, hgs); } override string kind() { - assert(false); + return "deallocator"; } override bool isDelete() { - assert(false); + return true; } override bool isVirtual() { - assert(false); + return false; } override bool addPreInvariant() { - assert(false); + return false; } override bool addPostInvariant() { - assert(false); + return false; } version (_DH) { diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/DivAssignExp.d --- a/dmd/DivAssignExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/DivAssignExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -106,7 +106,7 @@ override Expression buildArrayLoop(Arguments fparams) { - assert(false); + return AssignExp_buildArrayLoop!(typeof(this))(fparams); } override Identifier opId() /* For operator overloading */ diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/DivExp.d --- a/dmd/DivExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/DivExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -118,12 +118,7 @@ override Expression buildArrayLoop(Arguments fparams) { - /* 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; + return Exp_buildArrayLoop!(typeof(this))(fparams); } override IntRange getIntRange() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/DotVarExp.d --- a/dmd/DotVarExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/DotVarExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -225,7 +225,36 @@ override Expression interpret(InterState istate) { - assert(false); + Expression e = EXP_CANT_INTERPRET; + +version (LOG) { + printf("DotVarExp.interpret() %.*s\n", toChars()); +} + + Expression ex = e1.interpret(istate); + if (ex !is EXP_CANT_INTERPRET) + { + if (ex.op == TOKstructliteral) + { + StructLiteralExp se = cast(StructLiteralExp)ex; + VarDeclaration v = var.isVarDeclaration(); + if (v) + { + e = se.getField(type, v.offset); + if (!e) + e = EXP_CANT_INTERPRET; + return e; + } + } else { + error("%s.%s is not yet implemented at compile time", ex.toChars(), var.toChars()); + } + } + +version (LOG) { + if (e is EXP_CANT_INTERPRET) + printf("DotVarExp.interpret() %.*s = EXP_CANT_INTERPRET\n", toChars()); +} + return e; } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/ForStatement.d --- a/dmd/ForStatement.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/ForStatement.d Fri Sep 03 20:46:58 2010 +0400 @@ -3,6 +3,7 @@ import dmd.common; import dmd.Statement; import dmd.Expression; +import dmd.GlobalExpressions; import dmd.Loc; import dmd.Scope; import dmd.InterState; @@ -156,7 +157,79 @@ override Expression interpret(InterState istate) { - assert(false); +version (LOG) { + printf("ForStatement.interpret()\n"); +} + if (istate.start == this) + istate.start = null; + + Expression e; + + if (init) + { + e = init.interpret(istate); + if (e is EXP_CANT_INTERPRET) + return e; + assert(!e); + } + + if (istate.start) + { + e = body_ ? body_.interpret(istate) : null; + if (istate.start) + return null; + if (e is EXP_CANT_INTERPRET) + return e; + if (e is EXP_BREAK_INTERPRET) + return null; + if (e is EXP_CONTINUE_INTERPRET) + goto Lcontinue; + if (e) + return e; + } + + while (true) + { + if (!condition) + goto Lhead; + e = condition.interpret(istate); + if (e is EXP_CANT_INTERPRET) + break; + if (!e.isConst()) + { + e = EXP_CANT_INTERPRET; + break; + } + if (e.isBool(true)) + { + Lhead: + e = body_ ? body_.interpret(istate) : null; + if (e is EXP_CANT_INTERPRET) + break; + if (e is EXP_BREAK_INTERPRET) + { + e = null; + break; + } + if (e && e !is EXP_CONTINUE_INTERPRET) + break; + Lcontinue: + if (increment) + { + e = increment.interpret(istate); + if (e is EXP_CANT_INTERPRET) + break; + } + } + else if (e.isBool(false)) + { + e = null; + break; + } + else + assert(0); + } + return e; } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/FuncExp.d --- a/dmd/FuncExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/FuncExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -87,7 +87,8 @@ override void scanForNestedRef(Scope sc) { - assert(false); + //printf("FuncExp.scanForNestedRef(%s)\n", toChars()); + //fd.parent = sc.parent; } override string toChars() @@ -122,7 +123,8 @@ override int inlineCost(InlineCostState* ics) { - assert(false); + // Right now, this makes the function be output to the .obj file twice. + return COST_MAX; } } diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/GotoCaseStatement.d --- a/dmd/GotoCaseStatement.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/GotoCaseStatement.d Fri Sep 03 20:46:58 2010 +0400 @@ -13,6 +13,11 @@ import dmd.BE; import dmd.WANT; +import dmd.backend.Util; +import dmd.backend.block; +import dmd.backend.BC; +import dmd.backend.Blockx; + class GotoCaseStatement : Statement { Expression exp; // NULL, or which case to goto @@ -75,6 +80,39 @@ override void toIR(IRState* irs) { - assert(false); + block* b; + Blockx* blx = irs.blx; + block* bdest = cs.cblock; + + if (!bdest) + { + bdest = block_calloc(blx); + cs.cblock = bdest; + } + + b = blx.curblock; + + // The rest is equivalent to GotoStatement + + // Adjust exception handler scope index if in different try blocks + if (b.Btry != bdest.Btry) + { + // Check that bdest is in an enclosing try block + for (block* bt = b.Btry; bt != bdest.Btry; bt = bt.Btry) + { + if (!bt) + { + //printf("b.Btry = %p, bdest.Btry = %p\n", b.Btry, bdest.Btry); + error("cannot goto into try block"); + break; + } + } + + //setScopeIndex(blx, b, bdest.Btry ? bdest.Btry.Bscope_index : -1); + } + + list_append(&b.Bsucc,bdest); + incUsage(irs, loc); + block_next(blx, BC.BCgoto, null); } } diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/IndexExp.d --- a/dmd/IndexExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/IndexExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -288,7 +288,14 @@ override void scanForNestedRef(Scope sc) { - assert(false); + e1.scanForNestedRef(sc); + + if (lengthVar) + { + //printf("lengthVar\n"); + lengthVar.parent = sc.parent; + } + e2.scanForNestedRef(sc); } override elem* toElem(IRState* irs) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/InterfaceDeclaration.d --- a/dmd/InterfaceDeclaration.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/InterfaceDeclaration.d Fri Sep 03 20:46:58 2010 +0400 @@ -50,7 +50,15 @@ override Dsymbol syntaxCopy(Dsymbol s) { - assert(false); + InterfaceDeclaration id; + + if (s) + id = cast(InterfaceDeclaration)s; + else + id = new InterfaceDeclaration(loc, ident, null); + + ClassDeclaration.syntaxCopy(id); + return id; } override void semantic(Scope sc) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/MinAssignExp.d --- a/dmd/MinAssignExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/MinAssignExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -81,7 +81,7 @@ override Expression buildArrayLoop(Arguments fparams) { - assert(false); + return AssignExp_buildArrayLoop!(typeof(this))(fparams); } override Identifier opId() /* For operator overloading */ diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/MinExp.d --- a/dmd/MinExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/MinExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -150,12 +150,7 @@ override Expression buildArrayLoop(Arguments fparams) { - /* 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; + return Exp_buildArrayLoop!(typeof(this))(fparams); } override Identifier opId() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/ModAssignExp.d --- a/dmd/ModAssignExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/ModAssignExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -38,12 +38,12 @@ override void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + AssignExp_buildArrayIdent(buf, arguments, "Mod"); } override Expression buildArrayLoop(Arguments fparams) { - assert(false); + return AssignExp_buildArrayLoop!(typeof(this))(fparams); } override Identifier opId() /* For operator overloading */ diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/ModExp.d --- a/dmd/ModExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/ModExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -85,12 +85,7 @@ override Expression buildArrayLoop(Arguments fparams) { - /* 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; + return Exp_buildArrayLoop!(typeof(this))(fparams); } override Identifier opId() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/MulAssignExp.d --- a/dmd/MulAssignExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/MulAssignExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -98,7 +98,7 @@ override Expression buildArrayLoop(Arguments fparams) { - assert(false); + return AssignExp_buildArrayLoop!(typeof(this))(fparams); } override Identifier opId() /* For operator overloading */ diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/MulExp.d --- a/dmd/MulExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/MulExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -123,12 +123,7 @@ override Expression buildArrayLoop(Arguments fparams) { - /* 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; + return Exp_buildArrayLoop!(typeof(this))(fparams); } override bool isCommutative() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/NegExp.d --- a/dmd/NegExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/NegExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -72,12 +72,15 @@ override void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + e1.buildArrayIdent(buf, arguments); + buf.writestring("Neg"); } override Expression buildArrayLoop(Arguments fparams) { - assert(false); + Expression ex1 = e1.buildArrayLoop(fparams); + Expression e = new NegExp(Loc(0), ex1); + return e; } override Identifier opId() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/NewAnonClassExp.d --- a/dmd/NewAnonClassExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/NewAnonClassExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -6,9 +6,14 @@ import dmd.Loc; import dmd.Scope; import dmd.ClassDeclaration; +import dmd.DeclarationExp; +import dmd.NewExp; +import dmd.CommaExp; +import dmd.PREC; import dmd.HdrGenState; import dmd.ArrayTypes; import dmd.TOK; +import dmd.expression.Util; class NewAnonClassExp : Expression { @@ -21,33 +26,75 @@ this(Loc loc, Expression thisexp, Expressions newargs, ClassDeclaration cd, Expressions arguments) { - assert(false); - super(loc, TOK.init, 0); + super(loc, TOKnewanonclass, NewAnonClassExp.sizeof); + this.thisexp = thisexp; + this.newargs = newargs; + this.cd = cd; + this.arguments = arguments; } override Expression syntaxCopy() { - assert(false); + return new NewAnonClassExp(loc, + thisexp ? thisexp.syntaxCopy() : null, + arraySyntaxCopy(newargs), + cast(ClassDeclaration)cd.syntaxCopy(null), + arraySyntaxCopy(arguments)); } - + override Expression semantic(Scope sc) { - assert(false); +version (LOGSEMANTIC) { + printf("NewAnonClassExp.semantic() %s\n", toChars()); + //printf("thisexp = %p\n", thisexp); + //printf("type: %s\n", type.toChars()); +} + + Expression d = new DeclarationExp(loc, cd); + d = d.semantic(sc); + + Expression n = new NewExp(loc, thisexp, newargs, cd.type, arguments); + + Expression c = new CommaExp(loc, d, n); + return c.semantic(sc); } override bool checkSideEffect(int flag) { - assert(false); + return true; } - void toCBuffer(OutBuffer buf, HdrGenState hgs) + void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - assert(false); + if (thisexp) + { + expToCBuffer(buf, hgs, thisexp, PREC.PREC_primary); + buf.writeByte('.'); + } + buf.writestring("new"); + if (newargs && newargs.dim) + { + buf.writeByte('('); + argsToCBuffer(buf, newargs, hgs); + buf.writeByte(')'); + } + buf.writestring(" class "); + if (arguments && arguments.dim) + { + buf.writeByte('('); + argsToCBuffer(buf, arguments, hgs); + buf.writeByte(')'); + } + //buf.writestring(" { }"); + if (cd) + { + cd.toCBuffer(buf, hgs); + } } override bool canThrow() { - assert(false); + return true; } } diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/NewDeclaration.d --- a/dmd/NewDeclaration.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/NewDeclaration.d Fri Sep 03 20:46:58 2010 +0400 @@ -5,10 +5,17 @@ import dmd.Loc; import dmd.ArrayTypes; import dmd.Dsymbol; +import dmd.Argument; +import dmd.ClassDeclaration; +import dmd.Type; +import dmd.TypeFunction; +import dmd.LINK; +import dmd.TY; import dmd.Scope; import dmd.OutBuffer; import dmd.HdrGenState; import dmd.STC; +import dmd.Id; class NewDeclaration : FuncDeclaration { @@ -17,43 +24,85 @@ this(Loc loc, Loc endloc, Arguments arguments, int varargs) { - assert(false); - super(loc, loc, null, STC.init, null); + super(loc, endloc, Id.classNew, STCstatic, null); + this.arguments = arguments; + this.varargs = varargs; } override Dsymbol syntaxCopy(Dsymbol) { - assert(false); + NewDeclaration f; + + f = new NewDeclaration(loc, endloc, null, varargs); + + FuncDeclaration.syntaxCopy(f); + + f.arguments = Argument.arraySyntaxCopy(arguments); + + return f; } override void semantic(Scope sc) { - assert(false); + ClassDeclaration cd; + Type tret; + + //printf("NewDeclaration.semantic()\n"); + + parent = sc.parent; + Dsymbol parent = toParent(); + cd = parent.isClassDeclaration(); + if (!cd && !parent.isStructDeclaration()) + { + error("new allocators only are for class or struct definitions"); + } + tret = Type.tvoid.pointerTo(); + type = new TypeFunction(arguments, tret, varargs, LINKd); + + type = type.semantic(loc, sc); + assert(type.ty == Tfunction); + + // Check that there is at least one argument of type size_t + TypeFunction tf = cast(TypeFunction)type; + if (Argument.dim(tf.parameters) < 1) + { + error("at least one argument of type size_t expected"); + } + else + { + Argument a = Argument.getNth(tf.parameters, 0); + if (!a.type.equals(Type.tsize_t)) + error("first argument must be type size_t, not %s", a.type.toChars()); + } + + FuncDeclaration.semantic(sc); } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { - assert(false); + buf.writestring("new"); + Argument.argsToCBuffer(buf, hgs, arguments, varargs); + bodyToCBuffer(buf, hgs); } override string kind() { - assert(false); + return "allocator"; } override bool isVirtual() { - assert(false); + return false; } override bool addPreInvariant() { - assert(false); + return false; } override bool addPostInvariant() { - assert(false); + return false; } override NewDeclaration isNewDeclaration() { return this; } diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/NewExp.d --- a/dmd/NewExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/NewExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -720,7 +720,7 @@ override bool checkSideEffect(int flag) { - assert(false); + return true; } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/NullExp.d --- a/dmd/NullExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/NullExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -138,7 +138,7 @@ override Expression interpret(InterState istate) { - assert(false); + return this; } override elem* toElem(IRState* irs) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/OrAssignExp.d --- a/dmd/OrAssignExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/OrAssignExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -36,12 +36,12 @@ override void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + AssignExp_buildArrayIdent(buf, arguments, "Or"); } override Expression buildArrayLoop(Arguments fparams) { - assert(false); + return AssignExp_buildArrayLoop!(typeof(this))(fparams); } override Identifier opId() /* For operator overloading */ diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/OrExp.d --- a/dmd/OrExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/OrExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -81,12 +81,12 @@ override void buildArrayIdent(OutBuffer buf, Expressions arguments) { - assert(false); + Exp_buildArrayIdent(buf, arguments, "Or"); } override Expression buildArrayLoop(Arguments fparams) { - assert(false); + return Exp_buildArrayLoop!(typeof(this))(fparams); } override MATCH implicitConvTo(Type t) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/Parser.d --- a/dmd/Parser.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/Parser.d Fri Sep 03 20:46:58 2010 +0400 @@ -1718,14 +1718,44 @@ return f; } + /***************************************** + * Parse a new definition: + * new(arguments) { body } + * Current token is 'new'. + */ NewDeclaration parseNew() { - assert(false); + NewDeclaration f; + scope Arguments arguments = new Arguments(); + int varargs; + Loc loc = this.loc; + + nextToken(); + arguments = parseParameters(&varargs); + f = new NewDeclaration(loc, Loc(0), arguments, varargs); + parseContracts(f); + return f; } + /***************************************** + * Parse a delete definition: + * delete(arguments) { body } + * Current token is 'delete'. + */ DeleteDeclaration parseDelete() { - assert(false); + DeleteDeclaration f; + scope Arguments arguments; + int varargs; + Loc loc = this.loc; + + nextToken(); + arguments = parseParameters(&varargs); + if (varargs) + error("... not allowed in delete function parameter list"); + f = new DeleteDeclaration(loc, Loc(0), arguments); + parseContracts(f); + return f; } Arguments parseParameters(int* pvarargs) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/RealExp.d --- a/dmd/RealExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/RealExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -110,7 +110,7 @@ override bool isBool(bool result) { - assert(false); + return result ? (value != 0) : (value == 0); } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/Statement.d --- a/dmd/Statement.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/Statement.d Fri Sep 03 20:46:58 2010 +0400 @@ -120,9 +120,11 @@ assert(false); } + // TRUE if statement uses exception handling + bool usesEH() { - assert(false); + return false; } BE blockExit() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/StructLiteralExp.d --- a/dmd/StructLiteralExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/StructLiteralExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -2,11 +2,13 @@ import dmd.common; import dmd.Expression; +import dmd.GlobalExpressions; import dmd.MOD; import dmd.TypeStruct; import dmd.TypeSArray; import dmd.expression.Util; import dmd.ErrorExp; +import dmd.Array; import dmd.Dsymbol; import dmd.VarDeclaration; import dmd.StructDeclaration; @@ -63,7 +65,7 @@ override Expression syntaxCopy() { - assert(false); + return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements)); } override Expression semantic(Scope sc) @@ -459,12 +461,163 @@ override Expression interpret(InterState istate) { - assert(false); + Expressions expsx = null; + +version (LOG) { + printf("StructLiteralExp.interpret() %.*s\n", toChars()); +} + /* We don't know how to deal with overlapping fields + */ + if (sd.hasUnions) + { + error("Unions with overlapping fields are not yet supported in CTFE"); + return EXP_CANT_INTERPRET; + } + + if (elements) + { + foreach (size_t i, Expression e; elements) + { + if (!e) + continue; + + Expression ex = e.interpret(istate); + if (ex is EXP_CANT_INTERPRET) + { + delete expsx; + return EXP_CANT_INTERPRET; + } + + /* If any changes, do Copy On Write + */ + if (ex != e) + { + if (!expsx) + { + expsx = new Expressions(); + expsx.setDim(elements.dim); + for (size_t j = 0; j < elements.dim; j++) + { + expsx[j] = elements[j]; + } + } + expsx[i] = ex; + } + } + } + if (elements && expsx) + { + expandTuples(expsx); + if (expsx.dim != elements.dim) + { + delete expsx; + return EXP_CANT_INTERPRET; + } + StructLiteralExp se = new StructLiteralExp(loc, sd, expsx); + se.type = type; + return se; + } + return this; } override dt_t** toDt(dt_t** pdt) { - assert(false); + Array dts; + dt_t *dt; + dt_t *d; + uint offset; + + //printf("StructLiteralExp.toDt() %s)\n", toChars()); + dts.setDim(sd.fields.dim); + dts.zero(); + assert(elements.dim <= sd.fields.dim); + + foreach (uint i, Expression e; elements) + { + if (!e) + continue; + + dt = null; + e.toDt(&dt); + dts.data[i] = dt; + } + + offset = 0; + foreach (uint j, VarDeclaration v; sd.fields) + { + d = cast(dt_t*)dts.data[j]; + if (!d) + { // An instance specific initializer was not provided. + // Look to see if there's a default initializer from the + // struct definition + if (v.init) + { + d = v.init.toDt(); + } + else if (v.offset >= offset) + { + uint k; + uint offset2 = v.offset + cast(uint)v.type.size(); + // Make sure this field (v) does not overlap any explicitly + // initialized field. + for (k = j + 1; 1; k++) + { + if (k == dts.dim) // didn't find any overlap + { + v.type.toDt(&d); + break; + } + VarDeclaration v2 = sd.fields[k]; + + if (v2.offset < offset2 && dts.data[k]) + break; // overlap + } + } + } + if (d) + { + if (v.offset < offset) + error("duplicate union initialization for %s", v.toChars()); + else + { + uint sz = dt_size(d); + uint vsz = cast(uint)v.type.size(); + uint voffset = v.offset; + assert(sz <= vsz); + + uint dim = 1; + for (Type vt = v.type.toBasetype(); vt.ty == Tsarray; vt = vt.nextOf().toBasetype()) + { + TypeSArray tsa = cast(TypeSArray)vt; + dim *= tsa.dim.toInteger(); + } + + for (size_t i = 0; i < dim; i++) + { + if (offset < voffset) + pdt = dtnzeros(pdt, voffset - offset); + if (!d) + { + if (v.init) + d = v.init.toDt(); + else + v.type.toDt(&d); + } + pdt = dtcat(pdt, d); + d = null; + offset = voffset + sz; + voffset += vsz / dim; + if (sz == vsz) + break; + } + } + } + } + + if (offset < sd.structsize) + pdt = dtnzeros(pdt, sd.structsize - offset); + + return pdt; } version(DMDV2) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/ThisExp.d --- a/dmd/ThisExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/ThisExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -131,7 +131,8 @@ override void scanForNestedRef(Scope sc) { - assert(false); + assert(var); + var.isVarDeclaration().checkNestedReference(sc, Loc(0)); } override int inlineCost(InlineCostState* ics) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/TypeFunction.d --- a/dmd/TypeFunction.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/TypeFunction.d Fri Sep 03 20:46:58 2010 +0400 @@ -4,6 +4,7 @@ import dmd.TypeNext; import dmd.TypeSArray; import dmd.TypeArray; +import dmd.TemplateTupleParameter; import dmd.ArrayTypes; import dmd.LINK; import dmd.StructDeclaration; @@ -12,6 +13,9 @@ import dmd.STC; import dmd.MOD; import dmd.PROT; +import dmd.TypeIdentifier; +import dmd.TemplateParameter; +import dmd.Tuple; import dmd.Type; import dmd.Loc; import dmd.Scope; @@ -26,6 +30,7 @@ import dmd.RET; import dmd.TY; import dmd.Util; +import dmd.TemplateInstance : isTuple; import dmd.backend.TYPE; import dmd.backend.PARAM; @@ -395,7 +400,100 @@ override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { - assert(false); + //printf("TypeFunction.deduceType()\n"); + //printf("\tthis = %d, ", ty); print(); + //printf("\ttparam = %d, ", tparam.ty); tparam.print(); + + // Extra check that function characteristics must match + if (tparam && tparam.ty == Tfunction) + { + TypeFunction tp = cast(TypeFunction)tparam; + if (varargs != tp.varargs || + linkage != tp.linkage) + return MATCHnomatch; + + size_t nfargs = Argument.dim(this.parameters); + size_t nfparams = Argument.dim(tp.parameters); + + /* See if tuple match + */ + if (nfparams > 0 && nfargs >= nfparams - 1) + { + /* See if 'A' of the template parameter matches 'A' + * of the type of the last function parameter. + */ + Argument fparam = Argument.getNth(tp.parameters, nfparams - 1); + assert(fparam); + assert(fparam.type); + if (fparam.type.ty != Tident) + goto L1; + TypeIdentifier tid = cast(TypeIdentifier)fparam.type; + if (tid.idents.dim) + goto L1; + + /* Look through parameters to find tuple matching tid.ident + */ + size_t tupi = 0; + for (; 1; tupi++) + { + if (tupi == parameters.dim) + goto L1; + TemplateParameter t = parameters[tupi]; + TemplateTupleParameter tup = t.isTemplateTupleParameter(); + if (tup && tup.ident.equals(tid.ident)) + break; + } + + /* The types of the function arguments [nfparams - 1 .. nfargs] + * now form the tuple argument. + */ + int tuple_dim = nfargs - (nfparams - 1); + + /* See if existing tuple, and whether it matches or not + */ + Object o = dedtypes[tupi]; + if (o) + { + // Existing deduced argument must be a tuple, and must match + Tuple t = isTuple(o); + if (!t || t.objects.dim != tuple_dim) + return MATCHnomatch; + for (size_t i = 0; i < tuple_dim; i++) + { + Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i); + if (!arg.type.equals(t.objects[i])) + return MATCHnomatch; + } + } + else + { // Create new tuple + Tuple t = new Tuple(); + t.objects.setDim(tuple_dim); + for (size_t i = 0; i < tuple_dim; i++) + { + Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i); + t.objects[i] = arg.type; + } + dedtypes[tupi] = t; + } + nfparams--; // don't consider the last parameter for type deduction + goto L2; + } + + L1: + if (nfargs != nfparams) + return MATCHnomatch; + L2: + for (size_t i = 0; i < nfparams; i++) + { + Argument a = Argument.getNth(this.parameters, i); + Argument ap = Argument.getNth(tp.parameters, i); + if (a.storageClass != ap.storageClass || + !a.type.deduceType(sc, ap.type, parameters, dedtypes)) + return MATCHnomatch; + } + } + return Type.deduceType(sc, tparam, parameters, dedtypes); } override TypeInfoDeclaration getTypeInfoDeclaration() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/UAddExp.d --- a/dmd/UAddExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/UAddExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -7,6 +7,7 @@ import dmd.Loc; import dmd.Scope; import dmd.TOK; +import dmd.Id; class UAddExp : UnaExp { @@ -35,6 +36,6 @@ override Identifier opId() { - assert(false); + return Id.uadd; } } diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/UnrolledLoopStatement.d --- a/dmd/UnrolledLoopStatement.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/UnrolledLoopStatement.d Fri Sep 03 20:46:58 2010 +0400 @@ -103,7 +103,18 @@ override int inlineCost(InlineCostState* ics) { - assert(false); + int cost = 0; + + foreach (Statement s; statements) + { + if (s) + { + cost += s.inlineCost(ics); + if (cost >= COST_MAX) + break; + } + } + return cost; } override Expression doInline(InlineDoState ids) @@ -113,7 +124,12 @@ override Statement inlineScan(InlineScanState* iss) { - assert(false); + foreach (ref Statement s; statements) + { + if (s) + s = s.inlineScan(iss); + } + return this; } override void toIR(IRState* irs) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/Util.d --- a/dmd/Util.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/Util.d Fri Sep 03 20:46:58 2010 +0400 @@ -75,7 +75,11 @@ void warning(T...)(Loc loc, string format, T t) { - assert(false); + if (global.params.warnings && !global.gag) + { + write("warning - "); + error(loc, format, t); + } } void error(T...)(Loc loc, string format, T t) diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/WhileStatement.d --- a/dmd/WhileStatement.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/WhileStatement.d Fri Sep 03 20:46:58 2010 +0400 @@ -48,7 +48,7 @@ override bool hasContinue() { - assert(false); + return true; } override bool usesEH() diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/XorAssignExp.d --- a/dmd/XorAssignExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/XorAssignExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -40,7 +40,7 @@ override Expression buildArrayLoop(Arguments fparams) { - assert(false); + return AssignExp_buildArrayLoop!(typeof(this))(fparams); } override Identifier opId() /* For operator overloading */ diff -r c77e9f4f1793 -r 9e39c7de8438 dmd/XorExp.d --- a/dmd/XorExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/XorExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -83,12 +83,7 @@ override Expression buildArrayLoop(Arguments fparams) { - /* 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; + return Exp_buildArrayLoop!(typeof(this))(fparams); } override MATCH implicitConvTo(Type t)