예제 #1
0
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     foreach (var statement in Statements)
     {
         statement.Compile(context, il);
     }
 }
예제 #2
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            Condition.Compile(context, il);
            var ifNotTrue = il.DefineLabel();

            il.Emit(EmitOpCodes.Brfalse, ifNotTrue);
            Statement.Compile(context, il);
            var statementReturned = il.Instructions.Last().OpCode == EmitOpCodes.Ret;

            if (Else != null)
            {
                EmitLabel end = null;
                if (!statementReturned)
                {
                    end = il.DefineLabel();
                    il.Emit(EmitOpCodes.Br, end);
                }
                il.MarkLabel(ifNotTrue);
                Else.Compile(context, il);
                if (!statementReturned)
                {
                    il.MarkLabel(end);
                    il.Emit(EmitOpCodes.Nop);
                }
            }
            else
            {
                il.MarkLabel(ifNotTrue);
            }
        }
예제 #3
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            var arrayType = GetExpressionType();

            if (Lengths.Count == 1)
            {
                il.Emit(EmitOpCodes.Ldc_I4, Lengths[0]);
                il.Emit(EmitOpCodes.Newarr, Type);
                for (var i = 0; i < Initializer.Length; i++)
                {
                    var element = (EmitExpression)Initializer[i];
                    il.Emit(EmitOpCodes.Dup);
                    il.Emit(EmitOpCodes.Ldc_I4, i);
                    element.Compile(context, il);
                    il.Emit(EmitOpCodes.Stelem, Type);
                }
            }
            else
            {
                var constructor = arrayType.Members.OfType <EmitConstructor>().Single(x => x.Parameters.Count() == Rank);
                var setter      = arrayType.Members.OfType <EmitMethod>().Single(x => x.Name == "Set");
                foreach (var length in Lengths)
                {
                    il.Emit(EmitOpCodes.Ldc_I4, length);
                }
                il.Emit(EmitOpCodes.Newobj, constructor);

                var indices = new int[Lengths.Count];
                Action <int, IEmitArrayElement> recurse = null;
                recurse = (level, element) =>
                {
                    if (level == Rank - 1)
                    {
                        var expression = (EmitExpression)element;
                        il.Emit(EmitOpCodes.Dup);
                        foreach (var index in indices)
                        {
                            il.Emit(EmitOpCodes.Ldc_I4, index);
                        }
                        expression.Compile(context, il);
                        il.Emit(EmitOpCodes.Call, setter);
                    }
                    else
                    {
                        for (var i = 0; i < element.Length; i++)
                        {
                            indices[level + 1] = i;
                            var current = element[i];
                            recurse(level + 1, current);
                        }
                    }
                };
                for (var i = 0; i < Initializer.Length; i++)
                {
                    var element = Initializer[i];
                    indices[0] = i;
                    recurse(0, element);
                }
            }
        }
예제 #4
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            switch (Operator)
            {
            case EmitBinaryOperator.Assign:
                ((IEmitReferenceExpression)Left).CompileAssignment(context, il, () => Right.Compile(context, il));
                break;

            case EmitBinaryOperator.BooleanAnd:
                Left.Compile(context, il);
                il.Emit(EmitOpCodes.Dup);

                var andEnd = il.DefineLabel();
                il.Emit(EmitOpCodes.Brfalse, andEnd);
                il.Emit(EmitOpCodes.Pop);

                Right.Compile(context, il);
                il.MarkLabel(andEnd);

                break;

            case EmitBinaryOperator.BooleanOr:
                Left.Compile(context, il);
                il.Emit(EmitOpCodes.Dup);

                var orEnd = il.DefineLabel();
                il.Emit(EmitOpCodes.Brtrue, orEnd);
                il.Emit(EmitOpCodes.Pop);

                Right.Compile(context, il);
                il.MarkLabel(orEnd);

                break;

            default:
                var instruction  = GetOpCode();
                var isInverted   = IsOperatorInverse();
                var isAssignment = IsOperatorAssignment();

                Left.Compile(context, il);
                Right.Compile(context, il);

                il.Emit(instruction);

                if (isInverted)
                {
                    il.Emit(EmitOpCodes.Ldc_I4_0);
                    il.Emit(EmitOpCodes.Ceq);
                }

                if (isAssignment)
                {
                    var local = il.DeclareLocal(typeof(bool));
                    il.Emit(EmitOpCodes.Stloc, local);
                    ((IEmitReferenceExpression)Left).CompileAssignment(context, il, () => il.Emit(EmitOpCodes.Ldloc, local));
                }

                break;
            }
        }
