Пример #1
0
        private static AstFor ParseForIn(TokenStream tks)
        {
            var si = tks.SourceInfo;

            tks.Expect(TokenType.For);
            var ident = tks.Expect(TokenType.Ident).StringValue;

            tks.Expect(TokenType.In);
            var @from = ParseExpression(tks);

            tks.Expect(TokenType.DotDot);
            var to       = ParseExpression(tks);
            var opTk     = tks.Accept(TokenType.Plus, TokenType.Minus);
            var updateOp = opTk?.Type ?? TokenType.Plus;

            tks.Expect(TokenType.LCurBracket);
            var body = ParseBody(tks);

            tks.Expect(TokenType.RCurBracket);

            var pre    = new AstDeclaration(si, ident, null, @from);
            var condOp = (updateOp == TokenType.Plus)
                    ? TokenType.LessThanEquals
                    : TokenType.GreaterThanEquals;
            var itrId   = new AstIdent(si, ident);
            var cond    = new AstBinaryOp(si, itrId, condOp, to);
            var update_ = new AstBinaryOp(si, itrId, updateOp, new AstNumber(si, 1));
            var update  = new AstAssign(si, itrId, update_);

            return(new AstFor(si, new List <AstNode> {
                pre
            }, cond, new List <AstExpression> {
                update
            }, body));
        }
Пример #2
0
        private static AstExpression ParseBinaryOpHelper(TokenStream tks, AstExpression lhs, int minPrec)
        {
            var si     = tks.SourceInfo;
            var binOps = BinaryOpPrec.Select(kvp => kvp.Key).ToArray();

            while (true)
            {
                var op       = tks.Current;
                var thisPrec = GetBinOpPrec(op);
                if (thisPrec < minPrec)
                {
                    return(lhs);
                }
                tks.ThrowIfTokenIsNotIn(binOps);
                tks.Advance();

                var rhs      = ParseUnaryOp(tks);
                var next     = tks.Current;
                var nextPrec = GetBinOpPrec(next);
                if (thisPrec < nextPrec ||
                    (thisPrec == nextPrec && IsBinOpRightAssoc(op)))
                {
                    rhs = ParseBinaryOpHelper(tks, rhs, thisPrec + 1);
                }
                lhs = new AstBinaryOp(si, lhs, op.Type, rhs);
            }
        }