static Variable ExtractValue(ParsingScript script) { if (script.TryCurrent() == '{') { return ExtractObject(script); } if (script.TryCurrent() == '[') { return ExtractArray(script); } var token = Utils.GetToken(script, SEP); return new Variable(token); }
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); }
static Variable ExtractValue(ParsingScript script) { if (script.TryCurrent() == '{') { return(ExtractObject(script)); } if (script.TryCurrent() == '[') { return(ExtractArray(script)); } bool canBeNumeric = script.Current != '"'; var token = Utils.GetToken(script, SEP); if (canBeNumeric && Utils.CanConvertToDouble(token, out double num)) { return(new Variable(num)); } return(new Variable(token)); }
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)); }
public static List <string> ExtractTokens(ParsingScript script) { List <string> tokens = new List <string>(); script.MoveForwardIf(Constants.START_ARG); while (script.TryCurrent() != Constants.END_GROUP) { string propName = Utils.GetToken(script, Constants.TOKEN_SEPARATION); script.MoveForwardIf(Constants.NEXT_ARG); tokens.Add(propName); } return(tokens); }
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)); }
public static string ReplaceSpaces(ParsingScript script, char replaceChar = ',', char end = Constants.END_STATEMENT) { StringBuilder sb = new StringBuilder(); while (script.StillValid() && script.TryCurrent() != end) { var token = GetBodyBetween(script, '\0', ' ', end); sb.Append(token + replaceChar); } if (sb.Length > 0 && sb[sb.Length - 1] == replaceChar) { sb.Remove(sb.Length - 1, 1); } return(sb.ToString()); }
static bool StillCollecting(string item, char[] to, ParsingScript script, ref string action) { char prev = script.TryPrevPrev(); char ch = script.TryPrev(); char next = script.TryCurrent(); if (to.Contains(ch) || ch == Constants.START_ARG || ch == Constants.START_GROUP || next == Constants.EMPTY) { return(false); } // Case of a negative number, or a pointer, or starting with the closing bracket: if (item.Length == 0 && ((ch == '-' && next != '-') || ch == '&' || ch == Constants.END_ARRAY || ch == Constants.END_ARG)) { return(true); } // Case of a scientific notation 1.2e+5 or 1.2e-5 or 1e5: if (Char.ToUpper(prev) == 'E' && (ch == '-' || ch == '+' || Char.IsDigit(ch)) && item.Length > 1 && Char.IsDigit(item[item.Length - 2])) { return(true); } // Otherwise if it's an action (+, -, *, etc.) or a space // we're done collecting current token. if ((action = Utils.ValidAction(script.FromPrev())) != null || (item.Length > 0 && ch == Constants.SPACE)) { return(false); } if (ch == Constants.TERNARY_OPERATOR) { script.Backward(); return(false); } return(true); }
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); }
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); }
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); }