| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- package evaluator
- import (
- "github/runnignwater/monkey/ast"
- "github/runnignwater/monkey/object"
- )
- var (
- NULL = &object.Null{}
- TRUE = &object.Boolean{Value: true}
- FALSE = &object.Boolean{Value: false}
- )
- func Eval(node ast.Node) object.Object {
- switch node := node.(type) {
- // Statements
- case *ast.Program:
- return evalStatements(node.Statements)
- case *ast.ExpressionStatement:
- return Eval(node.Expression)
- // Expression
- case *ast.IntegerLiteral:
- return &object.Integer{Value: node.Value}
- case *ast.Boolean:
- return nativeBooleanObject(node.Value)
- case *ast.PrefixExpression:
- right := Eval(node.Right)
- return evalPrefixExpression(node.Operator, right)
- case *ast.InfixExpression:
- left := Eval(node.Left)
- right := Eval(node.Right)
- return evalInfixExpression(node.Operator, left, right)
- }
- return nil
- }
- func evalStatements(stmts []ast.Statement) object.Object {
- var result object.Object
- for _, statement := range stmts {
- result = Eval(statement)
- }
- return result
- }
- func nativeBooleanObject(input bool) *object.Boolean {
- if input {
- return TRUE
- } else {
- return FALSE
- }
- }
- func evalPrefixExpression(operator string, right object.Object) object.Object {
- switch operator {
- case "!":
- return evalBangOperatorExpression(right)
- case "-":
- return evalMinusPreOperatorExpression(right)
- default:
- return NULL
- }
- }
- func evalInfixExpression(operator string, left object.Object, right object.Object) object.Object {
- switch {
- case left.Type() == object.IntegerObj && right.Type() == object.IntegerObj:
- return evalIntegerInfixExpression(operator, left, right)
- case operator == "==":
- return nativeBooleanObject(left == right)
- case operator == "!=":
- return nativeBooleanObject(left != right)
- default:
- return NULL
- }
- }
- func evalIntegerInfixExpression(operator string,
- left object.Object, right object.Object) object.Object {
- leftVal := left.(*object.Integer).Value
- rightVal := right.(*object.Integer).Value
- switch operator {
- case "+":
- return &object.Integer{Value: leftVal + rightVal}
- case "-":
- return &object.Integer{Value: leftVal - rightVal}
- case "*":
- return &object.Integer{Value: leftVal * rightVal}
- case "/":
- return &object.Integer{Value: leftVal / rightVal}
- case "<":
- return nativeBooleanObject(leftVal < rightVal)
- case ">":
- return nativeBooleanObject(leftVal > rightVal)
- case "==":
- return nativeBooleanObject(leftVal == rightVal)
- case "!=":
- return nativeBooleanObject(leftVal != rightVal)
- default:
- return NULL
- }
- }
- func evalMinusPreOperatorExpression(right object.Object) object.Object {
- if right.Type() != object.IntegerObj {
- return NULL
- }
- value := right.(*object.Integer).Value
- return &object.Integer{Value: -value}
- }
- func evalBangOperatorExpression(right object.Object) object.Object {
- switch right {
- case TRUE:
- return FALSE
- case FALSE:
- return TRUE
- default:
- return FALSE
- }
- }
|