mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 19:42:50 -06:00
Add binary instances
This commit is contained in:
@@ -1,18 +1,9 @@
|
|||||||
-- {-# LANGUAGE BangPatterns, FlexibleContexts #-}
|
|
||||||
module GF.Compile.GrammarToLPGF (mkCanon2lpgf) where
|
module GF.Compile.GrammarToLPGF (mkCanon2lpgf) where
|
||||||
|
|
||||||
import LPGF (LPGF (..))
|
import LPGF (LPGF (..))
|
||||||
import qualified LPGF as L
|
import qualified LPGF as L
|
||||||
|
|
||||||
--import GF.Compile.Export
|
|
||||||
-- import GF.Compile.GeneratePMCFG
|
|
||||||
-- import GF.Compile.GenerateBC
|
|
||||||
--
|
|
||||||
import PGF.CId
|
import PGF.CId
|
||||||
-- import PGF.Internal(fidInt,fidFloat,fidString,fidVar)
|
|
||||||
-- import PGF.Internal(updateProductionIndices)
|
|
||||||
-- import qualified PGF.Internal as C
|
|
||||||
-- import qualified PGF.Internal as D
|
|
||||||
import GF.Grammar.Predef
|
import GF.Grammar.Predef
|
||||||
import GF.Grammar.Grammar
|
import GF.Grammar.Grammar
|
||||||
import qualified GF.Grammar.Lookup as Look
|
import qualified GF.Grammar.Lookup as Look
|
||||||
@@ -26,11 +17,8 @@ import GF.Data.Operations
|
|||||||
|
|
||||||
import Control.Monad (forM_)
|
import Control.Monad (forM_)
|
||||||
import Data.List (elemIndex)
|
import Data.List (elemIndex)
|
||||||
-- import qualified Data.Set as Set
|
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Data.Maybe (mapMaybe)
|
import Data.Maybe (mapMaybe)
|
||||||
-- import qualified Data.IntMap as IntMap
|
|
||||||
-- import Data.Array.IArray
|
|
||||||
|
|
||||||
mkCanon2lpgf :: Options -> SourceGrammar -> ModuleName -> IOE LPGF
|
mkCanon2lpgf :: Options -> SourceGrammar -> ModuleName -> IOE LPGF
|
||||||
mkCanon2lpgf opts gr am = do
|
mkCanon2lpgf opts gr am = do
|
||||||
@@ -42,30 +30,22 @@ mkCanon2lpgf opts gr am = do
|
|||||||
L.concretes = Map.fromList cncs
|
L.concretes = Map.fromList cncs
|
||||||
}
|
}
|
||||||
where
|
where
|
||||||
-- cenv = resourceValues opts gr
|
|
||||||
|
|
||||||
mkAbstr :: ModuleName -> IOE (CId, L.Abstr)
|
mkAbstr :: ModuleName -> IOE (CId, L.Abstr)
|
||||||
mkAbstr am = do
|
mkAbstr am = do
|
||||||
let
|
let
|
||||||
-- aflags = err (const noOptions) mflags (lookupModule gr am)
|
|
||||||
|
|
||||||
adefs =
|
adefs =
|
||||||
[((cPredefAbs,c), AbsCat (Just (L NoLoc []))) | c <- [cFloat,cInt,cString]] ++
|
[((cPredefAbs,c), AbsCat (Just (L NoLoc []))) | c <- [cFloat,cInt,cString]] ++
|
||||||
Look.allOrigInfos gr am
|
Look.allOrigInfos gr am
|
||||||
|
|
||||||
-- flags = Map.fromList [(mkCId f,x) | (f,x) <- optionsPGF aflags]
|
-- funs = Map.fromList [ (i2i f, mkType [] ty)
|
||||||
|
-- | ((m,f),AbsFun (Just (L _ ty)) ma mdef _) <- adefs
|
||||||
|
-- , let arity = mkArity ma mdef ty
|
||||||
|
-- ]
|
||||||
|
--
|
||||||
|
-- cats = Map.fromList [ (i2i c, ())
|
||||||
|
-- | ((m,c),AbsCat (Just (L _ cont))) <- adefs
|
||||||
|
-- ]
|
||||||
|
|
||||||
funs = Map.fromList [ (i2i f, mkType [] ty)
|
|
||||||
| ((m,f),AbsFun (Just (L _ ty)) ma mdef _) <- adefs
|
|
||||||
, let arity = mkArity ma mdef ty
|
|
||||||
]
|
|
||||||
|
|
||||||
cats = Map.fromList [ (i2i c, ())
|
|
||||||
| ((m,c),AbsCat (Just (L _ cont))) <- adefs
|
|
||||||
]
|
|
||||||
|
|
||||||
-- catfuns cat =
|
|
||||||
-- [(0,i2i f) | ((m,f),AbsFun (Just (L _ ty)) _ _ (Just True)) <- adefs, snd (GM.valCat ty) == cat]
|
|
||||||
return (mi2i am, L.Abstr {
|
return (mi2i am, L.Abstr {
|
||||||
-- L.cats = cats,
|
-- L.cats = cats,
|
||||||
-- L.funs = funs
|
-- L.funs = funs
|
||||||
@@ -104,7 +84,7 @@ mkCanon2lpgf opts gr am = do
|
|||||||
R asgns -> do
|
R asgns -> do
|
||||||
ts <- sequence [ term2lin cxt mtype term | (_, (mtype, term)) <- asgns ]
|
ts <- sequence [ term2lin cxt mtype term | (_, (mtype, term)) <- asgns ]
|
||||||
return $ L.LFTuple ts
|
return $ L.LFTuple ts
|
||||||
QC qiV -> do -- qi = ZeroEng.Sg
|
QC qiV -> do
|
||||||
QC qiP <- mtype
|
QC qiP <- mtype
|
||||||
let vs = [ ic | QC ic <- fromErr [] $ Look.lookupParamValues gr qiP ]
|
let vs = [ ic | QC ic <- fromErr [] $ Look.lookupParamValues gr qiP ]
|
||||||
ix <- elemIndex qiV vs
|
ix <- elemIndex qiV vs
|
||||||
@@ -116,253 +96,18 @@ mkCanon2lpgf opts gr am = do
|
|||||||
L.lins = lins
|
L.lins = lins
|
||||||
})
|
})
|
||||||
|
|
||||||
-- let cflags = err (const noOptions) mflags (lookupModule gr cm)
|
|
||||||
-- ciCmp | flag optCaseSensitive cflags = compare
|
|
||||||
-- | otherwise = C.compareCaseInsensitve
|
|
||||||
--
|
|
||||||
-- (ex_seqs,cdefs) <- addMissingPMCFGs
|
|
||||||
-- Map.empty
|
|
||||||
-- ([((cPredefAbs,c), CncCat (Just (L NoLoc GM.defLinType)) Nothing Nothing Nothing Nothing) | c <- [cInt,cFloat,cString]] ++
|
|
||||||
-- Look.allOrigInfos gr cm)
|
|
||||||
--
|
|
||||||
-- let flags = Map.fromList [(mkCId f,x) | (f,x) <- optionsPGF cflags]
|
|
||||||
--
|
|
||||||
-- seqs = (mkArray . C.sortNubBy ciCmp . concat) $
|
|
||||||
-- (Map.keys ex_seqs : [maybe [] elems (mseqs mi) | (m,mi) <- allExtends gr cm])
|
|
||||||
--
|
|
||||||
-- ex_seqs_arr = mkMapArray ex_seqs :: Array SeqId Sequence
|
|
||||||
--
|
|
||||||
-- !(!fid_cnt1,!cnccats) = genCncCats gr am cm cdefs
|
|
||||||
-- !(!fid_cnt2,!productions,!lindefs,!linrefs,!cncfuns)
|
|
||||||
-- = genCncFuns gr am cm ex_seqs_arr ciCmp seqs cdefs fid_cnt1 cnccats
|
|
||||||
--
|
|
||||||
-- printnames = genPrintNames cdefs
|
|
||||||
-- return (mi2i cm, D.Concr flags
|
|
||||||
-- printnames
|
|
||||||
-- cncfuns
|
|
||||||
-- lindefs
|
|
||||||
-- linrefs
|
|
||||||
-- seqs
|
|
||||||
-- productions
|
|
||||||
-- IntMap.empty
|
|
||||||
-- Map.empty
|
|
||||||
-- cnccats
|
|
||||||
-- IntMap.empty
|
|
||||||
-- fid_cnt2)
|
|
||||||
-- where
|
|
||||||
-- -- if some module was compiled with -no-pmcfg, then
|
|
||||||
-- -- we have to create the PMCFG code just before linking
|
|
||||||
-- addMissingPMCFGs seqs [] = return (seqs,[])
|
|
||||||
-- addMissingPMCFGs seqs (((m,id), info):is) = do
|
|
||||||
-- (seqs,info) <- addPMCFG opts gr cenv Nothing am cm seqs id info
|
|
||||||
-- (seqs,is ) <- addMissingPMCFGs seqs is
|
|
||||||
-- return (seqs, ((m,id), info) : is)
|
|
||||||
|
|
||||||
i2i :: Ident -> CId
|
i2i :: Ident -> CId
|
||||||
i2i = utf8CId . ident2utf8
|
i2i = utf8CId . ident2utf8
|
||||||
|
|
||||||
mi2i :: ModuleName -> CId
|
mi2i :: ModuleName -> CId
|
||||||
mi2i (MN i) = i2i i
|
mi2i (MN i) = i2i i
|
||||||
|
|
||||||
mkType :: [Ident] -> A.Type -> L.Type
|
-- mkType :: [Ident] -> A.Type -> L.Type
|
||||||
mkType scope t =
|
-- mkType scope t =
|
||||||
case GM.typeForm t of
|
-- case GM.typeForm t of
|
||||||
(hyps,(_,cat),args) -> L.Type (map (\(bt,i,t) -> i2i i) hyps) (i2i cat)
|
-- (hyps,(_,cat),args) -> L.Type (map (\(bt,i,t) -> i2i i) hyps) (i2i cat)
|
||||||
-- (hyps,(_,cat),args) -> let (scope',hyps') = mkContext scope hyps
|
|
||||||
-- in D.Type hyps' (i2i cat) (map (mkExp scope') args)
|
|
||||||
|
|
||||||
-- mkExp :: [Ident] -> A.Term -> C.Expr
|
-- mkArity (Just a) _ ty = a -- known arity, i.e. defined function
|
||||||
-- mkExp scope t =
|
-- mkArity Nothing (Just _) ty = 0 -- defined function with no arity - must be an axiom
|
||||||
-- case t of
|
-- mkArity Nothing _ ty = let (ctxt, _, _) = GM.typeForm ty -- constructor
|
||||||
-- Q (_,c) -> C.EFun (i2i c)
|
-- in length ctxt
|
||||||
-- QC (_,c) -> C.EFun (i2i c)
|
|
||||||
-- Vr x -> case lookup x (zip scope [0..]) of
|
|
||||||
-- Just i -> C.EVar i
|
|
||||||
-- Nothing -> C.EMeta 0
|
|
||||||
-- Abs b x t-> C.EAbs b (i2i x) (mkExp (x:scope) t)
|
|
||||||
-- App t1 t2-> C.EApp (mkExp scope t1) (mkExp scope t2)
|
|
||||||
-- EInt i -> C.ELit (C.LInt (fromIntegral i))
|
|
||||||
-- EFloat f -> C.ELit (C.LFlt f)
|
|
||||||
-- K s -> C.ELit (C.LStr s)
|
|
||||||
-- Meta i -> C.EMeta i
|
|
||||||
-- _ -> C.EMeta 0
|
|
||||||
--
|
|
||||||
-- mkPatt scope p =
|
|
||||||
-- case p of
|
|
||||||
-- A.PP (_,c) ps->let (scope',ps') = mapAccumL mkPatt scope ps
|
|
||||||
-- in (scope',C.PApp (i2i c) ps')
|
|
||||||
-- A.PV x -> (x:scope,C.PVar (i2i x))
|
|
||||||
-- A.PAs x p -> let (scope',p') = mkPatt scope p
|
|
||||||
-- in (x:scope',C.PAs (i2i x) p')
|
|
||||||
-- A.PW -> ( scope,C.PWild)
|
|
||||||
-- A.PInt i -> ( scope,C.PLit (C.LInt (fromIntegral i)))
|
|
||||||
-- A.PFloat f -> ( scope,C.PLit (C.LFlt f))
|
|
||||||
-- A.PString s -> ( scope,C.PLit (C.LStr s))
|
|
||||||
-- A.PImplArg p-> let (scope',p') = mkPatt scope p
|
|
||||||
-- in (scope',C.PImplArg p')
|
|
||||||
-- A.PTilde t -> ( scope,C.PTilde (mkExp scope t))
|
|
||||||
--
|
|
||||||
-- mkContext :: [Ident] -> A.Context -> ([Ident],[C.Hypo])
|
|
||||||
-- mkContext scope hyps = mapAccumL (\scope (bt,x,ty) -> let ty' = mkType scope ty
|
|
||||||
-- in if x == identW
|
|
||||||
-- then ( scope,(bt,i2i x,ty'))
|
|
||||||
-- else (x:scope,(bt,i2i x,ty'))) scope hyps
|
|
||||||
--
|
|
||||||
-- mkDef gr arity (Just eqs) = Just ([C.Equ ps' (mkExp scope' e) | L _ (ps,e) <- eqs, let (scope',ps') = mapAccumL mkPatt [] ps]
|
|
||||||
-- ,generateByteCode gr arity eqs
|
|
||||||
-- )
|
|
||||||
-- mkDef gr arity Nothing = Nothing
|
|
||||||
|
|
||||||
mkArity (Just a) _ ty = a -- known arity, i.e. defined function
|
|
||||||
mkArity Nothing (Just _) ty = 0 -- defined function with no arity - must be an axiom
|
|
||||||
mkArity Nothing _ ty = let (ctxt, _, _) = GM.typeForm ty -- constructor
|
|
||||||
in length ctxt
|
|
||||||
|
|
||||||
-- genCncCats gr am cm cdefs =
|
|
||||||
-- let (index,cats) = mkCncCats 0 cdefs
|
|
||||||
-- in (index, Map.fromList cats)
|
|
||||||
-- where
|
|
||||||
-- mkCncCats index [] = (index,[])
|
|
||||||
-- mkCncCats index (((m,id),CncCat (Just (L _ lincat)) _ _ _ _):cdefs)
|
|
||||||
-- | id == cInt =
|
|
||||||
-- let cc = pgfCncCat gr lincat fidInt
|
|
||||||
-- (index',cats) = mkCncCats index cdefs
|
|
||||||
-- in (index', (i2i id,cc) : cats)
|
|
||||||
-- | id == cFloat =
|
|
||||||
-- let cc = pgfCncCat gr lincat fidFloat
|
|
||||||
-- (index',cats) = mkCncCats index cdefs
|
|
||||||
-- in (index', (i2i id,cc) : cats)
|
|
||||||
-- | id == cString =
|
|
||||||
-- let cc = pgfCncCat gr lincat fidString
|
|
||||||
-- (index',cats) = mkCncCats index cdefs
|
|
||||||
-- in (index', (i2i id,cc) : cats)
|
|
||||||
-- | otherwise =
|
|
||||||
-- let cc@(C.CncCat _s e _) = pgfCncCat gr lincat index
|
|
||||||
-- (index',cats) = mkCncCats (e+1) cdefs
|
|
||||||
-- in (index', (i2i id,cc) : cats)
|
|
||||||
-- mkCncCats index (_ :cdefs) = mkCncCats index cdefs
|
|
||||||
--
|
|
||||||
-- genCncFuns :: Grammar
|
|
||||||
-- -> ModuleName
|
|
||||||
-- -> ModuleName
|
|
||||||
-- -> Array SeqId Sequence
|
|
||||||
-- -> (Sequence -> Sequence -> Ordering)
|
|
||||||
-- -> Array SeqId Sequence
|
|
||||||
-- -> [(QIdent, Info)]
|
|
||||||
-- -> FId
|
|
||||||
-- -> Map.Map CId D.CncCat
|
|
||||||
-- -> (FId,
|
|
||||||
-- IntMap.IntMap (Set.Set D.Production),
|
|
||||||
-- IntMap.IntMap [FunId],
|
|
||||||
-- IntMap.IntMap [FunId],
|
|
||||||
-- Array FunId D.CncFun)
|
|
||||||
-- genCncFuns gr am cm ex_seqs ciCmp seqs cdefs fid_cnt cnccats =
|
|
||||||
-- let (fid_cnt1,funs_cnt1,funs1,lindefs,linrefs) = mkCncCats cdefs fid_cnt 0 [] IntMap.empty IntMap.empty
|
|
||||||
-- (fid_cnt2,funs_cnt2,funs2,prods) = mkCncFuns cdefs fid_cnt1 funs_cnt1 funs1 lindefs Map.empty IntMap.empty
|
|
||||||
-- in (fid_cnt2,prods,lindefs,linrefs,array (0,funs_cnt2-1) funs2)
|
|
||||||
-- where
|
|
||||||
-- mkCncCats [] fid_cnt funs_cnt funs lindefs linrefs =
|
|
||||||
-- (fid_cnt,funs_cnt,funs,lindefs,linrefs)
|
|
||||||
-- mkCncCats (((m,id),CncCat _ _ _ _ (Just (PMCFG prods0 funs0))):cdefs) fid_cnt funs_cnt funs lindefs linrefs =
|
|
||||||
-- let !funs_cnt' = let (s_funid, e_funid) = bounds funs0
|
|
||||||
-- in funs_cnt+(e_funid-s_funid+1)
|
|
||||||
-- lindefs' = foldl' (toLinDef (am,id) funs_cnt) lindefs prods0
|
|
||||||
-- linrefs' = foldl' (toLinRef (am,id) funs_cnt) linrefs prods0
|
|
||||||
-- funs' = foldl' (toCncFun funs_cnt (m,mkLinDefId id)) funs (assocs funs0)
|
|
||||||
-- in mkCncCats cdefs fid_cnt funs_cnt' funs' lindefs' linrefs'
|
|
||||||
-- mkCncCats (_ :cdefs) fid_cnt funs_cnt funs lindefs linrefs =
|
|
||||||
-- mkCncCats cdefs fid_cnt funs_cnt funs lindefs linrefs
|
|
||||||
--
|
|
||||||
-- mkCncFuns [] fid_cnt funs_cnt funs lindefs crc prods =
|
|
||||||
-- (fid_cnt,funs_cnt,funs,prods)
|
|
||||||
-- mkCncFuns (((m,id),CncFun _ _ _ (Just (PMCFG prods0 funs0))):cdefs) fid_cnt funs_cnt funs lindefs crc prods =
|
|
||||||
-- let ---Ok ty_C = fmap GM.typeForm (Look.lookupFunType gr am id)
|
|
||||||
-- ty_C = err error (\x -> x) $ fmap GM.typeForm (Look.lookupFunType gr am id)
|
|
||||||
-- !funs_cnt' = let (s_funid, e_funid) = bounds funs0
|
|
||||||
-- in funs_cnt+(e_funid-s_funid+1)
|
|
||||||
-- !(fid_cnt',crc',prods')
|
|
||||||
-- = foldl' (toProd lindefs ty_C funs_cnt)
|
|
||||||
-- (fid_cnt,crc,prods) prods0
|
|
||||||
-- funs' = foldl' (toCncFun funs_cnt (m,id)) funs (assocs funs0)
|
|
||||||
-- in mkCncFuns cdefs fid_cnt' funs_cnt' funs' lindefs crc' prods'
|
|
||||||
-- mkCncFuns (_ :cdefs) fid_cnt funs_cnt funs lindefs crc prods =
|
|
||||||
-- mkCncFuns cdefs fid_cnt funs_cnt funs lindefs crc prods
|
|
||||||
--
|
|
||||||
-- toProd lindefs (ctxt_C,res_C,_) offs st (Production fid0 funid0 args0) =
|
|
||||||
-- let !((fid_cnt,crc,prods),args) = mapAccumL mkArg st (zip ctxt_C args0)
|
|
||||||
-- set0 = Set.fromList (map (C.PApply (offs+funid0)) (sequence args))
|
|
||||||
-- fid = mkFId res_C fid0
|
|
||||||
-- !prods' = case IntMap.lookup fid prods of
|
|
||||||
-- Just set -> IntMap.insert fid (Set.union set0 set) prods
|
|
||||||
-- Nothing -> IntMap.insert fid set0 prods
|
|
||||||
-- in (fid_cnt,crc,prods')
|
|
||||||
-- where
|
|
||||||
-- mkArg st@(fid_cnt,crc,prods) ((_,_,ty),fid0s ) =
|
|
||||||
-- case fid0s of
|
|
||||||
-- [fid0] -> (st,map (flip C.PArg (mkFId arg_C fid0)) ctxt)
|
|
||||||
-- fid0s -> case Map.lookup fids crc of
|
|
||||||
-- Just fid -> (st,map (flip C.PArg fid) ctxt)
|
|
||||||
-- Nothing -> let !crc' = Map.insert fids fid_cnt crc
|
|
||||||
-- !prods' = IntMap.insert fid_cnt (Set.fromList (map C.PCoerce fids)) prods
|
|
||||||
-- in ((fid_cnt+1,crc',prods'),map (flip C.PArg fid_cnt) ctxt)
|
|
||||||
-- where
|
|
||||||
-- (hargs_C,arg_C) = GM.catSkeleton ty
|
|
||||||
-- ctxt = mapM (mkCtxt lindefs) hargs_C
|
|
||||||
-- fids = map (mkFId arg_C) fid0s
|
|
||||||
--
|
|
||||||
-- mkLinDefId id = prefixIdent "lindef " id
|
|
||||||
--
|
|
||||||
-- toLinDef res offs lindefs (Production fid0 funid0 args) =
|
|
||||||
-- if args == [[fidVar]]
|
|
||||||
-- then IntMap.insertWith (++) fid [offs+funid0] lindefs
|
|
||||||
-- else lindefs
|
|
||||||
-- where
|
|
||||||
-- fid = mkFId res fid0
|
|
||||||
--
|
|
||||||
-- toLinRef res offs linrefs (Production fid0 funid0 [fargs]) =
|
|
||||||
-- if fid0 == fidVar
|
|
||||||
-- then foldr (\fid -> IntMap.insertWith (++) fid [offs+funid0]) linrefs fids
|
|
||||||
-- else linrefs
|
|
||||||
-- where
|
|
||||||
-- fids = map (mkFId res) fargs
|
|
||||||
--
|
|
||||||
-- mkFId (_,cat) fid0 =
|
|
||||||
-- case Map.lookup (i2i cat) cnccats of
|
|
||||||
-- Just (C.CncCat s e _) -> s+fid0
|
|
||||||
-- Nothing -> error ("GrammarToPGF.mkFId: missing category "++showIdent cat)
|
|
||||||
--
|
|
||||||
-- mkCtxt lindefs (_,cat) =
|
|
||||||
-- case Map.lookup (i2i cat) cnccats of
|
|
||||||
-- Just (C.CncCat s e _) -> [(C.fidVar,fid) | fid <- [s..e], Just _ <- [IntMap.lookup fid lindefs]]
|
|
||||||
-- Nothing -> error "GrammarToPGF.mkCtxt failed"
|
|
||||||
--
|
|
||||||
-- toCncFun offs (m,id) funs (funid0,lins0) =
|
|
||||||
-- let mseqs = case lookupModule gr m of
|
|
||||||
-- Ok (ModInfo{mseqs=Just mseqs}) -> mseqs
|
|
||||||
-- _ -> ex_seqs
|
|
||||||
-- in (offs+funid0,C.CncFun (i2i id) (amap (newIndex mseqs) lins0)):funs
|
|
||||||
-- where
|
|
||||||
-- newIndex mseqs i = binSearch (mseqs ! i) seqs (bounds seqs)
|
|
||||||
--
|
|
||||||
-- binSearch v arr (i,j)
|
|
||||||
-- | i <= j = case ciCmp v (arr ! k) of
|
|
||||||
-- LT -> binSearch v arr (i,k-1)
|
|
||||||
-- EQ -> k
|
|
||||||
-- GT -> binSearch v arr (k+1,j)
|
|
||||||
-- | otherwise = error "binSearch"
|
|
||||||
-- where
|
|
||||||
-- k = (i+j) `div` 2
|
|
||||||
--
|
|
||||||
-- genPrintNames cdefs =
|
|
||||||
-- Map.fromAscList [(i2i id, name) | ((m,id),info) <- cdefs, name <- prn info]
|
|
||||||
-- where
|
|
||||||
-- prn (CncFun _ _ (Just (L _ tr)) _) = [flatten tr]
|
|
||||||
-- prn (CncCat _ _ _ (Just (L _ tr)) _) = [flatten tr]
|
|
||||||
-- prn _ = []
|
|
||||||
--
|
|
||||||
-- flatten (K s) = s
|
|
||||||
-- flatten (Alts x _) = flatten x
|
|
||||||
-- flatten (C x y) = flatten x +++ flatten y
|
|
||||||
--
|
|
||||||
-- mkArray lst = listArray (0,length lst-1) lst
|
|
||||||
-- mkMapArray map = array (0,Map.size map-1) [(v,k) | (k,v) <- Map.toList map]
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import PGF.CId
|
|||||||
import PGF.Expr (Expr)
|
import PGF.Expr (Expr)
|
||||||
import PGF.Tree (Tree (..), expr2tree, prTree)
|
import PGF.Tree (Tree (..), expr2tree, prTree)
|
||||||
|
|
||||||
|
import Data.Binary (Binary, get, put, encodeFile, decodeFile)
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Text.Printf (printf)
|
import Text.Printf (printf)
|
||||||
|
|
||||||
@@ -16,30 +17,30 @@ data LPGF = LPGF {
|
|||||||
absname :: CId,
|
absname :: CId,
|
||||||
abstract :: Abstr,
|
abstract :: Abstr,
|
||||||
concretes :: Map.Map CId Concr
|
concretes :: Map.Map CId Concr
|
||||||
} deriving (Read, Show)
|
} deriving (Show)
|
||||||
|
|
||||||
-- | Abstract syntax
|
-- | Abstract syntax
|
||||||
data Abstr = Abstr {
|
data Abstr = Abstr {
|
||||||
-- cats :: Map.Map CId (),
|
-- cats :: Map.Map CId (),
|
||||||
-- funs :: Map.Map CId Type
|
-- funs :: Map.Map CId Type
|
||||||
} deriving (Read, Show)
|
} deriving (Show)
|
||||||
|
|
||||||
-- | Concrete syntax
|
-- | Concrete syntax
|
||||||
data Concr = Concr {
|
data Concr = Concr {
|
||||||
-- lincats :: Map.Map CId LinType, -- ^ assigning a linearization type to each category
|
-- lincats :: Map.Map CId LinType, -- ^ assigning a linearization type to each category
|
||||||
lins :: Map.Map CId LinFun -- ^ assigning a linearization function to each function
|
lins :: Map.Map CId LinFun -- ^ assigning a linearization function to each function
|
||||||
} deriving (Read, Show)
|
} deriving (Show)
|
||||||
|
|
||||||
-- | Abstract function type
|
-- | Abstract function type
|
||||||
data Type = Type [CId] CId
|
-- data Type = Type [CId] CId
|
||||||
deriving (Read, Show)
|
-- deriving (Show)
|
||||||
|
|
||||||
-- | Linearisation type
|
-- | Linearisation type
|
||||||
data LinType =
|
data LinType =
|
||||||
LTStr
|
LTStr
|
||||||
| LTInt Int
|
| LTInt Int
|
||||||
| LTProduct [LinType]
|
| LTProduct [LinType]
|
||||||
deriving (Read, Show)
|
deriving (Show)
|
||||||
|
|
||||||
-- | Linearisation function
|
-- | Linearisation function
|
||||||
data LinFun =
|
data LinFun =
|
||||||
@@ -50,16 +51,47 @@ data LinFun =
|
|||||||
| LFTuple [LinFun]
|
| LFTuple [LinFun]
|
||||||
| LFProjection LinFun LinFun -- ^ In order for the projection to be well-formed, t1 must be a tuple and t2 an integer within the bounds of the size of the tuple
|
| LFProjection LinFun LinFun -- ^ In order for the projection to be well-formed, t1 must be a tuple and t2 an integer within the bounds of the size of the tuple
|
||||||
| LFArgument Int
|
| LFArgument Int
|
||||||
deriving (Read, Show)
|
deriving (Show, Read)
|
||||||
|
|
||||||
|
instance Binary LPGF where
|
||||||
|
put lpgf = do
|
||||||
|
put (absname lpgf)
|
||||||
|
put (abstract lpgf)
|
||||||
|
put (concretes lpgf)
|
||||||
|
get = do
|
||||||
|
an <- get
|
||||||
|
abs <- get
|
||||||
|
concs <- get
|
||||||
|
return $ LPGF {
|
||||||
|
absname = an,
|
||||||
|
abstract = abs,
|
||||||
|
concretes = concs
|
||||||
|
}
|
||||||
|
|
||||||
|
instance Binary Abstr where
|
||||||
|
put abs = return ()
|
||||||
|
get = return $ Abstr {}
|
||||||
|
|
||||||
|
instance Binary Concr where
|
||||||
|
put concr = put (lins concr)
|
||||||
|
get = do
|
||||||
|
ls <- get
|
||||||
|
return $ Concr {
|
||||||
|
lins = ls
|
||||||
|
}
|
||||||
|
|
||||||
|
instance Binary LinFun where
|
||||||
|
put = put . show
|
||||||
|
get = read <$> get
|
||||||
|
|
||||||
abstractName :: LPGF -> CId
|
abstractName :: LPGF -> CId
|
||||||
abstractName = absname
|
abstractName = absname
|
||||||
|
|
||||||
encodeFile :: FilePath -> LPGF -> IO ()
|
encodeFile :: FilePath -> LPGF -> IO ()
|
||||||
encodeFile path lpgf = writeFile path (show lpgf)
|
encodeFile = Data.Binary.encodeFile
|
||||||
|
|
||||||
readLPGF :: FilePath -> IO LPGF
|
readLPGF :: FilePath -> IO LPGF
|
||||||
readLPGF path = read <$> readFile path
|
readLPGF = Data.Binary.decodeFile
|
||||||
|
|
||||||
-- | Helper for building concat trees
|
-- | Helper for building concat trees
|
||||||
mkConcat :: [LinFun] -> LinFun
|
mkConcat :: [LinFun] -> LinFun
|
||||||
@@ -81,12 +113,11 @@ linearizeConcr concr expr = lin2string $ lin (expr2tree expr)
|
|||||||
where
|
where
|
||||||
lin :: Tree -> LinFun
|
lin :: Tree -> LinFun
|
||||||
lin tree = case tree of
|
lin tree = case tree of
|
||||||
Fun f as -> v
|
Fun f as ->
|
||||||
where
|
case Map.lookup f (lins concr) of
|
||||||
Just t = Map.lookup f (lins concr)
|
Just t -> eval (map lin as) t
|
||||||
ts = map lin as
|
_ -> error $ printf "Lookup failed for function: %s" (showCId f)
|
||||||
v = eval ts t
|
x -> error $ printf "Cannot lin: %s" (prTree x)
|
||||||
x -> error $ printf "Cannot lin %s" (prTree x)
|
|
||||||
|
|
||||||
-- | Evaluation context is a sequence of terms
|
-- | Evaluation context is a sequence of terms
|
||||||
type Context = [LinFun]
|
type Context = [LinFun]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import LPGF
|
import LPGF
|
||||||
import PGF (Tree, mkCId, mkApp, readLanguage, showLanguage, showExpr)
|
import PGF (Tree, mkCId, mkApp, showLanguage, showExpr)
|
||||||
import GF (compileToLPGF, writeLPGF)
|
import GF (compileToLPGF, writeLPGF)
|
||||||
import GF.Support (noOptions)
|
import GF.Support (noOptions)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user