예제 #5
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            Condition.Compile(context, il);
            var ifNotTrue = il.DefineLabel();
            il.Emit(EmitOpCodes.Brfalse, ifNotTrue);
            Statement.Compile(context, il);
            var statementReturned = il.Instructions.Last().OpCode == EmitOpCodes.Ret;

            if (Else != null)
            {
                EmitLabel end = null;
                if (!statementReturned)
                {
                    end = il.DefineLabel();
                    il.Emit(EmitOpCodes.Br, end);
                }
                il.MarkLabel(ifNotTrue);
                Else.Compile(context, il);
                if (!statementReturned)
                {
                    il.MarkLabel(end);
                    il.Emit(EmitOpCodes.Nop);
                }
            }
            else
            {
                il.MarkLabel(ifNotTrue);
            }
        }
예제 #6
0
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     if (Value == null)
     {
         il.Emit(EmitOpCodes.Ldnull);
     }
     else if (Value is int)
     {
         il.Emit(EmitOpCodes.Ldc_I4, (int)Value);
     }
     else if (Value is long)
     {
         il.Emit(EmitOpCodes.Ldc_I8, (long)Value);
     }
     else if (Value is float)
     {
         il.Emit(EmitOpCodes.Ldc_R4, (float)Value);
     }
     else if (Value is double)
     {
         il.Emit(EmitOpCodes.Ldc_R8, (double)Value);
     }
     else if (Value is bool)
     {
         il.Emit(EmitOpCodes.Ldc_I4, (bool)Value ? 1 : 0);
     }
     else if (Value is string)
     {
         il.Emit(EmitOpCodes.Ldstr, (string)Value);
     }
     else
     {
         throw new Exception();
     }
 }
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     foreach (var variable in Variables)
     {
         var local = il.DeclareLocal(variable.Type);
         variable.SetData(context, local);
     }
 }
        public void CompileAssignment(EmitCompilerContext context, EmitIl il, Action compileValue)
        {
            var local = Variable.GetData(context);

            compileValue();
            il.Emit(EmitOpCodes.Dup);       // We want to leave the assigned value on the stack, since assignment is an expression
            il.Emit(EmitOpCodes.Stloc, local);
        }
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            var arrayType = GetExpressionType();

            if (Lengths.Count == 1)
            {
                il.Emit(EmitOpCodes.Ldc_I4, Lengths[0]);
                il.Emit(EmitOpCodes.Newarr, Type);
                for (var i = 0; i < Initializer.Length; i++)
                {
                    var element = (EmitExpression)Initializer[i];
                    il.Emit(EmitOpCodes.Dup);
                    il.Emit(EmitOpCodes.Ldc_I4, i);
                    element.Compile(context, il);
                    il.Emit(EmitOpCodes.Stelem, Type);
                }
            }
            else
            {
                var constructor = arrayType.Members.OfType<EmitConstructor>().Single(x => x.Parameters.Count() == Rank);
                var setter = arrayType.Members.OfType<EmitMethod>().Single(x => x.Name == "Set");
                foreach (var length in Lengths)
                    il.Emit(EmitOpCodes.Ldc_I4, length);
                il.Emit(EmitOpCodes.Newobj, constructor);

                var indices = new int[Lengths.Count];
                Action<int, IEmitArrayElement> recurse = null;
                recurse = (level, element) =>
                {
                    if (level == Rank - 1)
                    {
                        var expression = (EmitExpression)element;
                        il.Emit(EmitOpCodes.Dup);
                        foreach (var index in indices)
                        {
                            il.Emit(EmitOpCodes.Ldc_I4, index);
                        }
                        expression.Compile(context, il);
                        il.Emit(EmitOpCodes.Call, setter);
                    }
                    else
                    {
                        for (var i = 0; i < element.Length; i++)
                        {
                            indices[level + 1] = i;
                            var current = element[i];
                            recurse(level + 1, current);
                        }
                    }
                };
                for (var i = 0; i < Initializer.Length; i++)
                {
                    var element = Initializer[i];
                    indices[0] = i;
                    recurse(0, element);
                }
            }
        }
