示例#1
0
        private static List <Variable> Split(ParsingScript script, char[] to)
        {
            List <Variable> listToMerge = new List <Variable>(16);

            if (!script.StillValid() || to.Contains(script.Current))
            {
                listToMerge.Add(Variable.EmptyInstance);
                script.Forward();
                return(listToMerge);
            }

            StringBuilder item            = new StringBuilder();
            int           arrayIndexDepth = 0;
            bool          inQuotes        = false;
            int           negated         = 0;

            string rest = script.Rest;

            if (rest == "b[a[0]];")
            {
                int stop = 1;
            }

            do // Main processing cycle of the first part.
            {
                string negateSymbol = Utils.IsNotSign(script.Rest);
                if (negateSymbol != null && !inQuotes)
                {
                    negated++;
                    script.Forward(negateSymbol.Length);
                    continue;
                }

                char ch = script.CurrentAndForward();
                CheckQuotesIndices(script, ch, ref inQuotes, ref arrayIndexDepth);
                string action = null;

                bool keepCollecting = inQuotes || arrayIndexDepth > 0 ||
                                      StillCollecting(item.ToString(), to, script, ref action);
                if (keepCollecting)
                {
                    // The char still belongs to the previous operand.
                    item.Append(ch);

                    bool goForMore = script.StillValid() &&
                                     (inQuotes || arrayIndexDepth > 0 || !to.Contains(script.Current));
                    if (goForMore)
                    {
                        continue;
                    }
                }

                if (SkipOrAppendIfNecessary(item, ch, to))
                {
                    continue;
                }
                string token = item.ToString();
                CheckConsistency(token, listToMerge, script);

                script.MoveForwardIf(Constants.SPACE);

                if (action != null && action.Length > 1)
                {
                    script.Forward(action.Length - 1);
                }

                // We are done getting the next token. The getValue() call below may
                // recursively call loadAndCalculate(). This will happen if extracted
                // item is a function or if the next item is starting with a START_ARG '('.
                ParserFunction func    = new ParserFunction(script, token, ch, ref action);
                Variable       current = func.GetValue(script);

                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 (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(listToMerge);
                }

                Variable cell = current.Clone();
                cell.Action = action;

                bool addIt = UpdateIfBool(script, ref cell, ref listToMerge);
                if (addIt)
                {
                    listToMerge.Add(cell);
                }
                item.Clear();
            } while (script.StillValid() &&
                     (inQuotes || arrayIndexDepth > 0 || !to.Contains(script.Current)));

            // This happens when called recursively inside of the math expression:
            script.MoveForwardIf(Constants.END_ARG);

            return(listToMerge);
        }
示例#2
0
 protected override Variable Evaluate(ParsingScript script)
 {
     return(new Variable(m_value));
 }
示例#3
0
        protected override Variable Evaluate(ParsingScript script)
        {
            Variable result = Interpreter.Instance.ProcessIf(script);

            return(result);
        }
示例#4
0
        public static bool ExtractParameterNames(List <Variable> args, string functionName, ParsingScript script)
        {
            CustomFunction custFunc = ParserFunction.GetFunction(functionName, script) as CustomFunction;

            if (custFunc == null)
            {
                return(false);
            }

            var realArgs = custFunc.RealArgs;

            for (int i = 0; i < args.Count && i < realArgs.Length; i++)
            {
                string name = args[i].CurrentAssign;
                args[i].ParamName = string.IsNullOrWhiteSpace(name) ? realArgs[i] : name;
            }
            return(true);
        }
示例#5
0
        public static string GetToken(ParsingScript script, char[] to)

        {
            char curr = script.TryCurrent();
            char prev = script.TryPrev();

            if (!to.Contains(Constants.SPACE))
            {
                // Skip a leading space unless we are inside of quotes
                while (curr == Constants.SPACE && prev != Constants.QUOTE)
                {
                    script.Forward();
                    curr = script.TryCurrent();
                    prev = script.TryPrev();
                }
            }

            // String in quotes
            bool inQuotes = curr == Constants.QUOTE;

            if (inQuotes)
            {
                int qend = script.Find(Constants.QUOTE, script.Pointer + 1);
                if (qend == -1)
                {
                    throw new ArgumentException("Unmatched quotes in [" +
                                                script.FromPrev() + "]");
                }
                string result = script.Substr(script.Pointer + 1, qend - script.Pointer - 1);
                script.Pointer = qend + 1;
                return(result);
            }

            script.MoveForwardIf(Constants.QUOTE);

            int end = script.FindFirstOf(to);

            end = end < 0 ? script.Size() : end;

            // Skip found characters that have a backslash before.
            while (end > 0 && end + 1 < script.Size() &&
                   script.String[end - 1] == '\\')
            {
                end = script.FindFirstOf(to, end + 1);
            }

            end = end < 0 ? script.Size() : end;

            if (script.At(end - 1) == Constants.QUOTE)
            {
                end--;
            }

            string var = script.Substr(script.Pointer, end - script.Pointer);

            // \"yes\" --> "yes"
            var            = var.Replace("\\\"", "\"");
            script.Pointer = end;

            script.MoveForwardIf(Constants.QUOTE, Constants.SPACE);

            return(var);
        }
