示例#1
0
        private AST_Helper.Expression parseHashLiteral()
        {
            HashLiteral hashLiteral = new HashLiteral {
                Token = this.curToken
            };

            while (!this.peekTokenIs(TokenHelper.TokenType.RBRACE))
            {
                this.nextToken();
                AST_Helper.Expression keyExpr = this.parseExpression(Parser_Helper.precedence.LOWEST);

                if (!this.expectPeek(TokenHelper.TokenType.COLON))
                {
                    return(null);
                }

                this.nextToken();
                AST_Helper.Expression valueExpr = this.parseExpression(Parser_Helper.precedence.LOWEST);

                hashLiteral.Pairs.Add(keyExpr, valueExpr);

                if (!this.peekTokenIs(TokenHelper.TokenType.RBRACE) && !this.expectPeek(TokenHelper.TokenType.COMMA))
                {
                    return(null);
                }
            }

            if (!this.expectPeek(TokenHelper.TokenType.RBRACE))
            {
                return(null);
            }

            return(hashLiteral);
        }
示例#2
0
        //this implements pratt parsing(top down recursive parsing)
        //DaBeaz's course implemented this with loop instead of recursion (so although top down, it is not recursive). Look in "Solution Items/stuff" folder
        //for snapshots showing his approach. Not only is it not recursive(he uses loops), but he has also created a func for each precendence level.
        //his approach is more readable than what we have here.
        private AST_Helper.Expression parseExpression(Parser_Helper.precedence precedence)
        {
            if (!this.prefixParseFns.ContainsKey(this.curToken.Type))
            {
                noPrefixParseFnError(this.curToken.Type);
                return(null);
            }
            Parser_Helper.prefixParserFn prefixParserFn = this.prefixParseFns[this.curToken.Type];

            AST_Helper.Expression leftExpr = prefixParserFn();

            while (!this.peekTokenIs(TokenHelper.TokenType.SEMICOLON) && precedence < this.peekPrecedence())
            {
                if (!this.infixParseFns.ContainsKey(this.peekToken.Type))
                {
                    return(leftExpr);
                }

                Parser_Helper.infixParseFn infixParseFn = this.infixParseFns[this.peekToken.Type];
                this.nextToken();
                leftExpr = infixParseFn(leftExpr);//construct a new leftExpr expression using current leftExpr and next expr as rightExpr
            }

            return(leftExpr);
        }
示例#3
0
        //this is called parseCallExpression in book.
        private AST_Helper.Expression parseFunctionCallExpression(AST_Helper.Expression function)
        {
            FunctionCallExpression functionCallExpression = new FunctionCallExpression {
                Token = this.curToken, Function = function
            };

            functionCallExpression.Arguments = this.parseExpressionList(TokenHelper.TokenType.RPAREN);

            return(functionCallExpression);
        }
示例#4
0
        //note that Grouped expression does not have a corresponding AST expression node. We have associated a 'prefixFunction' with LParen
        //as soon we enouncter that in a expression, we read the expression starting from LParen till RParen in the usual manner. Grouped Expression
        //is pushed down in the AST and sits at a lower level from non-grouped epxressions thus enforcing the precedence hierarchy.
        //For the other way around, when we serialize AST Tree, the ToString() method takes care for adding the parenthisis as it goes traversing the tree.
        private AST_Helper.Expression parseGroupedExpression()
        {
            this.nextToken();

            AST_Helper.Expression expression = this.parseExpression(Parser_Helper.precedence.LOWEST);

            if (!this.expectPeek(TokenHelper.TokenType.RPAREN))
            {
                return(null);
            }

            return(expression);
        }
示例#5
0
        private AST_Helper.Expression parseInfixExpression(AST_Helper.Expression left)
        {
            InfixExpression infixExpression = new InfixExpression {
                Token = this.curToken, Operator = this.curToken.Literal, Left = left
            };

            Parser_Helper.precedence precedence = this.curPrecedence();//precedence level of current token
            this.nextToken();

            //recursice call back to parseExpression. Control arrived here from parseExpression which we are now calling back
            infixExpression.Right = this.parseExpression(precedence);//it is here we pass precedence using the current context

            return(infixExpression);
        }
示例#6
0
        private AST_Helper.Expression parseIndexExpression(AST_Helper.Expression leftExpr)
        {
            ArrayIndexExpression arrayIndexExpression = new ArrayIndexExpression {
                Token = this.curToken, Left = leftExpr
            };

            this.nextToken();
            arrayIndexExpression.Index = this.parseExpression(Parser_Helper.precedence.LOWEST);

            if (!this.expectPeek(TokenHelper.TokenType.RBRACKET))
            {
                return(null);
            }

            return(arrayIndexExpression);
        }