예제 #1
0
        protected override NodeBase expand(Context ctx, bool mustReturn)
        {
            if (!IsConstant)
            {
                return(Kind == LogicalOperatorKind.And
                                        ? Expr.If(LeftOperand, Expr.Block(Expr.Cast <bool>(RightOperand)), Expr.Block(Expr.False()))
                                        : Expr.If(LeftOperand, Expr.Block(Expr.True()), Expr.Block(Expr.Cast <bool>(RightOperand))));
            }

            return(base.expand(ctx, mustReturn));
        }
예제 #2
0
        /// <summary>
        /// Saves the value to an array location.
        /// </summary>
        private void emitSetArray(Context ctx)
        {
            var gen = ctx.CurrentMethod.Generator;

            var exprType = Expression.Resolve(ctx);
            var itemType = exprType.GetElementType();

            Expression.Emit(ctx, true);
            Expr.Cast(Index, typeof(int)).Emit(ctx, true);
            Expr.Cast(Value, itemType).Emit(ctx, true);
            gen.EmitSaveIndex(itemType);
        }
예제 #3
0
        /// <summary>
        /// Emits the code for retrieving an array item by index.
        /// </summary>
        private void compileArray(Context ctx)
        {
            var gen = ctx.CurrentMethod.Generator;

            var exprType = Expression.Resolve(ctx);
            var itemType = exprType.GetElementType();

            Expression.Emit(ctx, true);
            Expr.Cast(Index, typeof(int)).Emit(ctx, true);

            gen.EmitLoadIndex(itemType, RefArgumentRequired || PointerRequired);
        }
예제 #4
0
        protected override NodeBase expand(Context ctx, bool mustReturn)
        {
            var fromType = Expression.Resolve(ctx);
            var toType   = Resolve(ctx);

            if (fromType.IsNullableType() && !toType.IsNullableType())
            {
                return(Expr.Cast(Expr.GetMember(Expression, "Value"), toType));
            }

            return(base.expand(ctx, mustReturn));
        }
예제 #5
0
파일: ParserTest.cs 프로젝트: taekun/lens
        public void Algebraic3()
        {
            var src = @"
type TestType
    Small of int
    Large of int
fun part:TestType (x:int) ->
    if x > 100 then
        (new Large x) as TestType
    else
        new Small x


var a = part 10
new [ a is TestType; a is Small; a is Large ]";

            var result = new NodeBase[]
            {
                Expr.Type(
                    "TestType",
                    Expr.Label("Small", "int"),
                    Expr.Label("Large", "int")
                    ),

                Expr.Fun(
                    "part",
                    "TestType",
                    new [] { Expr.Arg("x", "int") },
                    Expr.If(
                        Expr.Greater(Expr.Get("x"), Expr.Int(100)),
                        Expr.Block(
                            Expr.Cast(
                                Expr.New("Large", Expr.Get("x")),
                                "TestType"
                                )
                            ),
                        Expr.Block(
                            Expr.New("Small", Expr.Get("x"))
                            )
                        )
                    ),

                Expr.Var("a", Expr.Invoke("part", Expr.Int(10))),
                Expr.Array(
                    Expr.Is(Expr.Get("a"), "TestType"),
                    Expr.Is(Expr.Get("a"), "Small"),
                    Expr.Is(Expr.Get("a"), "Large")
                    )
            };

            TestParser(src, result);
        }
예제 #6
0
        /// <summary>
        /// Assigns a closured variable that is declared in current scope.
        /// </summary>
        private void emitSetClosuredLocal(Context ctx, Local name)
        {
            var gen = ctx.CurrentMethod.Generator;

            gen.EmitLoadLocal(ctx.Scope.ActiveClosure.ClosureVariable);

            Expr.Cast(Value, name.Type).Emit(ctx, true);

            var clsType  = ctx.Scope.ActiveClosure.ClosureType.TypeInfo;
            var clsField = ctx.ResolveField(clsType, name.ClosureFieldName);

            gen.EmitSaveField(clsField.FieldInfo);
        }
예제 #7
0
        /// <summary>
        /// Loads both arguments and converts them to the biggest common type.
        /// </summary>
        protected void LoadAndConvertNumerics(Context ctx, Type type = null)
        {
            var left  = LeftOperand.Resolve(ctx);
            var right = RightOperand.Resolve(ctx);

            if (type == null)
            {
                type = TypeExtensions.GetNumericOperationType(left, right);
            }

            Expr.Cast(LeftOperand, type).Emit(ctx, true);
            Expr.Cast(RightOperand, type).Emit(ctx, true);
        }
