Beispiel #1
0
        //  genexpr_for  ::= "for" target_list "in" or_test [genexpr_iter]
        //  genexpr_iter ::= (genexpr_for | genexpr_if) *
        //
        //  "for" has NOT been eaten before entering this method
        private Expression ParseGeneratorExpression(Expression expr) {
            ForStatement root = ParseGenExprFor();
            Statement current = root;

            for (; ; ) {
                if (PeekToken(Tokens.KeywordForToken)) {
                    current = NestGenExpr(current, ParseGenExprFor());
                } else if (PeekToken(Tokens.KeywordIfToken)) {
                    current = NestGenExpr(current, ParseGenExprIf());
                } else {
                    // Generator Expressions have an implicit function definition and yield around their expression.
                    //  (x for i in R)
                    // becomes:
                    //   def f(): 
                    //     for i in R: yield (x)
                    ExpressionStatement ys = new ExpressionStatement(new YieldExpression(expr));
                    ys.Expression.SetLoc(_globalParent, expr.IndexSpan);
                    ys.SetLoc(_globalParent, expr.IndexSpan);
                    NestGenExpr(current, ys);
                    break;
                }
            }

            // We pass the outermost iterable in as a parameter because Python semantics
            // say that this one piece is computed at definition time rather than iteration time
            const string fname = "<genexpr>";
            Parameter parameter = new Parameter("__gen_$_parm__", 0);
            FunctionDefinition func = new FunctionDefinition(fname, new Parameter[] { parameter }, root);
            func.IsGenerator = true;
            func.SetLoc(_globalParent, root.StartIndex, GetEnd());
            func.HeaderIndex = root.EndIndex;

            //  Transform the root "for" statement
            Expression outermost = root.List;
            NameExpression ne = new NameExpression("__gen_$_parm__");
            ne.SetLoc(_globalParent, outermost.IndexSpan);
            root.List = ne;

            GeneratorExpression ret = new GeneratorExpression(func, outermost);
            ret.SetLoc(_globalParent, expr.StartIndex, GetEnd());
            return ret;
        }
Beispiel #2
0
        //  decorators ::=
        //      decorator+
        //  decorator ::=
        //      "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE
        private List<Expression> ParseDecorators() {
            List<Expression> decorators = new List<Expression>();

            while (MaybeEat(TokenKind.At)) {
                var start = GetStart();
                Expression decorator = new NameExpression(ReadName());
                decorator.SetLoc(_globalParent, start, GetEnd());
                while (MaybeEat(TokenKind.Dot)) {
                    string name = ReadNameMaybeNone();
                    decorator = new MemberExpression(decorator, name);
                    decorator.SetLoc(_globalParent, GetStart(), GetEnd());
                }
                decorator.SetLoc(_globalParent, start, GetEnd());

                if (MaybeEat(TokenKind.LeftParenthesis)) {
                    if (_sink != null) {
                        _sink.StartParameters(GetSourceSpan());
                    }
                    Arg[] args = FinishArgumentList(null);
                    decorator = FinishCallExpr(decorator, args);
                }
                decorator.SetLoc(_globalParent, start, GetEnd());
                EatNewLine();

                decorators.Add(decorator);
            }

            return decorators;
        }
Beispiel #3
0
        // primary: atom | attributeref | subscription | slicing | call 
        // atom:    identifier | literal | enclosure 
        // enclosure: 
        //      parenth_form | 
        //      list_display | 
        //      generator_expression | 
        //      dict_display | 
        //      string_conversion | 
        //      yield_atom 
        private Expression ParsePrimary() {
            Token t = PeekToken();
            Expression ret;
            switch (t.Kind) {
                case TokenKind.LeftParenthesis: // parenth_form, generator_expression, yield_atom
                    NextToken();
                    return FinishTupleOrGenExp();
                case TokenKind.LeftBracket:     // list_display
                    NextToken();
                    return FinishListValue();
                case TokenKind.LeftBrace:       // dict_display
                    NextToken();
                    return FinishDictOrSetValue();
                case TokenKind.BackQuote:       // string_conversion
                    NextToken();
                    return FinishStringConversion();
                case TokenKind.Name:            // identifier
                    NextToken();
                    string name = (string)t.Value;
                    if (_sink != null) {
                        _sink.StartName(GetSourceSpan(), name);
                    }
                    ret = new NameExpression(FixName(name));
                    ret.SetLoc(_globalParent, GetStart(), GetEnd());
                    return ret;
                case TokenKind.Constant:        // literal
                    NextToken();
                    var start = GetStart();
                    object cv = t.Value;
                    string cvs = cv as string;
                    if (cvs != null) {
                        cv = FinishStringPlus(cvs);
                    } else {
                        Bytes bytes = cv as Bytes;
                        if (bytes != null) {
                            cv = FinishBytesPlus(bytes);
                        }
                    }

                    if (t is UnicodeStringToken) {
                        ret = ConstantExpression.MakeUnicode((string)cv);
                    } else {
                        ret = new ConstantExpression(cv);
                    }
                    ret.SetLoc(_globalParent, start, GetEnd());
                    return ret;
                default:
                    ReportSyntaxError(_lookahead.Token, _lookahead.Span, ErrorCodes.SyntaxError, _allowIncomplete || _tokenizer.EndContinues);

                    // error node
                    ret = new ErrorExpression();
                    ret.SetLoc(_globalParent, _lookahead.Span.Start, _lookahead.Span.End);
                    return ret;
            }
        }
