/// <summary>
 /// Analyses the tokens to produce an AST of Expr.
 /// When <paramref name="allowGlobalUse"/> is true and <see cref="Config.GlobalScope"/> is true, the top-level declarations
 /// go into the global scope.
 /// </summary>
 /// <param name="p">Tokeinzer to analyse.</param>
 /// <param name="allowGlobalUse">False to scope declarations to this analysis.</param>
 /// <returns>The AST (that may be a <see cref="SyntaxErrorExpr"/> or contains such errors).</returns>
 public Expr Analyse(JSTokenizer p, bool allowGlobalUse = true)
 {
     _parser = p;
     if (!(allowGlobalUse && _scope.GlobalScope))
     {
         _scope.OpenScope();
     }
     return(HandleBlock(Expression(0)));
 }
        Expr HandleAssign(Expr left, bool pureAssign = false)
        {
            var          location = _parser.Location;
            AccessorExpr a        = left as AccessorExpr;

            if (a == null)
            {
                return(new SyntaxErrorExpr(location, "Invalid assignment left-hand side."));
            }
            if (pureAssign || _parser.Match(JSTokenizerToken.Assign))
            {
                return(new AssignExpr(location, a, Expression(JSTokenizer.PrecedenceLevel(JSTokenizerToken.Comma))));
            }
            JSTokenizerToken binaryTokenType = JSTokenizer.FromAssignOperatorToBinary(_parser.CurrentToken);

            _parser.Forward();
            return(new AssignExpr(location, a, new BinaryExpr(location, left, binaryTokenType, Expression(0))));
        }
        Expr HandleUnaryExpr()
        {
            var loc = _parser.Location;
            var t   = _parser.CurrentToken;

            _parser.Forward();
            // Unary operators are JSTokenizerToken.OpLevel14, except Minus and Plus that are classified as binary operators and are associated to OpLevel12.
            var right = Expression(JSTokenizer.PrecedenceLevel(JSTokenizerToken.OpLevel14));

            if (t == JSTokenizerToken.PlusPlus || t == JSTokenizerToken.MinusMinus)
            {
                AccessorExpr a = right as AccessorExpr;
                if (a == null)
                {
                    return(new SyntaxErrorExpr(loc, "invalid increment operand."));
                }
                return(new PrePostIncDecExpr(loc, a, t == JSTokenizerToken.PlusPlus, true, right.IsStatement));
            }
            return(new UnaryExpr(loc, t, right));
        }
        Expr HandleCall(Expr left)
        {
            SourceLocation loc        = _parser.PrevNonCommentLocation;
            IList <Expr>   parameters = null;

            if (!_parser.Match(JSTokenizerToken.ClosePar))
            {
                for ( ; ;)
                {
                    Debug.Assert(JSTokenizer.PrecedenceLevel(JSTokenizerToken.Comma) == 2);
                    Expr e = Expression(2);
                    if (e is SyntaxErrorExpr)
                    {
                        return(e);
                    }

                    if (parameters == null)
                    {
                        parameters = new List <Expr>();
                    }
                    parameters.Add(e);

                    if (_parser.Match(JSTokenizerToken.ClosePar))
                    {
                        break;
                    }
                    if (!_parser.Match(JSTokenizerToken.Comma))
                    {
                        return(new SyntaxErrorExpr(_parser.Location, "Expected ) opened at {0}.", loc));
                    }
                }
            }
            var arguments = parameters != null?parameters.ToArray() : Expr.EmptyArray;

            return(new AccessorCallExpr(loc, left, arguments, _parser.Match(JSTokenizerToken.SemiColon)));
        }
Exemple #5
0
            NotImplementedException UnsupportedOperatorException()
            {
                string msg = String.Format("Unsupported binary operator: '{0}' ({1}).", JSTokenizer.Explain(Expr.BinaryOperatorToken), (int)Expr.BinaryOperatorToken);

                return(new NotImplementedException(msg));
            }
Exemple #6
0
 /// <summary>
 /// This is just to ease debugging.
 /// </summary>
 /// <returns>Readable expression.</returns>
 public override string ToString()
 {
     return(Left.ToString() + JSTokenizer.Explain(BinaryOperatorToken) + Right.ToString());
 }
Exemple #7
0
 public override string ToString()
 {
     return(JSTokenizer.Explain(TokenType) + Expression.ToString());
 }
 Expr HandleLogicalExpr(Expr left)
 {
     _parser.Forward();
     // Right associative operators to support short-circuit (hence the -1 on the level).
     return(new BinaryExpr(_parser.PrevNonCommentLocation, left, _parser.PrevNonCommentToken, Expression(JSTokenizer.PrecedenceLevel(_parser.PrevNonCommentToken) - 1)));
 }
 Expr HandleBinaryExpr(Expr left)
 {
     _parser.Forward();
     return(new BinaryExpr(_parser.PrevNonCommentLocation, left, _parser.PrevNonCommentToken, Expression(JSTokenizer.PrecedenceLevel(_parser.PrevNonCommentToken))));
 }
Exemple #10
0
            NotSupportedException UnsupportedOperatorException()
            {
                string msg = String.Format("Unsupported unary operator: '{0}' ({1}).", JSTokenizer.Explain(Expr.TokenType), (int)Expr.TokenType);

                return(new NotSupportedException(msg));
            }