Mercurial > projects > ddmd
diff dmd/WithStatement.d @ 129:010eb8f0e18d
further work on dmd test suite
author | korDen |
---|---|
date | Sun, 05 Sep 2010 15:32:22 +0400 |
parents | e28b18c23469 |
children | e3afd1303184 |
line wrap: on
line diff
--- a/dmd/WithStatement.d Sat Sep 04 01:33:05 2010 +0100 +++ b/dmd/WithStatement.d Sun Sep 05 15:32:22 2010 +0400 @@ -6,12 +6,29 @@ import dmd.VarDeclaration; import dmd.Loc; import dmd.OutBuffer; +import dmd.ScopeDsymbol; +import dmd.TypeExp; +import dmd.TOK; +import dmd.Initializer; +import dmd.ExpInitializer; +import dmd.Id; +import dmd.ScopeExp; +import dmd.WithScopeSymbol; +import dmd.TY; +import dmd.Type; import dmd.HdrGenState; import dmd.InlineScanState; import dmd.IRState; import dmd.Scope; import dmd.BE; +import dmd.backend.Symbol; +import dmd.backend.block; +import dmd.backend.Blockx; +import dmd.backend.elem; +import dmd.backend.Util; +import dmd.backend.OPER; + class WithStatement : Statement { Expression exp; @@ -28,12 +45,74 @@ override Statement syntaxCopy() { - assert(false); + WithStatement s = new WithStatement(loc, exp.syntaxCopy(), body_ ? body_.syntaxCopy() : null); + return s; } override Statement semantic(Scope sc) { - assert(false); + ScopeDsymbol sym; + Initializer init; + + //printf("WithStatement.semantic()\n"); + exp = exp.semantic(sc); + exp = resolveProperties(sc, exp); + if (exp.op == TOKimport) + { + ScopeExp es = cast(ScopeExp)exp; + + sym = es.sds; + } + else if (exp.op == TOKtype) + { + TypeExp es = cast(TypeExp)exp; + + sym = es.type.toDsymbol(sc).isScopeDsymbol(); + if (!sym) + { + error("%s has no members", es.toChars()); + body_ = body_.semantic(sc); + return this; + } + } + else + { + Type t = exp.type; + + assert(t); + t = t.toBasetype(); + if (t.isClassHandle()) + { + init = new ExpInitializer(loc, exp); + wthis = new VarDeclaration(loc, exp.type, Id.withSym, init); + wthis.semantic(sc); + + sym = new WithScopeSymbol(this); + sym.parent = sc.scopesym; + } + else if (t.ty == Tstruct) + { + Expression e = exp.addressOf(sc); + init = new ExpInitializer(loc, e); + wthis = new VarDeclaration(loc, e.type, Id.withSym, init); + wthis.semantic(sc); + sym = new WithScopeSymbol(this); + sym.parent = sc.scopesym; + } + else + { + error("with expressions must be class objects, not '%s'", exp.type.toChars()); + return null; + } + } + sc = sc.push(sym); + + if (body_) + body_ = body_.semantic(sc); + + sc.pop(); + + return this; } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) @@ -48,7 +127,14 @@ override BE blockExit() { - assert(false); + BE result = BEnone; + if (exp.canThrow()) + result = BEthrow; + if (body_) + result |= body_.blockExit(); + else + result |= BEfallthru; + return result; } override Statement inlineScan(InlineScanState* iss) @@ -58,6 +144,34 @@ override void toIR(IRState* irs) { - assert(false); + Symbol* sp; + elem* e; + elem* ei; + ExpInitializer ie; + Blockx* blx = irs.blx; + + //printf("WithStatement.toIR()\n"); + if (exp.op == TOKimport || exp.op == TOKtype) + { + } + else + { + // Declare with handle + sp = wthis.toSymbol(); + symbol_add(sp); + + // Perform initialization of with handle + ie = wthis.init.isExpInitializer(); + assert(ie); + ei = ie.exp.toElem(irs); + e = el_var(sp); + e = el_bin(OPeq,e.Ety, e, ei); + elem_setLoc(e, loc); + incUsage(irs, loc); + block_appendexp(blx.curblock,e); + } + // Execute with block + if (body_) + body_.toIR(irs); } }