Beispiel #1
0
        internal Variable ProcessTry(ParsingScript script)
        {
            int       startTryCondition = script.Pointer - 1;
            int       currentStackLevel = ParserFunction.GetCurrentStackLevel();
            Exception exception         = null;

            Variable result = null;

            try {
                result = ProcessBlock(script);
            } catch (Exception exc) {
                exception = exc;
            }

            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);
        }
Beispiel #2
0
        public static void SkipRestExpr(ParsingScript script)
        {
            int  argRead  = 0;
            bool inQuotes = false;
            char previous = Constants.EMPTY;

            while (script.StillValid())
            {
                char currentChar = script.Current;
                if (inQuotes && currentChar != Constants.QUOTE)
                {
                    script.Forward();
                    continue;
                }

                switch (currentChar)
                {
                case Constants.QUOTE:
                    if (previous != '\\')
                    {
                        inQuotes = !inQuotes;
                    }
                    break;

                case Constants.START_ARG:
                    argRead++;
                    break;

                case Constants.END_ARG:
                    argRead--;
                    if (argRead < 0)
                    {
                        return;
                    }
                    break;

                case Constants.END_STATEMENT:
                    return;

                case Constants.TERNARY_OPERATOR:
                case Constants.NEXT_ARG:
                    if (argRead <= 0)
                    {
                        return;
                    }
                    break;

                default:
                    break;
                }

                script.Forward();
                previous = currentChar;
            }
        }
Beispiel #3
0
        protected override Variable Evaluate(ParsingScript script)
        {
            if (script.Substr().StartsWith(" .."))
            {
                script.Forward();
            }
            string newDir = Utils.GetStringOrVarValue(script);

            try {
                if (newDir == "..")
                {
                    string        pwd    = Directory.GetCurrentDirectory();
                    DirectoryInfo parent = Directory.GetParent(pwd);
                    if (parent == null)
                    {
                        throw new ArgumentException("No parent exists.");
                    }
                    newDir = parent.FullName;
                }
                if (newDir.Length == 0)
                {
                    newDir = Environment.GetEnvironmentVariable("HOME");
                }
                Directory.SetCurrentDirectory(newDir);

                newDir = Directory.GetCurrentDirectory();
            } catch (Exception exc) {
                throw new ArgumentException("Couldn't change directory: " + exc.Message);
            }

            return(new Variable(newDir));
        }
Beispiel #4
0
        public static Variable GetItem(ParsingScript script, bool eatLast = true)
        {
            script.MoveForwardIf(Constants.NEXT_ARG, Constants.SPACE);
            Utils.CheckNotEnd(script);

            bool inQuotes = script.Current == Constants.QUOTE;

            if (script.Current == Constants.START_GROUP)
            {
                // We are extracting a list between curly braces.
                script.Forward(); // Skip the first brace.
                bool     isList = true;
                Variable value  = new Variable();
                value.Tuple = GetArgs(script,
                                      Constants.START_GROUP, Constants.END_GROUP, out isList);
                return(value);
            }

            // A variable, a function, or a number.
            Variable var = script.Execute(Constants.NEXT_OR_END_ARRAY);

            //value = var.Clone();

            if (inQuotes)
            {
                script.MoveForwardIf(Constants.QUOTE);
            }
            if (eatLast)
            {
                script.MoveForwardIf(Constants.END_ARG, Constants.SPACE);
            }
            return(var);
        }
Beispiel #5
0
        internal Variable ProcessDoWhile(ParsingScript script)
        {
            int      startDoCondition = script.Pointer;
            bool     stillValid       = true;
            Variable result           = Variable.EmptyInstance;

            while (stillValid)
            {
                script.Pointer = startDoCondition;

                result = ProcessBlock(script);
                if (result.IsReturn || result.Type == Variable.VarType.BREAK)
                {
                    script.Pointer = startDoCondition;
                    break;
                }
                script.Forward(Constants.WHILE.Length + 1);
                Variable condResult = script.Execute(Constants.END_ARG_ARRAY);
                stillValid = Convert.ToBoolean(condResult.Value);
                if (!stillValid)
                {
                    break;
                }
            }

            SkipBlock(script);
            return(result.IsReturn ? result : Variable.EmptyInstance);
        }
        protected override Variable Evaluate(ParsingScript script)
        {
            // First check if this element is part of an array:
            if (script.TryPrev() == Constants.START_ARRAY)
            {
                // There is an index given - it must be for an element of the tuple.
                if (m_value.Tuple == null || m_value.Tuple.Count == 0)
                {
                    throw new ArgumentException("No tuple exists for the index");
                }

                if (m_arrayIndices == null)
                {
                    string startName = script.Substr(script.Pointer - 1);
                    m_arrayIndices = Utils.GetArrayIndices(ref startName, ref m_delta);
                }

                script.Forward(m_delta);

                Variable result = Utils.ExtractArrayElement(m_value, m_arrayIndices);
                return(result);
            }

            // Otherwise just return the stored value.
            return(m_value);
        }
