Exemple #1
0
        public int GetLinkingCount(LinkedExprNode Node)
        {
            var Ret = 0;

            if (this is LinkingNode)
            {
                var LinkingNode = this as LinkingNode;
                if (LinkingNode.LinkedNode == Node)
                {
                    Ret++;
                }
            }

            for (var i = 0; i < LinkedNodes.Count; i++)
            {
                var Linked = LinkedNodes[i].Node;
                Ret += Linked.GetLinkingCount(Node);
            }

            if (Children != null)
            {
                for (var i = 0; i < Children.Length; i++)
                {
                    Ret += Children[i].GetLinkingCount(Node);
                }
            }

            return(Ret);
        }
Exemple #2
0
        public override PluginResult NewNode(ref ExpressionNode Node)
        {
            if (Node is StrExpressionNode)
            {
                var IdNode  = Node as StrExpressionNode;
                var Preproc = State.GlobalContainer.Preprocessor;
                var Macro   = Preproc.GetMacro(IdNode.Code.ToString());

                if (IfDef)
                {
                    Node = Parent.NewNode(Constants.GetBoolValue(Container, Macro != null, Node.Code));
                    return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                }
                else if (Macro != null)
                {
                    if (Macro.Value == null)
                    {
                        State.Messages.Add(MessageId.MacroWithoutValue, Node.Code);
                        return(PluginResult.Failed);
                    }

                    Macro.Used = true;
                    if (Macro.Parameters == null || Macro.Parameters.Count == 0)
                    {
                        Node = Macro.Value.Copy(Parent, Mode: BeginEndMode.None, Code: IdNode.Code);
                    }
                    else
                    {
                        Node = Parent.NewNode(new MacroExpressionNode(Macro, Node.Code));
                    }
                    return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                }
            }

            // ------------------------------------------------------------------------------------
            else if (Node is OpExpressionNode)
            {
                var OpNode = Node as OpExpressionNode;
                var Ch     = OpNode.Children;
                var Op     = OpNode.Operator;

                if (Op == Operator.Call && Ch[0] is MacroExpressionNode)
                {
                    var MFunc = Ch[0] as MacroExpressionNode;
                    var Macro = MFunc.Macro;
                    Macro.Used = true;

                    if (Ch.Length != Macro.Parameters.Count + 1)
                    {
                        State.Messages.Add(MessageId.ParamCount, Node.Code);
                        return(PluginResult.Failed);
                    }

                    var Nodes    = new AutoAllocatedList <ExpressionNode>();
                    var LnkNodes = new AutoAllocatedList <LinkedExprNode>();
                    for (var i = 1; i < Ch.Length; i++)
                    {
                        if (!(Ch[i] is OpExpressionNode))
                        {
                            Nodes.Add(Ch[i]);
                        }
                        else
                        {
                            var N = new LinkedExprNode(Ch[i]);
                            LnkNodes.Add(N);
                            Nodes.Add(new LinkingNode(N, Node.Code));
                        }
                    }

                    PluginFunc Func = (ref ExpressionNode x) =>
                    {
                        if (x is MacroArgNode)
                        {
                            var ArgIndex = (x as MacroArgNode).Index;
                            x = Nodes[ArgIndex].Copy(Parent, Mode: BeginEndMode.None);
                            return(x == null ? PluginResult.Failed : PluginResult.Ready);
                        }

                        return(PluginResult.Succeeded);
                    };

                    Node = Macro.Value.Copy(Parent, Func, BeginEndMode.None);
                    if (Node == null)
                    {
                        return(PluginResult.Failed);
                    }

                    Node.LinkedNodes.AddRange(LnkNodes);
                    Node = Parent.NewNode(Node);
                    return(Node == null ? PluginResult.Failed : PluginResult.Ready);
                }
            }

            // ------------------------------------------------------------------------------------
            if (!CheckMacroNodes(Node))
            {
                return(PluginResult.Failed);
            }
            else
            {
                return(PluginResult.Succeeded);
            }
        }
Exemple #3
0
 public LinkingNode(LinkedExprNode Node, CodeString Code, ExpressionFlags Flags = ExpressionFlags.None)
     : base(Code, Flags)
 {
     this.LinkedNode = Node;
 }
Exemple #4
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);
        }
