Beispiel #1
0
        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);
        }
Beispiel #2
0
        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
            });
        }
Beispiel #3
0
        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);
        }