-- Datentyp für While-Programme gemäß Übung 6 CB (WS03) module ProgType where import List(transpose) data Program = Prog String [Var] [Stmt] -- Name Deklarationen Anweisungen type Var = String data Stmt = Print Var | Assign Var Expr | If Cond [Stmt] | While Cond [Stmt] data Cond = Rel RelOp Expr Expr data RelOp = Eq | NEq | LE | LEq | GR | GEq -- = != < <= > >= data Expr = V Var | N Int | Op Char Expr Expr ------------------------ Show --------------------------------- instance Show Program where showsPrec _ (Prog name vars stmts) = showString ("program "++name ++ "\n vars: ") . shows vars . showString "\n" . shows stmts instance Show Stmt where showsPrec _ stmt x = show_stmts "" [stmt] ++ x showList stmts x = show_stmts "" stmts ++ x instance Show Cond where showsPrec _ (Rel op e1 e2) = shows e1 . shows op . shows e2 instance Show RelOp where showsPrec _ Eq = showString " = " showsPrec _ NEq = showString " != " showsPrec _ LE = showString " < " showsPrec _ LEq = showString " <= " showsPrec _ GR = showString " > " showsPrec _ GEq = showString " >= " instance Show Expr where showsPrec _ (V var) = showString var showsPrec _ (N int) = shows int showsPrec _ (Op c e1 e2) = showString "(" . shows e1 . showString (' ':c:" ") . shows e2 . showString ")" -- indentation function: show_stmts :: String -> [Stmt] -> String show_stmts _ [] = "" show_stmts ind ((Print var ):ss) = ind ++ "print " ++ var ++ rest where rest = "\n" ++ show_stmts ind ss show_stmts ind ((Assign st e):ss) = ind ++ st ++ " := " ++ (show e) ++ rest where rest = "\n" ++ show_stmts ind ss show_stmts ind ((If e s1 ):ss) = ind ++ "if "++(show e)++" then \n" ++ (show_stmts ('\t':ind) s1) ++ rest where rest = "\n" ++ show_stmts ind ss show_stmts ind ((While c st):ss) = ind ++ "while "++(show c)++" do\n"++ (show_stmts ('\t':ind) st)++rest where rest = "\n" ++ show_stmts ind ss -- Testdaten ----------------------------- stmts = take 20 $ drop 40 stmts' shuffle :: [[a]] -> [a] shuffle = concat . transpose stmts' = shuffle [ [Assign var exp | var <- vars , exp <- exps ], cycle [Print var | var <- vars ], [ If c [While c [s1,s2]] | s1 <- stmts', s2 <- stmts',c <- conds ] , [ While c [If c [s1,s2]] | s1 <- stmts', s2 <- stmts',c <- conds ] ] vars = ["a","b","c"] exps = take 3 exps' exps' = (map V vars) ++ map N [1..3] ++ [ Op op e1 e2 | op <- "+*",e1 <- exps', e2 <- exps' ] conds = [ Rel op e1 (exps'!!13) | e1 <- exps, op <- [Eq,LE,GEq]] sampleprogram = Prog "Testprogramm" vars stmts