예제 #8
0
파일: IfNode.cs 프로젝트: vplemyannik/lens
        /// <summary>
        /// Emits one branch of the condition (true or false).
        /// </summary>
        private void EmitBranch(Context ctx, NodeBase branch, bool mustReturn)
        {
            var desiredType = Resolve(ctx);

            mustReturn &= !desiredType.IsVoid();
            var branchType = branch.Resolve(ctx, mustReturn);

            if (!branchType.IsVoid() && !desiredType.IsVoid())
            {
                branch = Expr.Cast(branch, desiredType);
            }

            branch.Emit(ctx, mustReturn);
        }
예제 #9
0
        protected override void EmitInternal(Context ctx, bool mustReturn)
        {
            var gen = ctx.CurrentMethod.Generator;

            if (OverloadedMethod == null)
            {
                EmitOperator(ctx);
                return;
            }

            var ps = OverloadedMethod.ArgumentTypes;

            Expr.Cast(Operand, ps[0]).Emit(ctx, true);
            gen.EmitCall(OverloadedMethod.MethodInfo);
        }
예제 #10
0
        /// <summary>
        /// Checks all items in the array with corresponding rules.
        /// </summary>
        private IEnumerable <NodeBase> ExpandItemChecksIterated(Context ctx, NodeBase expression, int count, Label nextStatement)
        {
            if (count == 0)
            {
                yield break;
            }

            var enumerableType = typeof(IEnumerable <>).MakeGenericType(_elementType);
            var enumeratorType = typeof(IEnumerator <>).MakeGenericType(_elementType);

            var enumeratorVar = ctx.Scope.DeclareImplicit(ctx, enumeratorType, false);

            yield return(Expr.Set(
                             enumeratorVar,
                             Expr.Invoke(
                                 Expr.Cast(expression, enumerableType),
                                 "GetEnumerator"
                                 )
                             ));

            for (var idx = 0; idx < count; idx++)
            {
                // if not iter.MoveNext() then jump!
                yield return(MakeJumpIf(
                                 nextStatement,
                                 Expr.Not(
                                     Expr.Invoke(
                                         Expr.Get(enumeratorVar),
                                         "MoveNext"
                                         )
                                     )
                                 ));

                var rules = ElementRules[idx].Expand(
                    ctx,
                    Expr.GetMember(
                        Expr.Get(enumeratorVar),
                        "Current"
                        ),
                    nextStatement
                    );

                foreach (var rule in rules)
                {
                    yield return(rule);
                }
            }
        }
예제 #11
0
파일: ParserTest.cs 프로젝트: taekun/lens
        public void Cast()
        {
            var src    = "let a = (b as List<int>).Count";
            var result = Expr.Let(
                "a",
                Expr.GetMember(
                    Expr.Cast(
                        Expr.Get("b"),
                        "List<int>"
                        ),
                    "Count"
                    )
                );

            TestParser(src, result);
        }
예제 #12
0
        protected override void emitCode(Context ctx, bool mustReturn)
        {
            var gen = ctx.CurrentMethod.Generator;

            if (_OverloadedMethod == null)
            {
                emitOperator(ctx);
                return;
            }

            var ps = _OverloadedMethod.ArgumentTypes;

            Expr.Cast(LeftOperand, ps[0]).Emit(ctx, true);
            Expr.Cast(RightOperand, ps[1]).Emit(ctx, true);
            gen.EmitCall(_OverloadedMethod.MethodInfo);
        }
예제 #13
0
        protected override void emitCode(Context ctx, bool mustReturn)
        {
            var gen  = ctx.CurrentMethod.Generator;
            var type = Value.Resolve(ctx);

            if (_Property != null)
            {
                var cast = Expr.Cast(Value, type);
                if (_Property.SetterMethod != null)
                {
                    cast.Emit(ctx, true);
                    gen.EmitCall(_Property.SetterMethod.MethodInfo);
                }
                else
                {
                    var method = typeof(GlobalPropertyHelper).GetMethod("Set").MakeGenericMethod(type);

                    gen.EmitConstant(ctx.ContextId);
                    gen.EmitConstant(_Property.PropertyId);
                    Expr.Cast(Value, type).Emit(ctx, true);
                    gen.EmitCall(method);
                }
            }
            else
            {
                var nameInfo = Local ?? ctx.Scope.FindLocal(Identifier);
                if (nameInfo != null)
                {
                    if (nameInfo.IsClosured)
                    {
                        if (nameInfo.ClosureDistance == 0)
                        {
                            emitSetClosuredLocal(ctx, nameInfo);
                        }
                        else
                        {
                            emitSetClosuredRemote(ctx, nameInfo);
                        }
                    }
                    else
                    {
                        emitSetLocal(ctx, nameInfo);
                    }
                }
            }
        }