Beispiel #7
0
        public Variable GetRefValue(string pointer, ParsingScript script)
        {
            if (string.IsNullOrWhiteSpace(pointer))
            {
                return(Variable.Undefined);
            }
            var refPointer = ParserFunction.GetVariable(pointer, null, true) as GetVarFunction;

            if (refPointer == null || string.IsNullOrWhiteSpace(refPointer.Value.Pointer))
            {
                return(Variable.Undefined);
            }

            var result = ParserFunction.GetVariable(refPointer.Value.Pointer, null, true);

            if (result is GetVarFunction)
            {
                return(((GetVarFunction)result).Value);
            }

            if (result is CustomFunction)
            {
                script.Forward();
                List <Variable> args = script.GetFunctionArgs();
                return(((CustomFunction)result).Run(args, script));
            }
            return(Variable.Undefined);
        }
Beispiel #8
0
        public static string GetBodyBetween(ParsingScript script, char open = Constants.START_ARG, char close = Constants.END_ARG)
        {
            // We are supposed to be one char after the beginning of the string, i.e.
            // we must not have the opening char as the first one.
            StringBuilder sb          = new StringBuilder(script.Size());
            int           braces      = 0;
            bool          inQuotes    = false;
            bool          inQuotes1   = false;
            bool          inQuotes2   = false;
            bool          checkBraces = true;
            char          prev        = Constants.EMPTY;
            char          prevprev    = Constants.EMPTY;

            for (; script.StillValid(); script.Forward())
            {
                char ch = script.Current;

                if (close != Constants.QUOTE)
                {
                    checkBraces = !inQuotes;
                    if (ch == Constants.QUOTE && !inQuotes1 && (prev != '\\' || prevprev == '\\'))
                    {
                        inQuotes = inQuotes2 = !inQuotes2;
                    }
                    if (ch == Constants.QUOTE1 && !inQuotes2 && (prev != '\\' || prevprev == '\\'))
                    {
                        inQuotes = inQuotes1 = !inQuotes1;
                    }
                }

                if (string.IsNullOrWhiteSpace(ch.ToString()) && sb.Length == 0)
                {
                    continue;
                }
                else if (checkBraces && ch == open)
                {
                    braces++;
                }
                else if (checkBraces && ch == close)
                {
                    braces--;
                }

                sb.Append(ch);
                prevprev = prev;
                prev     = ch;
                if (braces < 0)
                {
                    if (ch == close)
                    {
                        sb.Remove(sb.Length - 1, 1);
                    }
                    break;
                }
            }

            return(sb.ToString());
        }
Beispiel #9
0
        public static string ExtractNextToken(ParsingScript script, char[] to, ref bool inQuotes,
                                              ref int arrayIndexDepth, ref int negated, out char ch, out string action, bool throwExc = true)
        {
            StringBuilder item = new StringBuilder();

            ch     = Constants.EMPTY;
            action = null;
            do
            {
                string negateSymbol = Utils.IsNotSign(script.Rest);
                if (negateSymbol != null && !inQuotes)
                {
                    negated++;
                    script.Forward(negateSymbol.Length);
                    continue;
                }

                ch = script.CurrentAndForward();
                CheckQuotesIndices(script, ch, ref inQuotes, ref arrayIndexDepth);

                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;
                }
                break;
            }while (true);

            string result = item.ToString();

            result = result.Replace("\\\\", "\\");
            result = result.Replace("\\\"", "\"");
            result = result.Replace("\\'", "'");

            if (throwExc && string.IsNullOrWhiteSpace(result) && action != "++" && action != "--" &&
                Utils.IsAction(script.Prev) && Utils.IsAction(script.PrevPrev))
            {
                Utils.ThrowErrorMsg("Can't process token [" + script.PrevPrev + script.Prev + script.Current +
                                    "].", script, script.Current.ToString());
            }

            return(result);
        }
