internal static CodeNode Parse(ParseInfo state, ref int index) { int i = index; while (Tools.IsWhiteSpace(state.Code[i])) { i++; } if (!Parser.Validate(state.Code, "for(", ref i) && (!Parser.Validate(state.Code, "for (", ref i))) { return(null); } while (Tools.IsWhiteSpace(state.Code[i])) { i++; } CodeNode init = null; CodeNode body = null; CodeNode condition = null; CodeNode post = null; CodeNode result = null; var labelsCount = state.LabelsCount; var oldVariablesCount = state.Variables.Count; state.LabelsCount = 0; state.lexicalScopeLevel++; try { init = VariableDefinition.Parse(state, ref i, true); if (init == null) { init = ExpressionTree.Parse(state, ref i, forForLoop: true); } if ((init is ExpressionTree) && (init as ExpressionTree).Type == OperationType.None && (init as ExpressionTree)._right == null) { init = (init as ExpressionTree)._left; } if (state.Code[i] != ';') { ExceptionHelper.Throw((new SyntaxError("Expected \";\" at + " + CodeCoordinates.FromTextPosition(state.Code, i, 0)))); } do { i++; }while (Tools.IsWhiteSpace(state.Code[i])); condition = state.Code[i] == ';' ? null as CodeNode : ExpressionTree.Parse(state, ref i, forForLoop: true); if (state.Code[i] != ';') { ExceptionHelper.Throw((new SyntaxError("Expected \";\" at + " + CodeCoordinates.FromTextPosition(state.Code, i, 0)))); } do { i++; }while (Tools.IsWhiteSpace(state.Code[i])); post = state.Code[i] == ')' ? null as CodeNode : ExpressionTree.Parse(state, ref i, forForLoop: true); while (Tools.IsWhiteSpace(state.Code[i])) { i++; } if (state.Code[i] != ')') { ExceptionHelper.Throw((new SyntaxError("Expected \";\" at + " + CodeCoordinates.FromTextPosition(state.Code, i, 0)))); } i++; Tools.SkipSpaces(state.Code, ref i); state.AllowBreak.Push(true); state.AllowContinue.Push(true); try { body = Parser.Parse(state, ref i, 0); var vds = body as VariableDefinition; if (vds != null) { if (vds.Kind >= VariableKind.ConstantInLexicalScope) { ExceptionHelper.ThrowSyntaxError("Block scope variables can not be declared in for-loop directly", state.Code, body.Position); } if (state.message != null) { state.message(MessageLevel.Warning, body.Position, body.Length, "Do not declare variables in for-loop directly"); } } } finally { state.AllowBreak.Pop(); state.AllowContinue.Pop(); } int startPos = index; index = i; result = new For() { _body = body, _condition = condition, _initializer = init, _post = post, labels = state.Labels.GetRange(state.Labels.Count - labelsCount, labelsCount).ToArray(), Position = startPos, Length = index - startPos }; var vars = CodeBlock.extractVariables(state, oldVariablesCount); result = new CodeBlock(new[] { result }) { _variables = vars, Position = result.Position, Length = result.Length }; } finally { state.lexicalScopeLevel--; } return(result); }
internal static CodeNode Parse(ParseInfo state, ref int index) { int i = index; Tools.SkipSpaces(state.Code, ref i); if (!Parser.Validate(state.Code, "for(", ref i) && (!Parser.Validate(state.Code, "for (", ref i))) { return(null); } Tools.SkipSpaces(state.Code, ref i); var result = new ForOf() { _labels = state.Labels.GetRange(state.Labels.Count - state.LabelsCount, state.LabelsCount).ToArray() }; VariableDescriptor[] vars = null; var oldVariablesCount = state.Variables.Count; state.lexicalScopeLevel++; try { var vStart = i; var variableName = ""; var variableNameStart = 0; var variableDef = VariableDefinition.Parse(state, ref i, true); if (variableDef == null) { if (state.Code[i] == ';') { return(null); } Tools.SkipSpaces(state.Code, ref i); variableNameStart = i; if (!Parser.ValidateName(state.Code, ref i, state.strict)) { return(null); } variableName = Tools.Unescape(state.Code.Substring(variableNameStart, i - variableNameStart), state.strict); variableDef = new Variable(variableName, state.lexicalScopeLevel) { Position = variableNameStart, Length = i - variableNameStart, ScopeLevel = state.lexicalScopeLevel }; Tools.SkipSpaces(state.Code, ref i); if (state.Code[i] == '=') { Tools.SkipSpaces(state.Code, ref i); var defVal = ExpressionTree.Parse(state, ref i, false, false, false, true, true); if (defVal == null) { return(defVal); } Expression exp = new AssignmentOperatorCache(variableDef as Variable); exp = new Assignment(exp, defVal) { Position = exp.Position, Length = defVal.EndPosition - exp.Position }; if (variableDef == exp._left._left) { variableDef = exp; } Tools.SkipSpaces(state.Code, ref i); } } else { variableName = (variableDef as VariableDefinition)._variables[0].name; } if (!Parser.Validate(state.Code, "of", ref i)) { if (oldVariablesCount < state.Variables.Count) { state.Variables.RemoveRange(oldVariablesCount, state.Variables.Count - oldVariablesCount); } return(null); } if (state.strict) { if (variableName == "arguments" || variableName == "eval") { ExceptionHelper.ThrowSyntaxError( "Parameters name may not be \"arguments\" or \"eval\" in strict mode at ", state.Code, variableDef.Position, variableDef.Length); } } if (variableDef is VariableDefinition) { if ((variableDef as VariableDefinition)._variables.Length > 1) { ExceptionHelper.ThrowSyntaxError("Too many variables in for-of loop", state.Code, i); } } result._variable = variableDef; state.LabelsCount = 0; Tools.SkipSpaces(state.Code, ref i); result._source = Parser.Parse(state, ref i, CodeFragmentType.Expression); Tools.SkipSpaces(state.Code, ref i); if (state.Code[i] != ')') { ExceptionHelper.Throw((new SyntaxError("Expected \")\" at + " + CodeCoordinates.FromTextPosition(state.Code, i, 0)))); } i++; state.AllowBreak.Push(true); state.AllowContinue.Push(true); result._body = Parser.Parse(state, ref i, 0); state.AllowBreak.Pop(); state.AllowContinue.Pop(); result.Position = index; result.Length = i - index; index = i; vars = CodeBlock.extractVariables(state, oldVariablesCount); } finally { state.lexicalScopeLevel--; } return(new CodeBlock(new[] { result }) { _variables = vars, Position = result.Position, Length = result.Length }); }
internal static CodeNode Parse(ParseInfo state, ref int index) { if (!Parser.Validate(state.Code, "export", ref index)) { return(null); } Tools.SkipSpaces(state.Code, ref index); var result = new ExportStatement(); var reexport = 0; if (Parser.Validate(state.Code, "*", ref index)) { reexport = 1; } else if (Parser.Validate(state.Code, "default", ref index)) { reexport = -1; Tools.SkipSpaces(state.Code, ref index); using (state.WithCodeContext(CodeContext.InExport)) { var variables = VariableDefinition.Parse(state, ref index); if (variables != null) { result._internalDefinition = variables; } else { var expression = ClassDefinition.Parse(state, ref index) ?? FunctionDefinition.Parse(state, ref index, BaseLibrary.FunctionKind.Function) ?? ExpressionTree.Parse(state, ref index); result._map.Add(new KeyValuePair <string, Expression>("", (Expression)expression)); } } } else if (state.Code[index] == '{') { parseExportMap(result, state, ref index); } else { using (state.WithCodeContext(CodeContext.InExport)) { reexport = -1; var definition = VariableDefinition.Parse(state, ref index) ?? ClassDefinition.Parse(state, ref index) ?? FunctionDefinition.Parse(state, ref index, BaseLibrary.FunctionKind.Function) ?? FunctionDefinition.Parse(state, ref index, BaseLibrary.FunctionKind.AsyncFunction); if (definition == null) { ExceptionHelper.ThrowSyntaxError(Strings.UnexpectedToken, state.Code, index); } result._internalDefinition = definition; } } Tools.SkipSpaces(state.Code, ref index); if (Parser.Validate(state.Code, "from", ref index)) { if (reexport == -1) { ExceptionHelper.ThrowSyntaxError("Reexport is not allowed with this syntax", state.Code, index - 4); } Tools.SkipSpaces(state.Code, ref index); var start = index; if (!Parser.ValidateString(state.Code, ref index, false)) { ExceptionHelper.ThrowSyntaxError("Expected module name", state.Code, index); } result._reexportSourceModuleName = Tools.Unescape(state.Code.Substring(start + 1, index - start - 2), false); } else if (reexport == 1) { ExceptionHelper.ThrowSyntaxError("Expected 'from'", state.Code, index); } return(result); }