示例#1
0
        private Expression ParsePrimaryExpression()
        {
            int start, end, globalStart;
            Expression ret;

            // lambda handling
            List<Parameter> parameters = new List<Parameter>();
            Parameter param;
            bool startBody = false;

            switch (PeekToken().Kind)
            {
                case TokenKind.Name:
                    NameToken nameToken = (NameToken)NextToken();
                    globalStart = GetStart();
                    if (_sink != null)
                        _sink.StartName(GetSourceSpan(), nameToken.Name);
                    ret = new NameExpression(nameToken.Name);
                    ret.SetLoc(_globalParent, GetStart(), GetEnd());
                    if (MaybeEat(TokenKind.Arrow))
                    {
                        param = new Parameter(nameToken.Name);
                        param.SetLoc(_globalParent, ret.IndexSpan);
                        parameters.Add(param);
                        startBody = true;
                        goto lambda;
                    }
                    return ret;

                case TokenKind.Constant:
                    ConstantValueToken constantToken = (ConstantValueToken)NextToken();
                    start = GetStart();
                    object cv = constantToken.Value;
                    if (cv == null)
                    {
                        ret = new ConstantExpression(null);
                    }
                    else if (cv is bool)
                    {
                        ret = new ConstantExpression((bool)cv);
                    }
                    else if (cv is string)
                    {
                        ret = new ConstantExpression((string)cv);
                    }
                    else if (cv is int)
                    {
                        ret = new ConstantExpression((int)cv);
                    }
                    else if (cv is Uninitialized)
                    {
                        ret = new ConstantExpression(Uninitialized.Instance);
                    }
                    else if (cv is double)
                    {
                        ret = new ConstantExpression((double)cv);
                    }
                    else if (cv is BigInteger)
                    {
                        ret = new ConstantExpression((BigInteger)cv);
                    }
                    else
                    {
                        throw Assert.Unreachable;
                    }
                    ret.SetLoc(_globalParent, GetStart(), GetEnd());
                    return ret;

                case TokenKind.LeftParenthesis:

                    NextToken();
                    start = GetStart();
                    globalStart = GetStart();
                    if (PeekToken().Kind == TokenKind.Name) // may be lambda: (a = 2) => a;
                    {
                        NameToken nt = (NameToken)NextToken();
                        if (PeekToken().Kind == TokenKind.RightParenthesis)
                        {
                            end = GetEnd();
                            start = GetStart();
                            NextToken();
                            if (MaybeEat(TokenKind.Arrow))
                            {
                                param = new Parameter(nt.Name);
                                param.SetLoc(_globalParent, GetStart(), end);
                                parameters.Add(param);
                                startBody = true;
                                goto lambda;
                            }
                            else
                            {
                                ret = new NameExpression(nt.Name);
                                ret.SetLoc(_globalParent, start, end);

                                ret = new ParenthesisExpression(ret);
                                ret.SetLoc(_globalParent, globalStart, GetEnd());
                                return ret;
                            }
                        }
                        else if (PeekToken().Kind == TokenKind.Assign)
                        {
                            end = GetEnd();
                            start = GetStart();
                            NextToken();
                            var left = new NameExpression(nt.Name);
                            left.SetLoc(_globalParent, start, end);
                            var right = ParseExpression();

                            if (PeekToken().Kind == TokenKind.RightParenthesis)
                            {
                                end = GetEnd();
                                NextToken();
                                if (MaybeEat(TokenKind.Arrow))
                                {
                                    param = new Parameter(nt.Name, right);
                                    param.SetLoc(_globalParent, left.StartIndex, right.EndIndex);
                                    parameters.Add(param);
                                    startBody = true;
                                    goto lambda;
                                }
                                else
                                {
                                    ret = new AssignExpression(TokenKind.Assign, left, right);
                                    ret.SetLoc(_globalParent, start, end);

                                    ret = new ParenthesisExpression(ret);
                                    ret.SetLoc(_globalParent, globalStart, GetEnd());
                                    return ret;
                                }
                            }
                            else if (PeekToken().Kind == TokenKind.Comma)
                            {
                                param = new Parameter(nt.Name, right);
                                param.SetLoc(_globalParent, start, GetEnd());
                                parameters.Add(param);
                                goto lambda;
                            }
                            else
                            {
                                throw Assert.Unreachable;
                            }
                        }
                        else if (PeekToken().Kind == TokenKind.Comma)
                        {
                            param = new Parameter(nt.Name);
                            param.SetLoc(_globalParent, GetStart(), GetEnd());
                            parameters.Add(param);
                            goto lambda;
                        }
                        else
                        {
                            throw Assert.Unreachable;
                        }
                    }
                    else if (PeekToken(TokenKind.RightParenthesis))
                    {
                        goto lambda;
                    }
                    else // not NameToken nor RightParen
                    {
                        ret = new ParenthesisExpression(ParseExpression());
                        Eat(TokenKind.RightParenthesis);
                        ret.SetLoc(_globalParent, globalStart, GetEnd());
                        return ret;
                    }

                    lambda: // parse the rest of the lambda
                    if (!startBody)
                    {
                        while (MaybeEat(TokenKind.Comma))
                        {
                            NameToken nt = (NameToken)NextToken(TokenKind.Name);
                            start = GetStart();
                            Expression defaultVal = MaybeEat(TokenKind.Assign) ? ParseExpression() : null;
                            param = new Parameter(nt.Name, defaultVal);
                            param.SetLoc(_globalParent, start, GetEnd());
                            parameters.Add(param);
                        }
                        Eat(TokenKind.RightParenthesis);
                        Eat(TokenKind.Arrow);
                    }

                    return ParseLambdaBody(globalStart, parameters.ToArray());

                case TokenKind.LeftBracket:
                    return ParseArrayLiteral();

                default:
                    return null; // syntax error
            }
        }
示例#2
0
        // assignment_expression: conditional_expression ( '=' conditional_expression )*
        private Expression ParseAssignmentExpression()
        {
            Expression ret = ParseConditionalExpression();
            if (ret == null)
                return ret;

            while (IsAssignToken(PeekToken()))
            {
                var token = NextToken();
                var start = ret.StartIndex;
                ret = new AssignExpression(token.Kind, ret, ParseConditionalExpression());
                ret.SetLoc(_globalParent, start, GetEnd());
            }
            return ret;
        }
示例#3
0
 public override bool Walk(AssignExpression node)
 {
     node.Parent = _currentScope;
     return true;
 }