parser_test.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package parser
  2. import (
  3. "github/runnignwater/monkey/ast"
  4. "github/runnignwater/monkey/lexer"
  5. "testing"
  6. )
  7. /**
  8. * @Author: simon
  9. * @Author: ynwdlxm@163.com
  10. * @Date: 2022/10/2 下午10:40
  11. * @Desc: LetStatement test case
  12. */
  13. func TestLetStatements(t *testing.T) {
  14. input := `
  15. let x = 5;
  16. let y = 10;
  17. let foo = 838383;
  18. `
  19. l := lexer.New(input)
  20. p := New(l)
  21. program := p.ParseProgram()
  22. checkParseErrors(t, p)
  23. if program == nil {
  24. t.Fatalf("ParseProgram() return nil")
  25. }
  26. if len(program.Statements) != 3 {
  27. t.Fatalf("Program.Statements does not contain 3 statements. got=%d", len(program.Statements))
  28. }
  29. tests := []struct {
  30. expectedIdentifies string
  31. }{
  32. {"x"},
  33. {"y"},
  34. {"foo"},
  35. }
  36. for i, tt := range tests {
  37. stmt := program.Statements[i]
  38. if !testLetStatement(t, stmt, tt.expectedIdentifies) {
  39. return
  40. }
  41. }
  42. }
  43. func TestReturnStatements(t *testing.T) {
  44. input := `
  45. return 5;
  46. return 10;
  47. return add(a,10);
  48. `
  49. l := lexer.New(input)
  50. p := New(l)
  51. program := p.ParseProgram()
  52. checkParseErrors(t, p)
  53. if len(program.Statements) != 3 {
  54. t.Fatalf("Program.Statements does not contain 3 statements. got=%d", len(program.Statements))
  55. }
  56. for _, stmt := range program.Statements {
  57. returnStmt, ok := stmt.(*ast.ReturnStatement)
  58. if !ok {
  59. t.Errorf("stmt not *ast.ReturnStatement. got=%T", stmt)
  60. continue
  61. }
  62. if returnStmt.TokenLiteral() != "return" {
  63. t.Errorf("returnStmt.TokenLiteral not 'return', got %q", returnStmt.TokenLiteral())
  64. }
  65. }
  66. }
  67. func checkParseErrors(t *testing.T, p *Parser) {
  68. errors := p.errors
  69. if len(errors) == 0 {
  70. return
  71. }
  72. t.Errorf("parse has %d errors.", len(errors))
  73. for _, msg := range errors {
  74. t.Errorf("parse error: %q", msg)
  75. }
  76. t.FailNow()
  77. }
  78. func testLetStatement(t *testing.T, s ast.Statement, name string) bool {
  79. if s.TokenLiteral() != "let" {
  80. t.Errorf("s.TokenLiteral() not 'let'. got =%q", s.TokenLiteral())
  81. return false
  82. }
  83. letStmt, ok := s.(*ast.LetStatement)
  84. if !ok {
  85. t.Errorf("s is not *ast.LetStatement. got=%T", s)
  86. return false
  87. }
  88. if letStmt.Name.Value != name {
  89. t.Errorf("letStmt.Name.Value not '%s'. got=%s", name, letStmt.Name.Value)
  90. return false
  91. }
  92. if letStmt.Name.TokenLiteral() != name {
  93. t.Errorf("s.name not '%s. got=%s", name, letStmt.Name)
  94. return false
  95. }
  96. return true
  97. }
  98. func TestIdentifier(t *testing.T) {
  99. input := "foobar;"
  100. l := lexer.New(input)
  101. p := New(l)
  102. program := p.ParseProgram()
  103. checkParseErrors(t, p)
  104. if len(program.Statements) != 1 {
  105. t.Fatalf("program has not enough statements. got=%d", len(program.Statements))
  106. }
  107. stmt, ok := program.Statements[0].(*ast.ExpressionStatement)
  108. if !ok {
  109. t.Fatalf("program.Statements[0] is not ast.ExpressionStatement. got=%T",
  110. program.Statements[0])
  111. }
  112. ident, ok := stmt.Expression.(*ast.Identifier)
  113. if !ok {
  114. t.Fatalf("exp not *ast.Identifier. got=%T", stmt.Expression)
  115. }
  116. if ident.Value != "foobar" {
  117. t.Fatalf("ident.Value not %s. got=%s", "foobar", ident.Value)
  118. }
  119. if ident.TokenLiteral() != "foobar" {
  120. t.Errorf("ident.TokenLiteral() not %s. got=%s", "foobar", ident.TokenLiteral())
  121. }
  122. }
  123. func TestIntegerLiteralExpression(t *testing.T) {
  124. input := "5;"
  125. l := lexer.New(input)
  126. p := New(l)
  127. program := p.ParseProgram()
  128. checkParseErrors(t, p)
  129. if len(program.Statements) != 1 {
  130. t.Fatalf("program has not enough statements. got=%d",
  131. len(program.Statements))
  132. }
  133. stmt, ok := program.Statements[0].(*ast.ExpressionStatement)
  134. if !ok {
  135. t.Fatalf("program.Statements[0] is not ast.ExpressionStatement. got=%T",
  136. program.Statements[0])
  137. }
  138. literal, ok := stmt.Expression.(*ast.IntegerLiteral)
  139. if !ok {
  140. t.Fatalf("exp not *ast.IntegerLiteral. got=%T", stmt.Expression)
  141. }
  142. if literal.Value != 5 {
  143. t.Errorf("literal.Value not %d. got=%d", 5, literal.Value)
  144. }
  145. if literal.TokenLiteral() != "5" {
  146. t.Errorf("literal.TokenLiteral not %s. got=%s", "5",
  147. literal.TokenLiteral())
  148. }
  149. }