Пример #1
0
        // returns the added operand node
        public static MathNode ParseOperand(string input)
        {
            if (input == null) { throw new UberScriptException("AddOperand input was null!"); }
            if (input == "") { throw new UberScriptException("AddOperand input was an empty string!"); }
            Object operand = input;
            OpType opType = OpType.Unassigned;
            try
            {
                int numCommas = 0;
                for (int i = 0; i < input.Length; i++)
                {
                    if (input[i] == ',') numCommas++;
                }
                if (input.StartsWith("0x"))
                {
                    try
                    {
                        if (isNegative) // might fail here
                        {
                            operand = Convert.ToInt32(input.Substring(2), 16);
                            opType = OpType.Int;
                        }
                        else
                        {
                            operand = Convert.ToUInt64(input.Substring(2), 16);
                            // try to use int if at all possible
                            if ((UInt64)operand < 2147483647) // 2^31 - 1
                            {
                                operand = Convert.ToInt32(input.Substring(2), 16);
                                opType = OpType.Int;
                            }
                            else
                                opType = OpType.UInt64;
                        }
                    }
                    catch // (InvalidCastException e)
                    {
                        // must be a string
                        operand = input;
                        opType = OpType.String;
                    }
                }
                else if (char.IsNumber(input[0]) || input[0] == '.')
                {
                    double doubleVal;
                    bool result = double.TryParse(input, out doubleVal);
                    if (result == false)
                    {
                        operand = input; // must be something like 016hello, so just treat it as a string
                        opType = OpType.String;
                    }
                    else
                    {
                        if (isNegative) { doubleVal = -doubleVal; isNegative = false; }
                        if (!input.Contains('.') && doubleVal % 1 < 0.0009765625) // 2^-10
                        {
                            // close enough to an integer value
                            operand = (int)doubleVal;
                            opType = OpType.Int;
                        }
                        else
                        {
                            operand = doubleVal;
                            opType = OpType.Double;
                        }
                    }
                }
                else if (input == "null")
                {
                    opType = OpType.Null;
                    operand = null;
                }
                else if (input.StartsWith("\""))
                {
                    // inside a quotation--> parse out the innards and set it to a string
                    if (!input.EndsWith("\"") || input.Length == 1)
                    {
                        throw new UberScriptException("ParseOperand input started with \" but did not end with \"... it must be balanced!");
                    }
                    input = input.Substring(1, input.Length - 2); // remove the front and back ""
                    bool justEscapedBackslash = false;
                    for (int ix = 0; ix < input.Length; ix++)
                    {
                        if (ix > 0 && input[ix - 1] == '\\')
                        {
                            // not super efficient, but oh well, it's only run once
                            if (!justEscapedBackslash)
                            {
                                if (input[ix] == '"')
                                {
                                    input = input.Substring(0, ix - 1) + input.Substring(ix); // remove the \, keep the "
                                    ix--;
                                }
                                else if (input[ix] == 't')
                                {
                                    input = input.Substring(0, ix - 1) + "\t" + input.Substring(ix + 1); // remove the \ and add a tab
                                    ix--;
                                }
                                else if (input[ix] == 'n')
                                {
                                    input = input.Substring(0, ix - 1) + "\n" + input.Substring(ix + 1); // remove the \ and add a new line
                                    ix--;
                                }
                                else if (input[ix] == 'r')
                                {
                                    input = input.Substring(0, ix - 1) + "\r" + input.Substring(ix + 1); // remove the \ and add a carriage return
                                    ix--;
                                }
                                else if (input[ix] == '\\')
                                {
                                    input = input.Substring(0, ix - 1) + input.Substring(ix); // keep only one of the \ characters 
                                    justEscapedBackslash = true;
                                    continue;
                                }
                            }
                            // otherwise ignore it
                        }
                        justEscapedBackslash = false;
                    }
                    operand = input;
                    opType = OpType.String;
                }
                else if (UberScriptFunctions.IsFunctionString(input))
                {
                    MathNode latestRootNode = currentRoot; // currentRoot is replaced when FunctionNode adds a mathtree for each arg
                    currentRoot = null;
                    operand = new FunctionNode(null, input); // can't add LineNumber here :(
                    if (isNegative) { ((FunctionNode)operand).NegateOutput = true; isNegative = false; }
                    opType = OpType.Func;
                    currentRoot = latestRootNode;
                }
                // NOTE: While the performance is not as good (perhaps), I'm going to rely on parsing list accession (e.g. objs.mobs[objs.mobs.count - 1]) 
                // on the fly (as is done in the PropertySetters and PropertyGetters functions) rather than pre-parsing it.
                /*
                else if (UberScriptFunctions.IsArrayAccessor(input))
                {
                    MathNode latestRootNode = currentRoot; // currentRoot is replaced when FunctionNode adds a mathtree for each arg
                    currentRoot = null;
                    operand = new ListAccessNode(null, input); // can't add LineNumber here :(
                    if (isNegative) { ((ListAccessNode)operand).NegateOutput = true; isNegative = false; }
                    opType = OpType.ListAccess;
                    currentRoot = latestRootNode;
                }*/

                /* // I'm not going to handle literal points e.g. (1,2,3)... use the LOC function instead (so you can do math in it)
                else if (numCommas > 1) // it must be a location if it is not a function and has 2 commas in it
                {
                    operand = "(" + input + ")";
                    opType = OpType.String;
                }*/
                else
                {
                    operand = input;
                    opType = OpType.String;
                }


                MathNode newOperandNode = new MathNode(null, null, opType, TreePriority.Operand, operand); // assigned into tree in constructor!
                return newOperandNode;
            }
            catch (Exception e)
            {
                Console.WriteLine("AddOperand error: " + e.Message + "\n" + e.StackTrace);
                throw new UberScriptException("AddOperand error for " + input, e);
            }
        }
Пример #2
0
 public static void AddOperationNode(ref string input, OpType opType, TreePriority priority, int i, ref int currentIndex)
 {
     string operand = input.Substring(currentIndex, i - currentIndex);
     MathNode newNode = new MathNode(null, null, opType, priority);
     char prevChar = i > 0 ? input[i-1] : '\0'; 
     bool twoCharOperator = false;
     char nextChar;
     if (opType == OpType.And || opType == OpType.Or || opType == OpType.NotEqualTo 
         || opType == OpType.EqualTo || opType == OpType.GThanOrEqualTo || opType == OpType.LThanOrEqualTo)
     {
         nextChar = input.Length > (i+2) ? input[i+2] : '\0';
         twoCharOperator = true;
     }
     else
     {
         nextChar = input.Length > (i+1) ? input[i+1] : '\0';
     }
     if (operand == "")
     {
         // the only character possible before an operator is )
         if (i > 0 && input[i - 1] == ')')
         {
             bool hasFollowingOpenParen = false; // special case--requires decreased priority when inserting this node
             if (nextChar == '(')
             {
                 hasFollowingOpenParen = true;
             }
             if (hasFollowingOpenParen)
             {
                 TreePriority prevPriority = newNode.Priority;
                 newNode.Priority = TreePriority.AddSub; // SHOULD THIS BE CHANGED TO JUST DECREASING BY ONE? OR ALWAYS ADD SUB?
                 InsertIntoTree(currentRoot, newNode);
                 newNode.Priority = prevPriority;
             }
             else InsertIntoTree(currentRoot, newNode);
         }
         else throw new UberScriptException("Math parse error: no operand before + for input= " + input);
     }
     else
     {
         if (currentRoot == null) { currentRoot = newNode; InsertIntoTree(currentRoot, ParseOperand(operand)); }
         else { InsertIntoTree(currentRoot, ParseOperand(operand)); InsertIntoTree(currentRoot, newNode); }
     }
     if (twoCharOperator)
         currentIndex = i + 2;
     else
         currentIndex = i + 1;
 }
Пример #3
0
        public static void InsertIntoTree(MathNode nodeToCheck, MathNode newNode)
        {
            if (nodeToCheck == null) { currentRoot = newNode; return; }
            try
            {
                if (newNode.Priority == TreePriority.Unassigned) { throw new Exception("Attempted to insert MathNode with unassigned priority--Not allowed!"); }
                if (newNode.Priority == TreePriority.Operand)
                {
                    if (nodeToCheck.OpTypeVal == OpType.OpenParenthesis && newNode.OpTypeVal != OpType.OpenParenthesis)
                    {
                        // should never be more than 1 open parenthesis in a row (b/c currentRootNode is replaced)...

                        // remove the Open Parenthesis node--it was just a placerholder
                        ReplaceNode(nodeToCheck, newNode, true); // becomes the new Current root until the next closing parenthesis
                        return;
                    }
                    // should never happen that two operands land on each other in this function
                    // EXCEPT if you get 2 open parentheses in a row
                    if (nodeToCheck.Priority > TreePriority.Operand
                        || (nodeToCheck.OpTypeVal == OpType.OpenParenthesis && newNode.OpTypeVal == OpType.OpenParenthesis))
                    {
                        if (nodeToCheck.Left == null) { nodeToCheck.Left = newNode; }
                        else if (nodeToCheck.Left.OpTypeVal == OpType.OpenParenthesis) { InsertIntoTree(nodeToCheck.Left, newNode); } // the only time operand can go left
                        else if (nodeToCheck.Right == null) { nodeToCheck.Right = newNode; }
                        else InsertIntoTree(nodeToCheck.Right, newNode);
                    }
                    else { throw new Exception("Cannot have operand land on operand in InsertIntoTree method!"); }
                }
                else // priority is > Operand... this will either push a branch down or replace an operator somewhere
                {
                    if (nodeToCheck.OpTypeVal == OpType.OpenParenthesis)
                    {
                        // something like ((5+5)*3), the * would have hit this case

                        // remove the Open Parenthesis node--it was just a placerholder
                        ReplaceNode(nodeToCheck, newNode, true); // becomes the new Current root until the next closing parenthesis
                    }
                    else if (nodeToCheck.Priority >= newNode.Priority) // push the branch down
                    {
                        if (nodeToCheck.Parent != null)
                        {
                            if (((MathNode)nodeToCheck.Parent).Right == nodeToCheck) { ((MathNode)nodeToCheck.Parent).Right = newNode; }
                            else { ((MathNode)nodeToCheck.Parent).Left = newNode; }
                        }
                        else
                        {
                            currentRoot = newNode;
                        }
                        if (currentRoot == nodeToCheck) currentRoot = newNode;
                        newNode.Left = nodeToCheck;
                    }
                    else // (nodeToCheck.Priority < newNode.Priority) // get underneath it, push operand down
                    {
                        if (nodeToCheck.Left == null)
                        { // DON"T throw new Exception("InsertIntoTree Higher priority operator found null left node!"); }
                            // actually this can happen in a case like (4+10), where the ( is replaced with the
                            // 4 and then the + tries to follow suit, but 4 is now the root node.
                            if (nodeToCheck.Priority == TreePriority.Operand)
                            {
                                if (nodeToCheck.Parent != null)
                                {
                                    if (((MathNode)nodeToCheck.Parent).Right == nodeToCheck) { ((MathNode)nodeToCheck.Parent).Right = newNode; }
                                    else { ((MathNode)nodeToCheck.Parent).Left = newNode; }
                                    if (currentRoot == nodeToCheck) currentRoot = newNode;
                                }
                                else
                                {
                                    currentRoot = newNode;
                                }
                                newNode.Left = nodeToCheck;
                            }
                        }
                        else if (nodeToCheck.Right == null) { throw new Exception("Right node should not be null here!"); }
                        else if (nodeToCheck.Right.Priority == TreePriority.Operand)
                        {
                            MathNode oldRight = ReplaceNode(nodeToCheck.Right, newNode, false);
                            newNode.Left = oldRight;
                        }
                        else InsertIntoTree(nodeToCheck.Right, newNode);
                    }
                }
            }
            catch (Exception e)
            {
                throw new UberScriptException("InsertIntoTree error: ", e);
            }
        }
