diff dmd/PowAssignExp.d @ 135:af1bebfd96a4 dmd2037

dmd 2.038
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Mon, 13 Sep 2010 22:19:42 +0100
parents
children 14feb7ae01a6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/PowAssignExp.d	Mon Sep 13 22:19:42 2010 +0100
@@ -0,0 +1,77 @@
+module dmd.PowAssignExp;
+
+import dmd.BinExp;
+import dmd.Scope;
+import dmd.Loc;
+import dmd.Identifier;
+import dmd.Expression;
+import dmd.TOK;
+import dmd.STC;
+import dmd.PowExp;
+import dmd.AssignExp;
+import dmd.Lexer;
+import dmd.VarDeclaration;
+import dmd.ExpInitializer;
+import dmd.DeclarationExp;
+import dmd.VarExp;
+import dmd.CommaExp;
+import dmd.ErrorExp;
+import dmd.Id;
+
+// Only a reduced subset of operations for now.
+class PowAssignExp : BinExp
+{
+    this(Loc loc, Expression e1, Expression e2)
+    {
+        super(loc, TOK.TOKpowass, PowAssignExp.sizeof, e1, e2);
+    }
+    
+    override Expression semantic(Scope sc)
+    {
+        Expression e;
+
+        if (type)
+	    return this;
+
+        BinExp.semantic(sc);
+        e2 = resolveProperties(sc, e2);
+
+        e = op_overload(sc);
+        if (e)
+	        return e;
+
+        e1 = e1.modifiableLvalue(sc, e1);
+        assert(e1.type && e2.type);
+
+        if ( (e1.type.isintegral() || e1.type.isfloating()) &&
+	     (e2.type.isintegral() || e2.type.isfloating()))
+        {
+	        if (e1.op == TOKvar)
+	        {   // Rewrite: e1 = e1 ^^ e2
+	            e = new PowExp(loc, e1.syntaxCopy(), e2);
+	            e = new AssignExp(loc, e1, e);
+	        }
+	        else
+	        {   // Rewrite: ref tmp = e1; tmp = tmp ^^ e2
+	            Identifier id = Lexer.uniqueId("__powtmp");
+	            auto v = new VarDeclaration(e1.loc, e1.type, id, new ExpInitializer(loc, e1));
+	            v.storage_class |= STC.STCref | STC.STCforeach;
+	            Expression de = new DeclarationExp(e1.loc, v);
+	            VarExp ve = new VarExp(e1.loc, v);
+	            e = new PowExp(loc, ve, e2);
+	            e = new AssignExp(loc, new VarExp(e1.loc, v), e);
+	            e = new CommaExp(loc, de, e);
+	        }
+	        e = e.semantic(sc);
+	        return e;
+        }
+        error("%s ^^= %s is not supported", e1.type.toChars(), e2.type.toChars() );
+        return new ErrorExp();
+    }
+    
+    // For operator overloading
+    Identifier opId()
+    {
+        return Id.powass;
+    }
+};
\ No newline at end of file