-- Datentyp für While-Programme gemäß Übung 6 GdC module ProgType where import List(transpose) -- Programm: Name Deklarationen Anweisungen data Program_ = Prog String [(Var,Type_)] [Stmt] data Type_ = I | B type Var = String data Stmt = Print_ Expr | Assign_ Var Expr | If_ Cond Stmt | While_ Cond Stmt | Block_ [Stmt] data Cond = Rel RelOp_ Expr Expr | And Cond Cond | Or Cond Cond 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 Type_ where showsPrec _ I = shows "Int" showsPrec _ B = shows "Bool" 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 showsPrec _ (And b1 b2) = showsBrackets b1 b2 '&' showsPrec _ (Or b1 b2) = showsBrackets b1 b2 '|' 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) = showsBrackets e1 e2 c showsBrackets :: (Show a) => a -> a -> Char -> ShowS showsBrackets x1 x2 op = showString "(" . shows x1 . showString (' ':op:" ") . shows x2 . showString ")" -- indentation function: show_stmts :: String -> [Stmt] -> String show_stmts _ [] = "" show_stmts ind ((Print_ e ):ss) = ind ++ "print " ++ show e ++ 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 show_stmts ind ((Block_ sts):ss) = ind ++ "{\n" ++ (show_stmts ('\t':ind) sts)++ ind ++ "}" ++ rest where rest = "\n" ++ show_stmts ind ss