Beispiel #1
0
            public IExpression GetExpression(IExpression[] expressions)
            {
                if (Members != expressions.Count())
                {
                    throw new ArgumentException();
                }
                var powers = new IExpression[Members, Exponent + 1];

                for (int i = 0; i < Members; i++)
                {
                    for (int j = 0; j < Exponent + 1; j++)
                    {
                        powers[i, j] = expressions[Members - i - 1].Power(new NumberExpression(new NumberDecimal(j, 0))).Format().Expand();
                    }
                }

                IExpression result = NumberExpression.Zero;

                foreach (var item in this)
                {
                    IExpression term = new NumberExpression(new NumberDecimal(item.Coefficient, 0));
                    for (int i = 0; i < item.Exponents.Count(); i++)
                    {
                        term = term.Multiply(powers[i, item.Exponents[i]]).Format().Expand();
                    }
                    result = result.Add(term);
                }
                return(result.Format().Expand());
            }
Beispiel #2
0
        public IExpression Expand(int PowerLevel = int.MaxValue)
        {
            var         items  = ExpandLevel(GetMembers().Select(a => a.Expand()).ToArray(), 0);
            IExpression result = NumberExpression.Zero;

            foreach (var item in items)
            {
                result = result.Add(item);
            }
            return(result);
        }
Beispiel #3
0
        public IExpression Expand(int PowerLevel = int.MaxValue)
        {
            IExpression result = NumberExpression.Zero;
            var         Lefts  = Helper.SplitAddition(this.Left.Expand()).Select(a => a.Expand()).ToArray();
            var         Rights = Helper.SplitAddition(this.Right.Expand()).Select(a => a.Expand()).ToArray();

            foreach (var item1 in Lefts)
            {
                foreach (var item2 in Rights)
                {
                    result = result.Add(item1.Multiply(item2));
                }
            }
            return(result);
        }
        public BatsmanStatisticsViewModel(IDataSeedService <PlayerInning> playerInningService, string filter)
        {
            _playerInningService = playerInningService ?? throw new ArgumentNullException($"playerService is null, cannot get match.");

            IExpression condition = Expression.Property("type").EqualTo(Expression.String("PlayerInning"));

            if (filter == "only tournament matches")
            {
                condition.Add(Expression.Property("tournamentId").IsNot(Expression.String(string.Empty)));
            }

            List <PlayerInning> playerinnings = _playerInningService.GetFilteredList(condition).ToList();

            BatsmanStatistics = playerinnings.GroupBy(pi => pi.PlayerId).Select(p => new PlayerStatistics(p.ToList())).ToList();
        }
Beispiel #5
0
        public static IExpression ExpandLevel(IExpression[] expressions, int currentLevel, IExpression current = null)
        {
            current = current ?? NumberExpression.One;
            IExpression result = NumberExpression.Zero;

            if (currentLevel == 0)
            {
                return(current);
            }
            foreach (var item in expressions)
            {
                var test = ExpandLevel(expressions, currentLevel - 1, current.Multiply(item));
                //Console.WriteLine($"{ currentLevel } {current} ({current}) * ({item}) = ({current.Multiply(item)}) { test } {result } {result.GetType() } { test.GetType() }");
                result = result.Add(test);
            }
            return(result);
        }
