module Language.Bond.Codegen.CustomMapping
( AliasMapping(..)
, Fragment(..)
, NamespaceMapping(..)
, parseAliasMapping
, parseNamespaceMapping
) where
import Data.Char
import Control.Applicative
import Prelude
import Text.Parsec hiding (many, optional, (<|>))
import Language.Bond.Syntax.Types
data Fragment =
Fragment String |
Placeholder Int
data AliasMapping = AliasMapping
{ aliasName :: QualifiedName
, aliasTemplate :: [Fragment]
}
data NamespaceMapping = NamespaceMapping
{ fromNamespace :: QualifiedName
, toNamespace :: QualifiedName
}
type Parser a = Parsec SourceName () a
whitespace :: Parser String
whitespace = many (char ' ') <?> "whitespace"
identifier :: Parser String
identifier = many1 (alphaNum <|> char '_') <?> "identifier"
qualifiedName :: Parser [String]
qualifiedName = sepBy1 identifier (char '.') <?> "qualified name"
symbol :: String -> Parser String
symbol s = whitespace *> string s <* whitespace
equal :: Parser String
equal = symbol "="
integer :: Parser Integer
integer = decimal <$> many1 digit <?> "decimal number"
where
decimal = foldl (\x d -> 10 * x + toInteger (digitToInt d)) 0
parseAliasMapping :: String -> Either ParseError AliasMapping
parseAliasMapping s = parse aliasMapping s s
where
aliasMapping = AliasMapping <$> qualifiedName <* equal <*> many1 (placeholder <|> fragment) <* eof
placeholder = Placeholder <$> fromIntegral <$> between (char '{') (char '}') integer
fragment = Fragment <$> many1 (noneOf "{")
parseNamespaceMapping :: String -> Either ParseError NamespaceMapping
parseNamespaceMapping s = parse namespaceMapping s s
where
namespaceMapping = NamespaceMapping <$> qualifiedName <* equal <*> qualifiedName