evaluator.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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 evalStatements(node.Statements)
  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. }
  27. return nil
  28. }
  29. func evalStatements(stmts []ast.Statement) object.Object {
  30. var result object.Object
  31. for _, statement := range stmts {
  32. result = Eval(statement)
  33. }
  34. return result
  35. }
  36. func nativeBooleanObject(input bool) *object.Boolean {
  37. if input {
  38. return TRUE
  39. } else {
  40. return FALSE
  41. }
  42. }
  43. func evalPrefixExpression(operator string, right object.Object) object.Object {
  44. switch operator {
  45. case "!":
  46. return evalBangOperatorExpression(right)
  47. case "-":
  48. return evalMinusPreOperatorExpression(right)
  49. default:
  50. return NULL
  51. }
  52. }
  53. func evalMinusPreOperatorExpression(right object.Object) object.Object {
  54. if right.Type() != object.IntegerObj {
  55. return NULL
  56. }
  57. value := right.(*object.Integer).Value
  58. return &object.Integer{Value: -value}
  59. }
  60. func evalBangOperatorExpression(right object.Object) object.Object {
  61. switch right {
  62. case TRUE:
  63. return FALSE
  64. case FALSE:
  65. return TRUE
  66. default:
  67. return FALSE
  68. }
  69. }