示例#6
0
        public virtual Task <Variable> GetProperty(string sPropertyName, List <Variable> args = null, ParsingScript script = null)
        {
            sPropertyName = Variable.GetActualPropertyName(sPropertyName, GetProperties());
            switch (sPropertyName)
            {
            case "Name": return(Task.FromResult(GetNameProperty()));

            case "Color": return(Task.FromResult(GetColorProperty()));

            case "Translate":
                return(Task.FromResult(
                           args != null && args.Count > 0 ?
                           Translate(args[0]) : Variable.EmptyInstance));

            default:
                return(Task.FromResult(Variable.EmptyInstance));
            }
        }
示例#7
0
 protected override Variable Evaluate(ParsingScript script)
 {
     return(new Variable(Math.Sqrt(1 / 2)));
 }
示例#8
0
 protected virtual Task <Variable> EvaluateAsync(ParsingScript script)
 {
     // If not overriden, the non-sync version will be called.
     return(Task.FromResult(Evaluate(script)));
 }
示例#9
0
        public static bool IsNumericFunction(string paramName, ParsingScript script = null)
        {
            ParserFunction function = ParserFunction.GetFunction(paramName, script);

            return(function is INumericFunction);
        }
示例#10
0
 public async Task <Variable> GetValueAsync(ParsingScript script)
 {
     return(await m_impl.EvaluateAsync(script));
 }
示例#11
0
 protected virtual Variable Evaluate(ParsingScript script)
 {
     // The real implementation will be in the derived classes.
     return(new Variable());
 }
示例#12
0
 public Variable GetValue(ParsingScript script)
 {
     return(m_impl.Evaluate(script));
 }
示例#13
0
        public static ParserFunction GetFunctionNamespace(string name, string nameSpace, ParsingScript script)
        {
            if (string.IsNullOrWhiteSpace(nameSpace))
            {
                return(null);
            }

            StackLevel level;

            if (!s_namespaces.TryGetValue(nameSpace, out level))
            {
                return(null);
            }

            var            vars = level.Variables;
            ParserFunction impl;

            if (vars.TryGetValue(name, out impl))
            {
                return(impl);
            }

            if (!name.StartsWith(nameSpace, StringComparison.OrdinalIgnoreCase))
            {
                name = nameSpace + "." + name;
                if (vars.TryGetValue(name, out impl))
                {
                    return(impl);
                }
                if (s_functions.TryGetValue(name, out impl))
                {
                    return(impl);
                }
            }

            return(null);
        }
示例#14
0
        public static ParserFunction GetFunctionNamespace(string name, ParsingScript script)
        {
            ParserFunction result = GetFunctionNamespace(name, s_namespace, script);

            return(result);
        }