Beispiel #6
0
        private IExpression ParseExpression()
        {
            IExpression x = ParseTerm();

            while (true)
            {
                if (Eat('+'))
                {
                    x = x.Add(ParseTerm());
                }
                else if (Eat('-'))
                {
                    x = x.Sub(ParseTerm());
                }
                else
                {
                    return(x);
                }
            }
        }
        public static IExpression Parse(string exp, out string[] parsedVariables)
        {
            // set up stacks
            Stack <char>        opts   = new Stack <char>();
            Stack <string>      vars   = new Stack <string>();
            Stack <IExpression> expres = new Stack <IExpression>();

            // getting the stacks to use
            string[] variables = GetVariableNames(exp);
            parsedVariables = variables;

            vars = GetVarStack(variables);

            char[] operations = GetOperators(exp);
            opts = GetOperatorStack(operations);

            expres.Push(null);
            IExpression expression = null;

            // expception handling
            if (opts.Count == 0 && vars.Count != 1)
            {
                throw new Exception(String.Format("An expression with multiple variables requires an operation: {0}", exp));
            }

            // whlie we still have operations to use
            while (opts.Count > 0)
            {
                char opt = opts.Pop();

                if (opt != '(' && opt != ')')
                // opt is actually an operator
                // later on i will need to implement Not
                {
                    if (expression == null)
                    {
                        expression = GetOperationExpression(opt);
                    }

                    expression.Add(new Variable(vars.Pop()));
                    // shortcircuiting so that i dont check an empty stack
                    if ((opts.Count == 0 && vars.Count > 0) || (opts.Count > 0 && opts.Peek() == ')'))
                    {
                        //TODO errors here when there is something like (x|y)&z
                        expression.Add(new Variable(vars.Pop()));
                    }
                }
                // opening a paren
                // push paren here, push null if it directly follows another open paren
                else if (opt == '(')
                {
                    expres.Push(expression);
                    expression = null;
                }
                // this will be for close paren
                else
                {
                    // close paren, pop expres
                    IExpression temp;
                    do
                    {
                        // TODO error here when there are more than 1 paren paris (())
                        temp = expres.Pop();
                        // only need to check for this because
                        // )( is not allowed and the preprocessor checks for it
                        if ((opts.Count > 0 && opts.Peek() != ')') && temp == null)
                        {
                            // make sure i don't have to pop it here
                            temp = GetOperationExpression(opts.Peek());
                        }

                        if (temp != null)
                        {
                            temp.Add(expression);
                            expression = temp;
                        }
                    }while(temp == null && expres.Count > 0);
                }
            }
            // yay for hotfix!
            if (expression == null && vars.Count == 1)
            {
                expression = new Variable(vars.Pop());
            }

            return(expression);
        }
Beispiel #8
0
        static void Process <T>(ILReader il, IExpression <T> exp, Stack <T> eval, T[] args, T[] locals)
        {
            var tailcall = false;

            while (il.MoveNext())
            {
                var x = il.Current;//.Simplify();
                T   rhs;
                switch (x.OpCode.Type())
                {
                //--------------- arithmetic instructions --------------
                case OpType.Add_ovf:
                case OpType.Add_ovf_un:
                    rhs = eval.Pop();
                    eval.Push(exp.AddOverflow(eval.Pop(), rhs));
                    break;

                case OpType.Add:
                    rhs = eval.Pop();
                    eval.Push(exp.Add(eval.Pop(), rhs));
                    break;

                case OpType.Sub:
                    rhs = eval.Pop();
                    eval.Push(exp.Subtract(eval.Pop(), rhs));
                    break;

                case OpType.Sub_ovf:
                case OpType.Sub_ovf_un:
                    rhs = eval.Pop();
                    eval.Push(exp.SubtractOverflow(eval.Pop(), rhs));
                    break;

                case OpType.Mul:
                    rhs = eval.Pop();
                    eval.Push(exp.Multiply(eval.Pop(), rhs));
                    break;

                case OpType.Mul_ovf:
                case OpType.Mul_ovf_un:
                    rhs = eval.Pop();
                    eval.Push(exp.MultiplyOverflow(eval.Pop(), rhs));
                    break;

                case OpType.Div:
                case OpType.Div_un:
                    rhs = eval.Pop();
                    eval.Push(exp.Divide(eval.Pop(), rhs));
                    break;

                case OpType.Neg:
                    eval.Push(exp.Negate(eval.Pop()));
                    break;

                case OpType.Rem:
                case OpType.Rem_un:
                    rhs = eval.Pop();
                    eval.Push(exp.Modulo(eval.Pop(), rhs));
                    break;

                //------------ logical/bitwise operations --------------
                case OpType.And:
                    rhs = eval.Pop();
                    eval.Push(exp.And(eval.Pop(), rhs));
                    break;

                case OpType.Or:
                    rhs = eval.Pop();
                    eval.Push(exp.Or(eval.Pop(), rhs));
                    break;

                case OpType.Not:
                    eval.Push(exp.Not(eval.Pop()));
                    break;

                case OpType.Box:
                    eval.Push(exp.Box(eval.Pop()));
                    break;

                case OpType.Shl:
                    rhs = eval.Pop();
                    eval.Push(exp.LeftShift(eval.Pop(), rhs));
                    break;

                case OpType.Shr:
                case OpType.Shr_un:
                    rhs = eval.Pop();
                    eval.Push(exp.RightShift(eval.Pop(), rhs));
                    break;

                //----------- Branching instructions ---------
                case OpType.Br:
                case OpType.Br_s:
                    il.Seek(x.Operand.Label);     // seek to branch label
                    eval.Push(exp.Goto(eval.Pop()));
                    break;

                case OpType.Beq:
                case OpType.Beq_s:
                    rhs = eval.Pop();
                    eval.Push(exp.Equal(eval.Pop(), rhs));
                    goto case OpType.Brtrue;

                case OpType.Bge:
                case OpType.Bge_un:
                case OpType.Bge_un_s:
                    rhs = eval.Pop();
                    eval.Push(exp.GreaterThanOrEqual(eval.Pop(), rhs));
                    goto case OpType.Brtrue;

                case OpType.Ble:
                case OpType.Ble_un:
                case OpType.Ble_un_s:
                    rhs = eval.Pop();
                    eval.Push(exp.LessThanOrEqual(eval.Pop(), rhs));
                    goto case OpType.Brtrue;

                case OpType.Blt:
                case OpType.Blt_un:
                case OpType.Blt_un_s:
                    rhs = eval.Pop();
                    eval.Push(exp.LessThan(eval.Pop(), rhs));
                    goto case OpType.Brtrue;

                case OpType.Bne_un:
                case OpType.Bne_un_s:
                    rhs = eval.Pop();
                    eval.Push(exp.NotEqual(eval.Pop(), rhs));
                    goto case OpType.Brtrue;

                case OpType.Brfalse:
                case OpType.Brfalse_s:
                    eval.Push(exp.Negate(eval.Pop()));
                    goto case OpType.Brtrue;

                case OpType.Brtrue:
                case OpType.Brtrue_s:
                    //FIXME: this duplicates expressions for every branch instead of unifying them. Need
                    //to track a Dictionary<Label, T>, and should skip Process() calls if the Label
                    //already exists (and patch it in with a goto).
                    var cond = eval.Pop();
                    if (!il.MoveNext())
                    {
                        throw new InvalidOperationException("Expected an instruction after branch!");
                    }
                    var elseStart = il.Mark();    // save current position
                    var thenStart = x.Operand.Label;
                    il.Seek(thenStart);           // seek to _then when branch condition true
                    Process(il, exp, eval, args, locals);
                    var _then = eval.Pop();       // extract _then expression
                    il.Seek(elseStart);           // seek to _else when branch condition false
                    Process(il, exp, eval, args, locals);
                    var _else = eval.Pop();       // extract _else expression
                    eval.Push(exp.If(cond, _then, _else));
                    break;

                case OpType.Switch:
                    var val = eval.Pop();
                    if (!il.MoveNext())
                    {
                        throw new InvalidOperationException("Expected an instruction after switch!");
                    }
                    var swt   = il.Mark();
                    var cases = x.ResolveBranches().Select(kv =>
                    {
                        il.Seek(kv.Value);
                        Process(il, exp, eval, args, locals);
                        return(new KeyValuePair <object, T>(kv.Key, eval.Pop()));
                    });
                    eval.Push(exp.Switch(val, cases));
                    il.Seek(swt);
                    break;

#if DEBUG
                //FIXME: extend ILReader to support consulting exception handling blocks:
                //  method.GetMethodBody().ExceptionHandlingClauses[0].TryOffset/TryLength/HandlerOffset
                //
                case OpType.Leave:
                case OpType.Leave_s:
                    //FIXME: should leave be treated differently from br?
                    //Process(il, exp, eval, args, locals);   // process the .try block
                    il.Seek(x.Operand.Label);     // seek to branch label
                    eval.Push(exp.Goto(eval.Pop()));
                    return;

                case OpType.Endfilter:     // return to try context?
                    //eval.Push()
                    return;

                //eval.Push(exp.EndFilter(eval.Pop()));
                //break;
                case OpType.Endfinally:
                    return;

                    //case OpType.Try:
                    //    Process(il, exp, eval, args, locals);
                    //    var leaveTry = eval.Pop();
                    //    if (il.Current.OpCode.Type() != OpType.Leave || il.Current.OpCode.Type() != OpType.Leave_s || !il.MoveNext())
                    //        throw new InvalidOperationException("Try-catch-finally requires .try block to end with a leave instruction.");
                    //    if (!il.MoveNext()) //FIXME: maybe shouldn't call this?
                    //        return;
                    //    var handlers = new Dictionary<Type, T>();
                    //    do
                    //    {
                    //        Process(il, exp, eval, args, locals);
                    //        if (il.Current.OpCode.Type() != OpType.Endfilter)
                    //    } while (il.Current.OpCode.Type() == OpType.Endfilter);
                    //    Process(il, exp, eval, args, locals);
                    //    if (il.Current.OpCode.Type() != OpType.Leave || il.Current.OpCode.Type() != OpType.Leave_s)
                    //        throw new InvalidOperationException("Try-catch-finally requires .try block to end with a leave instruction.");
                    //    while (il.Current.OpCode.Type() == OpType.Endfinally);
                    //    //eval.Push(exp.TryCatchFinally(leaveTry, ));
                    //    break;
#endif

                    //------------ Method call instructions ---------------
#if DEBUG
                //FIXME: indirect calls and method pointers require decoding method signatures.
                //See incomplete CallSignature type.
                case OpType.Ldftn:
                    eval.Push(exp.GetPointer(x.ResolveMethod(), default(T)));
                    break;

                case OpType.Ldvirtftn:
                    eval.Push(exp.GetPointer(x.ResolveMethod(), eval.Pop()));
                    break;

                case OpType.Calli:
                    var sig = x.ResolveSignature();
                    //var args =
                    var entry = eval.Pop();
                    eval.Push(exp.CallIndirect(sig, entry, tailcall, args));
                    tailcall = false;
                    break;
#endif
                case OpType.Call:
                case OpType.Callvirt:
                    var method  = x.ResolveMethod();
                    var mparams = method.GetParameters();
                    var margs   = mparams.Select((a, i) => Cast(eval.Pop(), mparams[i].ParameterType, exp))
                                  .Reverse()
                                  .ToArray();
                    var minstance = method.IsStatic ? default(T) : eval.Pop();
                    eval.Push(exp.Call(method, tailcall, minstance, margs));
                    tailcall = false;
                    break;

                case OpType.Jmp:
                    eval.Push(exp.Jump(x.ResolveMethod()));
                    break;

                case OpType.Cpblk:
                    rhs = eval.Pop();
                    var src = eval.Pop();
                    eval.Push(exp.BlockCopy(eval.Pop(), src, rhs));
                    break;

                case OpType.Cpobj:
                    rhs = eval.Pop();
                    eval.Push(exp.StructCopy(eval.Pop(), rhs, x.ResolveType()));
                    break;

                case OpType.Initblk:
                    rhs = eval.Pop();
                    var value = eval.Pop();
                    eval.Push(exp.BlockInit(eval.Pop(), value, rhs));
                    break;

                case OpType.Initobj:
                    eval.Push(exp.ObjectInit(eval.Pop(), x.ResolveType()));
                    break;

                //---------------- Load/store instructions -------------
                case OpType.Sizeof:
                    eval.Push(exp.SizeOf(x.ResolveType()));
                    break;

                case OpType.Localloc:
                    eval.Push(exp.LocalAlloc(eval.Pop()));
                    break;

                case OpType.Ldsflda:
                case OpType.Ldflda:
                    var afield = x.ResolveField();
                    eval.Push(exp.AddressOf(exp.Field(afield, afield.IsStatic ? default(T) : eval.Pop())));
                    break;

                case OpType.Ldarga:
                case OpType.Ldarga_s:
                    eval.Push(exp.AddressOf(args[x.Operand.Int16]));
                    break;

                case OpType.Ldloca:
                case OpType.Ldloca_s:
                    eval.Push(exp.AddressOf(locals[x.Operand.Int16]));
                    break;

                case OpType.Ldarg:
                case OpType.Ldarg_s:
                    eval.Push(args[x.Operand.Int16]);
                    break;

                case OpType.Ldarg_0:
                    eval.Push(args[0]);
                    break;

                case OpType.Ldarg_1:
                    eval.Push(args[1]);
                    break;

                case OpType.Ldarg_2:
                    eval.Push(args[2]);
                    break;

                case OpType.Ldarg_3:
                    eval.Push(args[3]);
                    break;

                case OpType.Ldc_i4_m1:
                    eval.Push(exp.Constant(-1));
                    break;

                case OpType.Ldc_i4_0:
                    eval.Push(exp.Constant(0));
                    break;

                case OpType.Ldc_i4_1:
                    eval.Push(exp.Constant(1));
                    break;

                case OpType.Ldc_i4_2:
                    eval.Push(exp.Constant(2));
                    break;

                case OpType.Ldc_i4_3:
                    eval.Push(exp.Constant(3));
                    break;

                case OpType.Ldc_i4_4:
                    eval.Push(exp.Constant(4));
                    break;

                case OpType.Ldc_i4_5:
                    eval.Push(exp.Constant(5));
                    break;

                case OpType.Ldc_i4_6:
                    eval.Push(exp.Constant(6));
                    break;

                case OpType.Ldc_i4_7:
                    eval.Push(exp.Constant(7));
                    break;

                case OpType.Ldc_i4_8:
                    eval.Push(exp.Constant(8));
                    break;

                case OpType.Ldc_i4:
                case OpType.Ldc_i4_s:
                    var i4 = x.Operand.Int32;
                    eval.Push(exp.Constant(i4));
                    break;

                case OpType.Ldc_i8:
                    var i8 = x.Operand.Int64;
                    eval.Push(exp.Constant(i8));
                    break;

                case OpType.Ldc_r8:
                    var r8 = x.Operand.Float64;
                    eval.Push(exp.Constant(r8));
                    break;

                case OpType.Ldc_r4:
                    var r4 = x.Operand.Float32;
                    eval.Push(exp.Constant(r4));
                    break;

                case OpType.Ldfld:
                case OpType.Ldsfld:
                    var lfield = x.ResolveField();
                    eval.Push(exp.Field(lfield, lfield.IsStatic ? default(T) : eval.Pop()));
                    return;

                case OpType.Ldlen:
                    eval.Push(exp.ArrayLength(eval.Pop()));
                    break;

                case OpType.Ldloc_0:
                    eval.Push(locals[0]);
                    break;

                case OpType.Ldloc_1:
                    eval.Push(locals[1]);
                    break;

                case OpType.Ldloc_2:
                    eval.Push(locals[2]);
                    break;

                case OpType.Ldloc_3:
                    eval.Push(locals[3]);
                    break;

                case OpType.Ldloc:
                case OpType.Ldloc_s:
                    eval.Push(locals[x.Operand.Int32]);
                    break;

                case OpType.Stloc_0:
                    eval.Push(exp.Assign(locals[0], eval.Pop()));
                    break;

                case OpType.Stloc_1:
                    eval.Push(exp.Assign(locals[1], eval.Pop()));
                    break;

                case OpType.Stloc_2:
                    eval.Push(exp.Assign(locals[2], eval.Pop()));
                    break;

                case OpType.Stloc_3:
                    eval.Push(exp.Assign(locals[3], eval.Pop()));
                    break;

                case OpType.Stloc:
                case OpType.Stloc_s:
                    eval.Push(exp.Assign(locals[x.Operand.Int16], eval.Pop()));
                    break;

                case OpType.Starg:
                case OpType.Starg_s:
                    eval.Push(exp.Assign(args[x.Operand.Int16], eval.Pop()));
                    break;

                case OpType.Stobj:
                    rhs = eval.Pop();
                    eval.Push(exp.Assign(eval.Pop(), rhs));
                    break;

                case OpType.Stsfld:
                case OpType.Stfld:
                    var sfield = x.ResolveField();
                    rhs = eval.Pop();
                    eval.Push(exp.Assign(exp.Field(sfield, sfield.IsStatic ? default(T) : eval.Pop()), rhs));
                    break;

                case OpType.Ldnull:
                    eval.Push(exp.Constant <object>(null));
                    break;

                case OpType.Ldstr:
                    eval.Push(exp.Constant(x.ResolveString()));
                    break;

                case OpType.Ldtoken:
                    eval.Push(exp.Constant(x.Resolve()));
                    break;

                case OpType.Nop:
                    break;

                case OpType.Pop:
                    eval.Pop();
                    break;

                case OpType.Ret:
                    Debug.Assert(eval.Count == 1);
                    eval.Push(exp.Return(eval.Pop()));
                    break;

                case OpType.Ldelem:
                case OpType.Ldelem_ref:
                case OpType.Ldelem_i:
                case OpType.Ldelem_i1:
                case OpType.Ldelem_i2:
                case OpType.Ldelem_i4:
                case OpType.Ldelem_i8:
                case OpType.Ldelem_r4:
                case OpType.Ldelem_r8:
                case OpType.Ldelem_u1:
                case OpType.Ldelem_u2:
                case OpType.Ldelem_u4:
                    rhs = eval.Pop();
                    eval.Push(exp.ArrayGet(eval.Pop(), rhs));
                    break;

                case OpType.Stelem:
                case OpType.Stelem_i:
                case OpType.Stelem_i1:
                case OpType.Stelem_i2:
                case OpType.Stelem_i4:
                case OpType.Stelem_i8:
                case OpType.Stelem_r4:
                case OpType.Stelem_r8:
                case OpType.Stelem_ref:
                    rhs = eval.Pop();
                    var idx = eval.Pop();
                    eval.Push(exp.ArraySet(eval.Pop(), idx, rhs));
                    break;

                case OpType.Ldind_ref:
                case OpType.Ldind_i:
                case OpType.Ldind_i1:
                case OpType.Ldind_i2:
                case OpType.Ldind_i4:
                case OpType.Ldind_i8:
                case OpType.Ldind_r4:
                case OpType.Ldind_r8:
                case OpType.Ldind_u1:
                case OpType.Ldind_u2:
                case OpType.Ldind_u4:
                    eval.Push(exp.AddressGet(eval.Pop()));
                    break;

                case OpType.Stind_ref:
                case OpType.Stind_i:
                case OpType.Stind_i1:
                case OpType.Stind_i2:
                case OpType.Stind_i4:
                case OpType.Stind_i8:
                case OpType.Stind_r4:
                case OpType.Stind_r8:
                    rhs = eval.Pop();
                    eval.Push(exp.AddressSet(eval.Pop(), rhs));
                    break;

                case OpType.Arglist:
                    eval.Push(exp.ArgumentList());
                    break;

                //-------------- Comparison instructions --------------
                case OpType.Isinst:
                    eval.Push(exp.TypeAs(eval.Pop(), x.ResolveType()));
                    break;

                case OpType.Ceq:
                    // a bool is a native int in CIL, and != is a comparison against 0
                    rhs = eval.Pop();
                    var lhs     = eval.Pop();
                    var tyleft  = exp.TypeOf(lhs);
                    var tyright = exp.TypeOf(rhs);
                    if (tyleft != typeof(bool) || tyleft == tyright)
                    {
                        eval.Push(exp.Equal(lhs, rhs));
                    }
                    else if (tyleft != typeof(bool) && tyright == typeof(bool))
                    {
                        eval.Push(exp.Equal(exp.Cast(lhs, tyright), rhs));
                    }
                    else if (tyright != typeof(bool) && tyleft == typeof(bool))
                    {
                        eval.Push(exp.Equal(lhs, exp.Cast(rhs, tyleft)));
                    }
                    else
                    {
                        throw new InvalidOperationException("Unknown bool comparison!");
                    }
                    break;

                case OpType.Cgt:
                case OpType.Cgt_un:
                    rhs = eval.Pop();
                    eval.Push(exp.GreaterThan(eval.Pop(), rhs));
                    break;

                case OpType.Clt:
                case OpType.Clt_un:
                    rhs = eval.Pop();
                    eval.Push(exp.LessThan(eval.Pop(), rhs));
                    break;

                case OpType.Ckfinite:
                    var isInfinity = exp.TypeOf(eval.Peek()) == typeof(float) ? r4IsInfinity : r8IsInfinity;
                    var ethrow     = exp.Throw(exp.New(arithError, new[] { exp.Constant("Value is not a finite number.") }));
                    var evalue     = eval.Pop();
                    eval.Push(exp.If(exp.Call(isInfinity, false, default(T), new[] { evalue }), ethrow, evalue));
                    break;

                case OpType.Constrained_:
                    break;

                //------------ Conversion instructions -------------
                case OpType.Castclass:
                    eval.Push(exp.Cast(eval.Pop(), x.ResolveType()));
                    break;

                case OpType.Conv_i:
                    eval.Push(exp.Cast(eval.Pop(), nativeInt));
                    break;

                case OpType.Conv_i1:
                    eval.Push(exp.Cast(eval.Pop(), typeof(sbyte)));
                    break;

                case OpType.Conv_i2:
                    eval.Push(exp.Cast(eval.Pop(), typeof(short)));
                    break;

                case OpType.Conv_i4:
                    eval.Push(exp.Cast(eval.Pop(), typeof(int)));
                    break;

                case OpType.Conv_i8:
                    eval.Push(exp.Cast(eval.Pop(), typeof(long)));
                    break;

                case OpType.Conv_ovf_i:
                case OpType.Conv_ovf_i_un:
                    eval.Push(exp.CastOverflow(eval.Pop(), nativeInt));
                    break;

                case OpType.Conv_ovf_i1:
                case OpType.Conv_ovf_i1_un:
                    eval.Push(exp.CastOverflow(eval.Pop(), typeof(sbyte)));
                    break;

                case OpType.Conv_ovf_i2:
                case OpType.Conv_ovf_i2_un:
                    eval.Push(exp.CastOverflow(eval.Pop(), typeof(short)));
                    break;

                case OpType.Conv_ovf_i4:
                case OpType.Conv_ovf_i4_un:
                    eval.Push(exp.CastOverflow(eval.Pop(), typeof(int)));
                    break;

                case OpType.Conv_ovf_i8:
                case OpType.Conv_ovf_i8_un:
                    eval.Push(exp.CastOverflow(eval.Pop(), typeof(long)));
                    break;

                case OpType.Conv_r4:
                case OpType.Conv_r_un:
                    eval.Push(exp.Cast(eval.Pop(), typeof(float)));
                    break;

                case OpType.Conv_r8:
                    eval.Push(exp.Cast(eval.Pop(), typeof(double)));
                    break;

                case OpType.Conv_u:
                    eval.Push(exp.Cast(eval.Pop(), typeof(UIntPtr)));
                    break;

                case OpType.Conv_u1:
                    eval.Push(exp.Cast(eval.Pop(), typeof(byte)));
                    break;

                case OpType.Conv_u2:
                    eval.Push(exp.Cast(eval.Pop(), typeof(ushort)));
                    break;

                case OpType.Conv_u4:
                    eval.Push(exp.Cast(eval.Pop(), typeof(uint)));
                    break;

                case OpType.Conv_u8:
                    eval.Push(exp.Cast(eval.Pop(), typeof(ulong)));
                    break;

                case OpType.Dup:
                    eval.Push(exp.Duplicate(eval.Pop()));
                    break;

                case OpType.Newarr:
                    var atype = x.ResolveType();
                    eval.Push(exp.Array(atype, new[] { eval.Pop() }));
                    break;

                case OpType.Newobj:
                    var ctor    = (ConstructorInfo)x.ResolveMethod();
                    var cparams = ctor.GetParameters();
                    var cargs   = cparams.Select(a => eval.Pop()).Reverse();
                    eval.Push(exp.New(ctor, cargs));
                    break;

                case OpType.Rethrow:
                    eval.Push(exp.Rethrow());
                    break;

                case OpType.Tail_:
                    tailcall = true;
                    break;

                case OpType.Unaligned_:
                    eval.Push(exp.Unaligned(eval.Pop()));
                    break;

                case OpType.Unbox:
                case OpType.Unbox_any:
                    eval.Push(exp.Unbox(eval.Pop(), x.ResolveType()));
                    break;

                //case OpType.Break:
                //    break;
                //case OpType.Volatile_:
                //    break;
                //case OpType.Refanytype:
                //case OpType.Refanyval:
                //case OpType.Mkrefany:
                //case OpType.Localloc:
                //case OpType.Readonly_:
                default:
                    throw new NotSupportedException("Instruction not supported: " + x);
                }
            }
        }