interpreter first version
This commit is contained in:
parent
05d670817e
commit
b5001499d7
4 changed files with 63 additions and 6 deletions
10
app/Main.hs
10
app/Main.hs
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
44
src/Lox/Interpreter.hs
Normal 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"
|
||||||
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue