parser.go (10313B)
1 package parser 2 3 import ( 4 "fmt" 5 "umx_compiler/ast" 6 "umx_compiler/lexer" 7 "umx_compiler/token" 8 "strconv" 9 ) 10 11 const ( 12 _ int = iota 13 LOWEST 14 EQUALS // == 15 LESSGREATER // > or < 16 SUM // + 17 PRODUCT // * 18 PREFIX // -X or !X 19 CALL // myFunction(x) 20 INDEX // array[index] 21 ) 22 23 var precedences = map[token.TokenType]int{ 24 token.EQUAL: EQUALS, 25 token.NOT_EQUAL: EQUALS, 26 token.LT: LESSGREATER, 27 token.GT: LESSGREATER, 28 token.PLUS: SUM, 29 token.MINUS: SUM, 30 token.SLASH: PRODUCT, 31 token.ASTERISK: PRODUCT, 32 token.LPAREN: CALL, 33 token.LBRACKET: INDEX, 34 } 35 36 type prefixParseFn func() ast.Expression 37 type infixParseFn func(ast.Expression) ast.Expression 38 39 type Parser struct { 40 l *lexer.Lexer 41 curToken token.Token 42 peekToken token.Token 43 errors []string 44 45 prefixParseFns map[token.TokenType]prefixParseFn 46 infixParseFns map[token.TokenType]infixParseFn 47 } 48 49 func New(l *lexer.Lexer) *Parser { 50 p := &Parser{ 51 l: l, 52 errors: []string{}, 53 } 54 p.nextToken() 55 p.nextToken() 56 57 p.prefixParseFns = make(map[token.TokenType]prefixParseFn) 58 p.registerPrefix(token.IDENT, p.parseIdentifier) 59 p.registerPrefix(token.INT, p.parseIntegerLiteral) 60 p.registerPrefix(token.SHRIEK, p.parsePrefixExpression) 61 p.registerPrefix(token.MINUS, p.parsePrefixExpression) 62 63 p.infixParseFns = make(map[token.TokenType]infixParseFn) 64 p.registerInfix(token.PLUS, p.parseInfixExpression) 65 p.registerInfix(token.MINUS, p.parseInfixExpression) 66 p.registerInfix(token.SLASH, p.parseInfixExpression) 67 p.registerInfix(token.ASTERISK, p.parseInfixExpression) 68 p.registerInfix(token.EQUAL, p.parseInfixExpression) 69 p.registerInfix(token.NOT_EQUAL, p.parseInfixExpression) 70 p.registerInfix(token.LT, p.parseInfixExpression) 71 p.registerInfix(token.GT, p.parseInfixExpression) 72 73 p.registerPrefix(token.TRUE, p.parseBoolean) 74 p.registerPrefix(token.FALSE, p.parseBoolean) 75 p.registerPrefix(token.LPAREN, p.parseGroupedExpression) 76 p.registerPrefix(token.IF, p.parseIfExpression) 77 p.registerPrefix(token.FUNCTION, p.parseFunctionLiteral) 78 79 p.registerInfix(token.LPAREN, p.parseCallExpression) 80 81 p.registerPrefix(token.STRING, p.parseStringLiteral) 82 p.registerPrefix(token.LBRACKET, p.parseArrayLiteral) 83 84 p.registerInfix(token.LBRACKET, p.parseIndexExpression) 85 86 p.registerPrefix(token.LCURLY, p.parseHashLiteral) 87 88 return p 89 } 90 91 func (p *Parser) Errors() []string { 92 return p.errors 93 } 94 95 func (p *Parser) nextToken() { 96 p.curToken = p.peekToken 97 p.peekToken = p.l.NextToken() 98 } 99 100 func (p *Parser) ParseProgram() *ast.Program { 101 program := &ast.Program{} 102 program.Statements = []ast.Statement{} 103 for p.curToken.Type != token.EOF { 104 statement := p.parseStatement() 105 if statement != nil { 106 program.Statements = append(program.Statements, statement) 107 } 108 p.nextToken() 109 } 110 return program 111 } 112 113 func (p *Parser) parseStatement() ast.Statement { 114 switch p.curToken.Type { 115 case token.LET: 116 return p.parseLetStatement() 117 case token.RETURN: 118 return p.parseReturnStatement() 119 default: 120 return p.parseExpressionStatement() 121 } 122 } 123 124 func (p *Parser) parseLetStatement() *ast.LetStatement { 125 statement := &ast.LetStatement{Token: p.curToken} 126 if !p.expectPeek(token.IDENT) { 127 return nil 128 } 129 statement.Name = &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal} 130 if !p.expectPeek(token.ASSIGN) { 131 return nil 132 } 133 p.nextToken() 134 statement.Value = p.parseExpression(LOWEST) 135 if p.peekTokenIs(token.SEMICOLON) { 136 p.nextToken() 137 } 138 139 return statement 140 } 141 142 func (p *Parser) parseReturnStatement() *ast.ReturnStatement { 143 statement := &ast.ReturnStatement{Token: p.curToken} 144 p.nextToken() 145 statement.ReturnValue = p.parseExpression(LOWEST) 146 for p.peekTokenIs(token.SEMICOLON) { 147 p.nextToken() 148 } 149 150 return statement 151 } 152 153 func (p *Parser) parseExpressionStatement() *ast.ExpressionStatement { 154 statement := &ast.ExpressionStatement{Token: p.curToken} 155 statement.Expression = p.parseExpression(LOWEST) 156 if p.peekTokenIs(token.SEMICOLON) { 157 p.nextToken() 158 } 159 return statement 160 } 161 162 func (p *Parser) parseExpression(precedence int) ast.Expression { 163 prefix := p.prefixParseFns[p.curToken.Type] 164 if prefix == nil { 165 p.noPrefixParseFnError(p.curToken.Type) 166 return nil 167 } 168 leftExp := prefix() 169 170 for !p.peekTokenIs(token.SEMICOLON) && precedence < p.peekPrecedence() { 171 infix := p.infixParseFns[p.peekToken.Type] 172 if infix == nil { 173 return leftExp 174 } 175 p.nextToken() 176 leftExp = infix(leftExp) 177 } 178 return leftExp 179 } 180 181 func (p *Parser) parseIdentifier() ast.Expression { 182 return &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal} 183 } 184 185 func (p *Parser) parseIntegerLiteral() ast.Expression { 186 lit := &ast.IntegerLiteral{Token: p.curToken} 187 value, err := strconv.ParseInt(p.curToken.Literal, 0, 64) 188 if err != nil { 189 msg := fmt.Sprintf("error parsing %q as int64", p.curToken.Literal) 190 p.errors = append(p.errors, msg) 191 return nil 192 } 193 lit.Value = value 194 return lit 195 } 196 197 func (p *Parser) curTokenIs(t token.TokenType) bool { 198 return p.curToken.Type == t 199 } 200 201 func (p *Parser) peekTokenIs(t token.TokenType) bool { 202 return p.peekToken.Type == t 203 } 204 205 func (p *Parser) expectPeek(t token.TokenType) bool { 206 if p.peekTokenIs(t) { 207 p.nextToken() 208 return true 209 } else { 210 p.peekError(t) 211 return false 212 } 213 } 214 215 func (p *Parser) peekError(t token.TokenType) { 216 msg := fmt.Sprintf("token expected: %s, got: %s", t, p.peekToken.Type) 217 p.errors = append(p.errors, msg) 218 } 219 220 func (p *Parser) peekPrecedence() int { 221 if p, ok := precedences[p.peekToken.Type]; ok { 222 return p 223 } 224 return LOWEST 225 } 226 227 func (p *Parser) curPrecedence() int { 228 if p, ok := precedences[p.curToken.Type]; ok { 229 return p 230 } 231 return LOWEST 232 } 233 234 func (p *Parser) registerPrefix(tokenType token.TokenType, fn prefixParseFn) { 235 p.prefixParseFns[tokenType] = fn 236 } 237 238 func (p *Parser) registerInfix(tokenType token.TokenType, fn infixParseFn) { 239 p.infixParseFns[tokenType] = fn 240 } 241 242 func (p *Parser) noPrefixParseFnError(t token.TokenType) { 243 msg := fmt.Sprintf("no prefix parse function for %s", t) 244 p.errors = append(p.errors, msg) 245 } 246 247 func (p *Parser) parsePrefixExpression() ast.Expression { 248 expression := &ast.PrefixExpression{ 249 Token: p.curToken, 250 Operator: p.curToken.Literal, 251 } 252 p.nextToken() 253 expression.Right = p.parseExpression(PREFIX) 254 return expression 255 } 256 257 func (p *Parser) parseInfixExpression(left ast.Expression) ast.Expression { 258 expression := &ast.InfixExpression{ 259 Token: p.curToken, 260 Operator: p.curToken.Literal, 261 Left: left, 262 } 263 precedence := p.curPrecedence() 264 p.nextToken() 265 expression.Right = p.parseExpression(precedence) 266 return expression 267 } 268 269 func (p *Parser) parseBoolean() ast.Expression { 270 return &ast.Boolean{Token: p.curToken, Value: p.curTokenIs(token.TRUE)} 271 } 272 273 func (p *Parser) parseGroupedExpression() ast.Expression { 274 p.nextToken() 275 expr := p.parseExpression(LOWEST) 276 if !p.expectPeek(token.RPAREN) { 277 return nil 278 } 279 return expr 280 } 281 282 func (p *Parser) parseIfExpression() ast.Expression { 283 expr := &ast.IfExpression{Token: p.curToken} 284 if !p.expectPeek(token.LPAREN) { 285 return nil 286 } 287 p.nextToken() 288 expr.Condition = p.parseExpression(LOWEST) 289 if !p.expectPeek(token.RPAREN) { 290 return nil 291 } 292 if !p.expectPeek(token.LCURLY) { 293 return nil 294 } 295 expr.Consequence = p.parseBlockStatement() 296 if p.peekTokenIs(token.ELSE) { 297 p.nextToken() 298 if !p.expectPeek(token.LCURLY) { 299 return nil 300 } 301 expr.Alternative = p.parseBlockStatement() 302 } 303 return expr 304 } 305 306 func (p *Parser) parseBlockStatement() *ast.BlockStatement { 307 block := &ast.BlockStatement{Token: p.curToken} 308 block.Statements = []ast.Statement{} 309 p.nextToken() 310 for !p.curTokenIs(token.RCURLY) && !p.curTokenIs(token.EOF) { 311 statement := p.parseStatement() 312 if statement != nil { 313 block.Statements = append(block.Statements, statement) 314 } 315 p.nextToken() 316 } 317 return block 318 } 319 320 func (p *Parser) parseFunctionLiteral() ast.Expression { 321 lit := &ast.FunctionLiteral{Token: p.curToken} 322 if !p.expectPeek(token.LPAREN) { 323 return nil 324 } 325 lit.Parameters = p.parseFunctionParameters() 326 if !p.expectPeek(token.LCURLY) { 327 return nil 328 } 329 lit.Body = p.parseBlockStatement() 330 return lit 331 } 332 333 func (p *Parser) parseFunctionParameters() []*ast.Identifier { 334 identifiers := []*ast.Identifier{} 335 if p.peekTokenIs(token.RPAREN) { 336 p.nextToken() 337 return identifiers 338 } 339 p.nextToken() 340 ident := &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal} 341 identifiers = append(identifiers, ident) 342 for p.peekTokenIs(token.COMMA) { 343 p.nextToken() 344 p.nextToken() 345 ident := &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal} 346 identifiers = append(identifiers, ident) 347 } 348 if !p.expectPeek(token.RPAREN) { 349 return nil 350 } 351 return identifiers 352 } 353 354 func (p *Parser) parseCallExpression(function ast.Expression) ast.Expression { 355 expr := &ast.CallExpression{Token: p.curToken, Function: function} 356 expr.Arguments = p.parseExpressionList(token.RPAREN) 357 return expr 358 } 359 360 func (p *Parser) parseExpressionList(end token.TokenType) []ast.Expression { 361 args := []ast.Expression{} 362 if p.peekTokenIs(end) { 363 p.nextToken() 364 return args 365 } 366 p.nextToken() 367 args = append(args, p.parseExpression(LOWEST)) 368 for p.peekTokenIs(token.COMMA) { 369 p.nextToken() 370 p.nextToken() 371 args = append(args, p.parseExpression(LOWEST)) 372 } 373 if !p.expectPeek(end) { 374 return nil 375 } 376 return args 377 } 378 379 func (p *Parser) parseStringLiteral() ast.Expression { 380 return &ast.StringLiteral{Token: p.curToken, Value: p.curToken.Literal} 381 } 382 383 func (p *Parser) parseArrayLiteral() ast.Expression { 384 array := &ast.ArrayLiteral{Token: p.curToken} 385 array.Elements = p.parseExpressionList(token.RBRACKET) 386 return array 387 } 388 389 func (p *Parser) parseIndexExpression(left ast.Expression) ast.Expression { 390 expr := &ast.IndexExpression{Token: p.curToken, Left: left} 391 p.nextToken() 392 expr.Index = p.parseExpression(LOWEST) 393 if !p.expectPeek(token.RBRACKET) { 394 return nil 395 } 396 return expr 397 } 398 399 func (p *Parser) parseHashLiteral() ast.Expression { 400 hash := &ast.HashLiteral{Token: p.curToken} 401 hash.Pairs = make(map[ast.Expression]ast.Expression) 402 for !p.peekTokenIs(token.RCURLY) { 403 p.nextToken() 404 key := p.parseExpression(LOWEST) 405 if !p.expectPeek(token.COLON) { 406 return nil 407 } 408 p.nextToken() 409 value := p.parseExpression(LOWEST) 410 hash.Pairs[key] = value 411 if !p.peekTokenIs(token.RCURLY) && !p.expectPeek(token.COMMA) { 412 return nil 413 } 414 } 415 if !p.expectPeek(token.RCURLY) { 416 return nil 417 } 418 return hash 419 }