Пример #4
0
        public void ParseMath(string input)
        {
            int currentIndex = 0;
            Stack<MathNode> prevRootNodes = new Stack<MathNode>();
            currentRoot = null;
            isNegative = false;
            int numOpenParensInFunctionCallString = 0; // should be 0 if we are not in a function call, never less than 0
            int totalOpenParens = 0; // should never be less than 0
            string operatorsSupportingUnaryMinus = "+-*/^%(<=>";
            bool insideQuotation = false;
            int totalOpenSquareBracket = 0;

            if (input == "")
            {
                currentRoot = new MathNode(null, null, OpType.String, TreePriority.Operand, String.Empty);
                Children.Add(currentRoot);
                return;
            }

            // if it is an array, there can be nothing more in the math tree
            if (input.StartsWith("[") && input.EndsWith("]"))
            {
                MathNode arrayNode = new MathNode(null, input, OpType.Array, TreePriority.Infinite);
                string inArray = input.Substring(1, input.Length - 2);
                List<string> elements = new List<string>();
                for (int i = 0; i < inArray.Length; i++)
                {
                    char c = inArray[i];
                    if (insideQuotation && c != '"')
                    {
                        continue;
                    }

                    if (c == '(')
                    {
                        totalOpenParens += 1;
                    }
                    else if (c == ')')
                    {
                        totalOpenParens -= 1;
                        if (totalOpenParens < 0) { throw new Exception("Unbalanced () characters in math string!"); }
                    }
                    else if (c == '[')
                    {
                        totalOpenSquareBracket += 1;
                    }
                    else if (c == ']')
                    {
                        totalOpenSquareBracket -= 1;
                        if (totalOpenSquareBracket < 0) { throw new Exception("Unbalanced [] characters in math string!"); }
                    }
                    else
                    {
                        if (totalOpenParens > 0 || totalOpenSquareBracket > 0)
                            continue;

                        if (c == '"')
                        {
                            
                            /* I'm not sure why I thought I need to do this here; it's taken care of in the MathTree parsing
                            if (i > 0 && inArray[i-1] == '\\')
                            {
                                // not super efficient, but oh well, it's only run once
                                inArray = inArray.Substring(0, i - 1) + inArray.Substring(i); // remove the \, keep the "
                                i--;
                            }
                            else
                            {
                                inArray = inArray.Substring(0, i) + inArray.Substring(i+1); // remove the "
                                i--;
                             */
                                insideQuotation = !insideQuotation;
                            //}
                        }
                        else if (c == ',')
                        {
                            elements.Add(inArray.Substring(0, i));
                            inArray = inArray.Substring(i+1);
                            i = -1;
                        }
                    }
                }
                if (inArray.Length > 0) { elements.Add(inArray); } // add final element

                ArrayList arrayList = new ArrayList(elements.Count + 10);

                foreach (string element in elements)
                {
                    arrayList.Add(new MathTree(null, element));
                }
                arrayNode.Value = arrayList;
                Children.Add(arrayNode);
                return;
            }

            bool justEscapedBackslash = false;
            for (int i = 0; i < input.Length; i++)
            {
                char c = input[i];
                string arg;
                
                if (insideQuotation && c != '"')
                {
                    if (c == '\\')
                    {
                        if (i > 0 && input[i - 1] == '\\' && !justEscapedBackslash)
                        {
                            justEscapedBackslash = true;
                            continue;
                        }
                    }
                    justEscapedBackslash = false;
                    continue;
                }

                if (c == '"')
                {
                    if (i > 0 && input[i - 1] == '\\' && !justEscapedBackslash)
                    {
                        continue; // it's an escaped \" character
                    }
                    else
                    {
                        // --> I'm putting this in the ParseOperand area
                        //input = input.Substring(0, i) + input.Substring(i+1); // remove the "
                        //i--;
                        insideQuotation = !insideQuotation;
                    }
                }


                if (totalOpenSquareBracket > 0 && c != ']')
                {
                   if (c == '[')
                    {
                        totalOpenSquareBracket++;
                    } 
                    continue;
                }
                else if (c == '[')
                {
                    totalOpenSquareBracket++;
                }
                else if (c == ']')
                {
                    if (totalOpenSquareBracket > 0)
                    {
                        totalOpenSquareBracket--;
                    }
                    else
                    {
                        throw new Exception("Unbalanced [] characters in list accessing string!");
                    }
                }

                if (numOpenParensInFunctionCallString > 0 && c != '(' && c != ')')
                {
                    // don't do anything in the middle of a function string
                    continue;
                }

                if (c == '|')
                {
                    if (input[i + 1] == '|')
                    {
                        AddOperationNode(ref input, OpType.Or, TreePriority.Or, i, ref currentIndex);
                        i++;
                    }
                    else
                    {
                        throw new UberScriptException("Single | encountered!  Use || for logical 'or' operator. Note that the bitwise '|' operator currently not supported!");
                        //AddOperationNode(ref input, OpType.BitOr, TreePriority.BitAnd, i, ref currentIndex);
                    }
                }
                else if (c == '&')
                {
                    if (input[i + 1] == '&')
                    {
                        AddOperationNode(ref input, OpType.And, TreePriority.And, i, ref currentIndex);
                        i++;
                    }
                    else
                    {
                        throw new UberScriptException("Single & encountered!  Use && for logical 'and' operator. Note that the bitwise '&' operator currently not supported!");
                        //AddOperationNode(ref input, OpType.BitAnd, TreePriority.BitAnd, i, ref currentIndex);
                    }
                }
                else if (c == '>')
                {
                    if (input[i+1] == '=')
                    {
                        AddOperationNode(ref input, OpType.GThanOrEqualTo, TreePriority.Comparison, i, ref currentIndex);
                        i++;
                    }
                    else
                    {
                        AddOperationNode(ref input, OpType.GThan, TreePriority.Comparison, i, ref currentIndex);
                    }
                }
                else if (c == '<')
                {
                    if (input[i+1] == '=')
                    {
                        AddOperationNode(ref input, OpType.LThanOrEqualTo, TreePriority.Comparison, i, ref currentIndex);
                        i++;
                    }
                    else
                    {
                        AddOperationNode(ref input, OpType.LThan, TreePriority.Comparison, i, ref currentIndex);
                    }
                }
                else if (c == '!')
                {
                    if (input[i + 1] == '=')
                    {
                        AddOperationNode(ref input, OpType.NotEqualTo, TreePriority.Comparison, i, ref currentIndex);
                        i++;
                    }
                    else
                    {
                        throw new UberScriptException("Cannot have a single = sign!");
                    }
                }
                else if (c == '=')
                {
                    if (input[i+1] == '=')
                    {
                        AddOperationNode(ref input, OpType.EqualTo, TreePriority.Comparison, i, ref currentIndex);
                        i++;
                    }
                    else
                    {
                        throw new UberScriptException("Cannot have a single = sign!");
                    }
                }
                else if (c == '+')
                {
                    AddOperationNode(ref input, OpType.Add, TreePriority.AddSub, i, ref currentIndex);
                }
                else if (c == '-')
                {
                    // i == 0 means a statment is STARTING with -, e.g. -6
                    // otherwise there is something like this ...+-6 or ...*-6, etc
                    if (i == 0 || (i > 0 && (operatorsSupportingUnaryMinus.Contains(input[i - 1]))))
                    {
                        isNegative = !isNegative;
                        currentIndex = i + 1;
                    }
                    else
                    {
                        AddOperationNode(ref input, OpType.Sub, TreePriority.AddSub, i, ref currentIndex);
                    }
                }
                else if (c == '*')
                {
                    AddOperationNode(ref input, OpType.Mul, TreePriority.MultDiv, i, ref currentIndex);
                }
                else if (c == '/')
                {
                    AddOperationNode(ref input, OpType.Div, TreePriority.MultDiv, i, ref currentIndex);
                }
                else if (c == '^')
                {
                    AddOperationNode(ref input, OpType.Pow, TreePriority.Power, i, ref currentIndex);
                }
                else if (c == '%')
                {
                    AddOperationNode(ref input, OpType.Mod, TreePriority.MultDiv, i, ref currentIndex);
                }
                else if (c == '(')
                {
                    totalOpenParens++;
                    // must check if it is a function call
                    if (numOpenParensInFunctionCallString == 0)
                    {
                        if (UberScriptFunctions.IsFunctionString(input.Substring(currentIndex, i - currentIndex).Trim()))
                        {
                            numOpenParensInFunctionCallString++;
                            continue;
                        }
                        // it's not a function call, it's an order of operations open parenthesis
                        prevRootNodes.Push(currentRoot);
                        MathNode openParenPlaceholder = new MathNode(null, null, OpType.OpenParenthesis, TreePriority.Operand);
                        InsertIntoTree(currentRoot, openParenPlaceholder);
                        currentRoot = openParenPlaceholder;
                        currentIndex = i + 1;
                    }
                    else
                    {
                        numOpenParensInFunctionCallString++; // keep incrementing it
                    }
                }
                else if (c == ')')
                {
                    totalOpenParens--;
                    if (totalOpenParens < 0) { throw new Exception("Unbalanced () characters in math string!"); }
                    if (numOpenParensInFunctionCallString > 0)
                    {
                        numOpenParensInFunctionCallString--;
                        if (numOpenParensInFunctionCallString < 0) { throw new Exception("Unbalanced () characters in function call string!"); }
                    }
                    else
                    {
                        // should be an operand or ) right before this )
                        arg = input.Substring(currentIndex, i - currentIndex).Trim();
                        if (arg == "" && !(i > 0 && input[i - 1] == ')')) { throw new UberScriptException("Math parse error: no operand before operator for input=" + input); }
                        if (currentRoot == null) { throw new UberScriptException("Math parse error: can't have ) without a ( currentRoot! input=" + input); } // should be impossible

                        if (arg != "") InsertIntoTree(currentRoot, ParseOperand(arg));
                        currentIndex = i + 1;
                        MathNode prevRootNode = prevRootNodes.Pop();
                        currentRoot.Priority = TreePriority.Infinite;
                        if (prevRootNode != null)
                        {
                            currentRoot = prevRootNode; // return up a level
                        }
                        // else the first character in the input was (, so there was no root node initially, so keep the currentNode
                    }
                }
            }

            if (insideQuotation) { throw new UberScriptException("Unbalanced \" characters! You must terminate strings with \""); };
            if (totalOpenParens > 0) { throw new UberScriptException("Did not have matching ()!"); }
            if (totalOpenSquareBracket > 0) { throw new UberScriptException("Did not have matching []!"); }

            if (currentIndex < input.Length)
            {
                if (currentRoot == null)
                {
                    currentRoot = ParseOperand(input.Substring(currentIndex, input.Length - currentIndex));
                }
                else
                {
                    InsertIntoTree(currentRoot, ParseOperand(input.Substring(currentIndex, input.Length - currentIndex)));
                }
            }
            Children.Add(currentRoot);
        }
