variables
This commit is contained in:
parent
f5e7b7c091
commit
cf9ae469ba
5 changed files with 122 additions and 35 deletions
|
|
@ -5,34 +5,49 @@ module Lox.Interpreter (
|
|||
|
||||
import Lox.Expr
|
||||
import Lox.Scanner
|
||||
import Lox.Environment
|
||||
import Control.Monad.State
|
||||
import Control.Monad
|
||||
|
||||
data InterpreterState = InterpreterState (IO ())
|
||||
data InterpreterState = InterpreterState {io :: IO (), environment :: Environment}
|
||||
|
||||
emptyInterpreter :: InterpreterState
|
||||
emptyInterpreter = InterpreterState (return ())
|
||||
emptyInterpreter = InterpreterState {io=return (), environment=emptyEnvironment}
|
||||
|
||||
runStatements :: [Stmt] -> IO ()
|
||||
runStatements s = io
|
||||
where InterpreterState io = execState (interpret s) emptyInterpreter
|
||||
where InterpreterState {io=io} = execState (interpret s) emptyInterpreter
|
||||
|
||||
interpret :: [Stmt] -> State InterpreterState ()
|
||||
interpret = foldr ((>>) . execute) (return ())
|
||||
|
||||
execute :: Stmt -> State InterpreterState ()
|
||||
execute (Print expr) = do
|
||||
execute (PrintStmt expr) = do
|
||||
value <- evalFrom expr
|
||||
modify (\(InterpreterState s) -> InterpreterState (s >> print value))
|
||||
execute (Expression value) = void $ evalFrom value
|
||||
modify (\s@(InterpreterState {io=io}) -> s {io=io >> print value})
|
||||
execute (ExpressionStmt value) = void $ evalFrom value
|
||||
execute (VariableStmt name expr) = do
|
||||
value <- evalFrom expr
|
||||
modify (\s@(InterpreterState {environment=env}) -> s {environment=define (tokenLexeme name) value env})
|
||||
|
||||
eval :: Expr -> IO Object
|
||||
eval expr = return $ evalState (evalFrom expr) $ InterpreterState (return ())
|
||||
eval expr = return $ evalState (evalFrom expr) emptyInterpreter
|
||||
|
||||
evalFrom :: Expr -> State InterpreterState Object
|
||||
evalFrom (Literal value) = return value
|
||||
evalFrom (Grouping expr) = evalFrom expr
|
||||
evalFrom (Unary op expr) = do
|
||||
evalFrom (LiteralExpr value) = return value
|
||||
evalFrom (VariableExpr name) = do
|
||||
maybeObject <- gets (\(InterpreterState {environment=env}) -> Lox.Environment.get (tokenLexeme name) env)
|
||||
case maybeObject of
|
||||
Nothing -> error "Undefined variable"
|
||||
Just object -> return object
|
||||
evalFrom (AssignmentExpr name expr) = do
|
||||
value <- evalFrom expr
|
||||
success <- state $ f value
|
||||
if success then return value else error "Undefined variable"
|
||||
where f value s@InterpreterState {environment=env} = let (success, newEnv) = assign (tokenLexeme name) value env in (success, s {environment=newEnv})
|
||||
|
||||
evalFrom (GroupingExpr expr) = evalFrom expr
|
||||
evalFrom (UnaryExpr op expr) = do
|
||||
right <- evalFrom expr
|
||||
case (tokenType op, right) of
|
||||
(MINUS, NumberObject x) -> return $ NumberObject (-x)
|
||||
|
|
@ -40,7 +55,7 @@ evalFrom (Unary op expr) = do
|
|||
(BANG, BoolObject x) -> return $ BoolObject (not x)
|
||||
(BANG, _) -> return $ BoolObject True
|
||||
_ -> error "Type error"
|
||||
evalFrom (Binary leftExpr op rightExpr) = do
|
||||
evalFrom (BinaryExpr leftExpr op rightExpr) = do
|
||||
left <- evalFrom leftExpr
|
||||
right <- evalFrom rightExpr
|
||||
case (tokenType op, left, right) of
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue