예제 #1
0
		public virtual void PostWalk(ParenthesisExpr node) { }
예제 #2
0
		// ParenthesisExpr
		public virtual bool Walk(ParenthesisExpr node) { return true; }
예제 #3
0
		public override void PostWalk(ParenthesisExpr node) { }
예제 #4
0
		// ParenthesisExpr
		public override bool Walk(ParenthesisExpr node) { return false; }
예제 #5
0
        private Expr ParsePrimaryExpr()
        {
            int start, end, globalStart;
            Expr ret;

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

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

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

                case TokenType.LeftParenthesis:

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

                                ret = new ParenthesisExpr(ret);
                                ret.SetLoc(_globalParent, globalStart, GetEnd());
                                return ret;
                            }
                        }
                        else if (PeekToken().Kind == TokenType.Assign)
                        {
                            end = GetEnd();
                            start = GetStart();
                            NextToken();
                            var left = new IdentifierExpr(nt.Name);
                            left.SetLoc(_globalParent, start, end);
                            var right = ParseExpr();

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

                                    ret = new ParenthesisExpr(ret);
                                    ret.SetLoc(_globalParent, globalStart, GetEnd());
                                    return ret;
                                }
                            }
                            else if (PeekToken().Kind == TokenType.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 == TokenType.Comma)
                        {
                            param = new Parameter(nt.Name);
                            param.SetLoc(_globalParent, GetStart(), GetEnd());
                            parameters.Add(param);
                            goto lambda;
                        }
                        else
                        {
                            throw Assert.Unreachable;
                        }
                    }
                    else if (PeekToken(TokenType.RightParenthesis))
                    {
                        goto lambda;
                    }
                    else // not NameToken nor RightParen
                    {
                        ret = new ParenthesisExpr(ParseExpr());
                        Eat(TokenType.RightParenthesis);
                        ret.SetLoc(_globalParent, globalStart, GetEnd());
                        return ret;
                    }

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

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

                case TokenType.LeftBracket:
                    return ParseArrayLiteral();

                default:
                    return null; // syntax error
            }
        }
		// ParenthesisExpr
		public override bool Walk(ParenthesisExpr node)
		{
			node.Parent = _currentScope;
			
			return base.Walk(node);
		}