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