calcString :: EExp -> MRSIO EExp
calcString str = case str of
    EStr s              -> return $ EStr s
    EAdd s1 s2          -> do
                              str1 <- calcString s1
                              str2 <- calcString s2
                              return $ concatenation str1 str2

    EFSub s             -> return s

    ELSub (EStr s) l    -> do i <- intFromEInt l
                              return $ EStr $ drop i s
    ERSub (EStr s) l    -> do i <- intFromEInt l
                              return $ EStr $ take i s
    ELRSub (EStr s) l r -> do {
        left <- intFromEInt l;
        right <- intFromEInt r;
        return $ EStr ((take (right - left)) $ drop left s)
      }
    EVar i              -> convertVar calcString i
calcString :: EExp -> MRSIO EExp
calcString str = case str of
    EStr s              -> return $ EStr s
    EAdd s1 s2          -> do
                              str1 <- calcString s1
                              str2 <- calcString s2
                              return $ concatenation str1 str2

    EFSub s             -> return s

    ELSub (EStr s) l    -> do i <- intFromEInt l
                              return $ EStr $ drop i s
    ERSub (EStr s) l    -> do i <- intFromEInt l
                              return $ EStr $ take i s
    ELRSub (EStr s) l r -> do {
        left <- intFromEInt l;
        right <- intFromEInt r;
        return $ EStr ((take (right - left)) $ drop left s)
      }
    EVar i              -> convertVar calcString i
calcString str = case str of
    EStr s              -> return $ EStr s
    EAdd s1 s2          -> do
                              str1 <- calcString s1
                              str2 <- calcString s2
                              return $ concatenation str1 str2

    EFSub s             -> return s

    ELSub (EStr s) l    -> do i <- intFromEInt l
                              return $ EStr $ drop i s
    ERSub (EStr s) l    -> do i <- intFromEInt l
                              return $ EStr $ take i s
    ELRSub (EStr s) l r -> do {
        left <- intFromEInt l;
        right <- intFromEInt r;
        return $ EStr ((take (right - left)) $ drop left s)
      }
    EVar i              -> convertVar calcString i