2001-09-24 Miguel de Icaza <miguel@ximian.com>
authorMiguel de Icaza <miguel@gnome.org>
Mon, 24 Sep 2001 18:34:15 +0000 (18:34 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Mon, 24 Sep 2001 18:34:15 +0000 (18:34 -0000)
* assign.cs: track location.
(Resolve): Use implicit conversions on assignment.

* literal.cs: Oops.  Not good, Emit of short access values should
pass (Bytes) or the wrong argument will be selected.

* expression.cs (Unary::Emit): Emit code for -expr.

(Unary::ResolveOperator): Handle `Substract' for non-constants
(substract from zero from the non-constants).
Deal with Doubles as well.

(Expression::ConvertImplicitRequired): New routine that reports an
error if no implicit conversion exists.

(Invocation::OverloadResolve): Store the converted implicit
expressions if we make them

svn path=/trunk/mcs/; revision=945

mcs/mcs/ChangeLog
mcs/mcs/TODO
mcs/mcs/assign.cs
mcs/mcs/cs-parser.jay
mcs/mcs/cs-tokenizer.cs
mcs/mcs/expression.cs
mcs/mcs/literal.cs
mcs/mcs/makefile

index 025c461ff0a44ac5557ec1413524cdb66f2b44f0..bc59ccce20a410f996e408a04f3925a7adf38ed0 100755 (executable)
@@ -1,3 +1,23 @@
+2001-09-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs: track location.
+       (Resolve): Use implicit conversions on assignment.
+
+       * literal.cs: Oops.  Not good, Emit of short access values should
+       pass (Bytes) or the wrong argument will be selected.
+
+       * expression.cs (Unary::Emit): Emit code for -expr.
+       
+       (Unary::ResolveOperator): Handle `Substract' for non-constants
+       (substract from zero from the non-constants).
+       Deal with Doubles as well. 
+       
+       (Expression::ConvertImplicitRequired): New routine that reports an
+       error if no implicit conversion exists. 
+
+       (Invocation::OverloadResolve): Store the converted implicit
+       expressions if we make them
+       
 2001-09-24  Ravi Pratap  <ravi@ximian.com>
 
        * class.cs (ConstructorInitializer): Take a Location argument.
index 00fa43010748a8eb7157df2c51ff2bb90022e943..87190a25b6812a69c1947435683fe33f1d3b7f3b 100644 (file)
 
        And we can also make sure that we dont generate extra pops.
 
+* ConvertImplicit
+
+       Currently ConvertImplicit will not catch things like:
+
+       - IntLiteral in a float context to generate a -FloatLiteral.
+       Instead it will perform an integer load followed by a conversion.
+
index 98d95856ceb91d97ab57b2ac73ff1317aef5f01e..a32516a8fbd5fdf6a77b26106bd29f98b8687ad3 100755 (executable)
@@ -13,11 +13,13 @@ using System.Reflection.Emit;
 namespace CIR {
        public class Assign : Expression {
                Expression target, source;
+               Location l;
                
-               public Assign (Expression target, Expression source)
+               public Assign (Expression target, Expression source, Location l)
                {
                        this.target = target;
                        this.source = source;
+                       this.l = l;
                }
 
                public Expression Target {
@@ -48,9 +50,19 @@ namespace CIR {
                        if (target == null || source == null)
                                return null;
 
+                       Type target_type = target.Type;
+                       Type source_type = source.Type;
+                       
+                       if (target_type != source_type){
+                               source = ConvertImplicitRequired (tc, source, target_type, l);
+                               if (source == null)
+                                       return null;
+                       }
+                       
                        if (!(target is LValue)){
                                tc.RootContext.Report.Error (131, "Left hand of an assignment must be a variable, a property or an indexer");
                        }
+                       type = target_type;
                        return this;
                }
 
index f31bd97f41552cdea67aad85a7783617075373c5..8413b73c4fab566bf47284772969bfa5175084ab 100755 (executable)
@@ -2050,77 +2050,97 @@ conditional_expression
 assignment_expression\r
        : unary_expression ASSIGN expression\r
          {\r
-               $$ = new Assign ((Expression) $1, (Expression) $3);\r
+               $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);\r
          }\r
        | unary_expression OP_MULT_ASSIGN expression\r
          {\r
+               Location l = lexer.Location;\r
+\r
                $$ = new Assign ((Expression) $1,\r
                                 new Binary (Binary.Operator.Multiply, \r
                                             (Expression) $1,\r
-                                            (Expression) $3, lexer.Location));\r
+                                            (Expression) $3, l), l);\r
          }\r
        | unary_expression OP_DIV_ASSIGN expression\r
          {\r
+               Location l = lexer.Location;\r
+\r
                $$ = new Assign ((Expression) $1,\r
                                 new Binary (Binary.Operator.Divide, \r
                                             (Expression) $1,\r
-                                            (Expression) $3, lexer.Location));\r
+                                            (Expression) $3, l), l);\r
          }\r
        | unary_expression OP_MOD_ASSIGN expression\r
          {\r
+               Location l = lexer.Location;\r
+\r
                $$ = new Assign ((Expression) $1,\r
                                 new Binary (Binary.Operator.Modulo, \r
                                             (Expression) $1,\r
-                                            (Expression) $3, lexer.Location));\r
+                                            (Expression) $3, l), l);\r
          }\r
        | unary_expression OP_ADD_ASSIGN expression\r
          {\r
+               Location l = lexer.Location;\r
+\r
                $$ = new Assign ((Expression) $1,\r
                                 new Binary (Binary.Operator.Add, \r
                                             (Expression) $1,\r
-                                            (Expression) $3, lexer.Location));\r
+                                            (Expression) $3, l), l);\r
          }\r
        | unary_expression OP_SUB_ASSIGN expression\r
          {\r
+               Location l = lexer.Location;\r
+\r
                $$ = new Assign ((Expression) $1,\r
                                 new Binary (Binary.Operator.Subtract, \r
                                             (Expression) $1,\r
-                                            (Expression) $3, lexer.Location));\r
+                                            (Expression) $3, l), l);\r
          }\r
        | unary_expression OP_SHIFT_LEFT_ASSIGN expression\r
          {\r
+               Location l = lexer.Location;\r
+\r
                $$ = new Assign ((Expression) $1,\r
                                 new Binary (Binary.Operator.ShiftLeft, \r
                                             (Expression) $1,\r
-                                            (Expression) $3, lexer.Location));\r
+                                            (Expression) $3, l), l);\r
          }\r
        | unary_expression OP_SHIFT_RIGHT_ASSIGN expression\r
          {\r
+               Location l = lexer.Location;\r
+\r
                $$ = new Assign ((Expression) $1,\r
                                 new Binary (Binary.Operator.ShiftRight, \r
                                             (Expression) $1,\r
-                                            (Expression) $3, lexer.Location));\r
+                                            (Expression) $3, l), l);\r
          }\r
        | unary_expression OP_AND_ASSIGN expression\r
          {\r
+               Location l = lexer.Location;\r
+\r
                $$ = new Assign ((Expression) $1,\r
                                 new Binary (Binary.Operator.BitwiseAnd, \r
                                             (Expression) $1,\r
-                                            (Expression) $3, lexer.Location));\r
+                                            (Expression) $3, l), l);\r
          }\r
        | unary_expression OP_OR_ASSIGN expression\r
          {\r
+               Location l = lexer.Location;\r
+\r
                $$ = new Assign ((Expression) $1,\r
                                 new Binary (Binary.Operator.BitwiseOr, \r
                                             (Expression) $1,\r
-                                            (Expression) $3, lexer.Location));\r
+                                            (Expression) $3, l), l);\r
          }\r
        | unary_expression OP_XOR_ASSIGN expression\r
          {\r
+               Location l = lexer.Location;\r
+\r
                $$ = new Assign ((Expression) $1,\r
                                 new Binary (Binary.Operator.ExclusiveOr, \r
                                             (Expression) $1,\r
-                                            (Expression) $3, lexer.Location));\r
+                                            (Expression) $3, l), l);\r
          }\r
        ;\r
 \r
