-- Type functions
getType :: EExp -> MRSIO Type
getType exp = case exp of
    BTrue        -> return TBool
    BFalse       -> return TBool
    BNot _       -> return TBool

    EOr _ _      -> return TBool
    EAnd _ _     -> return TBool
    EAss _ _     -> return TBool
    ENAss _ _    -> return TBool
    ELt _ _      -> return TBool
    EGt _ _      -> return TBool
    ELEt _ _     -> return TBool
    EGEt _ _     -> return TBool

    EAdd e _     -> getType e
    ESub _ _     -> return TInt
    EMul _ _     -> return TInt
    EDiv _ _     -> return TInt

    EInt _       -> return TInt
    EChar _      -> return TChar
    EStr _       -> return TStr
    EFSub _      -> return TStr
    ELSub _ _    -> return TStr
    ERSub _ _    -> return TStr
    ELRSub _ _ _ -> return TStr
    EKey e _     -> do con_t <- getType e
                       return $ getContainerValueType con_t
    ELen _       -> return TFunc
    EOrd _       -> return TFunc
    EArrI _      -> return (TArr TInt TInt)
    EDict _ t1 t2-> return (TDict t1 t2)
    EVar v       -> askType v
    Call (Ident "longitudo") _    -> return TInt
    Call (Ident "ord") _          -> return TInt
    Call id _    -> askType id
    EFunc _ t _ _-> return t
    e            -> do putStr_Err $ "unknown type: " ++ show e
                       return TBool
getType :: EExp -> MRSIO Type
getType exp = case exp of
    BTrue        -> return TBool
    BFalse       -> return TBool
    BNot _       -> return TBool

    EOr _ _      -> return TBool
    EAnd _ _     -> return TBool
    EAss _ _     -> return TBool
    ENAss _ _    -> return TBool
    ELt _ _      -> return TBool
    EGt _ _      -> return TBool
    ELEt _ _     -> return TBool
    EGEt _ _     -> return TBool

    EAdd e _     -> getType e
    ESub _ _     -> return TInt
    EMul _ _     -> return TInt
    EDiv _ _     -> return TInt

    EInt _       -> return TInt
    EChar _      -> return TChar
    EStr _       -> return TStr
    EFSub _      -> return TStr
    ELSub _ _    -> return TStr
    ERSub _ _    -> return TStr
    ELRSub _ _ _ -> return TStr
    EKey e _     -> do con_t <- getType e
                       return $ getContainerValueType con_t
    ELen _       -> return TFunc
    EOrd _       -> return TFunc
    EArrI _      -> return (TArr TInt TInt)
    EDict _ t1 t2-> return (TDict t1 t2)
    EVar v       -> askType v
    Call (Ident "longitudo") _    -> return TInt
    Call (Ident "ord") _          -> return TInt
    Call id _    -> askType id
    EFunc _ t _ _-> return t
    e            -> do putStr_Err $ "unknown type: " ++ show e
                       return TBool
getType exp = case exp of
    BTrue        -> return TBool
    BFalse       -> return TBool
    BNot _       -> return TBool

    EOr _ _      -> return TBool
    EAnd _ _     -> return TBool
    EAss _ _     -> return TBool
    ENAss _ _    -> return TBool
    ELt _ _      -> return TBool
    EGt _ _      -> return TBool
    ELEt _ _     -> return TBool
    EGEt _ _     -> return TBool

    EAdd e _     -> getType e
    ESub _ _     -> return TInt
    EMul _ _     -> return TInt
    EDiv _ _     -> return TInt

    EInt _       -> return TInt
    EChar _      -> return TChar
    EStr _       -> return TStr
    EFSub _      -> return TStr
    ELSub _ _    -> return TStr
    ERSub _ _    -> return TStr
    ELRSub _ _ _ -> return TStr
    EKey e _     -> do con_t <- getType e
                       return $ getContainerValueType con_t
    ELen _       -> return TFunc
    EOrd _       -> return TFunc
    EArrI _      -> return (TArr TInt TInt)
    EDict _ t1 t2-> return (TDict t1 t2)
    EVar v       -> askType v
    Call (Ident "longitudo") _    -> return TInt
    Call (Ident "ord") _          -> return TInt
    Call id _    -> askType id
    EFunc _ t _ _-> return t
    e            -> do putStr_Err $ "unknown type: " ++ show e
                       return TBool