static async Task <bool> UpdateIfTernaryAsync(ParsingScript script, string token, char ch, List <Variable> listInput, Action <List <Variable> > listToMerge) { if (listInput.Count < 1 || ch != Constants.TERNARY_OPERATOR || token.Length > 0) { return(false); } Variable arg1 = MergeList(listInput); script.MoveForwardIf(Constants.TERNARY_OPERATOR); Variable arg2 = await script.ExecuteAsync(Constants.TERNARY_SEPARATOR); script.MoveForwardIf(Constants.TERNARY_SEPARATOR); Variable arg3 = await script.ExecuteAsync(Constants.NEXT_OR_END_ARRAY); script.MoveForwardIf(Constants.NEXT_OR_END_ARRAY); double condition = arg1.AsDouble(); Variable result = condition != 0 ? arg2 : arg3; listInput.Clear(); listInput.Add(result); listToMerge(listInput); return(true); }
private async Task <Variable> ProcessBlockAsync(ParsingScript script) { int blockStart = script.Pointer; Variable result = null; if (script.Debugger != null) { bool done = false; result = await script.Debugger.DebugBlockIfNeeded(script, done, (newDone) => { done = newDone; }); if (done) { return(result); } } while (script.StillValid()) { int endGroupRead = script.GoToNextStatement(); if (endGroupRead > 0 || !script.StillValid()) { return(result != null ? result : new Variable()); } result = await script.ExecuteAsync(); if (result.IsReturn || result.Type == Variable.VarType.BREAK || result.Type == Variable.VarType.CONTINUE) { return(result); } } return(result); }
public async Task <Variable> ProcessAsync(string script, string filename = "", bool mainFile = false) { Dictionary <int, int> char2Line; string data = Utils.ConvertToScript(script, out char2Line, filename); if (string.IsNullOrWhiteSpace(data)) { return(null); } ParsingScript toParse = new ParsingScript(data, 0, char2Line); toParse.OriginalScript = script; toParse.Filename = filename; if (mainFile) { toParse.MainFilename = toParse.Filename; } Variable result = null; while (toParse.Pointer < data.Length) { result = await toParse.ExecuteAsync(); toParse.GoToNextStatement(); } return(result); }
async Task ProcessCanonicalForAsync(ParsingScript script, string forString) { string[] forTokens = forString.Split(Constants.END_STATEMENT); if (forTokens.Length != 3) { throw new ArgumentException("Expecting: for(init; condition; loopStatement)"); } int startForCondition = script.Pointer; ParsingScript initScript = new ParsingScript(forTokens[0] + Constants.END_STATEMENT); ParsingScript condScript = new ParsingScript(forTokens[1] + Constants.END_STATEMENT); ParsingScript loopScript = new ParsingScript(forTokens[2] + Constants.END_STATEMENT); initScript.ParentScript = script; condScript.ParentScript = script; loopScript.ParentScript = script; await initScript.ExecuteAsync(null, 0); int cycles = 0; bool stillValid = true; while (stillValid) { Variable condResult = await condScript.ExecuteAsync(null, 0); stillValid = Convert.ToBoolean(condResult.Value); if (!stillValid) { break; } if (MAX_LOOPS > 0 && ++cycles >= MAX_LOOPS) { throw new ArgumentException("Looks like an infinite loop after " + cycles + " cycles."); } script.Pointer = startForCondition; Variable result = await ProcessBlockAsync(script); if (result.IsReturn || result.Type == Variable.VarType.BREAK) { //script.Pointer = startForCondition; //SkipBlock(script); //return; break; } await loopScript.ExecuteAsync(null, 0); } script.Pointer = startForCondition; SkipBlock(script); }
internal async Task <Variable> ProcessIfAsync(ParsingScript script) { int startIfCondition = script.Pointer; Variable result = await script.ExecuteAsync(Constants.END_ARG_ARRAY); bool isTrue = Convert.ToBoolean(result.Value); if (isTrue) { result = await ProcessBlockAsync(script); if (result.IsReturn || result.Type == Variable.VarType.BREAK || result.Type == Variable.VarType.CONTINUE) { // We are here from the middle of the if-block. Skip it. script.Pointer = startIfCondition; SkipBlock(script); } SkipRestBlocks(script); //return result; return(result.IsReturn || result.Type == Variable.VarType.BREAK || result.Type == Variable.VarType.CONTINUE ? result : Variable.EmptyInstance); } // We are in Else. Skip everything in the If statement. SkipBlock(script); ParsingScript nextData = new ParsingScript(script); nextData.ParentScript = script; string nextToken = Utils.GetNextToken(nextData); if (Constants.ELSE_IF == nextToken) { script.Pointer = nextData.Pointer + 1; result = await ProcessIfAsync(script); } else if (Constants.ELSE == nextToken) { script.Pointer = nextData.Pointer + 1; result = await ProcessBlockAsync(script); } return(result.IsReturn || result.Type == Variable.VarType.BREAK || result.Type == Variable.VarType.CONTINUE ? result : Variable.EmptyInstance); }
public static async Task <List <Variable> > GetArrayIndicesAsync(ParsingScript script, string varName, int end, Action <string, int> updateVals) { List <Variable> indices = new List <Variable>(); int argStart = varName.IndexOf(Constants.START_ARRAY); if (argStart < 0) { return(indices); } int firstIndexStart = argStart; while (argStart < varName.Length && varName[argStart] == Constants.START_ARRAY) { int argEnd = varName.IndexOf(Constants.END_ARRAY, argStart + 1); if (argEnd == -1 || argEnd <= argStart + 1) { break; } ParsingScript tempScript = script.GetTempScript(varName, argStart); /*ParsingScript tempScript = new ParsingScript(varName, argStart); * tempScript.ParentScript = script; * tempScript.Char2Line = script.Char2Line; * tempScript.Filename = script.Filename; * tempScript.OriginalScript = script.OriginalScript; * tempScript.InTryBlock = script.InTryBlock;*/ tempScript.MoveForwardIf(Constants.START_ARG, Constants.START_ARRAY); Variable index = await tempScript.ExecuteAsync(Constants.END_ARRAY_ARRAY); indices.Add(index); argStart = argEnd + 1; } if (indices.Count > 0) { varName = varName.Substring(0, firstIndexStart); end = argStart - 1; } updateVals(varName, end); return(indices); }
public static async Task<Variable> Execute(ParsingScript script) { char[] toArray = Constants.END_PARSE_ARRAY; Variable result = null; Exception exception = null; #if UNITY_EDITOR || UNITY_STANDALONE || MAIN_THREAD_CHECK // Do nothing: already on the main thread #elif __ANDROID__ scripting.Droid.MainActivity.TheView.RunOnUiThread(() => { #elif __IOS__ scripting.iOS.AppDelegate.GetCurrentController().InvokeOnMainThread(() => { #else #endif try { #if __IOS__ || __ANDROID__ result = script.Execute(toArray); #else result = await script.ExecuteAsync(toArray); #endif } catch (ParsingException exc) { exception = exc; } #if UNITY_EDITOR || UNITY_STANDALONE || MAIN_THREAD_CHECK // Do nothing: already on the main thread or main thread is not required #elif __ANDROID__ || __IOS__ }); #endif if (exception != null) { throw exception; } if (result.Type == Variable.VarType.QUIT) { DebuggerServer.StopServer(); } return result; } }
internal async Task <Variable> ProcessWhileAsync(ParsingScript script) { int startWhileCondition = script.Pointer; // A check against an infinite loop. int cycles = 0; bool stillValid = true; Variable result = Variable.EmptyInstance; while (stillValid) { script.Pointer = startWhileCondition; //int startSkipOnBreakChar = from; Variable condResult = await script.ExecuteAsync(Constants.END_ARG_ARRAY); stillValid = Convert.ToBoolean(condResult.Value); if (!stillValid) { break; } // Check for an infinite loop if we are comparing same values: if (MAX_LOOPS > 0 && ++cycles >= MAX_LOOPS) { throw new ArgumentException("Looks like an infinite loop after " + cycles + " cycles."); } result = await ProcessBlockAsync(script); if (result.IsReturn || result.Type == Variable.VarType.BREAK) { script.Pointer = startWhileCondition; break; } } // The while condition is not true anymore: must skip the whole while // block before continuing with next statements. SkipBlock(script); return(result.IsReturn ? result : Variable.EmptyInstance); }
public static async Task <Variable> GetItemAsync(ParsingScript script, bool eatLast = true) { script.MoveForwardIf(Constants.NEXT_ARG, Constants.SPACE); Utils.CheckNotEnd(script); bool inQuotes = script.Current == Constants.QUOTE; bool inQuotes1 = script.Current == Constants.QUOTE1; 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 = await GetArgsAsync(script, Constants.START_GROUP, Constants.END_GROUP, (outList) => { isList = outList; }); return(value); } // A variable, a function, or a number. Variable var = await script.ExecuteAsync(Constants.NEXT_OR_END_ARRAY); //value = var.Clone(); if (inQuotes) { script.MoveForwardIf(Constants.QUOTE); } else if (inQuotes1) { script.MoveForwardIf(Constants.QUOTE1); } if (eatLast) { script.MoveForwardIf(Constants.END_ARG, Constants.SPACE); } return(var); }