private Expression parseExpression(Precedence precedence) { ParserTracing.Trace($"expression({precedence})"); if (!_prefixParseFunctions.TryGetValue(_currentToken.Type, out var prefix)) { noPrefixParseFnError(_currentToken.Type); return(null); } var leftExp = prefix(); while (!peekTokenIs(TokenType.SEMICOLON) && precedence < peekPrecedence()) { if (!_infixParseFunctions.TryGetValue(_peekToken.Type, out var infix)) { return(null); } nextToken(); leftExp = infix(leftExp); } ParserTracing.Untrace($"expression({precedence})"); return(leftExp); }
private LetStatement parseLetStatement() { ParserTracing.Trace("let statement"); var token = _currentToken; if (!expectPeek(TokenType.IDENT)) { return(null); } var name = new Identifier { Token = _currentToken, Value = _currentToken.Literal }; if (!expectPeek(TokenType.EQUALS)) { return(null); } nextToken(); var value = parseExpression(Precedence.LOWEST); if (!expectPeek(TokenType.SEMICOLON)) { return(null); } ParserTracing.Untrace("let statement"); return(new LetStatement { Token = token, Name = name, Value = value }); }
private Expression parseBoolean() { ParserTracing.Trace("boolean"); ParserTracing.Untrace("boolean"); return(new BooleanExpression { Token = _currentToken, Value = curTokenIs(TokenType.TRUE) }); }
private Expression parseIdentifier() { ParserTracing.Trace("identifier"); ParserTracing.Untrace("identifier"); return(new Identifier { Token = _currentToken, Value = _currentToken.Literal }); }
private Expression parseCallExpression(Expression function) { ParserTracing.Trace("call expression"); var token = _currentToken; var arguments = parseExpressionList(TokenType.RPAREN); ParserTracing.Untrace("call expression"); return(new CallExpression { Token = token, Function = function, Arguments = arguments }); }
private Expression parsePrefixExpression() { ParserTracing.Trace("prefix expression"); var token = _currentToken; var op = _currentToken.Literal; nextToken(); var right = parseExpression(Precedence.PREFIX); ParserTracing.Untrace("prefix expression"); return(new PrefixExpression { Token = token, Op = op, Right = right }); }
private Expression parseGroupedExpression() { ParserTracing.Trace("grouped expression"); nextToken(); var exp = parseExpression(Precedence.LOWEST); if (!expectPeek(TokenType.RPAREN)) { return(null); } ParserTracing.Untrace("grouped expression"); return(exp); }
private Expression parseInfixExpression(Expression left) { ParserTracing.Trace("infix expression"); var token = _currentToken; var op = _currentToken.Literal; var precedence = curPrecedence(); nextToken(); var right = parseExpression(precedence); ParserTracing.Untrace("infix expression"); return(new InfixExpression { Token = token, Left = left, Op = op, Right = right }); }
private ExpressionStatement parseExpressionStatement() { ParserTracing.Trace("expression statement"); var token = _currentToken; var expression = parseExpression(Precedence.LOWEST); if (peekTokenIs(TokenType.SEMICOLON)) { nextToken(); } ParserTracing.Untrace("expression statement"); return(new ExpressionStatement { Token = token, Expression = expression }); }
private ReturnStatement parseReturnStatement() { ParserTracing.Trace("return statement"); var token = _currentToken; nextToken(); var returnValue = parseExpression(Precedence.LOWEST); if (!expectPeek(TokenType.SEMICOLON)) { return(null); } ParserTracing.Untrace("return statement"); return(new ReturnStatement { Token = token, ReturnValue = returnValue }); }
private Expression parseIntegerLiteral() { ParserTracing.Trace("integer literal"); var token = _currentToken; if (!Int64.TryParse(_currentToken.Literal, System.Globalization.NumberStyles.None, null, out var value)) { var msg = $"could not parse \"{_currentToken.Literal}\" as integer"; ParserTracing.Error(msg); _errors.Add(msg); return(null); } ParserTracing.Untrace("integer literal"); return(new IntegerLiteral { Token = token, Value = value }); }
private Expression parseIfExpression() { ParserTracing.Trace("if expression"); var token = _currentToken; if (!expectPeek(TokenType.LPAREN)) { return(null); } nextToken(); var condition = parseExpression(Precedence.LOWEST); if (!expectPeek(TokenType.RPAREN)) { return(null); } if (!expectPeek(TokenType.LBRACE)) { return(null); } var consequence = parseBlockStatement(); BlockStatement alternative = null; if (peekTokenIs(TokenType.ELSE)) { nextToken(); if (!expectPeek(TokenType.LBRACE)) { return(null); } alternative = parseBlockStatement(); } ParserTracing.Untrace("if expression"); return(new IfExpression { Token = token, Condition = condition, Consequence = consequence, Alternative = alternative }); }
public Program ParseProgram() { var program = new Program(); ParserTracing.Trace("program"); while (_currentToken.Type != TokenType.EOF) { var stmt = parseStatement(); if (stmt != null) { program.Statements.Add(stmt); } nextToken(); } ParserTracing.Untrace("program"); return(program); }
private ImmutableList <Identifier> parseFunctionParameters() { ParserTracing.Trace("function parameters"); var identifiers = new List <Identifier>(); if (peekTokenIs(TokenType.RPAREN)) { nextToken(); return(identifiers.ToImmutableList()); } nextToken(); var ident = new Identifier { Token = _currentToken, Value = _currentToken.Literal }; identifiers.Add(ident); while (peekTokenIs(TokenType.COMMA)) { nextToken(); nextToken(); var suffixIdent = new Identifier { Token = _currentToken, Value = _currentToken.Literal }; identifiers.Add(suffixIdent); } if (!expectPeek(TokenType.RPAREN)) { return(null); } ParserTracing.Untrace("function parameters"); return(identifiers.ToImmutableList()); }
private Statement parseStatement() { ParserTracing.Trace("statement"); Statement s; switch (_currentToken.Type) { case TokenType.LET: s = parseLetStatement(); break; case TokenType.RETURN: s = parseReturnStatement(); break; default: s = parseExpressionStatement(); break; } ParserTracing.Untrace("statement"); return(s); }
private Expression parseFunctionLiteral() { ParserTracing.Trace("function"); var token = _currentToken; if (!expectPeek(TokenType.LPAREN)) { return(null); } var parameters = parseFunctionParameters(); if (!expectPeek(TokenType.LBRACE)) { return(null); } var body = parseBlockStatement(); ParserTracing.Untrace("function"); return(new FunctionLiteral { Token = token, Parameters = parameters, Body = body }); }
private BlockStatement parseBlockStatement() { ParserTracing.Trace("block statement"); var token = _currentToken; var statements = new List <Statement>(); nextToken(); while (!curTokenIs(TokenType.RBRACE) && !curTokenIs(TokenType.EOF)) { var stmt = parseStatement(); if (stmt != null) { statements.Add(stmt); } nextToken(); } ParserTracing.Untrace("block statement"); return(new BlockStatement { Token = token, Statements = statements.ToImmutableArray() }); }