evaluator.go 4.7 KB

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