evaluator.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  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. case *ast.ArrayLiteral:
  75. elements := evalExpressions(node.Element, env)
  76. if len(elements) == 1 && isError(elements[0]) {
  77. // return object.Error
  78. return elements[0]
  79. }
  80. return &object.Array{Elements: elements}
  81. case *ast.IndexExpression:
  82. left := Eval(node.Left, env)
  83. if isError(left) {
  84. return left
  85. }
  86. index := Eval(node.Index, env)
  87. if isError(index) {
  88. return index
  89. }
  90. return evalIndexExpression(left, index)
  91. case *ast.HashLiteral:
  92. return evalHashLiteral(node, env)
  93. }
  94. return nil
  95. }
  96. func applyFunction(fn object.Object, args []object.Object) object.Object {
  97. switch fn := fn.(type) {
  98. case *object.Function:
  99. extendEnv := extendFunctionEnv(fn, args)
  100. evaluated := Eval(fn.Body, extendEnv)
  101. return unwrapReturnValue(evaluated)
  102. case *object.Builtin:
  103. return fn.Fn(args...)
  104. default:
  105. return newError("not a function: %s", fn.Type())
  106. }
  107. }
  108. func extendFunctionEnv(fn *object.Function, args []object.Object) *object.Environment {
  109. env := object.NewEnclosedEnvironment(fn.Env)
  110. for paramIdx, param := range fn.Parameters {
  111. env.Set(param.Value, args[paramIdx])
  112. }
  113. return env
  114. }
  115. func unwrapReturnValue(obj object.Object) object.Object {
  116. if returnValue, ok := obj.(*object.ReturnValue); ok {
  117. return returnValue.Value
  118. }
  119. return obj
  120. }
  121. func newError(format string, a ...interface{}) *object.Error {
  122. return &object.Error{Msg: fmt.Sprintf(format, a...)}
  123. }
  124. func evalProgram(node *ast.Program, env *object.Environment) object.Object {
  125. var result object.Object
  126. for _, stmt := range node.Statements {
  127. result = Eval(stmt, env)
  128. // skip return 后面的语句
  129. switch result := result.(type) {
  130. case *object.ReturnValue:
  131. return result.Value
  132. case *object.Error:
  133. return result
  134. }
  135. }
  136. return result
  137. }
  138. func nativeBooleanObject(input bool) *object.Boolean {
  139. if input {
  140. return TRUE
  141. } else {
  142. return FALSE
  143. }
  144. }
  145. func evalPrefixExpression(operator string, right object.Object) object.Object {
  146. switch operator {
  147. case "!":
  148. return evalBangOperatorExpression(right)
  149. case "-":
  150. return evalMinusPreOperatorExpression(right)
  151. default:
  152. return newError("unknown operator: %s%s", operator, right.Type())
  153. }
  154. }
  155. func evalInfixExpression(operator string, left object.Object, right object.Object) object.Object {
  156. switch {
  157. case left.Type() == object.IntegerObj && right.Type() == object.IntegerObj:
  158. return evalIntegerInfixExpression(operator, left, right)
  159. case left.Type() == object.StringObj && right.Type() == object.StringObj:
  160. return evalStringInfixExpression(operator, left, right)
  161. case operator == "==":
  162. return nativeBooleanObject(left == right)
  163. case operator == "!=":
  164. return nativeBooleanObject(left != right)
  165. case left.Type() != right.Type():
  166. return newError("type mismatch: %s %s %s", left.Type(), operator, right.Type())
  167. default:
  168. return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type())
  169. }
  170. }
  171. func evalIfExpression(node *ast.IfExpression, env *object.Environment) object.Object {
  172. condition := Eval(node.Condition, env)
  173. if isError(condition) {
  174. return condition
  175. }
  176. if isTruthy(condition) {
  177. return Eval(node.Consequence, env)
  178. } else if node.Alternative != nil {
  179. return Eval(node.Alternative, env)
  180. } else {
  181. return NULL
  182. }
  183. }
  184. func evalBlockStatements(block *ast.BlockStatement, env *object.Environment) object.Object {
  185. var result object.Object
  186. for _, stmt := range block.Statements {
  187. result = Eval(stmt, env)
  188. if result != nil {
  189. rt := result.Type()
  190. if rt == object.ReturnValueObj || rt == object.ErrorObj {
  191. return result
  192. }
  193. }
  194. }
  195. return result
  196. }
  197. func evalIntegerInfixExpression(operator string,
  198. left object.Object, right object.Object) object.Object {
  199. leftVal := left.(*object.Integer).Value
  200. rightVal := right.(*object.Integer).Value
  201. switch operator {
  202. case "+":
  203. return &object.Integer{Value: leftVal + rightVal}
  204. case "-":
  205. return &object.Integer{Value: leftVal - rightVal}
  206. case "*":
  207. return &object.Integer{Value: leftVal * rightVal}
  208. case "/":
  209. return &object.Integer{Value: leftVal / rightVal}
  210. case "<":
  211. return nativeBooleanObject(leftVal < rightVal)
  212. case ">":
  213. return nativeBooleanObject(leftVal > rightVal)
  214. case "==":
  215. return nativeBooleanObject(leftVal == rightVal)
  216. case "!=":
  217. return nativeBooleanObject(leftVal != rightVal)
  218. default:
  219. return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type())
  220. }
  221. }
  222. func evalStringInfixExpression(operator string,
  223. left object.Object, right object.Object) object.Object {
  224. // Only identifier + is valid
  225. if operator != "+" {
  226. return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type())
  227. }
  228. leftVal := left.(*object.String).Value
  229. rightVal := right.(*object.String).Value
  230. return &object.String{Value: leftVal + rightVal}
  231. }
  232. func evalMinusPreOperatorExpression(right object.Object) object.Object {
  233. if right.Type() != object.IntegerObj {
  234. return newError("unknown operator: -%s", right.Type())
  235. }
  236. value := right.(*object.Integer).Value
  237. return &object.Integer{Value: -value}
  238. }
  239. func evalBangOperatorExpression(right object.Object) object.Object {
  240. switch right {
  241. case TRUE:
  242. return FALSE
  243. case FALSE:
  244. return TRUE
  245. default:
  246. return FALSE
  247. }
  248. }
  249. func evalIdentifier(node *ast.Identifier, env *object.Environment) object.Object {
  250. if val, ok := env.Get(node.Value); ok {
  251. return val
  252. }
  253. if builtin, ok := builtins[node.Value]; ok {
  254. return builtin
  255. }
  256. return newError("identifier not found: " + node.Value)
  257. }
  258. func evalExpressions(exps []ast.Expression, env *object.Environment) []object.Object {
  259. var result []object.Object
  260. for _, e := range exps {
  261. evaluated := Eval(e, env)
  262. if isError(evaluated) {
  263. return []object.Object{evaluated}
  264. }
  265. result = append(result, evaluated)
  266. }
  267. return result
  268. }
  269. func evalIndexExpression(left, index object.Object) object.Object {
  270. switch {
  271. case left.Type() == object.ArrayObj && index.Type() == object.IntegerObj:
  272. return evalArrayIndexExpression(left, index)
  273. case left.Type() == object.HashObj:
  274. return evalHashIndexExpression(left, index)
  275. default:
  276. return newError("index operator not supported: %s", left.Type())
  277. }
  278. }
  279. func evalArrayIndexExpression(array, index object.Object) object.Object {
  280. arrayObj := array.(*object.Array)
  281. idx := index.(*object.Integer).Value
  282. max := int64(len(arrayObj.Elements) - 1)
  283. if idx < 0 || idx > max {
  284. return NULL
  285. }
  286. return arrayObj.Elements[idx]
  287. }
  288. func evalHashIndexExpression(hash, index object.Object) object.Object {
  289. hashObj := hash.(*object.Hash)
  290. key, ok := index.(object.Hashtable)
  291. if !ok {
  292. return newError("unusable as hash key: %s", index.Type())
  293. }
  294. pair, ok := hashObj.Pairs[key.HashKey()]
  295. if !ok {
  296. return NULL
  297. }
  298. return pair.Value
  299. }
  300. func evalHashLiteral(node *ast.HashLiteral, env *object.Environment) object.Object {
  301. pairs := make(map[object.HashKey]object.HashPair)
  302. for keyNode, valueNode := range node.Pairs {
  303. key := Eval(keyNode, env)
  304. if isError(key) {
  305. return key
  306. }
  307. hashKey, ok := key.(object.Hashtable)
  308. if !ok {
  309. return newError("unusable as hash key: %s", key.Type())
  310. }
  311. value := Eval(valueNode, env)
  312. if isError(value) {
  313. return value
  314. }
  315. hashed := hashKey.HashKey()
  316. pairs[hashed] = object.HashPair{Key: key, Value: value}
  317. }
  318. return &object.Hash{Pairs: pairs}
  319. }
  320. func isTruthy(obj object.Object) bool {
  321. switch obj {
  322. case NULL:
  323. return false
  324. case TRUE:
  325. return true
  326. case FALSE:
  327. return false
  328. default:
  329. return true
  330. }
  331. }
  332. func isError(obj object.Object) bool {
  333. if obj != nil {
  334. return obj.Type() == object.ErrorObj
  335. }
  336. return false
  337. }