Beispiel #4
0
        // atom: '(' [testlist_gexp] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist1 '`' | NAME | NUMBER | STRING+
        private Expression ParsePrimary()
        {
            Token t = NextToken();
            Expression ret;
            switch (t.Kind) {
                case TokenKind.LeftParenthesis:
                    return FinishTupleOrGenExp();
                case TokenKind.LeftBracket:
                    return FinishListValue();
                case TokenKind.LeftBrace:
                    return FinishDictValue();
                case TokenKind.BackQuote:
                    return FinishBackquote();
                case TokenKind.Name:
                    CodeSpan span = GetSpan();
                    SymbolId name = (SymbolId)t.Value;
                    context.Sink.StartName(span, name.GetString());
                    ret = new NameExpression(FixName(name));
                    ret.SetLoc(GetExternal(), GetStart(), GetEnd());
                    return ret;
                case TokenKind.Constant:
                    Location start = GetStart();
                    object cv = t.Value;
                    if (cv is String) {
                        cv = FinishStringPlus((string)cv);
                    }
                    // todo handle STRING+
                    ret = new ConstantExpression(cv);
                    ret.SetLoc(GetExternal(), start, GetEnd());
                    return ret;
                default:
                    ReportSyntaxError(t, ErrorCodes.SyntaxError, allowingIncomplete);

                    // error node
                    ret = new ErrorExpression();
                    ret.SetLoc(GetExternal(), GetStart(), GetEnd());
                    return ret;
            }
        }
Beispiel #5
0
 //  parameter ::=
 //      identifier | "(" sublist ")"
 Expression ParseParameter(Dictionary<SymbolId, SymbolId> names)
 {
     Token t = NextToken();
     Expression ret = null;
     switch (t.Kind) {
         case TokenKind.LeftParenthesis: // sublist
             ret = ParseSublist(names);
             Eat(TokenKind.RightParenthesis);
             break;
         case TokenKind.Name:  // identifier
             CodeSpan span = GetSpan();
             SymbolId name = (SymbolId)t.Value;
             context.Sink.StartName(span, name.GetString());
             name = FixName(name);
             CheckUniqueParameter(names, name);
             ret = new NameExpression(name);
             ret.SetLoc(GetExternal(), span);
             break;
         default:
             ReportSyntaxError(t);
             ret = new ErrorExpression();
             ret.SetLoc(GetExternal(), GetStart(), GetEnd());
             break;
     }
     return ret;
 }
Beispiel #6
0
 private NameExpression ParseNameExpr(Dictionary<SymbolId, SymbolId> names)
 {
     SymbolId name = ReadName();
     if (name != SymbolTable.Empty) {
         CheckUniqueParameter(names, name);
     }
     NameExpression ne = new NameExpression(name);
     ne.SetLoc(GetExternal(), GetStart(), GetEnd());
     return ne;
 }
Beispiel #7
0
        //  decorators ::=
        //      decorator+
        //  decorator ::=
        //      "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE
        private List<Expression> ParseDecorators()
        {
            List<Expression> decorators = new List<Expression>();

            while (MaybeEat(TokenKind.At)) {
                Location start = GetStart();
                Expression decorator = new NameExpression(ReadName());
                decorator.SetLoc(GetExternal(), start, GetEnd());
                while (MaybeEat(TokenKind.Dot)) {
                    SymbolId name = ReadNameMaybeNone();
                    decorator = new FieldExpression(decorator, name);
                    decorator.SetLoc(GetExternal(), GetStart(), GetEnd());
                }
                decorator.SetLoc(GetExternal(), start, GetEnd());

                if (MaybeEat(TokenKind.LeftParenthesis)) {
                    context.Sink.StartParameters(GetSpan());
                    Arg[] args = FinishArgumentList(null);
                    decorator = FinishCallExpr(decorator, args);
                }
                decorator.SetLoc(GetExternal(), start, GetEnd());
                Eat(TokenKind.NewLine);

                decorators.Add(decorator);
            }

            return decorators;
        }
Beispiel #8
0
        // funcdef: [decorators] 'def' NAME parameters ':' suite
        // this gets called with "@" look-ahead
        private FunctionDefinition ParseDecoratedFuncDef()
        {
            Location start = GetStart();
            List<Expression> decorators = ParseDecorators();
            FunctionDefinition fnc = ParseFuncDef();
            Expression root = new NameExpression(fnc.Name);
            root.SetLoc(GetExternal(), start, GetEnd());

            for (int i = decorators.Count; i > 0; i--) {
                Expression decorator = (Expression)decorators[i - 1];
                root = FinishCallExpr(decorator, new Arg(root));
                root.SetLoc(GetExternal(), decorator.Start, decorator.End);
            }
            fnc.Decorators = root;

            return fnc;
        }