예제 #1
0
 public static void UpdateFunction(Variable variable)
 {
     UpdateFunction(variable.ParsingToken, new GetVarFunction(variable));
 }
예제 #2
0
        public Variable Run(List <Variable> args)
        {
            RegisterArguments(args);

            List <string>         argsStr    = new List <string>();
            List <double>         argsNum    = new List <double>();
            List <List <string> > argsArrStr = new List <List <string> >();
            List <List <double> > argsArrNum = new List <List <double> >();
            List <Dictionary <string, string> > argsMapStr = new List <Dictionary <string, string> >();
            List <Dictionary <string, double> > argsMapNum = new List <Dictionary <string, double> >();
            List <Variable> argsVar = new List <Variable>();

            for (int i = 0; i < m_args.Length; i++)
            {
                Variable typeVar = m_argsMap[m_args[i]];
                if (typeVar.Type == Variable.VarType.STRING)
                {
                    argsStr.Add(args[i].AsString());
                }
                else if (typeVar.Type == Variable.VarType.NUMBER)
                {
                    argsNum.Add(args[i].AsDouble());
                }
                else if (typeVar.Type == Variable.VarType.ARRAY_STR)
                {
                    List <string> subArrayStr = new List <string>();
                    var           tuple       = args[i].Tuple;
                    for (int j = 0; j < tuple.Count; j++)
                    {
                        subArrayStr.Add(tuple[j].AsString());
                    }
                    argsArrStr.Add(subArrayStr);
                }
                else if (typeVar.Type == Variable.VarType.ARRAY_NUM)
                {
                    List <double> subArrayNum = new List <double>();
                    var           tuple       = args[i].Tuple;
                    for (int j = 0; j < tuple.Count; j++)
                    {
                        subArrayNum.Add(tuple[j].AsDouble());
                    }
                    argsArrNum.Add(subArrayNum);
                }
                else if (typeVar.Type == Variable.VarType.MAP_STR)
                {
                    Dictionary <string, string> subMapStr = new Dictionary <string, string>();
                    var tuple = args[i].Tuple;
                    var keys  = args[i].GetKeys();
                    for (int j = 0; j < tuple.Count; j++)
                    {
                        subMapStr.Add(keys[j], tuple[j].AsString());
                    }
                    argsMapStr.Add(subMapStr);
                }
                else if (typeVar.Type == Variable.VarType.MAP_NUM)
                {
                    Dictionary <string, double> subMapNum = new Dictionary <string, double>();
                    var tuple = args[i].Tuple;
                    var keys  = args[i].GetKeys();
                    for (int j = 0; j < tuple.Count; j++)
                    {
                        subMapNum.Add(keys[j], tuple[j].AsDouble());
                    }
                    argsMapNum.Add(subMapNum);
                }
                else if (typeVar.Type == Variable.VarType.VARIABLE)
                {
                    argsVar.Add(args[i]);
                }
            }

            Variable result = Precompiler.AsyncMode ?
                              m_precompiler.RunAsync(argsStr, argsNum, argsArrStr, argsArrNum, argsMapStr, argsMapNum, argsVar, false) :
                              m_precompiler.Run(argsStr, argsNum, argsArrStr, argsArrNum, argsMapStr, argsMapNum, argsVar, false);

            ParserFunction.PopLocalVariables(m_stackLevel.Id);

            return(result);
        }
예제 #3
0
        public static async Task <double> GetDouble(string paramName, ParsingScript script = null)
        {
            Variable result = await GetVar(paramName, script);

            return(result.AsDouble());
        }
예제 #4
0
 static bool CanMergeCells(Variable leftCell, Variable rightCell)
 {
     return(GetPriority(leftCell.Action) >= GetPriority(rightCell.Action));
 }
