crafting-interpreters-hs/src/Lox/Interpreter.hs

45 lines
1.7 KiB
Haskell
Raw Normal View History

2025-12-25 18:41:04 +03:00
module Lox.Interpreter (
eval
) where
import Lox.Expr
import Lox.Scanner
import Control.Monad.State
data InterpreterState = InterpreterState
2025-12-29 23:57:15 +03:00
eval :: Expr -> IO Object
eval expr = return $ evalState (interpret expr) InterpreterState
2025-12-25 18:41:04 +03:00
interpret :: Expr -> State InterpreterState Object
interpret (Literal value) = return value
interpret (Grouping expr) = interpret expr
interpret (Unary op expr) = do
right <- interpret expr
2025-12-25 18:48:12 +03:00
case (tokenType op, right) of
2025-12-25 18:41:04 +03:00
(MINUS, NumberObject x) -> return $ NumberObject (-x)
(BANG, NullObject) -> return $ BoolObject False
(BANG, BoolObject x) -> return $ BoolObject (not x)
(BANG, _) -> return $ BoolObject True
_ -> error "Type error"
interpret (Binary leftExpr op rightExpr) = do
left <- interpret leftExpr
right <- interpret rightExpr
2025-12-25 18:48:12 +03:00
case (tokenType op, left, right) of
2025-12-25 18:41:04 +03:00
(PLUS, NumberObject x, NumberObject y) -> return $ NumberObject (x + y)
(MINUS, NumberObject x, NumberObject y) -> return $ NumberObject (x - y)
(SLASH, NumberObject x, NumberObject y) -> return $ NumberObject (x / y)
(STAR, NumberObject x, NumberObject y) -> return $ NumberObject (x * y)
(GREATER, NumberObject x, NumberObject y) -> return $ BoolObject (x > y)
(GREATER_EQUAL, NumberObject x, NumberObject y) -> return $ BoolObject (x >= y)
(LESS, NumberObject x, NumberObject y) -> return $ BoolObject (x < y)
(LESS_EQUAL, NumberObject x, NumberObject y) -> return $ BoolObject (x <= y)
(PLUS, StringObject s, StringObject t) -> return $ StringObject (s ++ t)
(EQUAL_EQUAL, x, y) -> return $ BoolObject (x == y)
_ -> error "Type error"