evaluator.go 5.2 KB

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