Пример #5
0
 /// <summary>
 /// Replaces the node in the tree, returns the replaced node
 /// </summary>
 /// <param name="nodeToReplace"></param>
 /// <param name="newNode"></param>
 /// <param name="replaceCurrent"></param>
 /// <returns></returns>
 public static MathNode ReplaceNode(MathNode nodeToReplace, MathNode newNode, bool replaceCurrent)
 {
     if (nodeToReplace.Parent == null)
     {
         currentRoot = newNode; // we're at the top root
         newNode.Left = nodeToReplace.Left;
         newNode.Right = nodeToReplace.Right;
         return nodeToReplace;
     } // in case it was the only thing in the tree
     if (((MathNode)nodeToReplace.Parent).Right == nodeToReplace) { ((MathNode)nodeToReplace.Parent).Right = newNode; }
     else { ((MathNode)nodeToReplace.Parent).Left = newNode; }
     newNode.Left = nodeToReplace.Left;
     newNode.Right = nodeToReplace.Right;
     if (replaceCurrent)
     {
         currentRoot = newNode;
     }
     return nodeToReplace;
 }
Пример #6
0
		/// <summary>
		///     Ugly function for taking Objects from the MathTree and adding them together...
		///     Not sure if there might be a better way (without calling up the C# compiler
		///     to sort things out which I think would be terrible performance)
		/// </summary>
		/// <param name="node"></param>
		/// <returns></returns>
		public static Object Calculate(TriggerObject trigObj, MathNode node)
		{
			// ordered in the most probable order, (in my opinion)
			bool isInDictionary = false;
			if (node == null)
			{
				return null;
			}
			if (node.Left == null && node.Right == null)
			{
				if (node.OpTypeVal == OpType.Func)
				{
					return ((FunctionNode)node.Value).Execute(trigObj, false); // true???
				}
				else if (node.Value is ArrayList)
				{
					ArrayList original = (ArrayList)node.Value;
					if (original.Count > 0 && original[0] is MathTree)
					{
						// if 1 element is a mathtree, then they are all mathtrees
						// ... created using this syntax: ["hello", "heh" + " hah"]
						ArrayList outputList = new ArrayList(original.Count);
						for (int i = 0; i < original.Count; i++)
						{
							outputList.Add(((MathTree)original[i]).Calculate(trigObj));
						}
						return outputList;
					}
					// otherwise it's a regular arraylist--just return it
					return original;
				}
				else if (node.Value is string && (string)node.Value != string.Empty)
				{
					string nodeValueString = (string)node.Value;
					string nodeValueStringLower = nodeValueString.ToLower();
					if (nodeValueStringLower == "false")
					{
						return false;
					}
					else if (nodeValueStringLower == "true")
					{
						return true;
					}
						// check if it is one of the local or global function ints, strings, doubles, or objs
					else
					{
						object possibleReturnValue = CheckDictionaries(trigObj, nodeValueString, out isInDictionary);
						if (isInDictionary)
						{
							return possibleReturnValue;
						}
					}
				}
				return node.Value;
			}
			Object operand1;
			Object operand2;
			if (node.Left.OpTypeVal == OpType.Int || node.Left.OpTypeVal == OpType.Double || node.Left.OpTypeVal == OpType.String ||
				node.Left.OpTypeVal == OpType.UInt64 || node.Left.OpTypeVal == OpType.Bool)
			{
				operand1 = node.Left.Value;
				if (operand1 is string && (string)operand1 != "")
				{
					// check if it is one of the local or global function ints, strings, doubles, or objs
					string operand1String = (string)operand1;
					string operand1StringLower = operand1String.ToLower();
					if (operand1StringLower == "false")
					{
						operand1 = false;
					}
					else if (operand1StringLower == "true")
					{
						operand1 = true;
					}

					object possibleReturnValue = CheckDictionaries(trigObj, operand1String, out isInDictionary);
					if (isInDictionary)
					{
						operand1 = possibleReturnValue;
					}
				}
			}
			else
			{
				operand1 = Calculate(trigObj, node.Left);
			}

			// hacky solution to extraneous parenthesis
			if (node.OpTypeVal == OpType.OpenParenthesis)
			{
				return operand1;
			}

			if (node.OpTypeVal == OpType.And)
			{
				// check whether we even need to find operand 2 (since if the
				// first argument is false, then arg1 && arg2 is false
				if (operand1 is bool)
				{
					if ((bool)operand1 == false)
					{
						return false;
					}
				}
				else
				{
					throw new UberScriptException("Cannot use && operator between non boolean: " + operand1);
				}
			}
			else if (node.OpTypeVal == OpType.Or)
			{
				// check whether we even need to find operand 2 (since if the
				// first argument is true, then arg1 || arg2 is true
				if (operand1 is bool)
				{
					if ((bool)operand1)
					{
						return true;
					}
				}
				else
				{
					throw new UberScriptException("Cannot use || operator between non boolean: " + operand1);
				}
			}

			if (node.Right.OpTypeVal == OpType.Int || node.Right.OpTypeVal == OpType.Double ||
				node.Right.OpTypeVal == OpType.String || node.Right.OpTypeVal == OpType.UInt64 || node.Left.OpTypeVal == OpType.Bool)
			{
				operand2 = node.Right.Value;
				if (operand2 is string && (string)operand2 != "")
				{
					// check if it is one of the local or global function ints, strings, doubles, or objs
					string operand2String = (string)operand2;
					string operand2StringLower = operand2String.ToLower();
					if (operand2StringLower == "false")
					{
						operand2 = false;
					}
					else if (operand2StringLower == "true")
					{
						operand2 = true;
					}

					object possibleReturnValue = CheckDictionaries(trigObj, operand2String, out isInDictionary);
					if (isInDictionary)
					{
						operand2 = possibleReturnValue;
					}
				}
			}
			else
			{
				operand2 = Calculate(trigObj, node.Right);
			}

            switch (node.OpTypeVal)
            {
                case OpType.Add:
                    if (operand1 is int)
                    {
                        if (operand2 is int)
                        {
                            return (int)operand1 + (int)operand2;
                        }
                        else if (operand2 is double)
                        {
                            return (int)operand1 + (double)operand2;
                        }
                        else if (operand2 is string)
                        {
                            return operand1 + (string)operand2;
                        }
                        else if (operand2 is UInt64)
                        {
                            return Convert.ToUInt64(operand1) + (UInt64)operand2;
                        }
                    }
                    else if (operand1 is double)
                    {
                        if (operand2 is int)
                        {
                            return (double)operand1 + (int)operand2;
                        }
                        else if (operand2 is double)
                        {
                            return (double)operand1 + (double)operand2;
                        }
                        else if (operand2 is string)
                        {
                            return operand1 + (string)operand2;
                        }
                        else if (operand2 is UInt64)
                        {
                            return (double)operand1 + (UInt64)operand2;
                        }
                    }
                    else if (operand1 is string)
                    {
                        return (string)operand1 + operand2;
                    }
                    else if (operand1 is UInt64)
                    {
                        if (operand2 is int)
                        {
                            return (UInt64)operand1 + (UInt64)operand2;
                        }
                        else if (operand2 is double)
                        {
                            return (UInt64)operand1 + (double)operand2;
                        }
                        else if (operand2 is string)
                        {
                            return operand1 + (string)operand2;
                        }
                        else if (operand2 is UInt64)
                        {
                            return (UInt64)operand1 + (UInt64)operand2;
                        }
                    }
                    else if (operand2 is string)
                    {
                        return operand1 + (string)operand2;
                    }
                    else if (operand1 is DateTime)
                    {
                        if (operand2 is TimeSpan)
                        {
                            return (DateTime)operand1 + (TimeSpan)operand2;
                        }
                    }
                    break;
                
                
                case OpType.Func:
                    // evaluate the function, if it isn't one of the 4 "primitives", then call return ToString on it.
				    Object output = ((FunctionNode)node.Value).Execute(trigObj, true);
				    if (output is int || output is double || output is string || output is UInt64)
				    {
					    return output;
				    }
				    //if (output is Mobile) return ((Mobile)output).Serial;
				    //if (output is Item) return ((Item)output).Serial;
				    return output.ToString();
                
                case OpType.Sub:
                    if (operand1 is string)
				    {
					    throw new UberScriptException("attempted to subtract using a string!:" + operand1);
				    }
				    if (operand2 is string)
				    {
					    throw new UberScriptException("attempted to subtract using a string!:" + operand2);
				    }
				    if (operand1 is int)
				    {
					    if (operand2 is int)
					    {
						    return (int)operand1 - (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (int)operand1 - (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return Convert.ToUInt64(operand1) - (UInt64)operand2;
					    }
				    }
				    else if (operand1 is double)
				    {
					    if (operand2 is int)
					    {
						    return (double)operand1 - (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (double)operand1 - (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (double)operand1 - (UInt64)operand2;
					    }
				    }
				    else if (operand1 is UInt64)
				    {
					    if (operand2 is int)
					    {
						    return (UInt64)operand1 - (UInt64)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (UInt64)operand1 - (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (UInt64)operand1 - (UInt64)operand2;
					    }
				    }
				    else if (operand1 is DateTime)
				    {
					    if (operand2 is DateTime)
					    {
						    return (DateTime)operand1 - (DateTime)operand2;
					    }
					    else if (operand2 is TimeSpan)
					    {
						    return (DateTime)operand1 - (TimeSpan)operand2;
					    }
				    }
                    break;
                
                
                case OpType.Mul:
                    if (operand1 is string)
				    {
					    throw new UberScriptException("attempted to multiply using a string!:" + operand1);
				    }
				    if (operand2 is string)
				    {
					    throw new UberScriptException("attempted to multiply using a string!:" + operand2);
				    }
				    if (operand1 is int)
				    {
					    if (operand2 is int)
					    {
						    return (int)operand1 * (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (int)operand1 * (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return Convert.ToUInt64(operand1) * (UInt64)operand2;
					    }
				    }
				    else if (operand1 is double)
				    {
					    if (operand2 is int)
					    {
						    return (double)operand1 * (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (double)operand1 * (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (double)operand1 * (UInt64)operand2;
					    }
				    }
				    else if (operand1 is UInt64)
				    {
					    if (operand2 is int)
					    {
						    return (UInt64)operand1 * (UInt64)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (UInt64)operand1 * (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (UInt64)operand1 * (UInt64)operand2;
					    }
				    }
                    break;


                case OpType.GThan:
                    if (operand1 == null || operand2 == null)
				    {
					    throw new UberScriptException("GThan had null argument!");
				    }
				    if (operand1 is string)
				    {
					    throw new UberScriptException("attempted to GThan using a string!:" + operand1);
				    }
				    if (operand2 is string)
				    {
					    throw new UberScriptException("attempted to GThan using a string!:" + operand2);
				    }
				    if (operand1 is int)
				    {
					    if (operand2 is int)
					    {
						    return (int)operand1 > (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (int)operand1 > (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return Convert.ToUInt64(operand1) > (UInt64)operand2;
					    }
				    }
				    else if (operand1 is double)
				    {
					    if (operand2 is int)
					    {
						    return (double)operand1 > (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (double)operand1 > (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (double)operand1 > (UInt64)operand2;
					    }
				    }
				    else if (operand1 is UInt64)
				    {
					    if (operand2 is int)
					    {
						    return (UInt64)operand1 > (UInt64)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (UInt64)operand1 > (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (UInt64)operand1 > (UInt64)operand2;
					    }
				    }
				    else if (operand1 is DateTime)
				    {
					    if (operand2 is DateTime)
					    {
						    return (DateTime)operand1 > (DateTime)operand2;
					    }
				    }
                    break;


                case OpType.LThan:
                    if (operand1 == null || operand2 == null)
				    {
					    throw new UberScriptException("LThan had null argument!");
				    }
				    if (operand1 is string)
				    {
					    throw new UberScriptException("attempted to LThan using a string!:" + operand1);
				    }
				    if (operand2 is string)
				    {
					    throw new UberScriptException("attempted to LThan using a string!:" + operand2);
				    }
				    if (operand1 is int)
				    {
					    if (operand2 is int)
					    {
						    return (int)operand1 < (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (int)operand1 < (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return Convert.ToUInt64(operand1) < (UInt64)operand2;
					    }
				    }
				    else if (operand1 is double)
				    {
					    if (operand2 is int)
					    {
						    return (double)operand1 < (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (double)operand1 < (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (double)operand1 < (UInt64)operand2;
					    }
				    }
				    else if (operand1 is UInt64)
				    {
					    if (operand2 is int)
					    {
						    return (UInt64)operand1 < (UInt64)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (UInt64)operand1 < (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (UInt64)operand1 < (UInt64)operand2;
					    }
				    }
				    else if (operand1 is DateTime)
				    {
					    if (operand2 is DateTime)
					    {
						    return (DateTime)operand1 < (DateTime)operand2;
					    }
				    }
                    break;


                case OpType.GThanOrEqualTo:
                    if (operand1 == null || operand2 == null)
				    {
					    throw new UberScriptException("GThanOrEqualTo had null argument!");
				    }
				    if (operand1 is string)
				    {
					    throw new UberScriptException("attempted to GThanOrEqualTo using a string!:" + operand1);
				    }
				    if (operand2 is string)
				    {
					    throw new UberScriptException("attempted to GThanOrEqualTo using a string!:" + operand2);
				    }
				    if (operand1 is int)
				    {
					    if (operand2 is int)
					    {
						    return (int)operand1 >= (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (int)operand1 >= (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return Convert.ToUInt64(operand1) >= (UInt64)operand2;
					    }
				    }
				    else if (operand1 is double)
				    {
					    if (operand2 is int)
					    {
						    return (double)operand1 >= (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (double)operand1 >= (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (double)operand1 >= (UInt64)operand2;
					    }
				    }
				    else if (operand1 is UInt64)
				    {
					    if (operand2 is int)
					    {
						    return (UInt64)operand1 >= (UInt64)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (UInt64)operand1 >= (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (UInt64)operand1 >= (UInt64)operand2;
					    }
				    }
				    else if (operand1 is DateTime)
				    {
					    if (operand2 is DateTime)
					    {
						    return (DateTime)operand1 >= (DateTime)operand2;
					    }
				    }
                    break;


                case OpType.LThanOrEqualTo:
                    if (operand1 == null || operand2 == null)
				    {
					    throw new UberScriptException("LThanOrEqualTo had null argument!");
				    }
				    if (operand1 is string)
				    {
					    throw new UberScriptException("attempted to LThanOrEqualTo using a string!:" + operand1);
				    }
				    if (operand2 is string)
				    {
					    throw new UberScriptException("attempted to LThanOrEqualTo using a string!:" + operand2);
				    }
				    if (operand1 is int)
				    {
					    if (operand2 is int)
					    {
						    return (int)operand1 <= (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (int)operand1 <= (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return Convert.ToUInt64(operand1) <= (UInt64)operand2;
					    }
				    }
				    else if (operand1 is double)
				    {
					    if (operand2 is int)
					    {
						    return (double)operand1 <= (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (double)operand1 <= (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (double)operand1 <= (UInt64)operand2;
					    }
				    }
				    else if (operand1 is UInt64)
				    {
					    if (operand2 is int)
					    {
						    return (UInt64)operand1 <= (UInt64)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (UInt64)operand1 <= (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (UInt64)operand1 <= (UInt64)operand2;
					    }
				    }
				    else if (operand1 is DateTime)
				    {
					    if (operand2 is DateTime)
					    {
						    return (DateTime)operand1 <= (DateTime)operand2;
					    }
				    }
                    break;


                case OpType.EqualTo:
                    if (operand1 == operand2)
				    {
					    return true;
				    }
				    if (operand1 != null && operand2 == null)
				    {
					    return false;
				    }
				    if (operand1 == null && operand2 != null)
				    {
					    return false;
				    }
				    if (operand1 is string && !(operand2 is string))
				    {
					    return ((string)operand1).ToLower() == (operand2 == null ? "null" : operand2.ToString().ToLower());
				    }
				    if (!(operand1 is string) && operand2 is string)
				    {
					    return (operand1 == null ? "null" : operand1.ToString().ToLower()) == ((string)operand2).ToLower();
				    }
				    if (operand1 is string && operand2 is string)
				    {
					    return ((string)operand1).ToLower() == ((string)operand2).ToLower();
				    }
				    if (operand1 is int)
				    {
					    if (operand2 is int)
					    {
						    return (int)operand1 == (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (int)operand1 == (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return Convert.ToUInt64(operand1) == (UInt64)operand2;
					    }
				    }
				    else if (operand1 is double)
				    {
					    if (operand2 is int)
					    {
						    return (double)operand1 == (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (double)operand1 == (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (double)operand1 == (UInt64)operand2;
					    }
				    }
				    else if (operand1 is UInt64)
				    {
					    if (operand2 is int)
					    {
						    return (UInt64)operand1 == (UInt64)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (UInt64)operand1 == (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (UInt64)operand1 == (UInt64)operand2;
					    }
				    }
				    else if (operand1 is DateTime)
				    {
					    if (operand2 is DateTime)
					    {
						    return (DateTime)operand1 == (DateTime)operand2;
					    }
				    }
				    else
				    {
					    return operand1.Equals(operand2); // could be objects
				    }
                    break;


                case OpType.NotEqualTo:
				    if (operand1 == operand2)
				    {
					    return false;
				    }
				    if (operand1 != null && operand2 == null)
				    {
					    return true;
				    }
				    if (operand1 == null && operand2 != null)
				    {
					    return true;
				    }
				    if (operand1 is string && !(operand2 is string))
				    {
					    return ((string)operand1).ToLower() == (operand2 == null ? "null" : operand2.ToString().ToLower());
				    }
				    if (!(operand1 is string) && operand2 is string)
				    {
					    return (operand1 == null ? "null" : operand1.ToString().ToLower()) == ((string)operand2).ToLower();
				    }
				    if (operand1 is string && operand2 is string)
				    {
					    return ((string)operand1).ToLower() != ((string)operand2).ToLower();
				    }
				    if (operand1 is int)
				    {
					    if (operand2 is int)
					    {
						    return (int)operand1 != (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (int)operand1 != (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return Convert.ToUInt64(operand1) != (UInt64)operand2;
					    }
				    }
				    else if (operand1 is double)
				    {
					    if (operand2 is int)
					    {
						    return (double)operand1 != (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (double)operand1 != (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (double)operand1 != (UInt64)operand2;
					    }
				    }
				    else if (operand1 is UInt64)
				    {
					    if (operand2 is int)
					    {
						    return (UInt64)operand1 != (UInt64)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (UInt64)operand1 != (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (UInt64)operand1 != (UInt64)operand2;
					    }
				    }
				    else if (operand1 is DateTime)
				    {
					    if (operand2 is DateTime)
					    {
						    return (DateTime)operand1 != (DateTime)operand2;
					    }
				    }
				    else
				    {
					    return !operand1.Equals(operand2); // could be objects
				    }
                    break;
                
                
                case OpType.And:
                    // if we have reached this point, then we already know that operand1 is true!
				    // (because right after finding the first operand we check whether it's false or not)
				    if (!(operand2 is bool))
				    {
					    throw new UberScriptException("Cannot use && operator between non booleans: " + operand1 + " " + operand2);
				    }
				    return operand2;
                
                
                case OpType.Or:
                    // if we have reached this point, then we already know that operand1 is false!
				    // (because right after finding the first operand we check whether it's true or not)
				    if (!(operand2 is bool))
				    {
					    throw new UberScriptException("Cannot use || operator between non booleans: " + operand1 + " " + operand2);
				    }
				    return (bool)operand2;

                    
                case OpType.Div:
                    if (operand1 is string)
				    {
					    throw new UberScriptException("attempted to multiply using a string!:" + operand1);
				    }
				    if (operand2 is string)
				    {
					    throw new UberScriptException("attempted to multiply using a string!:" + operand2);
				    }
				    if (operand1 is int)
				    {
					    if (operand2 is int)
					    {
						    return (int)operand1 / (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (int)operand1 / (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return Convert.ToUInt64(operand1) / (UInt64)operand2;
					    }
				    }
				    else if (operand1 is double)
				    {
					    if (operand2 is int)
					    {
						    return (double)operand1 / (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (double)operand1 / (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (double)operand1 / (UInt64)operand2;
					    }
				    }
				    else if (operand1 is UInt64)
				    {
					    if (operand2 is int)
					    {
						    return (UInt64)operand1 / (UInt64)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (UInt64)operand1 / (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (UInt64)operand1 / (UInt64)operand2;
					    }
				    }
                    break;

                case OpType.Pow:
                    if (operand1 is string)
				    {
					    throw new UberScriptException("attempted to multiply using a string!:" + operand1);
				    }
				    if (operand2 is string)
				    {
					    throw new UberScriptException("attempted to multiply using a string!:" + operand2);
				    }
				    if (operand1 is int)
				    {
					    if (operand2 is int)
					    {
						    return Math.Pow((int)operand1, (int)operand2);
					    }
					    else if (operand2 is double)
					    {
						    return Math.Pow((int)operand1, (double)operand2);
					    }
					    else if (operand2 is UInt64)
					    {
						    return Math.Pow(Convert.ToUInt64(operand1), (UInt64)operand2);
					    }
				    }
				    else if (operand1 is double)
				    {
					    if (operand2 is int)
					    {
						    return Math.Pow((double)operand1, (int)operand2);
					    }
					    else if (operand2 is double)
					    {
						    return Math.Pow((double)operand1, (double)operand2);
					    }
					    else if (operand2 is UInt64)
					    {
						    return Math.Pow((double)operand1, (UInt64)operand2);
					    }
				    }
				    else if (operand1 is UInt64)
				    {
					    if (operand2 is int)
					    {
						    return Math.Pow((UInt64)operand1, (UInt64)operand2);
					    }
					    else if (operand2 is double)
					    {
						    return Math.Pow((UInt64)operand1, (double)operand2);
					    }
					    else if (operand2 is UInt64)
					    {
						    return Math.Pow((UInt64)operand1, (UInt64)operand2);
					    }
				    }
                    break;
                case OpType.Mod:
                    if (operand1 is string)
				    {
					    throw new UberScriptException("attempted to multiply using a string!:" + operand1);
				    }
				    if (operand2 is string)
				    {
					    throw new UberScriptException("attempted to multiply using a string!:" + operand2);
				    }
				    if (operand1 is int)
				    {
					    if (operand2 is int)
					    {
						    return (int)operand1 % (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (int)operand1 % (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return Convert.ToUInt64(operand1) % (UInt64)operand2;
					    }
				    }
				    else if (operand1 is double)
				    {
					    if (operand2 is int)
					    {
						    return (double)operand1 % (int)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (double)operand1 % (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (double)operand1 % (UInt64)operand2;
					    }
				    }
				    else if (operand1 is UInt64)
				    {
					    if (operand2 is int)
					    {
						    return (UInt64)operand1 % (UInt64)operand2;
					    }
					    else if (operand2 is double)
					    {
						    return (UInt64)operand1 % (double)operand2;
					    }
					    else if (operand2 is UInt64)
					    {
						    return (UInt64)operand1 % (UInt64)operand2;
					    }
				    }
                    break;
            }

			throw new UberScriptException("Calculate MathNode did not have an assigned OpType!: value=" + node.Value);
		}