예제 #5
0
        private static void MergeNumbers(Variable leftCell, Variable rightCell, ParsingScript script)
        {
            if (rightCell.Type != Variable.VarType.NUMBER)
            {
                rightCell.Value = rightCell.AsDouble();
            }
            switch (leftCell.Action)
            {
            case "%":
                leftCell.Value %= rightCell.Value;
                break;

            case "*":
                leftCell.Value *= rightCell.Value;
                break;

            case "/":
                if (rightCell.Value == 0.0)
                {
                    throw new ArgumentException("Division by zero");
                }
                leftCell.Value /= rightCell.Value;
                break;

            case "+":
                if (rightCell.Type != Variable.VarType.NUMBER)
                {
                    leftCell.String = leftCell.AsString() + rightCell.String;
                }
                else
                {
                    leftCell.Value += rightCell.Value;
                }
                break;

            case "-":
                leftCell.Value -= rightCell.Value;
                break;

            case "<":
                leftCell.Value = Convert.ToDouble(leftCell.Value < rightCell.Value);
                break;

            case ">":
                leftCell.Value = Convert.ToDouble(leftCell.Value > rightCell.Value);
                break;

            case "<=":
                leftCell.Value = Convert.ToDouble(leftCell.Value <= rightCell.Value);
                break;

            case ">=":
                leftCell.Value = Convert.ToDouble(leftCell.Value >= rightCell.Value);
                break;

            case "==":
                leftCell.Value = Convert.ToDouble(leftCell.Value == rightCell.Value);
                break;

            case "!=":
                leftCell.Value = Convert.ToDouble(leftCell.Value != rightCell.Value);
                break;

            case "&":
                leftCell.Value = (int)leftCell.Value & (int)rightCell.Value;
                break;

            case "^":
                leftCell.Value = (int)leftCell.Value ^ (int)rightCell.Value;
                break;

            case "|":
                leftCell.Value = (int)leftCell.Value | (int)rightCell.Value;
                break;

            case "&&":
                leftCell.Value = Convert.ToDouble(
                    Convert.ToBoolean(leftCell.Value) && Convert.ToBoolean(rightCell.Value));
                break;

            case "||":
                leftCell.Value = Convert.ToDouble(
                    Convert.ToBoolean(leftCell.Value) || Convert.ToBoolean(rightCell.Value));
                break;

            case "**":
                leftCell.Value = Math.Pow(leftCell.Value, rightCell.Value);
                break;

            case ")":
                Utils.ThrowErrorMsg("Can't process last token [" + rightCell.Value + "] in the expression.",
                                    script, script.Current.ToString());
                break;

            default:
                Utils.ThrowErrorMsg("Can't process operation [" + leftCell.Action + "] in the expression.",
                                    script, leftCell.Action);
                break;
            }
        }
예제 #6
0
        static bool UpdateResult(ParsingScript script, char[] to, List <Variable> listToMerge, string token, bool negSign,
                                 ref Variable current, ref int negated, ref string action)
        {
            if (current == null)
            {
                current = Variable.EmptyInstance;
            }
            current.ParsingToken = token;

            if (negSign)
            {
                current = new Variable(-1 * current.Value);
            }

            if (negated > 0 && current.Type == Variable.VarType.NUMBER)
            {
                // If there has been a NOT sign, this is a boolean.
                // Use XOR (true if exactly one of the arguments is true).
                bool neg = !((negated % 2 == 0) ^ Convert.ToBoolean(current.Value));
                current = new Variable(Convert.ToDouble(neg));
                negated = 0;
            }

            if (script.Current == '.')
            {
                bool inQuotes        = false;
                int  arrayIndexDepth = 0;
                script.Forward();
                string property = ExtractNextToken(script, to, ref inQuotes, ref arrayIndexDepth, ref negated, out _, out action);

                Variable propValue = current.Type == Variable.VarType.ENUM ?
                                     current.GetEnumProperty(property, script) :
                                     current.GetProperty(property, script);
                current = propValue;
            }

            if (action == null)
            {
                action = UpdateAction(script, to);
            }
            else
            {
                script.MoveForwardIf(action[0]);
            }

            char next = script.TryCurrent(); // we've already moved forward
            bool done = listToMerge.Count == 0 &&
                        (next == Constants.END_STATEMENT ||
                         (action == Constants.NULL_ACTION && current.Type != Variable.VarType.NUMBER) ||
                         current.IsReturn);

            if (done)
            {
                if (action != null && action != Constants.END_ARG_STR)
                {
                    throw new ArgumentException("Action [" +
                                                action + "] without an argument.");
                }
                // If there is no numerical result, we are not in a math expression.
                listToMerge.Add(current);
                return(true);
            }

            Variable cell = current.Clone();

            cell.Action = action;

            bool addIt = UpdateIfBool(script, cell, (Variable newCell) => { cell = newCell; }, listToMerge, (List <Variable> var) => { listToMerge = var; });

            if (addIt)
            {
                listToMerge.Add(cell);
            }
            return(false);
        }