Beispiel #10
0
        internal Variable ProcessSwitch(ParsingScript script)
        {
            Variable switchValue = Utils.GetItem(script);

            script.Forward();

            Variable result  = Variable.EmptyInstance;
            var      caseSep = ":".ToCharArray();

            bool caseDone = false;

            while (script.StillValid())
            {
                var nextToken = Utils.GetBodySize(script, Constants.CASE, Constants.DEFAULT);
                if (string.IsNullOrEmpty(nextToken))
                {
                    break;
                }
                if (nextToken == Constants.DEFAULT && !caseDone)
                {
                    result = ProcessBlock(script);
                    break;
                }
                if (!caseDone)
                {
                    Variable caseValue = script.Execute(caseSep);
                    script.Forward();

                    if (switchValue.Type == caseValue.Type && switchValue.Equals(caseValue))
                    {
                        caseDone = true;
                        result   = ProcessBlock(script);
                        if (script.Prev == '}')
                        {
                            break;
                        }
                        script.Forward();
                    }
                }
            }
            script.MoveForwardIfNotPrevious('}');
            script.GoToNextStatement();
            return(result);
        }
Beispiel #11
0
        protected override Variable Evaluate(ParsingScript script)
        {
            Variable arg1 = script.ExecuteTo(Constants.NEXT_ARG);

            script.Forward(); // eat separation
            Variable arg2 = script.ExecuteTo(Constants.END_ARG);

            arg1.Value = Math.Pow(arg1.Value, arg2.Value);
            return(arg1);
        }
Beispiel #12
0
        async Task <string> ProcessRepl(string repl, string filename = "")
        {
            ReplMode = true;

            Dictionary <int, int> char2Line;
            string        script     = Utils.ConvertToScript(repl, out char2Line);
            ParsingScript tempScript = new ParsingScript(script, 0, char2Line);

            tempScript.OriginalScript = repl;
            tempScript.Debugger       = this;
            if (!string.IsNullOrWhiteSpace(filename))
            {
                tempScript.Filename = filename;
            }

            Variable result    = null;
            bool     excThrown = false;
            string   stringRes = "";

            try
            {
                while (tempScript.Pointer < script.Length)
                {
                    result = await DebuggerUtils.Execute(tempScript);

                    tempScript.GoToNextStatement();
                    while (tempScript.TryCurrent() == Constants.END_STATEMENT)
                    {
                        tempScript.Forward();
                    }
                }

                if (TrySendFile(result, tempScript, ref excThrown) || excThrown)
                {
                    return("");
                }

                stringRes = string.IsNullOrEmpty(Output) ? "" : Output + (Output.EndsWith("\n") ? "" : "\n");

                stringRes += result == null ? "" : result.AsString();
                stringRes += (stringRes.EndsWith("\n") ? "" : "\n");
            }
            catch (Exception exc)
            {
                Console.WriteLine("ProcessRepl Exception: " + exc);
                return(""); // The exception was already thrown and sent back.
            }
            finally
            {
                ReplMode = false;
            }


            return(stringRes);
        }