예제 #14
0
        protected override void EmitInternal(Context ctx, bool mustReturn)
        {
            var gen      = ctx.CurrentMethod.Generator;
            var dictType = Resolve(ctx);

            var tmpVar = ctx.Scope.DeclareImplicit(ctx, dictType, true);

            var ctor      = ctx.ResolveConstructor(dictType, new[] { typeof(int) });
            var addMethod = ctx.ResolveMethod(dictType, "Add", new[] { _keyType, _valueType });

            var count = Expressions.Count;

            gen.EmitConstant(count);
            gen.EmitCreateObject(ctor.ConstructorInfo);
            gen.EmitSaveLocal(tmpVar.LocalBuilder);

            foreach (var curr in Expressions)
            {
                var currKeyType = curr.Key.Resolve(ctx);
                var currValType = curr.Value.Resolve(ctx);

                ctx.CheckTypedExpression(curr.Key, currKeyType);
                ctx.CheckTypedExpression(curr.Value, currValType, true);

                if (currKeyType != _keyType)
                {
                    Error(curr.Key, CompilerMessages.DictionaryKeyTypeMismatch, currKeyType, _keyType, _valueType);
                }

                if (!_valueType.IsExtendablyAssignableFrom(currValType))
                {
                    Error(curr.Value, CompilerMessages.DictionaryValueTypeMismatch, currValType, _keyType, _valueType);
                }

                gen.EmitLoadLocal(tmpVar.LocalBuilder);

                curr.Key.Emit(ctx, true);
                Expr.Cast(curr.Value, _valueType).Emit(ctx, true);

                gen.EmitCall(addMethod.MethodInfo, addMethod.IsVirtual);
            }

            gen.EmitLoadLocal(tmpVar.LocalBuilder);
        }
예제 #15
0
파일: NewArrayNode.cs 프로젝트: taekun/lens
        protected override void emitCode(Context ctx, bool mustReturn)
        {
            var gen    = ctx.CurrentMethod.Generator;
            var tmpVar = ctx.Scope.DeclareImplicit(ctx, Resolve(ctx), true);

            // create array
            var count = Expressions.Count;

            gen.EmitConstant(count);
            gen.EmitCreateArray(_ItemType);
            gen.EmitSaveLocal(tmpVar.LocalBuilder);

            for (var idx = 0; idx < count; idx++)
            {
                var currType = Expressions[idx].Resolve(ctx);

                ctx.CheckTypedExpression(Expressions[idx], currType, true);

                if (!_ItemType.IsExtendablyAssignableFrom(currType))
                {
                    error(Expressions[idx], CompilerMessages.ArrayElementTypeMismatch, currType, _ItemType);
                }

                gen.EmitLoadLocal(tmpVar.LocalBuilder);
                gen.EmitConstant(idx);

                var cast = Expr.Cast(Expressions[idx], _ItemType);

                if (_ItemType.IsValueType)
                {
                    gen.EmitLoadIndex(_ItemType, true);
                    cast.Emit(ctx, true);
                    gen.EmitSaveObject(_ItemType);
                }
                else
                {
                    cast.Emit(ctx, true);
                    gen.EmitSaveIndex(_ItemType);
                }
            }

            gen.EmitLoadLocal(tmpVar.LocalBuilder);
        }
예제 #16
0
        /// <summary>
        /// Returns the code to concatenate two dictionaries.
        /// </summary>
        private NodeBase DictExpand(Context ctx)
        {
            var keyValueTypes = LeftOperand.Resolve(ctx).GetGenericArguments();
            var dictType      = typeof(Dictionary <,>).MakeGenericType(keyValueTypes);
            var currType      = typeof(KeyValuePair <,>).MakeGenericType(keyValueTypes);
            var tmpDict       = ctx.Scope.DeclareImplicit(ctx, dictType, false);
            var tmpCurr       = ctx.Scope.DeclareImplicit(ctx, currType, false);

            // a = new Dictionary<T, T2>(<left>)
            // foreach(var kvp in <right>)
            //    a[kvp.Key] = kvp.Value
            return(Expr.Block(
                       Expr.Set(
                           tmpDict,
                           Expr.New(
                               dictType,
                               Expr.Cast(
                                   LeftOperand,
                                   typeof(IDictionary <,>).MakeGenericType(keyValueTypes)
                                   )
                               )
                           ),
                       Expr.For(
                           tmpCurr,
                           RightOperand,
                           Expr.Block(
                               Expr.SetIdx(
                                   Expr.Get(tmpDict),
                                   Expr.GetMember(
                                       Expr.Get(tmpCurr),
                                       "Key"
                                       ),
                                   Expr.GetMember(
                                       Expr.Get(tmpCurr),
                                       "Value"
                                       )
                                   )
                               )
                           ),
                       Expr.Get(tmpDict)
                       ));
        }
