more tc of gfcc

This commit is contained in:
aarne
2007-10-01 13:18:43 +00:00
parent 984a265f65
commit 8179f5dcf9
3 changed files with 72 additions and 23 deletions

View File

@@ -3,6 +3,7 @@ module GF.Canon.GFCC.CheckGFCC where
import GF.Canon.GFCC.DataGFCC import GF.Canon.GFCC.DataGFCC
import GF.Canon.GFCC.AbsGFCC import GF.Canon.GFCC.AbsGFCC
import GF.Canon.GFCC.PrintGFCC import GF.Canon.GFCC.PrintGFCC
import GF.Canon.GFCC.ErrM
import qualified Data.Map as Map import qualified Data.Map as Map
import Control.Monad import Control.Monad
@@ -20,31 +21,76 @@ checkGFCC gfcc = andMapM (checkConcrete gfcc) $ Map.assocs $ concretes gfcc
checkConcrete :: GFCC -> (CId,Map.Map CId Term) -> IO Bool checkConcrete :: GFCC -> (CId,Map.Map CId Term) -> IO Bool
checkConcrete gfcc (lang,cnc) = checkConcrete gfcc (lang,cnc) =
labelBoolIO (printTree lang) $ andMapM (checkLin gfcc lang) $ linRules cnc labelBoolIO ("happened in language " ++ printTree lang) $
andMapM (checkLin gfcc lang) $ linRules cnc
checkLin :: GFCC -> CId -> (CId,Term) -> IO Bool checkLin :: GFCC -> CId -> (CId,Term) -> IO Bool
checkLin gfcc lang (f,t) = checkLin gfcc lang (f,t) =
labelBoolIO (printTree f) $ checkTerm (lintype gfcc lang f) $ inline gfcc lang t labelBoolIO ("happened in function " ++ printTree f) $
checkTerm (lintype gfcc lang f) $ inline gfcc lang t
inferTerm :: [Tpe] -> Term -> Maybe Tpe
inferTerm args trm = case trm of
K _ -> return str
C i -> return $ ints i
V i -> if i < length args
then (return $ args !! i)
else error ("index " ++ show i)
S ts -> do
tys <- mapM infer ts
if all (==str) tys
then return str
else error ("only strings expected in: " ++ printTree trm
++ " instead of " ++ unwords (map printTree tys)
)
R ts -> do
tys <- mapM infer ts
return $ tuple tys
P t u -> do
R tys <- infer t
case u of
C i -> if (i < length tys)
then (return $ tys !! i) -- record: index must be known
else error ("too few fields in " ++ printTree (R tys))
_ -> if all (==head tys) tys -- table: must be same
then return (head tys)
else error ("projection " ++ printTree trm)
FV ts -> return $ head ts ---- empty variants; check equality
W s r -> infer r
_ -> error ("no type inference for " ++ printTree trm)
where
infer = inferTerm args
checkTerm :: LinType -> Term -> IO Bool checkTerm :: LinType -> Term -> IO Bool
checkTerm (args,val) trm = case (val,trm) of checkTerm (args,val) trm = case inferTerm args trm of
(R tys, R trs) -> do Just ty -> if eqType ty val then return True else do
let (ntys,ntrs) = (length tys,length trs) putStrLn $ "term: " ++ printTree trm ++
b <- checkCond "\nexpected type: " ++ printTree val ++
("number of fields in " ++ prtrm ++ " does not match " ++ prval) (ntys == ntrs) "\ninferred type: " ++ printTree ty
bs <- andMapM (uncurry check) (zip tys trs) return False
return $ b && bs _ -> do
(R _, W _ r) -> check val r putStrLn $ "cannot infer type of " ++ printTree trm
_ -> return True return False
where
checkCond msg cond = if cond then return True else (putStrLn msg >> return False) eqType :: Tpe -> Tpe -> Bool
check ty tr = checkTerm (args,ty) tr eqType inf exp = case (inf,exp) of
prtrm = printTree trm (C k, C n) -> k <= n -- only run-time corr.
prval = printTree val (R rs,R ts) -> length rs == length ts && and [eqType r t | (r,t) <- zip rs ts]
_ -> inf == exp
-- should be in a generic module, but not in the run-time DataGFCC -- should be in a generic module, but not in the run-time DataGFCC
type LinType = ([Term],Term) type Tpe = Term
type LinType = ([Tpe],Tpe)
tuple :: [Tpe] -> Tpe
tuple = R
ints :: Int -> Tpe
ints = C
str :: Tpe
str = S []
lintype :: GFCC -> CId -> CId -> LinType lintype :: GFCC -> CId -> CId -> LinType
lintype gfcc lang fun = case lookType gfcc fun of lintype gfcc lang fun = case lookType gfcc fun of

