protected override Variable Evaluate(ParsingScript script) { if (script.Substr().StartsWith(" ..")) { script.Forward(); } string newDir = Utils.GetItem(script).AsString(); 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)); }
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 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 = UpdateIfTernary(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); }
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); }
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 && token != Constants.DEFAULT) { 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 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); if (to.Contains(Constants.END_ARRAY) && ch == Constants.END_ARRAY && item[item.Length - 1] != Constants.END_ARRAY && item.ToString().Contains(Constants.START_ARRAY)) { item.Append(ch); } 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); }