evaluator.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package evaluator
  2. import (
  3. "github/runnignwater/monkey/ast"
  4. "github/runnignwater/monkey/object"
  5. )
  6. var (
  7. NULL = &object.Null{}
  8. TRUE = &object.Boolean{Value: true}
  9. FALSE = &object.Boolean{Value: false}
  10. )
  11. func Eval(node ast.Node) object.Object {
  12. switch node := node.(type) {
  13. // Statements
  14. case *ast.Program:
  15. return evalProgram(node)
  16. case *ast.ExpressionStatement:
  17. return Eval(node.Expression)
  18. // Expression
  19. case *ast.IntegerLiteral:
  20. return &object.Integer{Value: node.Value}
  21. case *ast.Boolean:
  22. return nativeBooleanObject(node.Value)
  23. case *ast.PrefixExpression:
  24. right := Eval(node.Right)
  25. return evalPrefixExpression(node.Operator, right)
  26. case *ast.InfixExpression:
  27. left := Eval(node.Left)
  28. right := Eval(node.Right)
  29. return evalInfixExpression(node.Operator, left, right)
  30. case *ast.BlockStatement:
  31. return evalBlockStatements(node)
  32. case *ast.IfExpression:
  33. return evalIfExpression(node)
  34. case *ast.ReturnStatement:
  35. val := Eval(node.ReturnValue)
  36. return &object.ReturnValue{Value: val}
  37. }
  38. return nil
  39. }
  40. func evalProgram(node *ast.Program) object.Object {
  41. var result object.Object
  42. for _, stmt := range node.Statements {
  43. result = Eval(stmt)
  44. // skip return 后面的语句
  45. if rVal, ok := result.(*object.ReturnValue); ok {
  46. return rVal.Value
  47. }
  48. }
  49. return result
  50. }
  51. func nativeBooleanObject(input bool) *object.Boolean {
  52. if input {
  53. return TRUE
  54. } else {
  55. return FALSE
  56. }
  57. }
  58. func evalPrefixExpression(operator string, right object.Object) object.Object {
  59. switch operator {
  60. case "!":
  61. return evalBangOperatorExpression(right)
  62. case "-":
  63. return evalMinusPreOperatorExpression(right)
  64. default:
  65. return NULL
  66. }
  67. }
  68. func evalInfixExpression(operator string, left object.Object, right object.Object) object.Object {
  69. switch {
  70. case left.Type() == object.IntegerObj && right.Type() == object.IntegerObj:
  71. return evalIntegerInfixExpression(operator, left, right)
  72. case operator == "==":
  73. return nativeBooleanObject(left == right)
  74. case operator == "!=":
  75. return nativeBooleanObject(left != right)
  76. default:
  77. return NULL
  78. }
  79. }
  80. func evalIfExpression(node *ast.IfExpression) object.Object {
  81. condition := Eval(node.Condition)
  82. if isTruthy(condition) {
  83. return Eval(node.Consequence)
  84. } else if node.Alternative != nil {
  85. return Eval(node.Alternative)
  86. } else {
  87. return NULL
  88. }
  89. }
  90. func evalBlockStatements(node *ast.BlockStatement) object.Object {
  91. var result object.Object
  92. for _, stmt := range node.Statements {
  93. result = Eval(stmt)
  94. if result != nil && result.Type() == object.ReturnValueObj {
  95. return result
  96. }
  97. }
  98. return result
  99. }
  100. func evalIntegerInfixExpression(operator string,
  101. left object.Object, right object.Object) object.Object {
  102. leftVal := left.(*object.Integer).Value
  103. rightVal := right.(*object.Integer).Value
  104. switch operator {
  105. case "+":
  106. return &object.Integer{Value: leftVal + rightVal}
  107. case "-":
  108. return &object.Integer{Value: leftVal - rightVal}
  109. case "*":
  110. return &object.Integer{Value: leftVal * rightVal}
  111. case "/":
  112. return &object.Integer{Value: leftVal / rightVal}
  113. case "<":
  114. return nativeBooleanObject(leftVal < rightVal)
  115. case ">":
  116. return nativeBooleanObject(leftVal > rightVal)
  117. case "==":
  118. return nativeBooleanObject(leftVal == rightVal)
  119. case "!=":
  120. return nativeBooleanObject(leftVal != rightVal)
  121. default:
  122. return NULL
  123. }
  124. }
  125. func evalMinusPreOperatorExpression(right object.Object) object.Object {
  126. if right.Type() != object.IntegerObj {
  127. return NULL
  128. }
  129. value := right.(*object.Integer).Value
  130. return &object.Integer{Value: -value}
  131. }
  132. func evalBangOperatorExpression(right object.Object) object.Object {
  133. switch right {
  134. case TRUE:
  135. return FALSE
  136. case FALSE:
  137. return TRUE
  138. default:
  139. return FALSE
  140. }
  141. }
  142. func isTruthy(obj object.Object) bool {
  143. switch obj {
  144. case NULL:
  145. return false
  146. case TRUE:
  147. return true
  148. case FALSE:
  149. return false
  150. default:
  151. return true
  152. }
  153. }