* 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
+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.
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.
+
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 {
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;
}
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
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
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
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
}\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
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'.
Arguments.Add (new Argument (expr, Argument.AType.Expression));
method = Invocation.OverloadResolve ((MethodGroupExpr) mg, Arguments, tc, location);
- if (method != null)
+ if (method != null){
return this;
+ }
}
//
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) ||
report23 (tc.RootContext.Report, expr.Type);
return null;
}
-
+ type = expr_type;
return this;
}
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;
}
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
// 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);
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);
get {
return expr;
}
+
+ set {
+ expr = value;
+ }
}
public bool Resolve (TypeContainer tc)
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) {
+ "' to '" + TypeManager.CSharpName (pd.ParameterType (j)) + "'");
return null;
}
+
+ //
+ // Update the argument with the implicit conversion
+ //
+ if (a_expr != conv)
+ a.Expr = conv;
}
return method;
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;
}
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)
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