Beispiel #13
0
        protected override Variable Evaluate(ParsingScript script)
        {
            string pattern = Utils.GetItem(script).String;

            if (string.IsNullOrWhiteSpace(pattern))
            {
                throw new ArgumentException("Couldn't extract process name");
            }

            int MAX_PROC_NAME = 26;

            Interpreter.Instance.AppendOutput(Utils.GetLine(), true);
            Interpreter.Instance.AppendOutput(String.Format("{0} {1} {2} {3} {4} {5}",
                                                            "Process Id".PadRight(15), "Process Name".PadRight(MAX_PROC_NAME),
                                                            "Working Set".PadRight(15), "Virt Mem".PadRight(15),
                                                            "Start Time".PadRight(15), "CPU Time".PadRight(25)), true);

            Process[]       processes = Process.GetProcessesByName(pattern);
            List <Variable> results   = new List <Variable>(processes.Length);

            for (int i = 0; i < processes.Length; i++)
            {
                Process pr         = processes[i];
                int     workingSet = (int)(((double)pr.WorkingSet64) / 1000000.0);
                int     virtMemory = (int)(((double)pr.VirtualMemorySize64) / 1000000.0);
                string  procTitle  = pr.ProcessName + " " + pr.MainWindowTitle.Split(null)[0];
                string  startTime  = pr.StartTime.ToString();
                if (procTitle.Length > MAX_PROC_NAME)
                {
                    procTitle = procTitle.Substring(0, MAX_PROC_NAME);
                }
                string procTime = string.Empty;
                try
                {
                    procTime = pr.TotalProcessorTime.ToString().Substring(0, 11);
                }
                catch (Exception) { }

                results.Add(new Variable(
                                string.Format("{0,15} {1," + MAX_PROC_NAME + "} {2,15} {3,15} {4,15} {5,25}",
                                              pr.Id, procTitle,
                                              workingSet, virtMemory, startTime, procTime)));
                Interpreter.Instance.AppendOutput(results.Last().String, true);
            }
            Interpreter.Instance.AppendOutput(Utils.GetLine(), true);

            if (script.TryCurrent() == Constants.NEXT_ARG)
            {
                script.Forward(); // eat end of statement semicolon
            }

            return(new Variable(results));
        }
        protected override Variable Evaluate(ParsingScript script)
        {
            bool prefix = string.IsNullOrWhiteSpace(m_name);

            if (prefix)// If it is a prefix we do not have the variable name yet.
            {
                m_name = Utils.GetToken(script, Constants.TOKEN_SEPARATION);
            }

            // Value to be added to the variable:
            int valueDelta  = m_action == Constants.INCREMENT ? 1 : -1;
            int returnDelta = prefix ? valueDelta : 0;

            // Check if the variable to be set has the form of x[a][b],
            // meaning that this is an array element.
            double          newValue     = 0;
            List <Variable> arrayIndices = Utils.GetArrayIndices(ref m_name);

            ParserFunction func = ParserFunction.GetFunction(m_name);

            Utils.CheckNotNull(m_name, func);

            Variable currentValue = func.GetValue(script);

            if (arrayIndices.Count > 0 || script.TryCurrent() == Constants.START_ARRAY)
            {
                if (prefix)
                {
                    string tmpName = m_name + script.Rest;
                    int    delta   = 0;
                    arrayIndices = Utils.GetArrayIndices(ref tmpName, ref delta);
                    script.Forward(Math.Max(0, delta - tmpName.Length));
                }

                Variable element = Utils.ExtractArrayElement(currentValue, arrayIndices);
                script.MoveForwardIf(Constants.END_ARRAY);

                newValue       = element.Value + returnDelta;
                element.Value += valueDelta;
            }
            else // A normal variable.
            {
                newValue            = currentValue.Value + returnDelta;
                currentValue.Value += valueDelta;
            }

            ParserFunction.AddGlobalOrLocalVariable(m_name,
                                                    new GetVarFunction(currentValue));
            return(new Variable(newValue));
        }
Beispiel #15
0
        static Variable ExtractArray(ParsingScript script)
        {
            Variable newValue = new Variable(Variable.VarType.ARRAY);

            while (script.StillValid() && (newValue.Count == 0 || script.Current == ','))
            {
                script.Forward();
                Variable addVariable = ExtractValue(script);
                newValue.AddVariable(addVariable);
            }
            script.MoveForwardIf(']');

            return(newValue);
        }
Beispiel #16
0
        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);
            }

            int    arrayIndexDepth = 0;
            bool   inQuotes        = false;
            int    negated         = 0;
            char   ch;
            string action;

            do
            { // Main processing cycle of the first part.
                string token = ExtractNextToken(script, to, ref inQuotes, ref arrayIndexDepth, ref negated, out ch, out action);

                bool ternary = UpdateIfTernary(script, token, ch, listToMerge, (List <Variable> newList) => { listToMerge = newList; });
                if (ternary)
                {
                    return(listToMerge);
                }

                bool negSign = CheckConsistencyAndSign(script, listToMerge, action, ref token);

                // We are done getting the next token. The GetValue() call below may
                // recursively call SplitAndMerge(). 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 (UpdateResult(script, to, listToMerge, token, negSign, ref current, ref negated, ref action))
                {
                    return(listToMerge);
                }
            } 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);
        }
