module Interpreter where import Prelude hiding (map) import Control.Monad import Control.Monad.Catch (finally) import Data.IORef (newIORef) import Data.Map as M hiding (map) import Compiler.AST.Program import Control.Monad.State.Strict import Interpreter.Common import Interpreter.Initialize import Interpreter.Interpreter import Interpreter.Lib.SDL interpret :: (InterpreterState -> InterpreterState) -> Program -> IO InterpreterState interpret stFn prg = snd <$> do sdlWindowsRef <- newIORef [] let istate = emptyIs sdlWindowsRef flip runStateT (stFn istate) $ (do loadBuiltIns interpretPassOne prg interpretPassTwo prg ) `finally` cleanupSDL interpretPassOne :: Program -> InterpretM () interpretPassOne x = mapM_ (\a -> fn a) x where fn :: ProgramStatement -> InterpretM () fn (FunctionDefStatement fdef@(FunctionDef name _ _)) = modify $ mapGlobalScope $ \s -> insert (SkIdentifier name) (ProcedureValue fdef) s fn _ = pure () interpretPassTwo :: Program -> InterpretM () interpretPassTwo x = mapM_ (\a -> fn a) x where fn :: ProgramStatement -> InterpretM () fn (FunctionDefStatement (FunctionDef _ _ _)) = pure () fn (NakedStatement fs) = void $ executeStatement fs fn (TopLevelComment _) = pure ()