public Node Resolve(Node expression) { switch (expression) { case UnaryOperatorNode un: switch (un.NodeType) { case NodeTypes.Plus: return(Node.Plus(Resolve(un.Argument))); case NodeTypes.Minus: return(Node.Minus(Resolve(un.Argument))); case NodeTypes.Not: return(Node.Not(Resolve(un.Argument))); } break; case BinaryOperatorNode bn: var left = Resolve(bn.Left); var right = Resolve(bn.Right); switch (bn.NodeType) { case NodeTypes.Add: return(Node.Add(left, right)); case NodeTypes.Subtract: return(Node.Subtract(left, right)); case NodeTypes.Multiply: return(Node.Multiply(left, right)); case NodeTypes.Divide: return(Node.Divide(left, right)); case NodeTypes.Modulo: return(Node.Modulo(left, right)); case NodeTypes.LessThan: return(Node.LessThan(left, right)); case NodeTypes.GreaterThan: return(Node.GreaterThan(left, right)); case NodeTypes.LessThanOrEqual: return(Node.LessThanOrEqual(left, right)); case NodeTypes.GreaterThanOrEqual: return(Node.GreaterThanOrEqual(left, right)); case NodeTypes.Equals: return(Node.Equals(left, right)); case NodeTypes.NotEquals: return(Node.NotEquals(left, right)); case NodeTypes.And: return(Node.And(left, right)); case NodeTypes.Or: return(Node.Or(left, right)); case NodeTypes.Xor: return(Node.Xor(left, right)); case NodeTypes.Pow: return(Node.Power(left, right)); } break; case TernaryOperatorNode tn: return(Node.Conditional(Resolve(tn.Condition), Resolve(tn.IfTrue), Resolve(tn.IfFalse))); case FunctionNode fn: var args = new Node[fn.Arguments.Count]; for (var i = 0; i < args.Length; i++) { args[i] = Resolve(fn.Arguments[i]); } var funtionUpdated = Node.Function(fn.Name, args); if (FunctionMap != null && FunctionMap.TryGetValue(fn.Name, out var function)) { if (function is StaticResolverFunction staticResolverFunction) { var i = 0; foreach (VariableNode argument in staticResolverFunction.Arguments) { VariableMap[argument.Name] = args[i]; i++; } var functionBodyResolved = Resolve(staticResolverFunction.GetBody()); return(functionBodyResolved); } if (function is DynamicResolverFunction dynamicResolverFunction) { var functionBodyResolved = dynamicResolverFunction.GetBody(args); return(functionBodyResolved); } } return(funtionUpdated); case ConstantNode cn: return(cn); case VariableNode vn: if (VariableMap != null && vn.NodeType == NodeTypes.Variable && VariableMap.TryGetValue(vn.Name, out var mapped)) { return(Resolve(mapped)); } else { var vargs = new VariableFoundEventArgs <VariableNode>(this, vn); OnUnknownVariableFound(vargs); if (vargs.Created) { return(vargs.Result); } else { return(vn); } } } return(expression); }
/// <summary> /// Called when a variable was found. /// </summary> /// <param name="args">The event arguments.</param> protected virtual void OnUnknownVariableFound(VariableFoundEventArgs <VariableNode> args) => UnknownVariableFound?.Invoke(this, args);