@@ -2599,7 +2619,7 @@ foreach_statement
                assign_e = new Assign (new LocalVariableReference (foreach_block, temp_id), \r
                                       new Invocation (\r
                                                new MemberAccess ((Expression) $6, "GetEnumerator"), \r
-                                               null, lexer.Location));\r
+                                               null, lexer.Location), lexer.Location);\r
                current_block.AddStatement (new StatementExpression (assign_e));\r
                ma = new MemberAccess (new LocalVariableReference (foreach_block, temp_id), "MoveNext");\r
                child_block = new Block (current_block);\r
@@ -2610,7 +2630,8 @@ foreach_statement
                                new Cast (\r
                                        (string) $3, \r
                                        new MemberAccess (\r
-                                               new LocalVariableReference (foreach_block, temp_id), "Current"))));\r
+                               new LocalVariableReference (foreach_block, temp_id), "Current")), \r
+                               lexer.Location));\r
 \r
                child_block.AddStatement (getcurrent);\r
                child_block.AddStatement ((Statement) $8);\r
@@ -3017,7 +3038,9 @@ Block declare_local_variables (string type, ArrayList variable_declarators)
                        Expression expr = (Expression) decl.expression_or_array_initializer;\r
                        Assign assign;\r
                        \r
-                       assign = new Assign (new LocalVariableReference (implicit_block, decl.identifier), expr);\r
+                       assign = new Assign (new LocalVariableReference (\r
+                                               implicit_block, decl.identifier), \r
+                                            expr, lexer.Location);\r
                        implicit_block.AddStatement (new StatementExpression (assign));\r
                } else {\r
                        Console.WriteLine ("Not handling Array initializers yet");\r
index 46c643fd3efb6ee7e1f064c42ccfbe2d1fd3d42f..70b2022dfdab20bdcd030faeb0e2c131d6169b99 100755 (executable)
@@ -886,7 +886,7 @@ namespace CIR
                }\r
        }\r
 \r