예제 #10
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            switch (Operator)
            {
                case EmitBinaryOperator.Assign:
                    ((IEmitReferenceExpression)Left).CompileAssignment(context, il, () => Right.Compile(context, il));
                    break;
                case EmitBinaryOperator.BooleanAnd:
                    Left.Compile(context, il);
                    il.Emit(EmitOpCodes.Dup);

                    var andEnd = il.DefineLabel();
                    il.Emit(EmitOpCodes.Brfalse, andEnd);
                    il.Emit(EmitOpCodes.Pop);

                    Right.Compile(context, il);
                    il.MarkLabel(andEnd);

                    break;
                case EmitBinaryOperator.BooleanOr:
                    Left.Compile(context, il);
                    il.Emit(EmitOpCodes.Dup);

                    var orEnd = il.DefineLabel();
                    il.Emit(EmitOpCodes.Brtrue, orEnd);
                    il.Emit(EmitOpCodes.Pop);

                    Right.Compile(context, il);
                    il.MarkLabel(orEnd);

                    break;
                default:
                    var instruction = GetOpCode();
                    var isInverted = IsOperatorInverse();
                    var isAssignment = IsOperatorAssignment();

                    Left.Compile(context, il);
                    Right.Compile(context, il);

                    il.Emit(instruction);

                    if (isInverted)
                    {
                        il.Emit(EmitOpCodes.Ldc_I4_0);
                        il.Emit(EmitOpCodes.Ceq);
                    }

                    if (isAssignment)
                    {
                        var local = il.DeclareLocal(typeof(bool));
                        il.Emit(EmitOpCodes.Stloc, local);
                        ((IEmitReferenceExpression)Left).CompileAssignment(context, il, () => il.Emit(EmitOpCodes.Ldloc, local));
                    }

                    break;
            }
        }
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            if (Arguments.Count != Method.Parameters.Count())
                throw new Exception($"Incorrect number of arguments passed to method {Method}");

            Target?.Compile(context, il);
            foreach (var argument in Arguments)
                argument.Compile(context, il);

            var opCode = Method.IsVirtual || Method.DeclaringType.IsInterface ? (IEmitOpCodeMethod)EmitOpCodes.Callvirt : EmitOpCodes.Call;

            il.Emit(opCode, Method);
        }
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            if (Arguments.Count != Method.Parameters.Count())
            {
                throw new Exception($"Incorrect number of arguments passed to method {Method}");
            }

            Target?.Compile(context, il);
            foreach (var argument in Arguments)
            {
                argument.Compile(context, il);
            }

            var opCode = Method.IsVirtual || Method.DeclaringType.IsInterface ? (IEmitOpCodeMethod)EmitOpCodes.Callvirt : EmitOpCodes.Call;

            il.Emit(opCode, Method);
        }
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     if (Lengths.Count == 1)
     {
         Lengths[0].Compile(context, il);
         il.Emit(EmitOpCodes.Newarr, Type);
     }
     else
     {
         var arrayType = GetExpressionType();
         var constructor = arrayType.Members.OfType<EmitConstructor>().Single(x => x.Parameters.Count() == Lengths.Count);
         foreach (var length in Lengths)
         {
             length.Compile(context, il);
         }
         il.Emit(EmitOpCodes.Newobj, constructor);
     }
 }
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     if (Lengths.Count == 1)
     {
         Lengths[0].Compile(context, il);
         il.Emit(EmitOpCodes.Newarr, Type);
     }
     else
     {
         var arrayType   = GetExpressionType();
         var constructor = arrayType.Members.OfType <EmitConstructor>().Single(x => x.Parameters.Count() == Lengths.Count);
         foreach (var length in Lengths)
         {
             length.Compile(context, il);
         }
         il.Emit(EmitOpCodes.Newobj, constructor);
     }
 }
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            // Special handling for value types without a constructor
            if (Constructor == null)
            {
                var local = il.DeclareLocal(Type);
                il.Emit(EmitOpCodes.Ldloca, local);
                il.Emit(EmitOpCodes.Initobj, Type);
                il.Emit(EmitOpCodes.Ldloc, local);
                return;
            }

            foreach (var argument in Arguments)
            {
                argument.Compile(context, il);
            }

            il.Emit(EmitOpCodes.Newobj, Constructor);
        }
예제 #16
0
 public override void Compile(EmitCompilerContext context, EmitIl il)
 {
     if (Value == null)
         il.Emit(EmitOpCodes.Ldnull);
     else if (Value is int)
         il.Emit(EmitOpCodes.Ldc_I4, (int)Value);
     else if (Value is long)
         il.Emit(EmitOpCodes.Ldc_I8, (long)Value);
     else if (Value is float)
         il.Emit(EmitOpCodes.Ldc_R4, (float)Value);
     else if (Value is double)
         il.Emit(EmitOpCodes.Ldc_R8, (double)Value);
     else if (Value is bool)
         il.Emit(EmitOpCodes.Ldc_I4, (bool)Value ? 1 : 0);
     else if (Value is string)
         il.Emit(EmitOpCodes.Ldstr, (string)Value);
     else
         throw new Exception();
 }
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            // Special handling for value types without a constructor
            if (Constructor == null)
            {
                var local = il.DeclareLocal(Type);
                il.Emit(EmitOpCodes.Ldloca, local);
                il.Emit(EmitOpCodes.Initobj, Type);
                il.Emit(EmitOpCodes.Ldloc, local);
                return;
            }

            foreach (var argument in Arguments)
            {
                argument.Compile(context, il);
            }

            il.Emit(EmitOpCodes.Newobj, Constructor);
        }
