summaryrefslogtreecommitdiff
path: root/src/GF/Canon/Look.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/GF/Canon/Look.hs')
-rw-r--r--src/GF/Canon/Look.hs141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/GF/Canon/Look.hs b/src/GF/Canon/Look.hs
new file mode 100644
index 000000000..a71d024c2
--- /dev/null
+++ b/src/GF/Canon/Look.hs
@@ -0,0 +1,141 @@
+module Look where
+
+import AbsGFC
+import GFC
+import PrGrammar
+import CMacros
+----import Values
+import MMacros
+import qualified Modules as M
+
+import Operations
+
+import Monad
+import List
+
+-- lookup in GFC. AR 2003
+
+-- linearization lookup
+
+lookupCncInfo :: CanonGrammar -> CIdent -> Err Info
+lookupCncInfo gr f@(CIQ m c) = do
+ mt <- M.lookupModule gr m
+ case mt of
+ M.ModMod a -> errIn ("module" +++ prt m) $
+ lookupTree prt c $ M.jments a
+ _ -> prtBad "not concrete module" m
+
+lookupLin :: CanonGrammar -> CIdent -> Err Term
+lookupLin gr f = do
+ info <- lookupCncInfo gr f
+ case info of
+ CncFun _ _ t _ -> return t
+ CncCat _ t _ -> return t
+ AnyInd _ n -> lookupLin gr $ redirectIdent n f
+
+lookupResInfo :: CanonGrammar -> CIdent -> Err Info
+lookupResInfo gr f@(CIQ m c) = do
+ mt <- M.lookupModule gr m
+ case mt of
+ M.ModMod a -> lookupTree prt c $ M.jments a
+ _ -> prtBad "not resource module" m
+
+lookupGlobal :: CanonGrammar -> CIdent -> Err Term
+lookupGlobal gr f = do
+ info <- lookupResInfo gr f
+ case info of
+ ResOper _ t -> return t
+ AnyInd _ n -> lookupGlobal gr $ redirectIdent n f
+ _ -> prtBad "cannot find global" f
+
+lookupParamValues :: CanonGrammar -> CIdent -> Err [Term]
+lookupParamValues gr pt@(CIQ m _) = do
+ info <- lookupResInfo gr pt
+ case info of
+ ResPar ps -> liftM concat $ mapM mkPar ps
+ AnyInd _ n -> lookupParamValues gr $ redirectIdent n pt
+ _ -> prtBad "cannot find parameter type" pt
+ where
+ mkPar (ParD f co) = do
+ vs <- liftM combinations $ mapM (allParamValues gr) co
+ return $ map (Con (CIQ m f)) vs
+
+-- this is needed since param type can also be a record type
+
+allParamValues :: CanonGrammar -> CType -> Err [Term]
+allParamValues cnc ptyp = case ptyp of
+ Cn pc -> lookupParamValues cnc pc
+ RecType r -> do
+ let (ls,tys) = unzip [(l,t) | Lbg l t <- r]
+ tss <- mapM allPV tys
+ return [R (map (uncurry Ass) (zip ls ts)) | ts <- combinations tss]
+ _ -> prtBad "cannot possibly find parameter values for" ptyp
+ where
+ allPV = allParamValues cnc
+
+-- runtime computation on GFC objects
+
+ccompute :: CanonGrammar -> [Term] -> Term -> Err Term
+ccompute cnc = comp []
+ where
+ comp g xs t = case t of
+ Arg (A _ i) -> errIn ("argument list") $ xs !? fromInteger i
+ Arg (AB _ _ i) -> errIn ("argument list for binding") $ xs !? fromInteger i
+ I c -> look c
+ LI c -> lookVar c g
+
+ -- short-cut computation of selections: compute the table only if needed
+ S u v -> do
+ u' <- compt u
+ case u' of
+ T _ [Cas [PW] b] -> compt b
+ T _ [Cas [PV x] b] -> do
+ v' <- compt v
+ comp ((x,v') : g) xs b
+ T _ cs -> do
+ v' <- compt v
+ if noVar v'
+ then matchPatt cs v' >>= compt
+ else return $ S u' v'
+
+ _ -> liftM (S u') $ compt v
+
+ P u l -> do
+ u' <- compt u
+ case u' of
+ R rs -> maybe (Bad ("unknown label" +++ prt l +++ "in" +++ prt u'))
+ return $
+ lookup l [ (x,y) | Ass x y <- rs]
+ _ -> return $ P u' l
+ FV ts -> liftM FV (mapM compt ts)
+ C E b -> compt b
+ C a E -> compt a
+ C a b -> do
+ a' <- compt a
+ b' <- compt b
+ return $ case (a',b') of
+ (E,_) -> b'
+ (_,E) -> a'
+ _ -> C a' b'
+ R rs -> liftM (R . map (uncurry Ass)) $
+ mapPairsM compt [(l,r) | Ass l r <- rs]
+
+ -- only expand the table when the table is really needed: use expandLin
+ T ty rs -> liftM (T ty . map (uncurry Cas)) $
+ mapPairsM compt [(l,r) | Cas l r <- rs]
+
+ Con c xs -> liftM (Con c) $ mapM compt xs
+
+ _ -> return t
+ where
+ compt = comp g xs
+ look c = lookupGlobal cnc c
+
+ lookVar c co = case lookup c co of
+ Just t -> return t
+ _ -> return $ LI c --- Bad $ "unknown local variable" +++ prt c ---
+
+ noVar v = case v of
+ LI _ -> False
+ R rs -> all noVar [t | Ass _ t <- rs]
+ _ -> True --- other cases?