Beispiel #17
0
        static Variable ExtractObject(ParsingScript script)
        {
            Variable newValue = new Variable(Variable.VarType.ARRAY);

            while (script.StillValid() && (newValue.Count == 0 || script.Current == ','))
            {
                script.Forward();
                string key = Utils.GetToken(script, SEP);
                script.MoveForwardIf(':');

                Variable valueVar = ExtractValue(script);
                newValue.SetHashVariable(key, valueVar);
            }
            script.MoveForwardIf('}');

            return(newValue);
        }
Beispiel #18
0
        static async Task <List <Variable> > SplitAsync(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);
            }

            int    arrayIndexDepth = 0;
            bool   inQuotes        = false;
            int    negated         = 0;
            char   ch;
            string action;

            do
            { // Main processing cycle of the first part.
                string token = ExtractNextToken(script, to, ref inQuotes, ref arrayIndexDepth, ref negated, out ch, out action);

                bool ternary = await UpdateIfTernaryAsync(script, token, ch, listToMerge, (List <Variable> newList) => { listToMerge = newList; });

                if (ternary)
                {
                    return(listToMerge);
                }

                bool negSign = CheckConsistencyAndSign(script, listToMerge, action, ref token);

                ParserFunction func    = new ParserFunction(script, token, ch, ref action);
                Variable       current = await func.GetValueAsync(script);

                if (UpdateResult(script, to, listToMerge, token, negSign, ref current, ref negated, ref action))
                {
                    return(listToMerge);
                }
            } 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);
        }
Beispiel #19
0
        internal async Task <Variable> ProcessForAsync(ParsingScript script)
        {
            string forString = Utils.GetBodyBetween(script, Constants.START_ARG, Constants.END_ARG);

            script.Forward();
            if (forString.Contains(Constants.END_STATEMENT.ToString()))
            {
                // Looks like: "for(i = 0; i < 10; i++)".
                await ProcessCanonicalForAsync(script, forString);
            }
            else
            {
                // Otherwise looks like: "for(item : array)"
                await ProcessArrayForAsync(script, forString);
            }

            return(Variable.EmptyInstance);
        }
Beispiel #20
0
        private static string UpdateAction(ParsingScript script, char[] to)
        {
            // We search a valid action till we get to the End of Argument ')'
            // or pass the end of string.
            if (!script.StillValid() || script.Current == Constants.END_ARG ||
                to.Contains(script.Current))
            {
                return(Constants.NULL_ACTION);
            }

            string action = Utils.ValidAction(script.Rest);

            // We need to advance forward not only the action length but also all
            // the characters we skipped before getting the action.
            int advance = action == null ? 0 : action.Length;

            script.Forward(advance);
            return(action == null ? Constants.NULL_ACTION : action);
        }
Beispiel #21
0
        protected override Variable Evaluate(ParsingScript script)
        {
            script.Forward(); // Skip opening parenthesis.
            string line = Console.ReadLine();

            if (!m_isNumber)
            {
                return(new Variable(line));
            }

            double number = Double.NaN;

            if (!Double.TryParse(line, out number))
            {
                throw new ArgumentException("Couldn't parse number [" + line + "]");
            }

            return(new Variable(number));
        }
Beispiel #22
0
        static bool CheckConsistencyAndSign(ParsingScript script, List <Variable> listToMerge, string action, ref string token)
        {
            if (Constants.CONTROL_FLOW.Contains(token) && listToMerge.Count > 0)
            {//&&
             //item != Constants.RETURN) {
             // This can happen when the end of statement ";" is forgotten.
                listToMerge.Clear();
                //throw new ArgumentException("Token [" +
                //   item + "] can't be part of an expression. Check \";\". Stopped at [" +
                //    script.Rest + " ...]");
            }

            script.MoveForwardIf(Constants.SPACE);

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

            bool negSign = CheckNegativeSign(ref token);

            return(negSign);
        }