예제 #18
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            var item = il.DeclareLocal(Item.Type);

            Item.SetData(context, item);

            EmitType genericEnumerableType = typeof(IEnumerable <>);
            var      enumerableType        = genericEnumerableType.MakeGenericType(Item.Type);
            var      getEnumeratorMethod   = enumerableType.Members.OfType <EmitMethod>().Single(x => x.Name == nameof(IEnumerable <object> .GetEnumerator));

            EmitType genericEnumeratorType = typeof(IEnumerator <>);
            var      enumeratorType        = genericEnumeratorType.MakeGenericType(Item.Type);
            var      moveNextMethod        = enumerableType.Members.OfType <EmitMethod>().Single(x => x.Name == nameof(IEnumerator <object> .MoveNext));
            var      getCurrentMethod      = enumerableType.Members.OfType <EmitProperty>().Single(x => x.Name == nameof(IEnumerator <object> .Current)).GetMethod;

            var enumerator = il.DeclareLocal(enumeratorType);

            Collection.Compile(context, il);
            il.Emit(EmitOpCodes.Callvirt, getEnumeratorMethod);
            il.Emit(EmitOpCodes.Stloc, enumerator);

            var topOfLoop = il.DefineLabel();
            var end       = il.DefineLabel();

            il.MarkLabel(topOfLoop);
            il.Emit(EmitOpCodes.Ldloc, enumerator);
            il.Emit(EmitOpCodes.Callvirt, moveNextMethod);
            il.Emit(EmitOpCodes.Brfalse, end);

            il.Emit(EmitOpCodes.Ldloc, enumerator);
            il.Emit(EmitOpCodes.Callvirt, getCurrentMethod);
            il.Emit(EmitOpCodes.Stloc, item);

            Statement.Compile(context, il);
            il.Emit(EmitOpCodes.Br, topOfLoop);

            il.MarkLabel(end);
            il.Emit(EmitOpCodes.Nop);
        }
예제 #19
0
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            var item = il.DeclareLocal(Item.Type);
            Item.SetData(context, item);

            EmitType genericEnumerableType = typeof(IEnumerable<>);
            var enumerableType = genericEnumerableType.MakeGenericType(Item.Type);
            var getEnumeratorMethod = enumerableType.Members.OfType<EmitMethod>().Single(x => x.Name == nameof(IEnumerable<object>.GetEnumerator));

            EmitType genericEnumeratorType = typeof(IEnumerator<>);
            var enumeratorType = genericEnumeratorType.MakeGenericType(Item.Type);
            var moveNextMethod = enumerableType.Members.OfType<EmitMethod>().Single(x => x.Name == nameof(IEnumerator<object>.MoveNext));
            var getCurrentMethod = enumerableType.Members.OfType<EmitProperty>().Single(x => x.Name == nameof(IEnumerator<object>.Current)).GetMethod;

            var enumerator = il.DeclareLocal(enumeratorType);

            Collection.Compile(context, il);
            il.Emit(EmitOpCodes.Callvirt, getEnumeratorMethod);
            il.Emit(EmitOpCodes.Stloc, enumerator);

            var topOfLoop = il.DefineLabel();
            var end = il.DefineLabel();

            il.MarkLabel(topOfLoop);
            il.Emit(EmitOpCodes.Ldloc, enumerator);
            il.Emit(EmitOpCodes.Callvirt, moveNextMethod);
            il.Emit(EmitOpCodes.Brfalse, end);

            il.Emit(EmitOpCodes.Ldloc, enumerator);
            il.Emit(EmitOpCodes.Callvirt, getCurrentMethod);
            il.Emit(EmitOpCodes.Stloc, item);

            Statement.Compile(context, il);
            il.Emit(EmitOpCodes.Br, topOfLoop);

            il.MarkLabel(end);
            il.Emit(EmitOpCodes.Nop);
        }
예제 #20
0
 public abstract void Compile(EmitCompilerContext context, EmitIl il);
예제 #21
0
 public abstract void Compile(EmitCompilerContext context, EmitIl il);
        public override void Compile(EmitCompilerContext context, EmitIl il)
        {
            var local = Variable.GetData(context);

            il.Emit(EmitOpCodes.Ldloc, local);
        }