private static List <Variable> Split(ParsingScript script, char[] to) { List <Variable> listToMerge = new List <Variable>(16); if (!script.StillValid() || to.Contains(script.Current)) { listToMerge.Add(Variable.EmptyInstance); script.Forward(); return(listToMerge); } StringBuilder item = new StringBuilder(); int arrayIndexDepth = 0; bool inQuotes = false; int negated = 0; string rest = script.Rest; if (rest == "b[a[0]];") { int stop = 1; } do // Main processing cycle of the first part. { string negateSymbol = Utils.IsNotSign(script.Rest); if (negateSymbol != null && !inQuotes) { negated++; script.Forward(negateSymbol.Length); continue; } char ch = script.CurrentAndForward(); CheckQuotesIndices(script, ch, ref inQuotes, ref arrayIndexDepth); string action = null; bool keepCollecting = inQuotes || arrayIndexDepth > 0 || StillCollecting(item.ToString(), to, script, ref action); if (keepCollecting) { // The char still belongs to the previous operand. item.Append(ch); bool goForMore = script.StillValid() && (inQuotes || arrayIndexDepth > 0 || !to.Contains(script.Current)); if (goForMore) { continue; } } if (SkipOrAppendIfNecessary(item, ch, to)) { continue; } string token = item.ToString(); CheckConsistency(token, listToMerge, script); script.MoveForwardIf(Constants.SPACE); if (action != null && action.Length > 1) { script.Forward(action.Length - 1); } // We are done getting the next token. The getValue() call below may // recursively call loadAndCalculate(). This will happen if extracted // item is a function or if the next item is starting with a START_ARG '('. ParserFunction func = new ParserFunction(script, token, ch, ref action); Variable current = func.GetValue(script); if (negated > 0 && current.Type == Variable.VarType.NUMBER) { // If there has been a NOT sign, this is a boolean. // Use XOR (true if exactly one of the arguments is true). bool neg = !((negated % 2 == 0) ^ Convert.ToBoolean(current.Value)); current = new Variable(Convert.ToDouble(neg)); negated = 0; } if (action == null) { action = UpdateAction(script, to); } else { script.MoveForwardIf(action[0]); } char next = script.TryCurrent(); // we've already moved forward bool done = listToMerge.Count == 0 && (next == Constants.END_STATEMENT || (action == Constants.NULL_ACTION && current.Type != Variable.VarType.NUMBER) || current.IsReturn); if (done) { if (action != null && action != Constants.END_ARG_STR) { throw new ArgumentException("Action [" + action + "] without an argument."); } // If there is no numerical result, we are not in a math expression. listToMerge.Add(current); return(listToMerge); } Variable cell = current.Clone(); cell.Action = action; bool addIt = UpdateIfBool(script, ref cell, ref listToMerge); if (addIt) { listToMerge.Add(cell); } item.Clear(); } while (script.StillValid() && (inQuotes || arrayIndexDepth > 0 || !to.Contains(script.Current))); // This happens when called recursively inside of the math expression: script.MoveForwardIf(Constants.END_ARG); return(listToMerge); }
protected override Variable Evaluate(ParsingScript script) { return(new Variable(m_value)); }
protected override Variable Evaluate(ParsingScript script) { Variable result = Interpreter.Instance.ProcessIf(script); return(result); }
public static bool ExtractParameterNames(List <Variable> args, string functionName, ParsingScript script) { CustomFunction custFunc = ParserFunction.GetFunction(functionName, script) as CustomFunction; if (custFunc == null) { return(false); } var realArgs = custFunc.RealArgs; for (int i = 0; i < args.Count && i < realArgs.Length; i++) { string name = args[i].CurrentAssign; args[i].ParamName = string.IsNullOrWhiteSpace(name) ? realArgs[i] : name; } return(true); }
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); }
public virtual Task <Variable> GetProperty(string sPropertyName, List <Variable> args = null, ParsingScript script = null) { sPropertyName = Variable.GetActualPropertyName(sPropertyName, GetProperties()); switch (sPropertyName) { case "Name": return(Task.FromResult(GetNameProperty())); case "Color": return(Task.FromResult(GetColorProperty())); case "Translate": return(Task.FromResult( args != null && args.Count > 0 ? Translate(args[0]) : Variable.EmptyInstance)); default: return(Task.FromResult(Variable.EmptyInstance)); } }
protected override Variable Evaluate(ParsingScript script) { return(new Variable(Math.Sqrt(1 / 2))); }
protected virtual Task <Variable> EvaluateAsync(ParsingScript script) { // If not overriden, the non-sync version will be called. return(Task.FromResult(Evaluate(script))); }
public static bool IsNumericFunction(string paramName, ParsingScript script = null) { ParserFunction function = ParserFunction.GetFunction(paramName, script); return(function is INumericFunction); }
public async Task <Variable> GetValueAsync(ParsingScript script) { return(await m_impl.EvaluateAsync(script)); }
protected virtual Variable Evaluate(ParsingScript script) { // The real implementation will be in the derived classes. return(new Variable()); }
public Variable GetValue(ParsingScript script) { return(m_impl.Evaluate(script)); }
public static ParserFunction GetFunctionNamespace(string name, string nameSpace, ParsingScript script) { if (string.IsNullOrWhiteSpace(nameSpace)) { return(null); } StackLevel level; if (!s_namespaces.TryGetValue(nameSpace, out level)) { return(null); } var vars = level.Variables; ParserFunction impl; if (vars.TryGetValue(name, out impl)) { return(impl); } if (!name.StartsWith(nameSpace, StringComparison.OrdinalIgnoreCase)) { name = nameSpace + "." + name; if (vars.TryGetValue(name, out impl)) { return(impl); } if (s_functions.TryGetValue(name, out impl)) { return(impl); } } return(null); }
public static ParserFunction GetFunctionNamespace(string name, ParsingScript script) { ParserFunction result = GetFunctionNamespace(name, s_namespace, script); return(result); }
protected override Variable Evaluate(ParsingScript script) { List <Variable> args = script.GetFunctionArgs(); Utils.CheckArgs(args.Count, 1, m_name); string source = Utils.GetSafeString(args, 0); string argument = Utils.GetSafeString(args, 1); string parameter = Utils.GetSafeString(args, 2, "case"); int startFrom = Utils.GetSafeInt(args, 3, 0); int length = Utils.GetSafeInt(args, 4, source.Length); StringComparison comp = StringComparison.Ordinal; if (parameter.Equals("nocase") || parameter.Equals("no_case")) { comp = StringComparison.OrdinalIgnoreCase; } source = source.Replace("\\\"", "\""); argument = argument.Replace("\\\"", "\""); switch (m_mode) { case Mode.CONTAINS: return(new Variable(source.IndexOf(argument, comp) >= 0)); case Mode.STARTS_WITH: return(new Variable(source.StartsWith(argument, comp))); case Mode.ENDS_WITH: return(new Variable(source.EndsWith(argument, comp))); case Mode.INDEX_OF: return(new Variable(source.IndexOf(argument, startFrom, comp))); case Mode.EQUALS: return(new Variable(source.Equals(argument, comp))); case Mode.REPLACE: return(new Variable(source.Replace(argument, parameter))); case Mode.UPPER: return(new Variable(source.ToUpper())); case Mode.LOWER: return(new Variable(source.ToLower())); case Mode.TRIM: return(new Variable(source.Trim())); case Mode.SUBSTRING: startFrom = Utils.GetSafeInt(args, 1, 0); length = Utils.GetSafeInt(args, 2, source.Length); length = Math.Min(length, source.Length - startFrom); return(new Variable(source.Substring(startFrom, length))); case Mode.BEETWEEN: case Mode.BEETWEEN_ANY: int index1 = source.IndexOf(argument); int index2 = m_mode == Mode.BEETWEEN ? source.IndexOf(parameter, index1 + 1) : source.IndexOfAny(parameter.ToCharArray(), index1 + 1); startFrom = index1 + argument.Length; if (index1 < 0 || index2 < index1) { throw new ArgumentException("Couldn't extract string between [" + argument + "] and [" + parameter + "] + from " + source); } string result = source.Substring(startFrom, index2 - startFrom); return(new Variable(result)); } return(new Variable(-1)); }
public static Variable SplitAndMerge(ParsingScript script) { return(SplitAndMerge(script, Constants.END_PARSE_ARRAY)); }
protected override Variable Evaluate(ParsingScript script) { string dirname = (!script.StillValid() || script.Current == Constants.END_STATEMENT) ? Directory.GetCurrentDirectory() : Utils.GetToken(script, Constants.NEXT_OR_END_ARRAY); //List<Variable> results = Utils.GetPathnames(dirname); List <Variable> results = new List <Variable>(); int index = dirname.IndexOf('*'); if (index < 0 && !Directory.Exists(dirname) && !File.Exists(dirname)) { throw new ArgumentException("Directory [" + dirname + "] doesn't exist"); } string pattern = Constants.ALL_FILES; try { string dir = index < 0 ? Path.GetFullPath(dirname) : dirname; if (File.Exists(dir)) { FileInfo fi = new FileInfo(dir); Interpreter.Instance.AppendOutput(Utils.GetPathDetails(fi, fi.Name), true); results.Add(new Variable(fi.Name)); return(new Variable(results)); } // Special dealing if there is a pattern (only * is supported at the moment) if (index >= 0) { pattern = Path.GetFileName(dirname); if (index > 0) { string prefix = dirname.Substring(0, index); DirectoryInfo di = Directory.GetParent(prefix); dirname = di.FullName; } else { dirname = "."; } } dir = Path.GetFullPath(dirname); // First get contents of the directory (unless there is a pattern) DirectoryInfo dirInfo = new DirectoryInfo(dir); if (pattern == Constants.ALL_FILES) { Interpreter.Instance.AppendOutput(Utils.GetPathDetails(dirInfo, "."), true); if (dirInfo.Parent != null) { Interpreter.Instance.AppendOutput(Utils.GetPathDetails(dirInfo.Parent, ".."), true); } } // Then get contents of all of the files in the directory FileInfo[] fileNames = dirInfo.GetFiles(pattern); foreach (FileInfo fi in fileNames) { try { Interpreter.Instance.AppendOutput(Utils.GetPathDetails(fi, fi.Name), true); results.Add(new Variable(fi.Name)); } catch (Exception) { continue; } } // Then get contents of all of the subdirs in the directory DirectoryInfo[] dirInfos = dirInfo.GetDirectories(pattern); foreach (DirectoryInfo di in dirInfos) { try { Interpreter.Instance.AppendOutput(Utils.GetPathDetails(di, di.Name), true); results.Add(new Variable(di.Name)); } catch (Exception) { continue; } } } catch (Exception exc) { throw new ArgumentException("Couldn't list directory: " + exc.Message); } return(new Variable(results)); }
public static async Task <Variable> SplitAndMergeAsync(ParsingScript script) { return(await SplitAndMergeAsync(script, Constants.END_PARSE_ARRAY)); }
internal Variable ProcessTry(ParsingScript script) { int startTryCondition = script.Pointer - 1; int currentStackLevel = ParserFunction.GetCurrentStackLevel(); Exception exception = null; Variable result = null; bool alreadyInTryBlock = script.InTryBlock; script.InTryBlock = true; try { result = ProcessBlock(script); } catch (Exception exc) { exception = exc; } finally { script.InTryBlock = alreadyInTryBlock; } if (exception != null || result.IsReturn || result.Type == Variable.VarType.BREAK || result.Type == Variable.VarType.CONTINUE) { // We are here from the middle of the try-block either because // an exception was thrown or because of a Break/Continue. Skip it. script.Pointer = startTryCondition; SkipBlock(script); } string catchToken = Utils.GetNextToken(script); script.Forward(); // skip opening parenthesis // The next token after the try block must be a catch. if (!Constants.CATCH_LIST.Contains(catchToken)) { throw new ArgumentException("Expecting a 'catch()' but got [" + catchToken + "]"); } string exceptionName = Utils.GetNextToken(script); script.Forward(); // skip closing parenthesis if (exception != null) { string excStack = CreateExceptionStack(exceptionName, currentStackLevel); ParserFunction.InvalidateStacksAfterLevel(currentStackLevel); GetVarFunction excMsgFunc = new GetVarFunction(new Variable(exception.Message)); ParserFunction.AddGlobalOrLocalVariable(exceptionName, excMsgFunc); GetVarFunction excStackFunc = new GetVarFunction(new Variable(excStack)); ParserFunction.AddGlobalOrLocalVariable(exceptionName + ".Stack", excStackFunc); result = ProcessBlock(script); ParserFunction.PopLocalVariable(exceptionName); } else { SkipBlock(script); } SkipRestBlocks(script); return(result); }
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); }
protected override Variable Evaluate(ParsingScript script) { return(new Variable(Math.Log10(Math.E))); }
private static void MergeNumbers(Variable leftCell, Variable rightCell, ParsingScript script) { if (rightCell.Type != Variable.VarType.NUMBER) { rightCell.Value = rightCell.AsDouble(); } switch (leftCell.Action) { case "%": leftCell.Value %= rightCell.Value; break; case "*": leftCell.Value *= rightCell.Value; break; case "/": if (rightCell.Value == 0.0) { throw new ArgumentException("Division by zero"); } leftCell.Value /= rightCell.Value; break; case "+": if (rightCell.Type != Variable.VarType.NUMBER) { leftCell.String = leftCell.AsString() + rightCell.String; } else { leftCell.Value += rightCell.Value; } break; case "-": leftCell.Value -= rightCell.Value; break; case "<": leftCell.Value = Convert.ToDouble(leftCell.Value < rightCell.Value); break; case ">": leftCell.Value = Convert.ToDouble(leftCell.Value > rightCell.Value); break; case "<=": leftCell.Value = Convert.ToDouble(leftCell.Value <= rightCell.Value); break; case ">=": leftCell.Value = Convert.ToDouble(leftCell.Value >= rightCell.Value); break; case "==": leftCell.Value = Convert.ToDouble(leftCell.Value == rightCell.Value); break; case "!=": leftCell.Value = Convert.ToDouble(leftCell.Value != rightCell.Value); break; case "&": leftCell.Value = (int)leftCell.Value & (int)rightCell.Value; break; case "^": leftCell.Value = (int)leftCell.Value ^ (int)rightCell.Value; break; case "|": leftCell.Value = (int)leftCell.Value | (int)rightCell.Value; break; case "&&": leftCell.Value = Convert.ToDouble( Convert.ToBoolean(leftCell.Value) && Convert.ToBoolean(rightCell.Value)); break; case "||": leftCell.Value = Convert.ToDouble( Convert.ToBoolean(leftCell.Value) || Convert.ToBoolean(rightCell.Value)); break; case "**": leftCell.Value = Math.Pow(leftCell.Value, rightCell.Value); break; case ")": Utils.ThrowErrorMsg("Can't process last token [" + rightCell.Value + "] in the expression.", script, script.Current.ToString()); break; default: Utils.ThrowErrorMsg("Can't process operation [" + leftCell.Action + "] in the expression.", script, leftCell.Action); break; } }
public static int ConvertToInt(object obj, ParsingScript script = null) { double num = ConvertToDouble(obj, script); return((int)num); }
protected override Variable Evaluate(ParsingScript script) { string path = Directory.GetCurrentDirectory(); return(new Variable(path)); }
protected override Variable Evaluate(ParsingScript script) { return(new Variable(Variable.VarType.CONTINUE)); }
protected override Variable Evaluate(ParsingScript script) { int threadID = Thread.CurrentThread.ManagedThreadId; return(new Variable(threadID.ToString())); }
protected override Variable Evaluate(ParsingScript script) { return(script.ExecuteTo(Constants.END_ARG)); }
protected override Variable Evaluate(ParsingScript script) { Console.Clear(); return(Variable.EmptyInstance); }
protected override Variable Evaluate(ParsingScript script) { return(Interpreter.Instance.ProcessFor(script)); }
bool Completed(ParsingScript debugging) { return((LastResult != null && LastResult.IsReturn) || !debugging.StillValid()); }