예제 #17
0
        public override IEnumerable <NodeBase> Expand(Context ctx, NodeBase expression, Label nextStatement)
        {
            yield return(MakeJumpIf(
                             nextStatement,
                             Expr.Not(Expr.Is(expression, _type))
                             ));

            foreach (var fieldRule in FieldRules)
            {
                var rules = fieldRule.Rule.Expand(
                    ctx,
                    Expr.GetMember(Expr.Cast(expression, _type), fieldRule.Name.FullSignature),
                    nextStatement
                    );

                foreach (var rule in rules)
                {
                    yield return(rule);
                }
            }
        }
예제 #18
0
        protected override NodeBase Expand(Context ctx, bool mustReturn)
        {
            var left   = LeftOperand.Resolve(ctx);
            var right  = RightOperand.Resolve(ctx);
            var common = Resolve(ctx);

            var body = Expr.Block();

            var leftAccessor = LeftOperand;

            if (!(LeftOperand is GetIdentifierNode))
            {
                var tmpVar = ctx.Scope.DeclareImplicit(ctx, left, false);
                body.Add(Expr.Set(tmpVar, LeftOperand));
                leftAccessor = Expr.Get(tmpVar);
            }

            var condition  = Expr.Compare(ComparisonOperatorKind.Equals, leftAccessor, Expr.Null());
            var leftResult = left.IsNullableType() && left != right
                ? Expr.GetMember(leftAccessor, nameof(Nullable <int> .Value))
                : leftAccessor;

            var rightResult = right.IsNullableType() && left != right
                ? Expr.GetMember(RightOperand, nameof(Nullable <int> .Value))
                : RightOperand;

            body.Add(
                Expr.If(
                    condition,
                    Expr.Block(
                        Expr.Cast(rightResult, common)
                        ),
                    Expr.Block(
                        Expr.Cast(leftResult, common)
                        )
                    )
                );

            return(body);
        }
예제 #19
0
        /// <summary>
        /// Invokes the object's custom indexer setter.
        /// </summary>
        private void emitSetCustomIndexer(Context ctx)
        {
            var gen = ctx.CurrentMethod.Generator;

            try
            {
                var idxDest = _Indexer.ArgumentTypes[0];
                var valDest = _Indexer.ArgumentTypes[1];

                Expression.Emit(ctx, true);

                Expr.Cast(Index, idxDest).Emit(ctx, true);
                Expr.Cast(Value, valDest).Emit(ctx, true);

                gen.EmitCall(_Indexer.MethodInfo);
            }
            catch (LensCompilerException ex)
            {
                ex.BindToLocation(this);
                throw;
            }
        }
예제 #20
0
        protected override void EmitInternal(Context ctx, bool mustReturn)
        {
            var gen = ctx.CurrentMethod.Generator;

            if (_invocationSource != null)
            {
                _invocationSource.EmitNodeForAccess(ctx);
            }

            if (ArgTypes.Length > 0)
            {
                var destTypes = _method.ArgumentTypes;
                for (var idx = 0; idx < Arguments.Count; idx++)
                {
                    var arg       = Arguments[idx];
                    var argRef    = arg is IPointerProvider && (arg as IPointerProvider).RefArgumentRequired;
                    var targetRef = destTypes[idx].IsByRef;

                    if (argRef != targetRef)
                    {
                        if (argRef)
                        {
                            Error(arg, CompilerMessages.ReferenceArgUnexpected);
                        }
                        else
                        {
                            Error(arg, CompilerMessages.ReferenceArgExpected, idx + 1, destTypes[idx].GetElementType());
                        }
                    }

                    var expr = argRef ? Arguments[idx] : Expr.Cast(Arguments[idx], destTypes[idx]);
                    expr.Emit(ctx, true);
                }
            }

            var isVirt = _invocationSource != null && _invocationSource.Resolve(ctx).IsClass;

            gen.EmitCall(_method.MethodInfo, isVirt);
        }
예제 #21
0
        protected override void EmitInternal(Context ctx, bool mustReturn)
        {
            var gen = ctx.CurrentMethod.Generator;

            if (_constructor != null)
            {
                if (ArgTypes.Length > 0)
                {
                    var destTypes = _constructor.ArgumentTypes;
                    for (var idx = 0; idx < Arguments.Count; idx++)
                    {
                        Expr.Cast(Arguments[idx], destTypes[idx]).Emit(ctx, true);
                    }
                }

                gen.EmitCreateObject(_constructor.ConstructorInfo);
            }
            else
            {
                Expr.Default(TypeSignature).Emit(ctx, true);
            }
        }
