-- $Id: WhileNTest.hs,v 1.6 2004/10/18 23:47:48 leavens Exp leavens $

-- Gary T. Leavens
-- Testing for the language of Chapter 2

module WhileNTest where
import WhileNParser
import WhileNUnparser
import TypeHelpers
import WhileNTyping
import WhileNSemantics
import WhileNDomains
import WhileNProgs
import Testing

sample_store :: DStore
sample_store = [1..3] -- usually these are allocated, but some still use loc


evalP :: Program -> String
evalP p = let (Tree_Subst (_ ::: Node atr _) _) = annotate [] p
          in if atr == Aerr
             then "type error"
             else show (meaningP p emptyEnv sample_store)

evalD :: TypeEnv -> DEnvironment -> Declaration -> String
evalD tenv env d = let (Tree_Subst (_ ::: Node atr _) _) = annotate tenv d
          in if atr == Aerr
             then "type error"
             else show (meaningD d env sample_store)

evalC :: TypeEnv -> DEnvironment -> Command -> String
evalC tenv env c = let (Tree_Subst (_ ::: Node atr _) _) = annotate tenv c
          in if atr == Aerr
             then "type error"
             else show (meaningC c env sample_store)

evalE :: TypeEnv -> DEnvironment -> Expression -> String
evalE tenv env e = let (Tree_Subst (_ ::: Node atr _) _) = annotate tenv e
          in if atr == Aerr
             then "type error"
             else show (meaningE e env sample_store)


repP :: String -> IO ()
repP = putStrLn . evalP . read
repD :: TypeEnv -> DEnvironment -> String -> IO ()
repD tenv env = putStrLn . (evalD tenv env) . read
repC :: TypeEnv -> DEnvironment -> String -> IO ()
repC tenv env = putStrLn . (evalC tenv env) . read
repE :: TypeEnv -> DEnvironment -> String -> IO ()
repE tenv env = putStrLn . (evalE tenv env) . read


test n = repP (prog n)


runP :: String -> DStore
runP p = let parsedP = (read p)
             (Tree_Subst (_ ::: Node atr _) _) = annotate [] parsedP
         in if atr == Aerr
	    then error "type error"
	    else meaningP parsedP emptyEnv sample_store


tests :: [TestCase DStore DStore]
tests = map (\(p,m) -> eqTest p (runP p) (m sample_store)) progs_with_results

-- The following runs all the test programs

go :: IO ()
go = run_tests tests

-- The following is a read_eval_print loop for programs.

read_eval_print :: IO()
read_eval_print =
  do putStr "? "
     catch (do p <- getLine
               putStrLn (show (runP p))
               read_eval_print)
           (\e -> return ())

-- The following allows one to read a program in from a file, and run it.
-- Note that Haskell's readFile primitive allows you to get a string
-- for a program from a file
     
run_from_file :: FilePath -> IO()
run_from_file f = 
   do p <- readFile f
      repP p
