packages feed

spade-0.1.0.3: src/Interpreter.hs

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 ()