check :: Condition -> Statement -> Reporter ()
check c s = let { ss = substatements s } in case c of  
    And cs -> forM_ cs $ \ c -> check c s
    No_Loops -> whine "Das Programm darf keine Schleifen enthalten." 
            $ filter ( \ case While {} -> True ; _ -> False ) ss
    No_Labels -> whine "Das Programm darf keine Marken enthalten." 
            $ filter ( \ case Label {} -> True ; _ -> False ) ss
    No_Gotos -> whine "Das Programm darf keine Sprünge enthalten." 
            $ filter ( \ case Goto {} -> True ; _ -> False ) ss
    Simple_Branches -> whine "Alle Verzweigungen sollen die Form 'if (b) goto l' haben."
            $ filter ( \ case 
                 Branch c y n -> case (y,n) of (Goto _, Nothing) -> False; _ -> True 
                 _ -> False ) ss
    Simple_Loops -> whine "Alle Schleifen sollen einfach sein (ohne break/continue)."
            $ filter ( \ case Break _ -> True ; Continue _ -> True ; _ -> False ) ss
    Flat -> case s of
        Block ss -> whine "Der Block darf keine Blöcke enthalten."
            $ filter ( \ case Block _ -> True ; _ -> False ) $ ss >>= substatements
        _ -> reject $ text "Das Programm soll ein Block sein."


check :: Condition -> Statement -> Reporter ()
check c s = let { ss = substatements s } in case c of  
    And cs -> forM_ cs $ \ c -> check c s
    No_Loops -> whine "Das Programm darf keine Schleifen enthalten." 
            $ filter ( \ case While {} -> True ; _ -> False ) ss
    No_Labels -> whine "Das Programm darf keine Marken enthalten." 
            $ filter ( \ case Label {} -> True ; _ -> False ) ss
    No_Gotos -> whine "Das Programm darf keine Sprünge enthalten." 
            $ filter ( \ case Goto {} -> True ; _ -> False ) ss
    Simple_Branches -> whine "Alle Verzweigungen sollen die Form 'if (b) goto l' haben."
            $ filter ( \ case 
                 Branch c y n -> case (y,n) of (Goto _, Nothing) -> False; _ -> True 
                 _ -> False ) ss
    Simple_Loops -> whine "Alle Schleifen sollen einfach sein (ohne break/continue)."
            $ filter ( \ case Break _ -> True ; Continue _ -> True ; _ -> False ) ss
    Flat -> case s of
        Block ss -> whine "Der Block darf keine Blöcke enthalten."
            $ filter ( \ case Block _ -> True ; _ -> False ) $ ss >>= substatements
        _ -> reject $ text "Das Programm soll ein Block sein."
check c s = let { ss = substatements s } in case c of  
    And cs -> forM_ cs $ \ c -> check c s
    No_Loops -> whine "Das Programm darf keine Schleifen enthalten." 
            $ filter ( \ case While {} -> True ; _ -> False ) ss
    No_Labels -> whine "Das Programm darf keine Marken enthalten." 
            $ filter ( \ case Label {} -> True ; _ -> False ) ss
    No_Gotos -> whine "Das Programm darf keine Sprünge enthalten." 
            $ filter ( \ case Goto {} -> True ; _ -> False ) ss
    Simple_Branches -> whine "Alle Verzweigungen sollen die Form 'if (b) goto l' haben."
            $ filter ( \ case 
                 Branch c y n -> case (y,n) of (Goto _, Nothing) -> False; _ -> True 
                 _ -> False ) ss
    Simple_Loops -> whine "Alle Schleifen sollen einfach sein (ohne break/continue)."
            $ filter ( \ case Break _ -> True ; Continue _ -> True ; _ -> False ) ss
    Flat -> case s of
        Block ss -> whine "Der Block darf keine Blöcke enthalten."
            $ filter ( \ case Block _ -> True ; _ -> False ) $ ss >>= substatements
        _ -> reject $ text "Das Programm soll ein Block sein."