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); }
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); } }
public LinkingNode(LinkedExprNode Node, CodeString Code, ExpressionFlags Flags = ExpressionFlags.None) : base(Code, Flags) { this.LinkedNode = Node; }
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); }
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); }
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); } }
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)); }