//
// (C) 2001 Ximian, Inc.
//
-
+using System;
+using System.Reflection;
using System.Reflection.Emit;
namespace CIR {
- public class Assign : Expression {
+ public class Assign : ExpressionStatement {
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 {
}
}
- public override Expression Resolve (TypeContainer tc)
+ public override Expression DoResolve (EmitContext ec)
{
- target = target.Resolve (tc);
- source = source.Resolve (tc);
+ target = target.Resolve (ec);
+ source = source.Resolve (ec);
if (target == null || source == null)
return null;
+
+ Type target_type = target.Type;
- return this;
- }
+ Type source_type = source.Type;
- void EmitLocalAssign (LocalVariableReference lv, ILGenerator ig)
- {
- VariableInfo vi = lv.VariableInfo;
- int idx = vi.Idx;
-
- switch (idx){
- case 0:
- ig.Emit (OpCodes.Stloc_0);
- break;
-
- case 1:
- ig.Emit (OpCodes.Stloc_1);
- break;
-
- case 2:
- ig.Emit (OpCodes.Stloc_2);
- break;
-
- case 3:
- ig.Emit (OpCodes.Stloc_3);
- break;
-
- default:
- if (idx < 255)
- ig.Emit (OpCodes.Stloc_S, idx);
- else
- ig.Emit (OpCodes.Stloc, idx);
- break;
+ if (target_type != source_type){
+ source = ConvertImplicitRequired (ec, source, target_type, l);
+ if (source == null)
+ return null;
}
+
+ if (!(target is LValue)){
+ Report.Error (131, "Left hand of an assignment must be a variable, a property or an indexer");
+ }
+ type = target_type;
+ eclass = ExprClass.Value;
+ return this;
}
- public void EmitParameterAssign (ParameterReference pr, ILGenerator ig)
+ void Emit (EmitContext ec, bool is_statement)
{
- int idx = pr.Idx;
+ ILGenerator ig = ec.ig;
- if (idx < 255)
- ig.Emit (OpCodes.Starg_S, idx);
- else
- ig.Emit (OpCodes.Starg, idx);
- }
+ if (target.ExprClass == ExprClass.Variable){
- public void EmitFieldAssign (FieldExpr field, ILGenerator ig)
- {
- if (field.IsStatic)
- ig.Emit (OpCodes.Stsfld, field.FieldInfo);
- else
- ig.Emit (OpCodes.Stfld, field.FieldInfo);
+ //
+ // If it is an instance field, load the this pointer
+ //
+ if (target is FieldExpr){
+ FieldExpr fe = (FieldExpr) target;
+
+ if (!fe.FieldInfo.IsStatic)
+ ig.Emit (OpCodes.Ldarg_0);
+ }
+
+ source.Emit (ec);
+
+ if (!is_statement)
+ ig.Emit (OpCodes.Dup);
+
+ ((LValue) target).Store (ec);
+ } else if (target.ExprClass == ExprClass.PropertyAccess){
+ // FIXME
+ throw new Exception ("Can not assign to properties yet");
+ } else if (target.ExprClass == ExprClass.IndexerAccess){
+ // FIXME
+ throw new Exception ("Can not assign to indexers yet");
+ }
}
public override void Emit (EmitContext ec)
{
- if (target.ExprClass == ExprClass.Variable){
- source.Emit (ec);
+ Emit (ec, false);
+ }
- if (target is LocalVariableReference){
- EmitLocalAssign ((LocalVariableReference) target, ec.ig);
- } else if (target is ParameterReference){
- EmitParameterAssign ((ParameterReference) target, ec.ig);
- } else if (target is FieldExpr){
- EmitFieldAssign ((FieldExpr) target, ec.ig);
- }
- }
+ public override void EmitStatement (EmitContext ec)
+ {
+ Emit (ec, true);
}
}
}
+