View File

@@ -96,7 +96,8 @@ compute mcfg lang args = comp where
proj r p = case (r,p) of proj r p = case (r,p) of
(_, FV ts) -> FV $ Prelude.map (proj r) ts (_, FV ts) -> FV $ Prelude.map (proj r) ts
(W s t, _) -> kks (s ++ getString (proj t p)) (W s t, _) -> kks (s ++ getString (proj t p))
(_,R is) -> comp $ foldl P r is
_ -> comp $ getField r (getIndex p) _ -> comp $ getField r (getIndex p)
getString t = case t of getString t = case t of

View File

@@ -65,7 +65,7 @@ mkCType :: Type -> C.Term
mkCType t = case t of mkCType t = case t of
EInt i -> C.C $ fromInteger i EInt i -> C.C $ fromInteger i
-- record parameter alias - created in gfc preprocessing -- record parameter alias - created in gfc preprocessing
RecType [(LIdent "_", i)] -> mkCType i ----RecType [(LIdent "_", i)] -> mkCType i
--- RecType [(LIdent "_", i), (LIdent "__", t)] -> C.RP (mkCType i) (mkCType t) --- RecType [(LIdent "_", i), (LIdent "__", t)] -> C.RP (mkCType i) (mkCType t)
RecType rs -> C.R [mkCType t | (_, t) <- rs] RecType rs -> C.R [mkCType t | (_, t) <- rs]
Table pt vt -> C.R $ replicate (getI (mkCType pt)) $ mkCType vt Table pt vt -> C.R $ replicate (getI (mkCType pt)) $ mkCType vt
@@ -83,7 +83,7 @@ mkTerm tr = case tr of
C.V (read (reverse (takeWhile (/='_') (reverse s)))) ---- from gf parser of gfc C.V (read (reverse (takeWhile (/='_') (reverse s)))) ---- from gf parser of gfc
EInt i -> C.C $ fromInteger i EInt i -> C.C $ fromInteger i
-- record parameter alias - created in gfc preprocessing -- record parameter alias - created in gfc preprocessing
R [(LIdent "_", (_,i))] -> mkTerm i ----R [(LIdent "_", (_,i))] -> mkTerm i
--- R [(LIdent "_", (_,i)), (LIdent "__", (_,t))] -> C.RP (mkTerm i) (mkTerm t) --- R [(LIdent "_", (_,i)), (LIdent "__", (_,t))] -> C.RP (mkTerm i) (mkTerm t)
-- ordinary record -- ordinary record
R rs -> C.R [mkTerm t | (_, (_,t)) <- rs] R rs -> C.R [mkTerm t | (_, (_,t)) <- rs]
@@ -273,10 +273,12 @@ term2term cgr env@(labels,untyps,typs) tr = case tr of
(l,(_,t)) <- unlock rs] (l,(_,t)) <- unlock rs]
rs' = [(mkLab i, (Nothing, t2t t)) | rs' = [(mkLab i, (Nothing, t2t t)) |
(i,(l,(_,t))) <- zip [0..] (unlock rs)] (i,(l,(_,t))) <- zip [0..] (unlock rs)]
in if (any (isStr . trmAss) rs) in
then R rs' ----if (any (isStr . trmAss) rs)
----then
R rs'
--- else mkValCase tr --- else mkValCase tr
else R [(LIdent "_", (Nothing, mkValCase tr'))] ----else R [(LIdent "_", (Nothing, mkValCase tr'))]
--- else R [(LIdent "_", (Nothing, mkValCase tr)), (LIdent "__",(Nothing,R rs'))] --- else R [(LIdent "_", (Nothing, mkValCase tr)), (LIdent "__",(Nothing,R rs'))]
P t l -> r2r tr P t l -> r2r tr
PI t l i -> EInt $ toInteger i PI t l i -> EInt $ toInteger i