interpreter first version

This commit is contained in:
Oleg Sobolev 2025-12-25 18:41:04 +03:00
parent 05d670817e
commit b5001499d7
4 changed files with 63 additions and 6 deletions

View file

@ -1,10 +1,12 @@
module Main where
import Lox.Scanner import Lox.Scanner
import Lox.Parser
import Lox.Interpreter
run :: String -> IO () run :: String -> IO ()
run source = mapM_ print tokens run source = print result
where tokens = scanTokensFromSource source where result = eval expr
expr = parse tokens
tokens = scanTokensFromSource source
main :: IO () main :: IO ()
main = getLine >>= run main = getLine >>= run

View file

@ -54,7 +54,7 @@ common warnings
ghc-options: -Wall ghc-options: -Wall
library library
exposed-modules: Lox.Scanner, Lox.Expr, Lox.Parser exposed-modules: Lox.Scanner, Lox.Expr, Lox.Parser, Lox.Interpreter
build-depends: base ^>=4.18.3.0, mtl, extra build-depends: base ^>=4.18.3.0, mtl, extra
hs-source-dirs: src hs-source-dirs: src
default-language: Haskell2010 default-language: Haskell2010

44
src/Lox/Interpreter.hs Normal file
View file

@ -0,0 +1,44 @@
module Lox.Interpreter (
eval
) where
import Lox.Expr
import Lox.Scanner
import Control.Monad.State
data InterpreterState = InterpreterState
eval :: Expr -> Object
eval expr = evalState (interpret expr) InterpreterState
interpret :: Expr -> State InterpreterState Object
interpret (Literal value) = return value
interpret (Grouping expr) = interpret expr
interpret (Unary op expr) = do
right <- interpret expr
case (getType op, right) of
(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
case (getType op, left, right) of
(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"

View file

@ -22,7 +22,18 @@ data TokenType = LEFT_PAREN | RIGHT_PAREN | LEFT_BRACE | RIGHT_BRACE
| EOF | EOF
deriving (Show, Eq) deriving (Show, Eq)
data Object = NullObject | StringObject String | NumberObject Double | BoolObject Bool deriving Show data Object = NullObject
| StringObject String
| NumberObject Double
| BoolObject Bool
deriving (Eq)
instance Show Object where
show NullObject = "Nil"
show (StringObject s) = show s
show (NumberObject x) = show x
show (BoolObject False) = "false"
show (BoolObject True) = "true"
data Token = Token { data Token = Token {
getType :: TokenType, getType :: TokenType,