예제 #22
0
        /// <summary>
        /// Creates the body of Equals(object).
        /// </summary>
        private void CreateGenericEquals()
        {
            var eq = CreateMethod(
                "Equals",
                "bool",
                new[] { Expr.Arg <object>("obj") },
                false,
                true
                );

            // if(this.ReferenceEquals null obj)
            //    false
            // else
            //    (this.ReferenceEquals this obj) || ( (obj.GetType () == this.GetType()) && (this.Equals obj as <Name>))

            eq.Body.Add(
                Expr.If(
                    Expr.Invoke(Expr.This(), "ReferenceEquals", Expr.Null(), Expr.Get("obj")),
                    Expr.Block(Expr.False()),
                    Expr.Block(
                        Expr.Or(
                            Expr.Invoke(Expr.This(), "ReferenceEquals", Expr.This(), Expr.Get("obj")),
                            Expr.And(
                                Expr.Equal(
                                    Expr.Invoke(Expr.Get("obj"), "GetType"),
                                    Expr.Invoke(Expr.This(), "GetType")
                                    ),
                                Expr.Invoke(
                                    Expr.This(),
                                    "Equals",
                                    Expr.Cast(Expr.Get("obj"), Name)
                                    )
                                )
                            )
                        )
                    )
                );
        }
예제 #23
0
        protected override void EmitInternal(Context ctx, bool mustReturn)
        {
            var gen      = ctx.CurrentMethod.Generator;
            var loopType = Resolve(ctx);
            var saveLast = mustReturn && !loopType.IsVoid();

            var beginLabel = gen.DefineLabel();
            var endLabel   = gen.DefineLabel();

            Local tmpVar = null;

            if (saveLast)
            {
                tmpVar = ctx.Scope.DeclareImplicit(ctx, loopType, false);
                Expr.Set(tmpVar, Expr.Default(loopType)).Emit(ctx, false);
            }

            gen.MarkLabel(beginLabel);

            Expr.Cast(Condition, typeof(bool)).Emit(ctx, true);
            gen.EmitConstant(false);
            gen.EmitBranchEquals(endLabel);

            Body.Emit(ctx, mustReturn);

            if (saveLast)
            {
                gen.EmitSaveLocal(tmpVar.LocalBuilder);
            }

            gen.EmitJump(beginLabel);

            gen.MarkLabel(endLabel);
            if (saveLast)
            {
                gen.EmitLoadLocal(tmpVar.LocalBuilder);
            }
        }
예제 #24
0
        public override IEnumerable <NodeBase> Expand(Context ctx, NodeBase expression, Label nextStatement)
        {
            // no need for temporary variable: field access is idempotent
            yield return(MakeJumpIf(
                             nextStatement,
                             Expr.Not(
                                 Expr.Is(expression, _type)
                                 )
                             ));

            var rules = LabelRule.Expand(
                ctx,
                Expr.GetMember(
                    Expr.Cast(expression, _type),
                    "Tag"
                    ),
                nextStatement
                );

            foreach (var rule in rules)
            {
                yield return(rule);
            }
        }
예제 #25
0
        /// <summary>
        /// Assigns a closured variable that has been imported from outer scopes.
        /// </summary>
        private void emitSetClosuredRemote(Context ctx, Local name)
        {
            var gen = ctx.CurrentMethod.Generator;

            gen.EmitLoadArgument(0);

            var dist = name.ClosureDistance;
            var type = (Type)ctx.CurrentType.TypeBuilder;

            while (dist > 1)
            {
                var rootField = ctx.ResolveField(type, EntityNames.ParentScopeFieldName);
                gen.EmitLoadField(rootField.FieldInfo);

                type = rootField.FieldType;
                dist--;
            }

            Expr.Cast(Value, name.Type).Emit(ctx, true);

            var clsField = ctx.ResolveField(type, name.ClosureFieldName);

            gen.EmitSaveField(clsField.FieldInfo);
        }
