cakyrespa-0.0.1: src/Language/Lojban/Read.hs
module Language.Lojban.Read (
Lojban(..),
Selbri(..),
Sumti(..),
Tag(..),
Mex(..),
RelativeClause(..),
readLojban
) where
import Language.Lojban.Parser hiding (
Tag, Sumti, Selbri, KOhA, FA, Brivla, BAI, Number, LI, RelativeClause,
Time, KU, Linkargs, FIhO)
import qualified Language.Lojban.Parser as P
import Data.Maybe
main = do
let ret = readLojban ".i ko carna fi lo zunle la'u li panono"
print ret
data Lojban
= Bridi Selbri [(Tag, Sumti)]
| Vocative String
| Free [Free]
| ParseError String
deriving (Show, Eq)
data Selbri
= Brivla String
| Linkargs Selbri Sumti
deriving (Show, Eq)
data Sumti
= KOhA String
| LA (Either String Selbri)
| LE Selbri
| LO Selbri (Maybe RelativeClause)
| LI Mex
| KU
| SFIhO Selbri Sumti
deriving (Show, Eq)
data RelativeClause
= POI Lojban
| Debug String
deriving (Show, Eq)
data Mex
= Number Double
deriving (Show, Eq)
data Tag
= FA Int
| FIhO Selbri
| BAI String
| Time [String]
deriving (Show, Eq)
readLojban :: String -> Lojban
readLojban = either (ParseError . show) process . parse
process :: Text -> Lojban
process (TopText _ _ [VocativeSumti [(_, v, _)] _ _] Nothing Nothing Nothing) =
Vocative v
process (IText_1 _ _ _ [VocativeSumti [(_, v, _)] _ _] Nothing) = Vocative v
process (IText_1 _ _ _ fs@(_ : _) Nothing) = Free fs
process (IText_1 _ _ _ _ (Just t)) = process t
process (TermsBridiTail ss _ _ (SelbriTailTerms selbri ts _ _)) =
Bridi (readSelbri selbri) $ processTagSumti ss ts
process (TermsBridiTail ss _ _ (P.Selbri selbri)) =
Bridi (readSelbri selbri) $ processTagSumti ss []
process (P.Selbri selbri) = Bridi (readSelbri selbri) []
process t = error $ "process: " ++ show t
processTagSumti :: [P.Sumti] -> [P.Sumti] -> [(Tag, Sumti)]
processTagSumti s t = let
(n, e, r) = readTagSumti 1 [] [] s
(_, _, r') = readTagSumti (if n > 1 then n else 2) e [] t in r ++ r'
readTagSumti :: Int -> [Int] -> [(Tag, Sumti)] -> [P.Sumti]
-> (Int, [Int], [(Tag, Sumti)])
readTagSumti n e r [] = (n, e, reverse r)
readTagSumti n e r (TagSumti t s : rest) = case readTag t of
(Just i, tag) -> readTagSumti (next i e) (i : e) ((tag, sumti) : r) rest
(_, tag) -> readTagSumti n e ((tag, sumti) : r) rest
where
sumti = readSumti s
readTagSumti n e r (s : rest) =
readTagSumti (next n e) (n : e) ((FA n, readSumti s) : r) rest
readTag :: P.Tag -> (Maybe Int, Tag)
readTag (P.FA (_, f, _) _) = let n = fromJust $ lookup f faList in (Just n, FA n)
readTag (P.BAI _ _ (_, b, _) _ _) = (Nothing, BAI b)
readTag (P.Time _ _ _ ts) = (Nothing, Time $ map readTime ts)
readTag t = error $ "readTag: " ++ show t
readTime :: IntervalProperty -> String
readTime (ZAhO (_, z, _) _) = z
faList :: [(String, Int)]
faList = [
("fa", 1),
("fe", 2),
("fi", 3),
("fo", 4),
("fu", 5)
]
readSumti :: P.Sumti -> Sumti
readSumti (P.KOhA (_, k, _) _) = KOhA k
readSumti (LALE (_, "lo", _) _ st _ _) = LO selbri relative
where (selbri, relative) = readSumtiTail st
readSumti (P.LI _ _ m _ _) = LI $ readMex m
readSumti (P.KU _ _) = KU
readSumti (TagSumti (P.FIhO (_, "fi'o", _) _ selbri _ _) sumti) =
SFIhO (readSelbri selbri) (readSumti sumti)
readSumti s = error $ "readSumti: " ++ show s
readMex :: Operand -> Mex
readMex (P.Number n _ _) = readNumber n
-- readNumber :: P.Number -> Mex
readNumber = Number . paToInt . map (\(_, p, _) -> p)
paToInt :: [String] -> Double
paToInt = pti . reverse
where
pti [] = 0
pti (p : rest) = fromJust (lookup p paList) + 10 * pti rest
paList = [
("no", 0),
("pa", 1),
("re", 2),
("ci", 3),
("vo", 4),
("mu", 5),
("xa", 6),
("ze", 7),
("bi", 8),
("so", 9)
]
readSumtiTail :: SumtiTail -> (Selbri, Maybe RelativeClause)
readSumtiTail (SelbriRelativeClauses s Nothing) =
(readSelbri s, Nothing)
readSumtiTail (SelbriRelativeClauses s (Just r)) =
(readSelbri s, Just $ readRelativeClauses r)
readRelativeClauses :: P.RelativeClause -> RelativeClause
readRelativeClauses (NOI (_, "poi", _) _ bridi _ _) =
POI $ process bridi
readRelativeClauses r = Debug $ show r
readSelbri :: P.Selbri -> Selbri
readSelbri (P.Brivla (_, b, _) _) = Brivla b
readSelbri (P.Linkargs selbri (BE (_, "be", _) _ sumti _ _ _)) =
Linkargs (readSelbri selbri) (readSumti sumti)
readSelbri s = error $ "readSelbri: " ++ show s
next :: Int -> [Int] -> Int
next n e
| (n + 1) `elem` e = next (n + 1) e
| otherwise = n + 1