internal static CodeNode Parse(ParseInfo state, ref int index) { //string code = state.Code; int i = index; if (!Parser.Validate(state.Code, "while (", ref i) && !Parser.Validate(state.Code, "while(", ref i)) { return(null); } int labelsCount = state.LabelsCount; state.LabelsCount = 0; while (Tools.IsWhiteSpace(state.Code[i])) { i++; } var condition = Parser.Parse(state, ref i, CodeFragmentType.Expression); while (i < state.Code.Length && Tools.IsWhiteSpace(state.Code[i])) { i++; } if (i >= state.Code.Length) { ExceptionHelper.Throw(new SyntaxError("Unexpected end of line.")); } if (state.Code[i] != ')') { throw new ArgumentException("code (" + i + ")"); } do { i++; }while (i < state.Code.Length && Tools.IsWhiteSpace(state.Code[i])); if (i >= state.Code.Length) { ExceptionHelper.Throw(new SyntaxError("Unexpected end of line.")); } state.AllowBreak.Push(true); state.AllowContinue.Push(true); int ccs = state.continiesCount; int cbs = state.breaksCount; var body = Parser.Parse(state, ref i, 0); if (body is FunctionDefinition) { if (state.strict) { ExceptionHelper.Throw((new NiL.JS.BaseLibrary.SyntaxError("In strict mode code, functions can only be declared at top level or immediately within another function."))); } if (state.message != null) { state.message(MessageLevel.CriticalWarning, CodeCoordinates.FromTextPosition(state.Code, body.Position, body.Length), "Do not declare function in nested blocks."); } body = new CodeBlock(new[] { body }); // для того, чтобы не дублировать код по декларации функции, // она оборачивается в блок, который сделает самовыпил на втором этапе, но перед этим корректно объявит функцию. } state.AllowBreak.Pop(); state.AllowContinue.Pop(); var pos = index; index = i; return(new While() { allowRemove = ccs == state.continiesCount && cbs == state.breaksCount, body = body, condition = condition, labels = state.Labels.GetRange(state.Labels.Count - labelsCount, labelsCount).ToArray(), Position = pos, Length = index - pos }); }
internal static CodeNode Parse(ParseInfo state, ref int index) { int i = index; if (!Parser.Validate(state.Code, "throw", ref i) || (!Parser.IsIdentifierTerminator(state.Code[i]))) { return(null); } while (i < state.Code.Length && Tools.IsWhiteSpace(state.Code[i]) && !Tools.IsLineTerminator(state.Code[i])) { i++; } var b = state.Code[i] == ';' || Tools.IsLineTerminator(state.Code[i]) ? null : (Expression)Parser.Parse(state, ref i, CodeFragmentType.Expression); if (b is Empty) { ExceptionHelper.Throw((new SyntaxError("Can't throw result of EmptyStatement " + CodeCoordinates.FromTextPosition(state.Code, i - 1, 0)))); } var pos = index; index = i; return(new Throw(b) { Position = pos, Length = index - pos }); }