parser.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package parser
  2. import (
  3. "code.osinet.fr/fgm/waiig15/ast"
  4. "code.osinet.fr/fgm/waiig15/lexer"
  5. "code.osinet.fr/fgm/waiig15/token"
  6. )
  7. type Parser struct {
  8. l *lexer.Lexer
  9. curToken token.Token
  10. peekToken token.Token
  11. }
  12. func New(l *lexer.Lexer) *Parser {
  13. p := &Parser{l: l}
  14. // Read two tokens, so curToken and peeToken are both set.
  15. p.nextToken()
  16. p.nextToken()
  17. return p
  18. }
  19. func (p *Parser) nextToken() {
  20. p.curToken = p.peekToken
  21. p.peekToken = p.l.NextToken()
  22. }
  23. func (p *Parser) ParseProgram() *ast.Program {
  24. program := &ast.Program{
  25. Statements: []ast.Statement{},
  26. }
  27. for !p.curTokenIs(token.EOF) {
  28. stmt := p.parseStatement()
  29. if stmt != nil {
  30. program.Statements = append(program.Statements, stmt)
  31. }
  32. p.nextToken()
  33. }
  34. return program
  35. }
  36. func (p *Parser) parseStatement() ast.Statement {
  37. switch p.curToken.Type {
  38. case token.LET:
  39. return p.parseLetStatement()
  40. default:
  41. return nil
  42. }
  43. }
  44. func (p *Parser) parseLetStatement() *ast.LetStatement {
  45. stmt := &ast.LetStatement{
  46. Token: p.curToken,
  47. }
  48. // Let statement starts with an IDENT token, so if next token is not an
  49. // IDENT, the next statement cannot be a Let statement.
  50. if !p.expectPeek(token.IDENT) {
  51. return nil
  52. }
  53. stmt.Name = &ast.Identifier{
  54. Token: p.curToken,
  55. Value: p.curToken.Literal,
  56. }
  57. // The previous expectPeek() call fetched the next token, so we should now
  58. // be on the assignment.
  59. if !p.expectPeek(token.ASSIGN) {
  60. return nil
  61. }
  62. // Skip the expression for now, progress to the semicolon terminating the
  63. // statement.
  64. for !p.curTokenIs(token.SEMICOLON) {
  65. p.nextToken()
  66. }
  67. return stmt
  68. }
  69. // Is the current token in the parser of the given type ?
  70. func (p *Parser) curTokenIs(t token.TokenType) bool {
  71. return p.curToken.Type == t
  72. }
  73. // Is the next token in the parser of the given type ? Don't consume it.
  74. func (p *Parser) peekTokenIs(t token.TokenType) bool {
  75. return p.peekToken.Type == t
  76. }
  77. // Is the next token in the parser of the given type ? If it is, consume it,
  78. // else don't.
  79. func (p *Parser) expectPeek(t token.TokenType) bool {
  80. if p.peekTokenIs(t) {
  81. p.nextToken()
  82. return true
  83. } else {
  84. return false
  85. }
  86. }