evaluator.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  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. case *ast.FunctionLiteral:
  59. params := node.Parameters
  60. body := node.Body
  61. return &object.Function{Parameters: params, Body: body, Env: env}
  62. case *ast.CallExpression:
  63. function := Eval(node.Function, env)
  64. if isError(function) {
  65. return function
  66. }
  67. args := evalExpressions(node.Arguments, env)
  68. if len(args) == 1 && isError(args[0]) {
  69. return args[0]
  70. }
  71. return applyFunction(function, args)
  72. case *ast.StringLiteral:
  73. return &object.String{Value: node.Value}
  74. }
  75. return nil
  76. }
  77. func applyFunction(fn object.Object, args []object.Object) object.Object {
  78. switch fn := fn.(type) {
  79. case *object.Function:
  80. extendEnv := extendFunctionEnv(fn, args)
  81. evaluated := Eval(fn.Body, extendEnv)
  82. return unwrapReturnValue(evaluated)
  83. case *object.Builtin:
  84. return fn.Fn(args...)
  85. default:
  86. return newError("not a function: %s", fn.Type())
  87. }
  88. }
  89. func extendFunctionEnv(fn *object.Function, args []object.Object) *object.Environment {
  90. env := object.NewEnclosedEnvironment(fn.Env)
  91. for paramIdx, param := range fn.Parameters {
  92. env.Set(param.Value, args[paramIdx])
  93. }
  94. return env
  95. }
  96. func unwrapReturnValue(obj object.Object) object.Object {
  97. if returnValue, ok := obj.(*object.ReturnValue); ok {
  98. return returnValue.Value
  99. }
  100. return obj
  101. }
  102. func newError(format string, a ...interface{}) *object.Error {
  103. return &object.Error{Msg: fmt.Sprintf(format, a...)}
  104. }
  105. func evalProgram(node *ast.Program, env *object.Environment) object.Object {
  106. var result object.Object
  107. for _, stmt := range node.Statements {
  108. result = Eval(stmt, env)
  109. // skip return 后面的语句
  110. switch result := result.(type) {
  111. case *object.ReturnValue:
  112. return result.Value
  113. case *object.Error:
  114. return result
  115. }
  116. }
  117. return result
  118. }
  119. func nativeBooleanObject(input bool) *object.Boolean {
  120. if input {
  121. return TRUE
  122. } else {
  123. return FALSE
  124. }
  125. }
  126. func evalPrefixExpression(operator string, right object.Object) object.Object {
  127. switch operator {
  128. case "!":
  129. return evalBangOperatorExpression(right)
  130. case "-":
  131. return evalMinusPreOperatorExpression(right)
  132. default:
  133. return newError("unknown operator: %s%s", operator, right.Type())
  134. }
  135. }
  136. func evalInfixExpression(operator string, left object.Object, right object.Object) object.Object {
  137. switch {
  138. case left.Type() == object.IntegerObj && right.Type() == object.IntegerObj:
  139. return evalIntegerInfixExpression(operator, left, right)
  140. case left.Type() == object.StringObj && right.Type() == object.StringObj:
  141. return evalStringInfixExpression(operator, left, right)
  142. case operator == "==":
  143. return nativeBooleanObject(left == right)
  144. case operator == "!=":
  145. return nativeBooleanObject(left != right)
  146. case left.Type() != right.Type():
  147. return newError("type mismatch: %s %s %s", left.Type(), operator, right.Type())
  148. default:
  149. return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type())
  150. }
  151. }
  152. func evalIfExpression(node *ast.IfExpression, env *object.Environment) object.Object {
  153. condition := Eval(node.Condition, env)
  154. if isError(condition) {
  155. return condition
  156. }
  157. if isTruthy(condition) {
  158. return Eval(node.Consequence, env)
  159. } else if node.Alternative != nil {
  160. return Eval(node.Alternative, env)
  161. } else {
  162. return NULL
  163. }
  164. }
  165. func evalBlockStatements(block *ast.BlockStatement, env *object.Environment) object.Object {
  166. var result object.Object
  167. for _, stmt := range block.Statements {
  168. result = Eval(stmt, env)
  169. if result != nil {
  170. rt := result.Type()
  171. if rt == object.ReturnValueObj || rt == object.ErrorObj {
  172. return result
  173. }
  174. }
  175. }
  176. return result
  177. }
  178. func evalIntegerInfixExpression(operator string,
  179. left object.Object, right object.Object) object.Object {
  180. leftVal := left.(*object.Integer).Value
  181. rightVal := right.(*object.Integer).Value
  182. switch operator {
  183. case "+":
  184. return &object.Integer{Value: leftVal + rightVal}
  185. case "-":
  186. return &object.Integer{Value: leftVal - rightVal}
  187. case "*":
  188. return &object.Integer{Value: leftVal * rightVal}
  189. case "/":
  190. return &object.Integer{Value: leftVal / rightVal}
  191. case "<":
  192. return nativeBooleanObject(leftVal < rightVal)
  193. case ">":
  194. return nativeBooleanObject(leftVal > rightVal)
  195. case "==":
  196. return nativeBooleanObject(leftVal == rightVal)
  197. case "!=":
  198. return nativeBooleanObject(leftVal != rightVal)
  199. default:
  200. return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type())
  201. }
  202. }
  203. func evalStringInfixExpression(operator string,
  204. left object.Object, right object.Object) object.Object {
  205. // Only identifier + is valid
  206. if operator != "+" {
  207. return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type())
  208. }
  209. leftVal := left.(*object.String).Value
  210. rightVal := right.(*object.String).Value
  211. return &object.String{Value: leftVal + rightVal}
  212. }
  213. func evalMinusPreOperatorExpression(right object.Object) object.Object {
  214. if right.Type() != object.IntegerObj {
  215. return newError("unknown operator: -%s", right.Type())
  216. }
  217. value := right.(*object.Integer).Value
  218. return &object.Integer{Value: -value}
  219. }
  220. func evalBangOperatorExpression(right object.Object) object.Object {
  221. switch right {
  222. case TRUE:
  223. return FALSE
  224. case FALSE:
  225. return TRUE
  226. default:
  227. return FALSE
  228. }
  229. }
  230. func evalIdentifier(node *ast.Identifier, env *object.Environment) object.Object {
  231. if val, ok := env.Get(node.Value); ok {
  232. return val
  233. }
  234. if builtin, ok := builtins[node.Value]; ok {
  235. return builtin
  236. }
  237. return newError("identifier not found: " + node.Value)
  238. }
  239. func evalExpressions(exps []ast.Expression, env *object.Environment) []object.Object {
  240. var result []object.Object
  241. for _, e := range exps {
  242. evaluated := Eval(e, env)
  243. if isError(evaluated) {
  244. return []object.Object{evaluated}
  245. }
  246. result = append(result, evaluated)
  247. }
  248. return result
  249. }
  250. func isTruthy(obj object.Object) bool {
  251. switch obj {
  252. case NULL:
  253. return false
  254. case TRUE:
  255. return true
  256. case FALSE:
  257. return false
  258. default:
  259. return true
  260. }
  261. }
  262. func isError(obj object.Object) bool {
  263. if obj != nil {
  264. return obj.Type() == object.ErrorObj
  265. }
  266. return false
  267. }