예제 #26
0
        protected override NodeBase expand(Context ctx, bool mustReturn)
        {
            if (_Wrapper.IsPartiallyApplied)
            {
                // (expr) _ a b _
                // is transformed into
                // (pa0:T1 pa1:T2) -> (expr) (pa0) (a) (b) (pa1)
                var argDefs  = new List <FunctionArgument>();
                var argExprs = new List <NodeBase>();
                for (var idx = 0; idx < _ArgTypes.Length; idx++)
                {
                    if (_ArgTypes[idx] == typeof(UnspecifiedType))
                    {
                        var argName = ctx.Unique.AnonymousArgName();
                        argDefs.Add(Expr.Arg(argName, _Wrapper.ArgumentTypes[idx].FullName));
                        argExprs.Add(Expr.Get(argName));
                    }
                    else
                    {
                        argExprs.Add(Arguments[idx]);
                    }
                }

                return(Expr.Lambda(argDefs, recreateSelfWithArgs(argExprs)));
            }

            if (_Wrapper.IsVariadic)
            {
                var srcTypes = _ArgTypes;
                var dstTypes = _Wrapper.ArgumentTypes;
                var lastDst  = dstTypes[dstTypes.Length - 1];
                var lastSrc  = srcTypes[srcTypes.Length - 1];

                // compress items into an array:
                //     fx a b c d
                // becomes
                //     fx a b (new[ c as X; d as X ])
                if (dstTypes.Length > srcTypes.Length || lastDst != lastSrc)
                {
                    var elemType   = lastDst.GetElementType();
                    var simpleArgs = Arguments.Take(dstTypes.Length - 1);
                    var combined   = Expr.Array(Arguments.Skip(dstTypes.Length - 1).Select(x => Expr.Cast(x, elemType)).ToArray());
                    return(recreateSelfWithArgs(simpleArgs.Union(new[] { combined })));
                }
            }

            return(base.expand(ctx, mustReturn));
        }
예제 #27
0
        /// <summary>
        /// Creates the body of GetHashCode().
        /// </summary>
        private void CreateGetHashCode()
        {
            var ghc = CreateMethod(
                "GetHashCode",
                typeof(int),
                Type.EmptyTypes,
                false,
                true
                );

            // var result = 0
            ghc.Body.Add(Expr.Var("result", Expr.Int(0)));

            // result ^= (<field> != null ? field.GetHashCode() : 0) * 397
            var id = 0;

            foreach (var f in _fields.Values)
            {
                var      fieldType = f.Type ?? Context.ResolveType(f.TypeSignature);
                NodeBase expr;
                if (fieldType.IsIntegerType())
                {
                    expr = Expr.GetMember(Expr.This(), f.Name);
                }
                else if (fieldType.IsValueType)
                {
                    expr = Expr.Invoke(
                        Expr.Cast(Expr.GetMember(Expr.This(), f.Name), typeof(object)),
                        "GetHashCode"
                        );
                }
                else
                {
                    expr = Expr.If(
                        Expr.NotEqual(
                            Expr.GetMember(Expr.This(), f.Name),
                            Expr.Null()
                            ),
                        Expr.Block(
                            Expr.Invoke(
                                Expr.GetMember(Expr.This(), f.Name),
                                "GetHashCode"
                                )
                            ),
                        Expr.Block(Expr.Int(0))
                        );
                }

                if (id < _fields.Count - 1)
                {
                    expr = Expr.Mult(expr, Expr.Int(397));
                }

                ghc.Body.Add(
                    Expr.Set("result", Expr.Xor(Expr.Get("result"), expr))
                    );

                id++;
            }

            ghc.Body.Add(Expr.Get("result"));
        }
