Пример #1
0
        public SimpleRecResult ExtractPropertyFunction(ref ExpressionNode Node, bool IsSetter)
        {
            var Res = ExtractPropertyFunction_OnlyId(ref Node, IsSetter);

            if (Res != SimpleRecResult.Unknown)
            {
                return(Res);
            }

            if (Expressions.GetOperator(Node) == Operator.Member)
            {
                var Ch     = Node.Children;
                var NewCh1 = Ch[1];
                Res = ExtractPropertyFunction_OnlyId(ref NewCh1, IsSetter);
                if (Res != SimpleRecResult.Succeeded)
                {
                    return(Res);
                }

                var NewCh   = new ExpressionNode[] { Ch[0], NewCh1 };
                var NewNode = new OpExpressionNode(Operator.Member, NewCh, Node.Code);
                NewNode.LinkedNodes.AddRange(Node.LinkedNodes);
                Node = Parent.NewNode(NewNode);
                return(Node == null ? SimpleRecResult.Failed : SimpleRecResult.Succeeded);
            }

            return(SimpleRecResult.Unknown);
        }
Пример #2
0
        public PluginResult NewOpNode(ref ExpressionNode Node)
        {
            var OpNode = Node as OpExpressionNode;
            var Op     = OpNode.Operator;
            var Ch     = OpNode.Children;

            // ------------------------------------------------------------------------------------
            if (Op == Operator.Reinterpret)
            {
                if (Ch[0] is ConstExpressionNode)
                {
#warning WARNING
                }

                return(PluginResult.Succeeded);
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Tuple || Op == Operator.Array)
            {
                var Type = Node.Type.RealId as NonrefArrayType;
                if (Op != Operator.Array || (Type != null && Type.Lengths != null && !(Type.TypeOfValues is AutomaticType)))
                {
                    if (Ch.TrueForAll(x => x is ConstExpressionNode))
                    {
                        var Constants = Ch.Select(x => (x as ConstExpressionNode).Value);
                        var SValue    = new StructuredValue(Constants.ToList());
                        Node = Parent.NewNode(new ConstExpressionNode(Node.Type, SValue, Node.Code));
                        return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                    }
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Index)
            {
                if (Ch.TrueForAll(x => x is ConstExpressionNode))
                {
                    var ConstCh0    = Ch[0] as ConstExpressionNode;
                    var NonrefArray = Ch[0].Type.RealId as NonrefArrayType;
                    var Dimensions  = NonrefArray.Lengths;
                    var Position    = 0;
                    var MulBy       = 1;

                    for (var i = Dimensions.Length - 1; i >= 0; i--)
                    {
                        var CChip1 = Ch[i + 1] as ConstExpressionNode;
                        var Index  = CChip1.Integer;

                        if (Index < 0 || Index >= Dimensions[i])
                        {
                            State.Messages.Add(MessageId.IndexOutOfRange, CChip1.Code);
                            return(PluginResult.Failed);
                        }

                        Position += (int)Index * MulBy;
                        MulBy    *= Dimensions[i];
                    }

                    var RetValue = ConstCh0.Value.GetMember(Position);
                    var RetType  = NonrefArray.TypeOfValues;

                    Node = Parent.NewNode(new ConstExpressionNode(RetType, RetValue, Node.Code));
                    return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Member)
            {
                var ConstCh0 = Ch[0] as ConstExpressionNode;
                var Member   = Ch[1] as IdExpressionNode;
                if (ConstCh0 != null && Member != null)
                {
                    if (ConstCh0.Value is StructuredValue || ConstCh0.Value is ZeroValue)
                    {
                        var SType       = ConstCh0.Type.UnderlyingStructureOrRealId as StructuredType;
                        var Members     = SType.StructuredScope.IdentifierList;
                        var MemberIndex = Members.IndexOf(Member.Identifier);
                        var RetValue    = ConstCh0.Value.GetMember(MemberIndex);
                        var RetType     = Member.Identifier.TypeOfSelf;

                        Node = Parent.NewNode(new ConstExpressionNode(RetType, RetValue, Node.Code));
                        return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                    }
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Cast)
            {
                var Child = Ch[0] as ConstExpressionNode;
                if (Child == null)
                {
                    return(PluginResult.Succeeded);
                }

                var To    = Expressions.GetIdentifier(Ch[1]);
                var RTo   = To.RealId as Type;
                var RFrom = Child.Type.RealId as Type;

                if (Child.Value is NullValue || RFrom is AutomaticType)
                {
                    var OldNode = Node;
                    if ((Node = Node.DetachChild(0)) == null)
                    {
                        return(PluginResult.Failed);
                    }

                    Node.Type   = OldNode.Type;
                    Node.Flags |= ExpressionFlags.FixedType;
                    return(PluginResult.Ready);
                }

                Predicate <Identifier> Func = x =>
                {
                    var Rx = x.RealId as Type;
                    if (Rx is PointerType || Rx is ReferenceType || Rx is PointerAndLength ||
                        ((Rx.TypeFlags & TypeFlags.ReferenceValue) != 0 && !(Rx is StringType)))
                    {
                        return(false);
                    }

                    return(true);
                };

                if (!Identifiers.ProcessTuple(RTo, Func))
                {
                    return(PluginResult.Succeeded);
                }

                if (RTo is TupleType && !(RFrom is TupleType))
                {
                    var TupleTo   = RTo as TupleType;
                    var ToMembers = TupleTo.StructuredScope.IdentifierList;
                    var TupleCh   = new ExpressionNode[ToMembers.Count];

                    for (var i = 0; i < ToMembers.Count; i++)
                    {
                        var ToType = ToMembers[i].Children[0];
                        var Value  = Child.Value.Convert(ToType);
                        if (Value == null)
                        {
                            var Params = new String[] { Child.Value.ToString(), ToType.Name.ToString() };
                            State.Messages.Add(MessageId.CannotConvertConst, Node.Code, Params);
                            return(PluginResult.Failed);
                        }

                        TupleCh[i] = Value.ToExpression(Parent, ToType, Node.Code);
                        if (TupleCh[i] == null)
                        {
                            return(PluginResult.Failed);
                        }
                    }

                    Node      = new OpExpressionNode(Operator.Tuple, TupleCh, Node.Code);
                    Node.Type = To;
                    Node      = Parent.NewNode(Node);
                    return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                }

                var Ret = Child.Value.Convert(RTo);
                if (Ret == null)
                {
                    var Params = new String[] { Child.Value.ToString(), To.Name.ToString() };
                    State.Messages.Add(MessageId.CannotConvertConst, Node.Code, Params);
                    return(PluginResult.Failed);
                }

                if (Ret is IntegerValue && Node.CheckingMode == CheckingMode.Unchecked)
                {
                    var IRet = Ret as IntegerValue;
                    IRet.Value = DataStoring.WrapToType(IRet.Value, RTo);
                }

                Node = Ret.ToExpression(Parent, To, Node.Code);
                return(Node == null ? PluginResult.Failed : PluginResult.Ready);
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.And || Op == Operator.Or)
            {
                var ConstIndex = Ch[0] is ConstExpressionNode ? 0 :
                                 (Ch[1] is ConstExpressionNode ? 1 : -1);

                if (ConstIndex != -1)
                {
                    var CNode = Ch[ConstIndex] as ConstExpressionNode;
                    var IsAnd = Op == Operator.And;

                    if (CNode.Bool == IsAnd)
                    {
                        Node = Node.DetachChild(1 - ConstIndex);
                        return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                    }

                    Node = Parent.NewNode(new ConstExpressionNode(Node.Type, new BooleanValue(!IsAnd), Node.Code));
                    return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Condition)
            {
                var Condition = Ch[0] as ConstExpressionNode;
                if (Condition != null)
                {
                    Node = Condition.Bool ? Ch[1] : Ch[2];
                    return(PluginResult.Ready);
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Op == Operator.Call)
            {
                var Res = NewCallOpNode(ref Node);
                if (Res != PluginResult.Succeeded)
                {
                    return(Res);
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Operators.IsCalculable(Op))
            {
                if (Ch[0] is ConstExpressionNode && (Ch.Length == 1 || Ch[1] is ConstExpressionNode))
                {
                    return(Evaluate(ref Node));
                }

                if (Operators.IsReversible(Op) && Ch[0] is ConstExpressionNode &&
                    Identifiers.IsScalarOrVectorNumber(Ch[0].Type) && !(Ch[1] is ConstExpressionNode))
                {
                    OpNode.Swap();
                    Op = OpNode.Operator;
                }

                if (Op == Operator.Add || Op == Operator.Subract)
                {
                    var ConstCh1 = Ch[1] as ConstExpressionNode;
                    if (ConstCh1 != null && Identifiers.IsScalarOrVectorNumber(ConstCh1.Type))
                    {
                        if (Constants.CompareTupleValues(ConstCh1.Value, x => x.Double == 0))
                        {
                            Node = Node.DetachChild(0);
                            return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                        }

                        var OpCh0 = Ch[0] as OpExpressionNode;
                        if (OpCh0 != null)
                        {
                            var Ch0Op = OpCh0.Operator;
                            var Ch0Ch = OpCh0.Children;
                            if (Ch0Op == Operator.Add || Ch0Op == Operator.Subract)
                            {
                                var ConstIndex = -1;
                                if (Ch0Ch[0] is ConstExpressionNode)
                                {
                                    ConstIndex = 0;
                                }
                                else if (Ch0Ch[1] is ConstExpressionNode)
                                {
                                    ConstIndex = 1;
                                }

                                if (ConstIndex != -1)
                                {
                                    var ConstCh0Chx = Ch0Ch[ConstIndex] as ConstExpressionNode;
                                    var NewOp       = Op == Ch0Op ? Operator.Add : Operator.Subract;

                                    ExpressionNode[] NewCh; // For strings
                                    if (NewOp == Operator.Add)
                                    {
                                        NewCh = new ExpressionNode[] { ConstCh0Chx, Ch[1] }
                                    }
                                    ;
                                    else
                                    {
                                        NewCh = new ExpressionNode[] { Ch[1], ConstCh0Chx }
                                    };

                                    Ch[0] = OpCh0.Children[1 - ConstIndex];
                                    Ch[1] = Parent.NewNode(new OpExpressionNode(NewOp, NewCh, Node.Code));
                                    if (Ch[1] == null)
                                    {
                                        return(PluginResult.Failed);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (Op == Operator.Multiply || Op == Operator.Divide)
                {
                    var ConstCh1 = Ch[1] as ConstExpressionNode;
                    if (ConstCh1 != null && Identifiers.IsScalarOrVectorNumber(ConstCh1.Type))
                    {
                        if (Constants.CompareTupleValues(ConstCh1.Value, x => x.Double == 1))
                        {
                            Node = Node.DetachChild(0);
                            return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                        }

                        if (Constants.CompareTupleValues(ConstCh1.Value, x => x.Double == 0) && Op == Operator.Multiply)
                        {
                            Node = Node.DetachChild(1);
                            return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                        }

                        var OpCh0 = Ch[0] as OpExpressionNode;
                        if (OpCh0 != null)
                        {
                            var Ch0Op = OpCh0.Operator;
                            var Ch0Ch = OpCh0.Children;
                            if (Ch0Op == Operator.Multiply || Ch0Op == Operator.Divide)
                            {
                                var ConstIndex = -1;
                                if (Ch0Ch[0] is ConstExpressionNode)
                                {
                                    ConstIndex = 0;
                                }
                                else if (Ch0Ch[1] is ConstExpressionNode)
                                {
                                    ConstIndex = 1;
                                }

                                if (ConstIndex != -1)
                                {
                                    var ConstCh0Chx = Ch0Ch[ConstIndex] as ConstExpressionNode;
                                    var NewOp       = Op == Ch0Op ? Operator.Multiply : Operator.Divide;
                                    var NewCh       = new ExpressionNode[] { Ch[1], ConstCh0Chx };

                                    Ch[0] = OpCh0.Children[1 - ConstIndex];
                                    Ch[1] = Parent.NewNode(new OpExpressionNode(NewOp, NewCh, Node.Code));
                                    if (Ch[1] == null)
                                    {
                                        return(PluginResult.Failed);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (Operators.IsRelEquality(Op))
                {
                    if (Ch[0] is ConstExpressionNode && !(Ch[1] is ConstExpressionNode))
                    {
                        OpNode.Swap();
                        Op = OpNode.Operator;
                    }

                    var ConstCh1 = Ch[1] as ConstExpressionNode;
                    var Type     = Ch[0].Type != null ? Ch[0].Type.RealId : null;
                    if (Type is UnsignedType && ConstCh1 != null && ConstCh1.Integer == 0)
                    {
                        if (Op == Operator.GreaterEqual)
                        {
                            Node = Constants.GetBoolValue(Container, true, Node.Code);
                            return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                        }
                        else if (Op == Operator.Greater)
                        {
                            OpNode.Operator = Op = Operator.Inequality;
                        }
                        else if (Op == Operator.Less)
                        {
                            Node = Constants.GetBoolValue(Container, false, Node.Code);
                            return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                        }
                        else if (Op == Operator.LessEqual)
                        {
                            OpNode.Operator = Op = Operator.Equality;
                        }
                    }
                }

                if (Op == Operator.Subract && Ch[1] is ConstExpressionNode)
                {
                    var ConstCh1 = Ch[1] as ConstExpressionNode;
                    if (ConstCh1 != null && ConstCh1.Type.RealId is NumberType && ConstCh1.CDouble < 0.0)
                    {
                        var NewCh = new ExpressionNode[] { ConstCh1 };
                        Ch[1] = Parent.NewNode(new OpExpressionNode(Operator.Negation, NewCh, Node.Code));
                        if (Ch[1] == null)
                        {
                            return(PluginResult.Failed);
                        }

                        OpNode.Operator = Op = Operator.Add;
                    }
                }
            }

            return(PluginResult.Succeeded);
        }
Пример #3
0
        public override PluginResult NewNode(ref ExpressionNode Node)
        {
            if (!CheckChildrenIdNodes(Node))
            {
                return(PluginResult.Failed);
            }

            var TempRes = ResolveLinkingAssigment(ref Node);

            if (TempRes != PluginResult.Succeeded)
            {
                return(TempRes);
            }

            var Extracted = false;

            for (var i = 0; i < Node.LinkedNodes.Count; i++)
            {
                var LNode = Node.LinkedNodes[i];
                SetIdNodeUsed(LNode.Node);

                LNode.Node = Extract(LNode.Node, ref Extracted);
                if (LNode.Node == null)
                {
                    return(PluginResult.Failed);
                }
            }

            var DontExtractProperties = false;
            var Ch = Node.Children;

            if (Node is OpExpressionNode)
            {
                var OpNode = Node as OpExpressionNode;
                var Op     = OpNode.Operator;

                if (Operators.IsIncDec(Op))
                {
                    var Linked   = new LinkedExprNode(Ch[0]);
                    var AddSubCh = new ExpressionNode[2]
                    {
                        Parent.NewNode(new LinkingNode(Linked, Node.Code)),
                        Parent.NewNode(Constants.GetIntValue(Container, 1, Node.Code, true)),
                    };

                    if (AddSubCh[0] == null || AddSubCh[1] == null)
                    {
                        return(PluginResult.Failed);
                    }

                    Operator AddSubOp;
                    if (Op == Operator.Increase)
                    {
                        AddSubOp = Operator.Add;
                    }
                    else if (Op == Operator.Decrease)
                    {
                        AddSubOp = Operator.Subract;
                    }
                    else
                    {
                        throw new ApplicationException();
                    }

                    var AssignmentCh = new ExpressionNode[2]
                    {
                        Parent.NewNode(new LinkingNode(Linked, Node.Code)),
                        Parent.NewNode(new OpExpressionNode(AddSubOp, AddSubCh, Node.Code))
                    };

                    if (AssignmentCh[0] == null || AssignmentCh[1] == null)
                    {
                        return(PluginResult.Failed);
                    }

                    Node = new OpExpressionNode(Operator.Assignment, AssignmentCh, Node.Code);
                    Node.LinkedNodes.Add(Linked);

                    if ((Node = Parent.NewNode(Node)) == null)
                    {
                        return(PluginResult.Failed);
                    }

                    return(PluginResult.Ready);
                }
                else if (Op == Operator.Assignment)
                {
                    PluginResult Res;
                    if (Ch[0] is IdExpressionNode && Ch[1] is IdExpressionNode)
                    {
                        var IdCh0 = Ch[0] as IdExpressionNode;
                        var IdCh1 = Ch[1] as IdExpressionNode;

                        if (IdCh0.Identifier.RealId is Variable && IdCh1.Identifier.RealId is Variable)
                        {
                            var Ch0NotUsed = Ch[1].CheckNodes(x =>
                            {
                                var xId = Expressions.GetIdentifier(x);
                                return(xId == null ? true : xId.RealId != IdCh0.Identifier.RealId);
                            });

                            if (Ch0NotUsed && DeclaredIds.Contains(IdCh1.Identifier.RealId))
                            {
                                var Ch1 = (ExpressionNode)IdCh1;
                                Res = ExpressionNode.ReplaceNodes(ref Ch1, Parent, (ref ExpressionNode x) =>
                                {
                                    var Idx = x as IdExpressionNode;
                                    if (Idx != null && Idx.Identifier.RealId == IdCh1.Identifier.RealId)
                                    {
                                        Vars.Remove(Idx);

                                        x = new IdExpressionNode(IdCh0.Identifier, Idx.Code);
                                        x.LinkedNodes.AddRange(Idx.LinkedNodes);
                                        return(Parent.NewNode(ref x));
                                    }

                                    return(PluginResult.Succeeded);
                                });

                                Node = Ch1;
                                DeclaredIds.Remove(IdCh1.Identifier.RealId);
                                return(Res == PluginResult.Failed ? Res : PluginResult.Ready);
                            }
                        }
                    }

                    var Ch0    = Ch[0];
                    var Linked = (LinkedExprNode)null;

                    Res = Expressions.ProcessTuple(Parent, ref Ch0, (x, Index) =>
                    {
                        if (x is IdExpressionNode)
                        {
                            var IdNode = x as IdExpressionNode;
                            Vars.AssignedIds.Add(IdNode);
                        }

                        Func <ExpressionNode> Value = () =>
                        {
                            LinkedExprNode LLinked;

                            var Ch1 = Ch[1];
                            var Ret = Expressions.GetTupleMember(Parent, ref Ch1, Index, out LLinked);
                            Ch[1]   = Ch1;

                            if (LLinked != null)
                            {
                                Linked = LLinked;
                            }

                            return(Ret);
                        };

                        var LRes = ExtractPropertySetter(x, Value, ref x, ref Extracted);
                        if (LRes == SimpleRecResult.Failed)
                        {
                            return(null);
                        }

                        return(x);
                    });

                    if (Res != PluginResult.Succeeded)
                    {
                        Ch0.LinkedNodes.AddRange(Node.LinkedNodes);
                        if (Linked != null)
                        {
                            Ch0.LinkedNodes.Add(Linked);
                        }
                        if (Res == PluginResult.Ready)
                        {
                            Node = Ch0;
                        }
                        return(Res);
                    }

                    SetIdNodeUsed(Ch[1]);
                }
                else if (Op == Operator.Member)
                {
                    var IdCh1 = Ch[1] as IdExpressionNode;
                    if (IdCh1 != null && IdCh1.Identifier.RealId is Property)
                    {
                        Ch[0] = ExtractPropertyGetter(Ch[0], ref Extracted);
                        if (Ch[0] == null)
                        {
                            return(PluginResult.Failed);
                        }

                        DontExtractProperties = true;
                    }

                    SetIdNodeUsed(Ch);
                }
                else if (Op == Operator.Index)
                {
                    var Id = Expressions.GetMemberIdentifier(Ch[0]);
                    if (Id != null && Id.RealId is Property)
                    {
                        for (var i = 1; i < Ch.Length; i++)
                        {
                            Ch[i] = ExtractPropertyGetter(Ch[i], ref Extracted);
                            if (Ch[i] == null)
                            {
                                return(PluginResult.Failed);
                            }
                        }

                        DontExtractProperties = true;
                    }

                    SetIdNodeUsed(Ch);
                }
                else if (Op == Operator.Address || Operators.IsReference(Op))
                {
                    var IdCh0 = Ch[0] as IdExpressionNode;
                    if (IdCh0 != null)
                    {
                        if (Op == Operator.Reference_IdMustBeAssigned)
                        {
                            if (IdCh0 != null)
                            {
                                Vars.UsedBeforeAssignIds.Add(IdCh0);
                            }
                        }
                        else if (Op == Operator.Reference_IdGetsAssigned)
                        {
                            if (IdCh0 != null)
                            {
                                Vars.AssignedIds.Add(IdCh0);
                            }

                            if (!Expressions.IsLValue(Ch[0]))
                            {
                                State.Messages.Add(MessageId.AddressOfRValue, Node.Code);
                                return(PluginResult.Failed);
                            }
                        }
                        else
                        {
                            if (IdCh0 != null)
                            {
                                Vars.AddressUsed.Add(IdCh0);
                            }
                        }
                    }
                }
                else if (Op == Operator.Cast)
                {
                    var From = Ch[0].Type;
                    var To   = Expressions.GetIdentifier(Ch[1]);

                    if (To.RealId is PointerType && From.RealId is ArrayType && Ch[0] is IdExpressionNode)
                    {
                        var IdCh0 = Ch[0] as IdExpressionNode;
                        Vars.AddressUsed.Add(IdCh0);
                    }
                    else
                    {
                        SetIdNodeUsed(Ch);
                    }
                }
                else if (Op == Operator.Tuple)
                {
                    DontExtractProperties = true;
                }
                else
                {
                    SetIdNodeUsed(Ch);
                }
            }
            else
            {
                SetIdNodeUsed(Ch);
            }

            if (Ch != null)
            {
                for (var i = 0; i < Ch.Length; i++)
                {
                    Ch[i] = ExtractPackedId(Ch[i], ref Extracted);
                    if (Ch[i] == null)
                    {
                        return(PluginResult.Failed);
                    }

                    if (!DontExtractProperties)
                    {
                        Ch[i] = ExtractPropertyGetter(Ch[i], ref Extracted);
                        if (Ch[i] == null)
                        {
                            return(PluginResult.Failed);
                        }
                    }

                    if (Expressions.GetOperator(Ch[i]) == Operator.Tuple)
                    {
                        var LocalExtracted = false;
                        var ChiCh          = Ch[i].Children;
                        for (var j = 0; j < ChiCh.Length; j++)
                        {
                            ChiCh[j] = ExtractPropertyGetter(ChiCh[j], ref LocalExtracted);
                            if (ChiCh[j] == null)
                            {
                                return(PluginResult.Failed);
                            }
                        }

                        if (LocalExtracted)
                        {
                            Ch[i] = Parent.NewNode(Ch[i]);
                            if (Ch[i] == null)
                            {
                                return(PluginResult.Failed);
                            }
                            Extracted = true;
                        }
                    }
                }
            }

            if (Extracted)
            {
                Node = Parent.NewNode(Node);
                return(PluginResult.Ready);
            }

            return(PluginResult.Succeeded);
        }
Пример #4
0
        public ExpressionNode ExtractPropertyGetter(ExpressionNode Node, ref bool Extracted)
        {
            ExpressionNode[] CallCh;
            AutoAllocatedList <LinkedExprNode> LinkedNodes =
                new AutoAllocatedList <LinkedExprNode>();

            if ((Node.Flags & ExpressionFlags.EnableGetter) != 0)
            {
                var Ch = Node.Children;
                CallCh = new ExpressionNode[Ch.Length - 1];

                if (Expressions.GetOperator(Ch[0]) == Operator.Member)
                {
                    var Ch0Ch  = Ch[0].Children;
                    var Linked = new LinkedExprNode(Ch0Ch[0]);
                    LinkedNodes.Add(Linked);

                    Ch0Ch[0] = Parent.NewNode(new LinkingNode(Linked, Node.Code));
                    if (Ch0Ch[0] == null || (Ch[0] = Parent.NewNode(Ch[0])) == null)
                    {
                        return(null);
                    }

                    var CallCh0Ch = new ExpressionNode[]
                    {
                        Parent.NewNode(new LinkingNode(Linked, Node.Code)),
                        CallCh[0] = GetGetterForSetter(Ch0Ch[1]),
                    };

                    if (CallCh0Ch[0] == null || CallCh0Ch[1] == null)
                    {
                        return(null);
                    }
                    CallCh[0] = Parent.NewNode(new OpExpressionNode(Operator.Member, CallCh0Ch, Node.Code));
                    if (CallCh[0] == null)
                    {
                        return(null);
                    }
                }
                else if (Ch[0] is IdExpressionNode)
                {
                    CallCh[0] = GetGetterForSetter(Ch[0]);
                }

                for (var i = 1; i < Ch.Length - 1; i++)
                {
                    var LinkedNode = new LinkedExprNode(Ch[i]);
                    LinkedNodes.Add(LinkedNode);

                    Node.Children[i] = Parent.NewNode(new LinkingNode(LinkedNode, Node.Code));
                    CallCh[i]        = Parent.NewNode(new LinkingNode(LinkedNode, Node.Code));
                    if (Node.Children[i] == null || CallCh[i] == null)
                    {
                        return(null);
                    }
                }

                Node = Parent.NewNode(Node);
                if (Node == null)
                {
                    return(null);
                }

                Node.Flags &= ~ExpressionFlags.EnableGetter;
                LinkedNodes.Add(new LinkedExprNode(Node, LinkedNodeFlags.NotRemovable));
            }
            else if (Expressions.GetOperator(Node) == Operator.Index)
            {
                var NewNode = Node.Children[0];
                var Res     = ExtractPropertyFunction(ref NewNode, false);
                if (Res == SimpleRecResult.Unknown)
                {
                    return(Node);
                }
                if (Res == SimpleRecResult.Failed)
                {
                    return(null);
                }

                CallCh    = Node.Children.Slice(0);
                CallCh[0] = NewNode;
            }
            else
            {
                var NewNode = Node;
                var Res     = ExtractPropertyFunction(ref NewNode, false);
                if (Res == SimpleRecResult.Unknown)
                {
                    return(Node);
                }
                if (Res == SimpleRecResult.Failed)
                {
                    return(null);
                }

                CallCh = new ExpressionNode[] { NewNode };
            }

            var Ret = new OpExpressionNode(Operator.Call, CallCh, Node.Code);

            Ret.LinkedNodes.AddRange(LinkedNodes);
            Extracted = true;
            return(Parent.NewNode(Ret));
        }
Пример #5
0
        public override PluginResult NewNode(ref ExpressionNode Node)
        {
            for (var i = 0; i < Node.LinkedNodes.Count; i++)
            {
                var LNode = Node.LinkedNodes[i];
                LNode.Node = ResolveNode(LNode.Node);
                if (LNode.Node == null)
                {
                    return(PluginResult.Failed);
                }
            }

            if (Node is StrExpressionNode)
            {
                return(PluginResult.Interrupt);
            }
            else if (Node is LinkingNode)
            {
                return(PluginResult.Interrupt);
            }
            else if (Node is IdExpressionNode)
            {
                var IdNode = Node as IdExpressionNode;
                var Id     = IdNode.Identifier.RealId;

                if (Id is LocalVariable)
                {
                    if (!Container.IsSubContainerOf(Id.Container) && Container != Id.Container)
                    {
                        throw new ApplicationException();
                    }
                }

                if (Id is ConstVariable)
                {
                    var Const = Id as ConstVariable;
                    if (Const.ConstInitValue == null)
                    {
                        throw new ApplicationException();
                    }

                    Node = Parent.NewNode(new ConstExpressionNode(Const.TypeOfSelf, Const.ConstInitValue, Node.Code));
                    if (Node == null)
                    {
                        return(PluginResult.Failed);
                    }

                    if (ConvertEnums != null && Const.TypeOfSelf == ConvertEnums)
                    {
                        Node = new OpExpressionNode(Operator.Cast, Node.Code)
                        {
                            Children = new ExpressionNode[] { Node },
                            Type     = ConvertEnums.TypeOfValues,
                        };

                        if ((Node = Parent.NewNode(Node)) == null)
                        {
                            return(PluginResult.Failed);
                        }
                    }

                    return(PluginResult.Ready);
                }

                return(PluginResult.Interrupt);
            }
            else if (Node is OpExpressionNode)
            {
                var OpNode = Node as OpExpressionNode;
                var Op     = OpNode.Operator;
                var Ch     = OpNode.Children;

                if (Op == Operator.Assignment)
                {
                    if ((Ch[1] = ResolveNode(Ch[1])) == null)
                    {
                        return(PluginResult.Failed);
                    }

                    if ((Ch[0] = ResolveNode(Ch[0], Ch[1].Type)) == null)
                    {
                        return(PluginResult.Failed);
                    }
                }
                else if (Op == Operator.Call)
                {
                    if (!ResolveParams(Ch))
                    {
                        return(PluginResult.Failed);
                    }

                    var OverloadData = Expressions.GetOverloadSelectData(Ch);
                    Ch[0] = ResolveNode(Ch[0], OverloadData: OverloadData);
                    if (Ch[0] == null)
                    {
                        return(PluginResult.Failed);
                    }

                    var Res = ProcessParams(ref Node);
                    if (Res != PluginResult.Succeeded)
                    {
                        return(Res);
                    }

                    if ((State.Language.Flags & LangaugeFlags.AllowMemberFuncStaticRef) != 0)
                    {
                        var Ch0Id = Expressions.GetIdentifier(Ch[0]);
                        if (Ch0Id != null && Ch0Id.IsInstanceIdentifier)
                        {
                            State.Messages.Add(MessageId.NonStatic, Ch[0].Code);
                            return(PluginResult.Failed);
                        }
                    }
                }
                else if (Op == Operator.NewArray)
                {
                    if (!ResolveParams(Ch))
                    {
                        return(PluginResult.Failed);
                    }

                    if (Ch[0] is StrExpressionNode)
                    {
                        var Type = Container.RecognizeIdentifier(Ch[0].Code, GetIdOptions.DefaultForType);
                        if (Type == null)
                        {
                            return(PluginResult.Failed);
                        }

                        if (Ch.Length < 2)
                        {
                            State.Messages.Add(MessageId.ParamCount, Node.Code);
                            return(PluginResult.Failed);
                        }

                        Node.Type     = new RefArrayType(Container, Type, Ch.Length - 1);
                        Node.Children = Ch.Slice(1);
                        return(PluginResult.Succeeded);
                    }

                    var Ch0Id = Expressions.GetIdentifier(Ch[0]);
                    if (Ch0Id != null && Ch0Id.RealId is Type)
                    {
                        if (Ch.Length < 2)
                        {
                            State.Messages.Add(MessageId.ParamCount, Node.Code);
                            return(PluginResult.Failed);
                        }

                        Node.Type     = new RefArrayType(Container, Ch0Id, Ch.Length - 1);
                        Node.Children = Ch.Slice(1);
                        return(PluginResult.Succeeded);
                    }
                }
                else if (Op == Operator.NewObject)
                {
                    if (!ResolveParams(Ch))
                    {
                        return(PluginResult.Failed);
                    }

                    Identifier ConstructType = null;
                    if (Ch[0] is StrExpressionNode)
                    {
                        ConstructType = Container.RecognizeIdentifier(Ch[0].Code, GetIdOptions.DefaultForType);
                        if (ConstructType == null)
                        {
                            return(PluginResult.Failed);
                        }
                    }
                    else if (Ch[0] is IdExpressionNode)
                    {
                        var IdCh0 = Ch[0] as IdExpressionNode;
                        if (IdCh0.Identifier.RealId is Type)
                        {
                            ConstructType = IdCh0.Identifier;
                        }
                    }

                    if (ConstructType != null)
                    {
                        Node.Type = ConstructType;
                        if (ConstructType.RealId is AutomaticType)
                        {
                            if (!(Ch[0] is IdExpressionNode))
                            {
                                Ch[0] = Parent.NewNode(new IdExpressionNode(ConstructType, Node.Code));
                                if (Ch[0] == null)
                                {
                                    return(PluginResult.Failed);
                                }
                            }

                            Ch[0] = ResolveNode(Ch[0]);
                            return(Ch[0] == null ? PluginResult.Failed : PluginResult.Succeeded);
                        }

                        if (Ch.Length == 1 && !(ConstructType.UnderlyingClassOrRealId is ClassType))
                        {
                            OpNode.Children = Ch = null;
                            return(PluginResult.Succeeded);
                        }

                        var Structured = ConstructType.UnderlyingClassOrRealId as StructuredType;
                        if (Structured == null)
                        {
                            State.Messages.Add(MessageId.ParamCount, Node.Code);
                            return(PluginResult.Failed);
                        }

                        var Options = GetIdOptions.Default;
                        Options.OverloadData = Expressions.GetOverloadSelectData(Ch);
                        Options.Func         = x => x is Constructor;

                        var Constructor = Identifiers.GetMember(State, Structured, null, Node.Code, Options);
                        if (Constructor == null)
                        {
                            return(PluginResult.Failed);
                        }

                        if (!Identifiers.VerifyAccess(Container, Constructor, Node.Code))
                        {
                            return(PluginResult.Failed);
                        }

                        Ch[0] = Parent.NewNode(new IdExpressionNode(Constructor, Ch[0].Code));
                        if (Ch[0] == null)
                        {
                            return(PluginResult.Failed);
                        }
                    }

                    Ch[0] = ResolveNode(Ch[0]);
                    if (Ch[0] == null)
                    {
                        return(PluginResult.Failed);
                    }

                    var Res = ProcessParams(ref Node);
                    if (Res != PluginResult.Succeeded)
                    {
                        return(Res);
                    }
                }
                else if (Op == Operator.Member)
                {
                    if ((Ch[0] = ResolveNode(Ch[0])) == null)
                    {
                        return(PluginResult.Failed);
                    }

                    return(PluginResult.Interrupt);
                }
                else if (Op == Operator.Tuple || Op == Operator.ScopeResolution)
                {
                    return(PluginResult.Interrupt);
                }
                else if (Ch != null)
                {
                    for (var i = 0; i < Ch.Length; i++)
                    {
                        Ch[i] = ResolveNode(Ch[i]);
                        if (Ch[i] == null)
                        {
                            return(PluginResult.Failed);
                        }
                    }

                    return(PluginResult.Succeeded);
                }
            }
            else if (Node.Children != null)
            {
                for (var i = 0; i < Node.Children.Length; i++)
                {
                    Node.Children[i] = ResolveNode(Node.Children[i]);
                    if (Node.Children[i] == null)
                    {
                        return(PluginResult.Failed);
                    }
                }
            }

            return(PluginResult.Succeeded);
        }