{-# LANGUAGE TemplateHaskell #-}

-- |Module `StringRewriting` include type of string rewriting system and useful
--  objects for working with it. This module also export other useful modules.
module StringRewriting (
    GeneratorsDescr,
    StringRewriting,
    stringRewriting,
    rules,
    generatorsDescr,
    module StringRewriting.Rule,
    module Containers,
    module Lens,
  ) where

import StringRewriting.Rule
import Containers
import Lens

import Data.Maybe (fromMaybe)

type GeneratorsDescr = IsoMap Generator String

data StringRewriting = SR
  { StringRewriting -> Rules
_rules :: Rules
  , StringRewriting -> GeneratorsDescr
_generatorsDescr :: GeneratorsDescr
  }

stringRewriting :: Rules -> GeneratorsDescr -> StringRewriting
stringRewriting :: Rules -> GeneratorsDescr -> StringRewriting
stringRewriting = Rules -> GeneratorsDescr -> StringRewriting
SR

makeLenses ''StringRewriting

instance Show StringRewriting where
    show :: StringRewriting -> String
show StringRewriting
sr =
        ((Rule -> String) -> Rules -> String)
-> Rules -> (Rule -> String) -> String
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Rule -> String) -> Rules -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (StringRewriting
srStringRewriting -> Getting Rules StringRewriting Rules -> Rules
forall s a. s -> Getting a s a -> a
^.Getting Rules StringRewriting Rules
Lens' StringRewriting Rules
rules) ((Rule -> String) -> String) -> (Rule -> String) -> String
forall a b. (a -> b) -> a -> b
$ \Rule
r ->
            let showGen :: Generator -> String
showGen Generator
g = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
"???" (StringRewriting
srStringRewriting
-> Getting (Maybe String) StringRewriting (Maybe String)
-> Maybe String
forall s a. s -> Getting a s a -> a
^.(GeneratorsDescr -> Const (Maybe String) GeneratorsDescr)
-> StringRewriting -> Const (Maybe String) StringRewriting
Lens' StringRewriting GeneratorsDescr
generatorsDescr((GeneratorsDescr -> Const (Maybe String) GeneratorsDescr)
 -> StringRewriting -> Const (Maybe String) StringRewriting)
-> Generator
-> Getting (Maybe String) StringRewriting (Maybe String)
forall c k v (m :: * -> *) x y.
(Indexable c k v, MonadFail m) =>
Getting x y c -> k -> Getting x y (m v)
.@Generator
g)
                showGWord :: [Generator] -> String
showGWord = [String] -> String
unwords ([String] -> String)
-> ([Generator] -> [String]) -> [Generator] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Generator -> String) -> [Generator] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Generator -> String
showGen
            in  [Generator] -> String
showGWord (Rule
rRule -> Getting [Generator] Rule [Generator] -> [Generator]
forall s a. s -> Getting a s a -> a
^.Getting [Generator] Rule [Generator]
Lens' Rule [Generator]
left) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" -> " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [Generator] -> String
showGWord (Rule
rRule -> Getting [Generator] Rule [Generator] -> [Generator]
forall s a. s -> Getting a s a -> a
^.Getting [Generator] Rule [Generator]
Lens' Rule [Generator]
right) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n"