예제 #28
0
        public void Compile()
        {
            if (!globalContext.EnableClassesTypes)
            {
                if (type.IsClass)
                {
                    throw new ArgumentException($"Can't compile serialization functions for type {type}. To enable classes types use SMAB(enableClassesTypes = true) constructor");
                }
            }

            var serializeGen   = new ILGen <Action <SerializeStream, object, SerializationContext, SerializationMethodsBase[]> >(type + "_serialize", true);
            var deserializeGen = new ILGen <Func <SerializeStream, DeserializationContext, SerializationMethodsBase[], object> >(type + "_deserialize", true);

            SerializationRule typeRule = (SerializationRule)type.GetCustomAttribute(typeof(SerializationRule));
            bool defaultIsSerializable = typeRule != null ? typeRule.IsSerializable : true;

            ILVar optimizationResult = deserializeGen.DeclareVar(typeof((bool, object)));

            //Context optimization
            if (!type.IsValueType)
            {
                serializeGen.If(serializeGen.args[2].CallMethod(OptimizeSerializationContextMethodInfo, serializeGen.args[0], serializeGen.args[1]));
                serializeGen.Return();
                serializeGen.EndIf();


                deserializeGen.Line(optimizationResult.Set(deserializeGen.args[1].CallMethod(OptimizeDeserializationContextMethodInfo, deserializeGen.args[0])));
                deserializeGen.If(optimizationResult.Field(OptimizationResultItem1));
                deserializeGen.Return(optimizationResult.Field(OptimizationResultItem2));
                deserializeGen.EndIf();
            }

            ILVar serializeObject   = serializeGen.DeclareVar(type);
            ILVar deserializeObject = deserializeGen.DeclareVar(type);



            serializeGen.Line(serializeObject.Set(Expr.Cast(serializeGen.args[1], type)));
            deserializeGen.Line(deserializeObject.Set(Expr.CreateUninitialized(type)));

            if (!type.IsValueType)
            {
                deserializeGen.Line(deserializeGen.args[1].CallMethod(AddObjectDesreializationContextMethodInfo, deserializeObject));
            }

            foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).OrderBy((FieldInfo fieldInfo) => fieldInfo.MetadataToken))
            {
                SerializationRule fieldRule = (SerializationRule)fieldInfo.GetCustomAttribute(typeof(SerializationRule));
                if (!(fieldRule != null ? fieldRule.IsSerializable : defaultIsSerializable))
                {
                    continue;
                }

                Type fieldType = fieldInfo.FieldType;

                if (SerializeStream.GetBaseTypeRWMethodsIfExists(fieldType, out RWMethodsInfo rwMethods))
                {
                    serializeGen.Line(serializeGen.args[0].CallMethod(rwMethods.writeMethodInfo, serializeObject.Field(fieldInfo)));
                    deserializeGen.Line(deserializeObject.Field(fieldInfo).Set(deserializeGen.args[0].CallMethod(rwMethods.readMethodInfo)));
                }
                else
                {
                    int fieldTypeSerializationIndex = GetTypeSerializationMethodsIndex(fieldType);
                    serializeGen.Line(serializeGen.args[3].Index(Expr.Const(fieldTypeSerializationIndex)).CallMethod(SerializeMethodInfo, serializeGen.args[0], serializeObject.Field(fieldInfo), serializeGen.args[2]));
                    deserializeGen.Line(deserializeObject.Field(fieldInfo).Set(Expr.Cast(deserializeGen.args[2].Index(Expr.Const(fieldTypeSerializationIndex)).CallMethod(DeserializeMethodInfo, serializeGen.args[0], serializeGen.args[1]), fieldType)));
                }
            }

            deserializeGen.Return(deserializeObject);

            serializationMethods.TypeSerializeMethod   = new SerializationMethodsWithDependencies.SerializeMethod(serializeGen.compile(globalContext.WithComments));
            serializationMethods.TypeDeserializeMethod = new SerializationMethodsWithDependencies.DeserializeMethod(deserializeGen.compile(globalContext.WithComments));
        }
