public ExpressionNode Copy(PluginRoot Plugin, PluginFunc Func = null, BeginEndMode Mode = BeginEndMode.Both, CodeString Code = new CodeString(), bool LeftType = false) { if ((Mode & BeginEndMode.Begin) != 0 && !Plugin.Begin()) { return(null); } if (!Code.IsValid) { Code = this.Code; } var Ret = Copy(Plugin.State, Code, x => { if (Func != null) { var Res = Func(ref x); if (Res == PluginResult.Failed) { return(null); } if (Res == PluginResult.Interrupt || Res == PluginResult.Ready) { return(x); } } return(Plugin.NewNode(x)); }); if ((Mode & BeginEndMode.End) != 0 && Ret != null) { Ret = Plugin.End(Ret); } if (Ret != null && LeftType) { Ret.Type = Type; } 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 static PluginResult ReplaceNodes(ref ExpressionNode Node, PluginRoot Plugin, PluginFunc Func, bool NoReplaceOnPluginCall = false) { var CallPluginOnce = false; for (var i = 0; i < Node.LinkedNodes.Count; i++) { var LNode = Node.LinkedNodes[i]; var OldNode = LNode.Node; var Res = ReplaceNodes(ref LNode.Node, Plugin, Func, NoReplaceOnPluginCall); if (Res == PluginResult.Failed) { return(Res); } if (Res != PluginResult.Succeeded || LNode.Node != OldNode) { CallPluginOnce = true; } } if (Node.Children != null) { for (var i = 0; i < Node.Children.Length; i++) { var OldNode = Node.Children[i]; var Res = ReplaceNodes(ref Node.Children[i], Plugin, Func, NoReplaceOnPluginCall); if (Res == PluginResult.Failed) { return(Res); } if (Res != PluginResult.Succeeded || Node.Children[i] != OldNode) { CallPluginOnce = true; } } } if (!CallPluginOnce || (CallPluginOnce && !NoReplaceOnPluginCall)) { var Res = Func(ref Node); if (Res != PluginResult.Succeeded) { return(Res); } } if (CallPluginOnce) { var OldType = Node.Type; var Res = Plugin.NewNode(ref Node); if (Res == PluginResult.Failed) { return(Res); } if (OldType != null && Node.Type != null && Node.Type.RealId != OldType.RealId) { if (Node.Type.UnderlyingStructureOrRealId is StructuredType) { throw new ApplicationException("Cannot change structured type of a node"); } } return(Res); } return(PluginResult.Succeeded); }