示例#15
0
        protected override Variable Evaluate(ParsingScript script)
        {
            List <Variable> args = script.GetFunctionArgs();

            Utils.CheckArgs(args.Count, 1, m_name);
            string source    = Utils.GetSafeString(args, 0);
            string argument  = Utils.GetSafeString(args, 1);
            string parameter = Utils.GetSafeString(args, 2, "case");
            int    startFrom = Utils.GetSafeInt(args, 3, 0);
            int    length    = Utils.GetSafeInt(args, 4, source.Length);

            StringComparison comp = StringComparison.Ordinal;

            if (parameter.Equals("nocase") || parameter.Equals("no_case"))
            {
                comp = StringComparison.OrdinalIgnoreCase;
            }

            source   = source.Replace("\\\"", "\"");
            argument = argument.Replace("\\\"", "\"");

            switch (m_mode)
            {
            case Mode.CONTAINS:
                return(new Variable(source.IndexOf(argument, comp) >= 0));

            case Mode.STARTS_WITH:
                return(new Variable(source.StartsWith(argument, comp)));

            case Mode.ENDS_WITH:
                return(new Variable(source.EndsWith(argument, comp)));

            case Mode.INDEX_OF:
                return(new Variable(source.IndexOf(argument, startFrom, comp)));

            case Mode.EQUALS:
                return(new Variable(source.Equals(argument, comp)));

            case Mode.REPLACE:
                return(new Variable(source.Replace(argument, parameter)));

            case Mode.UPPER:
                return(new Variable(source.ToUpper()));

            case Mode.LOWER:
                return(new Variable(source.ToLower()));

            case Mode.TRIM:
                return(new Variable(source.Trim()));

            case Mode.SUBSTRING:
                startFrom = Utils.GetSafeInt(args, 1, 0);
                length    = Utils.GetSafeInt(args, 2, source.Length);
                length    = Math.Min(length, source.Length - startFrom);
                return(new Variable(source.Substring(startFrom, length)));

            case Mode.BEETWEEN:
            case Mode.BEETWEEN_ANY:
                int index1 = source.IndexOf(argument);
                int index2 = m_mode == Mode.BEETWEEN ? source.IndexOf(parameter, index1 + 1) :
                             source.IndexOfAny(parameter.ToCharArray(), index1 + 1);
                startFrom = index1 + argument.Length;

                if (index1 < 0 || index2 < index1)
                {
                    throw new ArgumentException("Couldn't extract string between [" + argument +
                                                "] and [" + parameter + "] + from " + source);
                }
                string result = source.Substring(startFrom, index2 - startFrom);
                return(new Variable(result));
            }

            return(new Variable(-1));
        }
示例#16
0
 public static Variable SplitAndMerge(ParsingScript script)
 {
     return(SplitAndMerge(script, Constants.END_PARSE_ARRAY));
 }
示例#17
0
        protected override Variable Evaluate(ParsingScript script)
        {
            string dirname = (!script.StillValid() || script.Current == Constants.END_STATEMENT) ?
                             Directory.GetCurrentDirectory() :
                             Utils.GetToken(script, Constants.NEXT_OR_END_ARRAY);

            //List<Variable> results = Utils.GetPathnames(dirname);
            List <Variable> results = new List <Variable>();

            int index = dirname.IndexOf('*');

            if (index < 0 && !Directory.Exists(dirname) && !File.Exists(dirname))
            {
                throw new ArgumentException("Directory [" + dirname + "] doesn't exist");
            }

            string pattern = Constants.ALL_FILES;

            try {
                string dir = index < 0 ? Path.GetFullPath(dirname) : dirname;
                if (File.Exists(dir))
                {
                    FileInfo fi = new FileInfo(dir);
                    Interpreter.Instance.AppendOutput(Utils.GetPathDetails(fi, fi.Name), true);
                    results.Add(new Variable(fi.Name));
                    return(new Variable(results));
                }
                // Special dealing if there is a pattern (only * is supported at the moment)
                if (index >= 0)
                {
                    pattern = Path.GetFileName(dirname);

                    if (index > 0)
                    {
                        string        prefix = dirname.Substring(0, index);
                        DirectoryInfo di     = Directory.GetParent(prefix);
                        dirname = di.FullName;
                    }
                    else
                    {
                        dirname = ".";
                    }
                }
                dir = Path.GetFullPath(dirname);
                // First get contents of the directory (unless there is a pattern)
                DirectoryInfo dirInfo = new DirectoryInfo(dir);

                if (pattern == Constants.ALL_FILES)
                {
                    Interpreter.Instance.AppendOutput(Utils.GetPathDetails(dirInfo, "."), true);
                    if (dirInfo.Parent != null)
                    {
                        Interpreter.Instance.AppendOutput(Utils.GetPathDetails(dirInfo.Parent, ".."), true);
                    }
                }

                // Then get contents of all of the files in the directory
                FileInfo[] fileNames = dirInfo.GetFiles(pattern);
                foreach (FileInfo fi in fileNames)
                {
                    try {
                        Interpreter.Instance.AppendOutput(Utils.GetPathDetails(fi, fi.Name), true);
                        results.Add(new Variable(fi.Name));
                    } catch (Exception) {
                        continue;
                    }
                }

                // Then get contents of all of the subdirs in the directory
                DirectoryInfo[] dirInfos = dirInfo.GetDirectories(pattern);
                foreach (DirectoryInfo di in dirInfos)
                {
                    try {
                        Interpreter.Instance.AppendOutput(Utils.GetPathDetails(di, di.Name), true);
                        results.Add(new Variable(di.Name));
                    } catch (Exception) {
                        continue;
                    }
                }
            } catch (Exception exc) {
                throw new ArgumentException("Couldn't list directory: " + exc.Message);
            }

            return(new Variable(results));
        }