-       public struct Location {\r
+       public class Location {\r
                public readonly string Name;\r
                public readonly int    Col;\r
                public readonly int    Row;\r
index fd2a4ad2a62cb16552d0c2aeed36ccbdf616a77e..7ea4d88ba35b555eef6760df8981e43b38466f44 100755 (executable)
@@ -402,6 +402,27 @@ namespace CIR {
                        return null;
                }
 
+               // <summary>
+               //   Attemptes to implicityly convert `target' into `type', using
+               //   ConvertImplicit.  If there is no implicit conversion, then
+               //   an error is signaled
+               // </summary>
+               static public Expression ConvertImplicitRequired (TypeContainer tc, Expression target,
+                                                                 Type type, Location l)
+               {
+                       Expression e;
+                       
+                       e = ConvertImplicit (target, type);
+                       if (e == null){
+                               string msg = "Can not convert implicity from `"+
+                                       TypeManager.CSharpName (target.Type) + "' to `" +
+                                       TypeManager.CSharpName (type) + "'";
+
+                               tc.RootContext.Report.Error (29, l, msg);
+                       }
+                       return e;
+               }
+               
                // <summary>
                //   Performs an explicit conversion of the expression `expr' whose
                //   type is expr.Type to `target_type'.
@@ -694,8 +715,9 @@ namespace CIR {
                                Arguments.Add (new Argument (expr, Argument.AType.Expression));
                                
                                method = Invocation.OverloadResolve ((MethodGroupExpr) mg, Arguments, tc, location);
-                               if (method != null)
+                               if (method != null){
                                        return this;
+                               }
                        }
 
                        //
@@ -708,14 +730,14 @@ namespace CIR {
                        if (expr_type == null)
                                return null;
                        
-                       if (oper == Operator.Negate && expr_type != TypeManager.bool_type) {
-                               report23 (tc.RootContext.Report, expr.Type);
-                               return null;
-                       } else {
-                               expr = ForceConversion (expr, TypeManager.int32_type);
-                               type = TypeManager.int32_type;
+                       if (oper == Operator.Negate){
+                               if (expr_type != TypeManager.bool_type) {
+                                       report23 (tc.RootContext.Report, expr.Type);
+                                       return null;
+                               } else
+                                       type = TypeManager.bool_type;
                        }
-                       
+
                        if (oper == Operator.BitComplement) {
                                if (!((expr_type == TypeManager.int32_type) ||
                                      (expr_type == TypeManager.uint32_type) ||
@@ -725,7 +747,7 @@ namespace CIR {
                                        report23 (tc.RootContext.Report, expr.Type);
                                        return null;
                                }
-                               
+                               type = expr_type;
                                return this;
                        }
 
@@ -736,26 +758,94 @@ namespace CIR {
                                return expr;
                        }
 
+                       //
+                       // Deals with -literals
+                       // int     operator- (int x)
+                       // long    operator- (long x)
+                       // float   operator- (float f)
+                       // double  operator- (double d)
+                       // decimal operator- (decimal d)
+                       //
                        if (oper == Operator.Subtract){
                                //
-                               // Fold -Constant into a negative constant
-                               
+                               // Fold a "- Constant" into a negative constant
+                               //
                        
                                Expression e = null;
-                               
+
+                               //
+                               // Is this a constant? 
+                               //
                                if (expr is IntLiteral)
                                        e = new IntLiteral (-((IntLiteral) expr).Value);
                                else if (expr is LongLiteral)
                                        e = new LongLiteral (-((LongLiteral) expr).Value);
                                else if (expr is FloatLiteral)
                                        e = new FloatLiteral (-((FloatLiteral) expr).Value);
-
+                               else if (expr is DoubleLiteral)
+                                       e = new DoubleLiteral (-((DoubleLiteral) expr).Value);
+                               else if (expr is DecimalLiteral)
+                                       e = new DecimalLiteral (-((DecimalLiteral) expr).Value);
+                               
                                if (e != null){
                                        e = e.Resolve (tc);
                                        return e;
                                }
 
-                               report23 (tc.RootContext.Report, expr.Type);
+                               //
+                               // Not a constant we can optimize, perform numeric 
+                               // promotions to int, long, double.
+                               //
+                               //
+                               // The following is inneficient, because we call
+                               // ConvertImplicit too many times.
+                               //
+                               // It is also not clear if we should convert to Float
+                               // or Double initially.
+                               //
+                               if (expr_type == TypeManager.uint32_type){
+                                       //
+                                       // FIXME: handle exception to this rule that
+                                       // permits the int value -2147483648 (-2^31) to
+                                       // bt written as a decimal interger literal
+                                       //
+                                       type = TypeManager.int64_type;
+                                       expr = ConvertImplicit (expr, type);
+                                       return this;
+                               }
+
+                               if (expr_type == TypeManager.uint64_type){
+                                       //
+                                       // FIXME: Handle exception of `long value'
+                                       // -92233720368547758087 (-2^63) to be written as
+                                       // decimal integer literal.
+                                       //
+                                       report23 (tc.RootContext.Report, expr_type);
+                                       return null;
+                               }
+
+                               e = ConvertImplicit (expr, TypeManager.int32_type);
+                               if (e != null){
+                                       expr = e;
+                                       type = e.Type;
+                                       return this;
+                               } 
+
+                               e = ConvertImplicit (expr, TypeManager.int64_type);
+                               if (e != null){
+                                       expr = e;
+                                       type = e.Type;
+                                       return this;
+                               }
+
+                               e = ConvertImplicit (expr, TypeManager.double_type);
+                               if (e != null){
+                                       expr = e;
+                                       type = e.Type;
+                                       return this;
+                               }
+
+                               report23 (tc.RootContext.Report, expr_type);
                                return null;
                        }
 
@@ -768,8 +858,10 @@ namespace CIR {
                            oper == Operator.PostDecrement || oper == Operator.PostIncrement){
                                if (expr.ExprClass == ExprClass.Variable){
                                        if (IsIncrementableNumber (expr_type) ||
-                                           expr_type == TypeManager.decimal_type)
+                                           expr_type == TypeManager.decimal_type){
+                                               type = expr_type;
                                                return this;
+                                       }
                                } else if (expr.ExprClass == ExprClass.IndexerAccess){
                                        //
                                        // FIXME: Verify that we have both get and set methods
@@ -811,8 +903,9 @@ namespace CIR {
 
                                // Note that operators are static anyway
                                
-                               if (Arguments != null) 
+                               if (Arguments != null) {
                                        Invocation.EmitArguments (ec, method, Arguments);
+                               }
                                
                                if (method is MethodInfo)
                                        ig.Emit (OpCodes.Call, (MethodInfo) method);
@@ -827,7 +920,9 @@ namespace CIR {
                                throw new Exception ("This should be caught by Resolve");
 
                        case Operator.Subtract:
-                               throw new Exception ("THis should have been caught by Resolve");
+                               expr.Emit (ec);
+                               ig.Emit (OpCodes.Neg);
+                               break;
                                
                        case Operator.Negate:
                                expr.Emit (ec);
@@ -1887,6 +1982,10 @@ namespace CIR {
                        get {
                                return expr;
                        }
+
+                       set {
+                               expr = value;
+                       }
                }
 
                public bool Resolve (TypeContainer tc)
@@ -2362,7 +2461,8 @@ namespace CIR {
                        for (int j = argument_count; j > 0;) {
                                j--;
                                Argument a = (Argument) Arguments [j];
-
+                               Expression a_expr = a.Expr;
+                               
                                Expression conv = ConvertImplicit (a.Expr, pd.ParameterType (j));
 
                                if (conv == null) {
@@ -2375,6 +2475,12 @@ namespace CIR {
                                               + "' to '" + TypeManager.CSharpName (pd.ParameterType (j)) + "'");
                                        return null;
                                }
+
+                               //
+                               // Update the argument with the implicit conversion
+                               //
+                               if (a_expr != conv)
+                                       a.Expr = conv;
                        }
                        
                        return method;
index ea7b300f53fce7895034ad9aca98eb72773250b5..57c610e4ac7035a16acc1bbca452f3073ebafea5 100755 (executable)
@@ -215,15 +215,45 @@ namespace CIR {
                                break;
 
                        default:
-                               if (i < 255)
-                                       ig.Emit (OpCodes.Ldc_I4_S, i);
-                               else
+                               if (i > 0 && i < 127){
+                                       ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
+                               else
                                        ig.Emit (OpCodes.Ldc_I4, i);
                                break;
                        }
                }
        }
 
+       public class UIntLiteral : Literal {
+               public readonly uint Value;
+
+               public UIntLiteral (uint l)
+               {
+                       Value = l;
+               }
+
+               override public string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override Expression Resolve (TypeContainer tc)
+               {
+                       type = TypeManager.uint32_type;
+
+                       return this;
+               }
+
+               public override bool Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       IntLiteral.EmitInt (ig, unchecked ((int) Value));
+                       return true;
+               }
+
+       }
+       
        public class LongLiteral : Literal {
                public readonly long Value;
 
@@ -316,16 +346,16 @@ namespace CIR {
        }
 
        public class DecimalLiteral : Literal {
-               decimal d;
+               public readonly decimal Value;
 
                public DecimalLiteral (decimal d)
                {
-                       this.d = d;
+                       Value = d;
                }
 
                override public string AsString ()
                {
-                       return d.ToString ();
+                       return Value.ToString ();
                }
 
                public override Expression Resolve (TypeContainer tc)
index 0a76dfdfaa4c145db5662ab5b61695dc0c9ef4de..9d5938c158f8a7020654ac821a28c08755edcf30 100755 (executable)
@@ -1,6 +1,6 @@
 ROOT=/cygdrive/$(subst \,/,$(subst :\,/,$(SYSTEMROOT)))
 CSC=$(ROOT)/microsoft.net/framework/v1.0.2914/csc.exe
-CSCFLAGS=/nologo /debug+ /debug:full 
+CSCFLAGS=/nologo /debug+ /debug:full  /optimize
 
 VERSION=0.13