Exemple #5
0
        private PluginResult ResolveLinkingAssigment(ref ExpressionNode Node)
        {
            if (Expressions.GetOperator(Node) != Operator.Assignment)
            {
                return(PluginResult.Succeeded);
            }

            var Ch         = Node.Children;
            var LinkingCh0 = Ch[0] as LinkingNode;

            if (LinkingCh0 == null)
            {
                return(PluginResult.Succeeded);
            }

            var Ch1Ch      = Ch[1].Children;
            var LCh1Ch0    = Ch1Ch[0] as LinkingNode;
            var LinkedNode = LinkingCh0.LinkedNode;

            if (LCh1Ch0 == null || LCh1Ch0.LinkedNode != LinkedNode ||
                !Node.LinkedNodes.Contains(LinkedNode) || LinkedNode.LinkingCount != 2)
            {
                throw new ApplicationException();
            }

            Node.LinkedNodes.Remove(LinkedNode);
            if (Expressions.GetOperator(LinkedNode.Node) == Operator.Tuple)
            {
                var OpLinked = LinkedNode.Node as OpExpressionNode;
                var LinkedCh = OpLinked.Children;

                var DstCh = new ExpressionNode[LinkedCh.Length];
                var SrcCh = new ExpressionNode[LinkedCh.Length];

                for (var i = 0; i < LinkedCh.Length; i++)
                {
                    ExpressionNode Dst, Src;
                    var            Linked = new LinkedExprNode(LinkedCh[i]);
                    if (!ProcessLinkedAssignmentMember(Node.Code, ref Linked, out Dst, out Src))
                    {
                        return(PluginResult.Failed);
                    }

                    DstCh[i] = Dst;
                    SrcCh[i] = Src;
                    Node.LinkedNodes.Add(Linked);
                }

                Ch[0]    = Parent.NewNode(new OpExpressionNode(Operator.Tuple, DstCh, Node.Code));
                Ch1Ch[0] = Parent.NewNode(new OpExpressionNode(Operator.Tuple, SrcCh, Node.Code));
                if (Ch[0] == null || Ch1Ch[0] == null)
                {
                    return(PluginResult.Failed);
                }
            }
            else
            {
                ExpressionNode Dst, Src;
                if (!ProcessLinkedAssignmentMember(Node.Code, ref LinkedNode, out Dst, out Src))
                {
                    return(PluginResult.Failed);
                }

                Ch[0]    = Dst;
                Ch1Ch[0] = Src;
                Node.LinkedNodes.Add(LinkedNode);
            }

            Ch[1] = Parent.NewNode(Ch[1]);
            if (Ch[1] == null)
            {
                return(PluginResult.Failed);
            }

            Node = Parent.NewNode(Node);
            return(Node == null ? PluginResult.Failed : PluginResult.Ready);
        }
Exemple #6
0
        private bool ProcessLinkedAssignmentMember(CodeString Code, ref LinkedExprNode LinkedNode,
                                                   out ExpressionNode Dst, out ExpressionNode Src)
        {
            Dst = null;
            Src = null;

            var MemberId = Expressions.GetMemberIdentifier(LinkedNode.Node);

            if (MemberId.RealId is Property)
            {
                if (LinkedNode.Node is IdExpressionNode)
                {
                    Dst = Parent.NewNode(new IdExpressionNode(MemberId, Code));
                    Src = Parent.NewNode(new IdExpressionNode(MemberId, Code));
                    return(Dst != null && Src != null);
                }
                else
                {
                    var LinkedOpNode = LinkedNode.Node as OpExpressionNode;
                    if (LinkedOpNode.Operator != Operator.Member)
                    {
                        throw new ApplicationException();
                    }

                    var NewLinkedNode = new LinkedExprNode(LinkedOpNode.Children[0]);
                    var DstCh         = new ExpressionNode[]
                    {
                        Parent.NewNode(new LinkingNode(NewLinkedNode, Code)),
                        Parent.NewNode(new IdExpressionNode(MemberId, Code)),
                    };

                    if (DstCh[0] == null || DstCh[1] == null)
                    {
                        return(false);
                    }

                    var SrcCh = new ExpressionNode[]
                    {
                        Parent.NewNode(new LinkingNode(NewLinkedNode, Code)),
                        Parent.NewNode(new IdExpressionNode(MemberId, Code)),
                    };

                    if (SrcCh[0] == null || SrcCh[1] == null)
                    {
                        return(false);
                    }

                    Dst        = Parent.NewNode(new OpExpressionNode(Operator.Member, DstCh, Code));
                    Src        = Parent.NewNode(new OpExpressionNode(Operator.Member, SrcCh, Code));
                    LinkedNode = NewLinkedNode;
                    return(Dst != null && Src != null);
                }
            }
            else if (IsClassMemberNode(LinkedNode.Node))
            {
                LinkedNode.Node = LinkedNode.Node.Children[0];

                Dst = Parent.NewNode(new LinkingNode(LinkedNode, Code));
                Src = Parent.NewNode(new LinkingNode(LinkedNode, Code));
                if (Dst == null || Src == null)
                {
                    return(false);
                }

                var MemberIdNode1 = Parent.NewNode(new IdExpressionNode(MemberId, Code));
                var MemberIdNode2 = Parent.NewNode(new IdExpressionNode(MemberId, Code));
                if (MemberIdNode1 == null || MemberIdNode2 == null)
                {
                    return(false);
                }

                var DstCh = new ExpressionNode[] { Dst, MemberIdNode1 };
                var SrcCh = new ExpressionNode[] { Src, MemberIdNode2 };

                Dst = Parent.NewNode(new OpExpressionNode(Operator.Member, DstCh, Code));
                Src = Parent.NewNode(new OpExpressionNode(Operator.Member, SrcCh, Code));
                return(Dst != null && Src != null);
            }
            else
            {
                LinkedNode.Node = Expressions.GetAddress(Parent, LinkedNode.Node, Code);
                if (LinkedNode.Node == null)
                {
                    return(false);
                }

                Dst = Parent.NewNode(new LinkingNode(LinkedNode, Code));
                Src = Parent.NewNode(new LinkingNode(LinkedNode, Code));
                if (Dst == null || Src == null)
                {
                    return(false);
                }

                Dst = Expressions.Indirection(Parent, Dst, Code);
                Src = Expressions.Indirection(Parent, Src, Code);
                return(Dst != null && Src != null);
            }
        }
Exemple #7
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));
        }