示例#18
0
 public static async Task <Variable> SplitAndMergeAsync(ParsingScript script)
 {
     return(await SplitAndMergeAsync(script, Constants.END_PARSE_ARRAY));
 }
示例#19
0
        internal Variable ProcessTry(ParsingScript script)
        {
            int       startTryCondition = script.Pointer - 1;
            int       currentStackLevel = ParserFunction.GetCurrentStackLevel();
            Exception exception         = null;

            Variable result = null;

            bool alreadyInTryBlock = script.InTryBlock;

            script.InTryBlock = true;
            try
            {
                result = ProcessBlock(script);
            }
            catch (Exception exc)
            {
                exception = exc;
            }
            finally
            {
                script.InTryBlock = alreadyInTryBlock;
            }

            if (exception != null || result.IsReturn ||
                result.Type == Variable.VarType.BREAK ||
                result.Type == Variable.VarType.CONTINUE)
            {
                // We are here from the middle of the try-block either because
                // an exception was thrown or because of a Break/Continue. Skip it.
                script.Pointer = startTryCondition;
                SkipBlock(script);
            }

            string catchToken = Utils.GetNextToken(script);

            script.Forward(); // skip opening parenthesis
                              // The next token after the try block must be a catch.
            if (!Constants.CATCH_LIST.Contains(catchToken))
            {
                throw new ArgumentException("Expecting a 'catch()' but got [" +
                                            catchToken + "]");
            }

            string exceptionName = Utils.GetNextToken(script);

            script.Forward(); // skip closing parenthesis

            if (exception != null)
            {
                string excStack = CreateExceptionStack(exceptionName, currentStackLevel);
                ParserFunction.InvalidateStacksAfterLevel(currentStackLevel);

                GetVarFunction excMsgFunc = new GetVarFunction(new Variable(exception.Message));
                ParserFunction.AddGlobalOrLocalVariable(exceptionName, excMsgFunc);
                GetVarFunction excStackFunc = new GetVarFunction(new Variable(excStack));
                ParserFunction.AddGlobalOrLocalVariable(exceptionName + ".Stack", excStackFunc);

                result = ProcessBlock(script);
                ParserFunction.PopLocalVariable(exceptionName);
            }
            else
            {
                SkipBlock(script);
            }

            SkipRestBlocks(script);
            return(result);
        }
示例#20
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);
        }
示例#21
0
 protected override Variable Evaluate(ParsingScript script)
 {
     return(new Variable(Math.Log10(Math.E)));
 }
示例#22
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;
            }
        }
示例#23
0
        public static int ConvertToInt(object obj, ParsingScript script = null)
        {
            double num = ConvertToDouble(obj, script);

            return((int)num);
        }
示例#24
0
        protected override Variable Evaluate(ParsingScript script)
        {
            string path = Directory.GetCurrentDirectory();

            return(new Variable(path));
        }
示例#25
0
 protected override Variable Evaluate(ParsingScript script)
 {
     return(new Variable(Variable.VarType.CONTINUE));
 }
示例#26
0
        protected override Variable Evaluate(ParsingScript script)
        {
            int threadID = Thread.CurrentThread.ManagedThreadId;

            return(new Variable(threadID.ToString()));
        }
示例#27
0
 protected override Variable Evaluate(ParsingScript script)
 {
     return(script.ExecuteTo(Constants.END_ARG));
 }
示例#28
0
 protected override Variable Evaluate(ParsingScript script)
 {
     Console.Clear();
     return(Variable.EmptyInstance);
 }
示例#29
0
 protected override Variable Evaluate(ParsingScript script)
 {
     return(Interpreter.Instance.ProcessFor(script));
 }
示例#30
0
 bool Completed(ParsingScript debugging)
 {
     return((LastResult != null && LastResult.IsReturn) ||
            !debugging.StillValid());
 }