예제 #29
0
        public static void Main(string[] args)
        {
            var  expr    = ExprParser.Instance.Parse("a + 'ola mundo \n \t \\'mundo\\' ola' * (6 + -9)");
            var  expr2   = ExprParser.Instance.Parse("-a");
            var  expr3   = ExprParser.Instance.Parse("-a + -(4 + 6)");
            var  expr4   = ExprParser.Instance.Parse("6");
            var  expr5   = ExprParser.Instance.Parse("6.0");
            var  expr6   = ExprParser.Instance.Parse("a + $a");
            var  expr7   = ExprParser.Instance.Parse("Articles.ArticleDescription == 'RTUY /(89)' ");
            var  expr8   = ExprParser.Instance.Parse(" FF1(a+b, 89, (9+1) * 2)");
            var  expr9   = ExprParser.Instance.Parse(" FF2(a+b )");
            var  expr10  = ExprParser.Instance.Parse("  a+ b >= 3 && 1");
            var  expr11  = ExprParser.Instance.Parse("  a+ b >= 3 && 1 ? (3 + 9) * 5:  a <= 3");
            var  expr12  = ExprParser.Instance.Parse("-(  a+ b >= 3 && 1 ? (3 + 9) * 5:  a <= 3)");
            var  expr13  = Expr.Parse("true");
            var  expr14  = Expr.Parse("false");
            var  expr15  = Expr.Parse("!true");
            Guid guid    = Guid.NewGuid();
            var  literal = (Literal)guid;
            var  update  = new Update <ExampleTable>(new ExampleTable {
                Key = guid
            });

            update.Execute(new Compiler(), out int n1);
            var update2 = new Update <ExampleTable>(new ExampleTable {
                Key = guid
            }, "Description");
            var select = new Query <ExampleTable>().InnerJoin(new Query("SomeTable"),
                                                              new string[] { "ForeignKey" },
                                                              new string[] { "SomeKey" });

            select.Execute(new Compiler());
            var select2 = new Query <ExampleTable>().LeftJoin(new Query("SomeTable"),
                                                              new string[] { "ForeignKey" },
                                                              new string[] { "SomeKey" });

            select2.Execute(new Compiler());

            var select3 = new Query <ExampleTable>().LeftJoin("SomeTable", "SomeTableAlias",
                                                              new string[] { "ForeignKey" },
                                                              new string[] { "SomeKey" });

            select3.Execute(new Compiler());
            var select4 = new Query <ExampleTable>()
                          .Select("a", "b", "c")
                          .Where(
                Expr.Eq("a", "ola")
                .And(Expr.Eq("b", 3))
                );

            select4.Execute(new Compiler());
            var insertOrUpdate = new Update <ExampleTable>(new ExampleTable {
                Key = guid
            }).InsertOrUpdate();

            insertOrUpdate.Execute(new Compiler(), out n1);

            var select5 = new Query <ExampleTable>().Where(Expr.NotNull("ForeignKey"));

            select5.Execute(new Compiler());

            var select6 = new Query <ExampleTable>().Where(Expr.NotIn("ForeignKey", new int[] { 8, 9, 10 }));

            select6.Execute(new Compiler());

            var select7 = new Query <ExampleTable>().Where(Expr.NotIn("ForeignKey", new List <string> {
                "8", "9", "10"
            }));

            select7.Execute(new Compiler());

            var select8 = new Query <ExampleTable>().Select(Expr.Count());

            select8.Execute(new Compiler());

            var select9 = new Query <ExampleTable>().Select(new Function("TTS", (Literal)1, (Literal)4));

            select9.Execute(new Compiler());

            var select10 = new Query <ExampleTable>().Select(Expr.Parse("MAX(ForeignKey)"));

            select10.Execute(new Compiler());

            var select11 = new Query <ExampleTable>().Select(Expr.Parse("MAX(ForeignKey)")).Select(" A ")
                           .OrderBy(true, "A", "C")
                           .OrderBy(false, "B")
                           .OrderBy(false, "D");

            select11.Execute(new Compiler());
            var select12 = new Query <ExampleTable>()
                           .Select("a", "b", "c")
                           .Where(
                Expr.EqVar("a", "ola")
                .And(Expr.EqVar("b", "3"))
                );

            select4.Execute(new Compiler());
            select12.Execute(new Compiler());
            Console.WriteLine(new Compiler().CompileToString(select12));

            var select13 = new Query <ExampleTable>().InnerJoin <ExampleTable>(Expr.EqParam("olaColumn", "ola"));

            select13.Execute(new Compiler());
            var select14 = new Query().Select(Expr.Exists(select13));

            select14.Execute(new Compiler());
            var select15 = new Query().Select(Expr.Parse("a.b == c.d && g.h == $a"));

            select15.Execute(new Compiler());
            var select16 = new Query().Select(Expr.Cast((Variable)"a.b", "decimal"));

            select16.Execute(new Compiler());
            var select17 = new Query().Select(Expr.Parse("Cast(a.b, 'decimal')"));

            select17.Execute(new Compiler());
            var select18 = new Query().Select(Expr.Parse("Cast(a.b, decimal)"));

            select18.Execute(new Compiler());
            Console.WriteLine("Hello World!");
        }
예제 #30
0
파일: IfNode.cs 프로젝트: vplemyannik/lens
        protected override void EmitInternal(Context ctx, bool mustReturn)
        {
            var gen = ctx.CurrentMethod.Generator;

            var condType = Condition.Resolve(ctx);

            if (!condType.IsExtendablyAssignableFrom(typeof(bool)))
            {
                Error(Condition, CompilerMessages.ConditionTypeMismatch, condType);
            }

            if (Condition.IsConstant && ctx.Options.UnrollConstants)
            {
                // result is known at compile time: just emit the corresponding branch's code
                var node = Condition.ConstantValue ? (NodeBase)TrueAction : FalseAction;
                if (node != null)
                {
                    var nodeType    = node.Resolve(ctx);
                    var desiredType = Resolve(ctx);
                    if (!nodeType.IsVoid() && !desiredType.IsVoid())
                    {
                        node = Expr.Cast(node, desiredType);
                    }

                    node.Emit(ctx, mustReturn);
                    if (!mustReturn && !node.Resolve(ctx).IsVoid())
                    {
                        gen.EmitPop();
                    }
                }

                return;
            }

            var endLabel   = gen.DefineLabel();
            var falseLabel = gen.DefineLabel();

            Expr.Cast(Condition, typeof(bool)).Emit(ctx, true);
            if (FalseAction == null)
            {
                // if (...) { ... }
                gen.EmitBranchFalse(endLabel);
                TrueAction.Emit(ctx, mustReturn);
                if (!TrueAction.Resolve(ctx).IsVoid())
                {
                    gen.EmitPop();
                }

                gen.MarkLabel(endLabel);
            }
            else
            {
                // if (...) { ... } else { ... }
                gen.EmitBranchFalse(falseLabel);
                EmitBranch(ctx, TrueAction, mustReturn);
                gen.EmitJump(endLabel);

                gen.MarkLabel(falseLabel);
                EmitBranch(ctx, FalseAction, mustReturn);

                gen.MarkLabel(endLabel);
            }
        }