public void GenerateSet(Expression right, MethodBodyGenerator generator, MethodCompileOption option = MethodCompileOption.None)
 {
     // first parameter to be Any
     if (right.Type != TypeProvider.AnyType)
     {
         if (right.Type.IsValueType)
         {
             generator.Box(right.Type);
         }
         generator.CallStatic(ReflectionHelpers.ImplicitAny);
     }
     generator.LoadString(Name);
     generator.LoadToken(right.Type);
     generator.Call((Func <RuntimeTypeHandle, Type>)Type.GetTypeFromHandle);
     generator.Call(typeof(IDynamicInvocable).GetInstanceMethod(nameof(IDynamicInvocable.SafeSetValue), TypeProvider.AnyType, typeof(string), typeof(Type)));
     if ((option & MethodCompileOption.Return) == 0)
     {
         generator.Pop();
         return;
     }
 }
Ejemplo n.º 2
0
        void CallPostFixMember(MethodBodyGenerator generator, IBinder binder, MethodCompileOption option)
        {
            // if no duplicate ex: i++ single line
            if ((option & MethodCompileOption.Dupplicate) == 0)
            {
                binder.GenerateSet(Operand, generator);
                return;
            }
            // i++ where i is member
            // intially member is loaded
            var temp = generator.DeclareVariable(binder.Type);

            // store the result to variable
            generator.StoreVariable(temp);
            // load the variable
            generator.LoadVariable(temp);
            // call operator
            generator.CallStatic(Method);
            // store operation result to member
            binder.GenerateSet(Operand, generator);
            //load the temp variable
            generator.LoadVariable(temp);
        }
Ejemplo n.º 3
0
        public override void GenerateCode(MethodBodyGenerator generator, MethodCompileOption option)
        {
            if (NodeType == ExpressionType.Parenthesized)
            {
                Operand.GenerateCode(generator, option);
                return;
            }
            var     operand = Operand;
            IBinder binder  = null;

            if (operand.NodeType == ExpressionType.Identifier)
            {
                //todo only for get; set; member
                //i++ or Member++
                binder = ((NameExpression)operand).Binder;
            }
            else if (operand.NodeType == ExpressionType.MemberAccess)
            {
                binder = ((MemberExpression)operand).Binder;
            }
            // todo: Conversion if value is short, byte lower data type

            switch (NodeType)
            {
            case ExpressionType.PostfixMinusMinus:
            case ExpressionType.PostfixPlusPlus:
                if (binder == null)
                {
                    throw new NullReferenceException(nameof(binder));
                }
                if ((binder.Attributes & BindingAttributes.HasThis) != 0)
                {
                    generator.LoadArgument(0);
                }
                operand.GenerateCode(generator, MethodCompileOption.Dupplicate);
                if ((binder.Attributes & BindingAttributes.Member) != 0)
                {
                    CallPostFixMember(generator, binder, option);
                    return;
                }
                if ((option & MethodCompileOption.Dupplicate) != 0)
                {
                    generator.Duplicate();
                }
                // call the operator
                generator.CallStatic(Method);
                // update value
                binder.GenerateSet(operand, generator);
                break;

            case ExpressionType.PrefixMinusMinus:
            case ExpressionType.PrefixPlusPlus:
                if (binder == null)
                {
                    throw new NullReferenceException(nameof(binder));
                }
                if ((binder.Attributes & BindingAttributes.HasThis) != 0)
                {
                    generator.LoadArgument(0);
                }
                operand.GenerateCode(generator, MethodCompileOption.Dupplicate);
                // call the operator
                generator.CallStatic(Method);
                if ((binder.Attributes & BindingAttributes.Member) != 0)
                {
                    CallPreFixMember(generator, binder, option);
                    return;
                }
                if ((option & MethodCompileOption.Dupplicate) != 0)
                {
                    generator.Duplicate();
                }
                // update value
                binder.GenerateSet(Operand, generator);
                break;

            default:
                // call the operator
                operand.GenerateCode(generator, AssignOption);
                generator.CallStatic(Method);
                break;
            }
        }