/// <summary>Runs the Operator on two operands.</summary> /// <param name="left">The left operand.</param> /// <param name="right">The right operand.</param> /// <param name="vars">The local variable storage.</param> /// <param name="context">An object representing context.</param> public CalcValue Run(CalcObject left, CalcObject right, CLLocalStore vars = null, CLContextProvider context = null) { // If the operator is value-based, we'll automatically convert expressions. if (ValueBasedLeft) { left = left.GetValue(vars, context); } if (ValueBasedRight) { right = right.GetValue(vars, context); } // Now get the func. CLBinaryOperatorFunc func = this[left.GetType(), right.GetType()]; // If it's null, we'll throw an exception. if (func == null) { throw new CLException( "Binary operator " + Symbol + " doesn't support parameters " + left.GetType().Name + " and " + right.GetType().Name ); } // Now let's run it. return(func(left, right, vars, context)); }
/// <summary> /// Adds a new function for the given types. /// </summary> /// <param name="left">The type of the left operand.</param> /// <param name="right">The type of the right operand.</param> /// <param name="func"> /// The function that handles those operands. /// </param> /// <param name="replaceChildren"> /// Iff <c>true</c>, the functions that handle types more derived than /// <c>left</c> and <c>right</c> should be removed from this operator. /// </param> public virtual void AddFunction(Type left, Type right, CLBinaryOperatorFunc func, bool replaceChildren = true) { Dictionary <Type, CLBinaryOperatorFunc> subDict; if (!Functions.ContainsKey(left)) { subDict = new Dictionary <Type, CLBinaryOperatorFunc>(); Functions[left] = subDict; } else { subDict = Functions[left]; } subDict[right] = func; // Now replace all the child types if necessary. if (replaceChildren) { foreach (Type leftTest in Functions.Keys) { if (leftTest.IsSubclassOf(left) || leftTest == left) { foreach (Type rightTest in Functions[leftTest].Keys) { if (rightTest.IsSubclassOf(right) || (rightTest == right && leftTest != left)) { Functions[left].Remove(right); } } } } } }
/// <summary> /// Throws an <c>InvalidOperationException</c>. To add a function, go /// through the <c>Parent</c> instead. /// </summary> public override void AddFunction(Type left, Type right, CLBinaryOperatorFunc func, bool replaceChildren) { throw new InvalidOperationException("For a CLComparisonOperator, functions must be added through the set."); }