Beispiel #23
0
        public static string GetBodyBetween(ParsingScript script, char open, char close)
        {
            // We are supposed to be one char after the beginning of the string, i.e.
            // we must not have the opening char as the first one.
            StringBuilder sb     = new StringBuilder(script.Size());
            int           braces = 0;

            for (; script.StillValid(); script.Forward())
            {
                char ch = script.Current;

                if (string.IsNullOrWhiteSpace(ch.ToString()) && sb.Length == 0)
                {
                    continue;
                }
                else if (ch == open)
                {
                    braces++;
                }
                else if (ch == close)
                {
                    braces--;
                }

                sb.Append(ch);
                if (braces == -1)
                {
                    if (ch == close)
                    {
                        sb.Remove(sb.Length - 1, 1);
                    }
                    break;
                }
            }

            return(sb.ToString());
        }
Beispiel #24
0
        public static string[] GetBaseClasses(ParsingScript script)
        {
            if (script.Current != ':')
            {
                return(new string[0]);
            }
            script.Forward();

            int endArgs = script.FindFirstOf(Constants.START_GROUP.ToString());

            if (endArgs < 0)
            {
                throw new ArgumentException("Couldn't extract base classes");
            }

            string argStr = script.Substr(script.Pointer, endArgs - script.Pointer);

            string[] args = argStr.Split(Constants.NEXT_ARG_ARRAY, StringSplitOptions.RemoveEmptyEntries);

            args           = args.Select(element => Constants.ConvertName(element.Trim())).ToArray();
            script.Pointer = endArgs + 1;

            return(args);
        }
Beispiel #25
0
        public static void PreprocessScript(ParsingScript script)
        {
            script.Pointer = 0;
            int    nestedLevel         = 0;
            int    functionNestedLevel = 0;
            int    pointerOffset       = 0;
            string currentFunction     = "";
            string prevToken           = "";

            bool inQuotes        = false;
            int  negated         = 0;
            int  arrayIndexDepth = 0;

            if (script.AllLabels == null)
            {
                script.AllLabels = new Dictionary <string, Dictionary <string, int> >();
            }
            if (script.LabelToFile == null)
            {
                script.LabelToFile = new Dictionary <string, string>();
            }

            while (script.StillValid())
            {
                char ch = script.Current;
                if (ch == '{')
                {
                    nestedLevel++;
                    script.Forward();
                    continue;
                }
                else if (ch == '}')
                {
                    nestedLevel--;
                    if (nestedLevel <= functionNestedLevel)
                    {
                        currentFunction = "";
                        pointerOffset   = 0;
                    }
                    script.Forward();
                    continue;
                }
                else if (ch == ':' && !string.IsNullOrWhiteSpace(prevToken))
                {
                    script.Forward();
                    Dictionary <string, int> labels;
                    if (!script.AllLabels.TryGetValue(currentFunction, out labels))
                    {
                        labels = new Dictionary <string, int>();
                    }
                    labels[prevToken] = script.Pointer + 1 - pointerOffset;
                    script.AllLabels[currentFunction] = labels;
                    script.LabelToFile[prevToken]     = script.Filename;
                    continue;
                }

                try
                {
                    string token = Parser.ExtractNextToken(script, Constants.TOKEN_SEPARATION,
                                                           ref inQuotes, ref arrayIndexDepth, ref negated, out _, out _, false);

                    if (token == Constants.FUNCTION)
                    {
                        script.Forward();
                        currentFunction     = Utils.GetToken(script, Constants.TOKEN_SEPARATION);
                        currentFunction     = Constants.ConvertName(currentFunction);
                        functionNestedLevel = nestedLevel;
                        var sig = Utils.GetFunctionSignature(script);
                        pointerOffset = script.Pointer + (currentFunction == "" ? 1 : 2);
                    }
                    prevToken = token;
                }
                catch (Exception exc)
                {
                    Console.WriteLine(exc.Message);
                    script.Forward();
                }
            }

            script.Pointer = 0;
        }
Beispiel #26
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();

                bool ternary = UpdateIfTernary(script, token, ch, ref listToMerge);
                if (ternary)
                {
                    return(listToMerge);
                }

                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);
                current.ParsingToken = token;

                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);
        }
Beispiel #27
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);
        }
Beispiel #28
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);
        }