33module GF.Compile.Compute.Concrete2
44 (Env , Scope , Value (.. ), Variants (.. ), Constraint , OptionInfo (.. ), ChoiceMap , cleanOptions ,
55 ConstValue (.. ), ConstVariants (.. ), Globals (.. ), PredefTable , EvalM ,
6- mapVariants , unvariants , variants2consts , consts2variants ,
7- runEvalM , runEvalMWithOpts , stdPredef , globals , withState ,
6+ mapVariants , mapVariantsC , unvariants , variants2consts ,
7+ mapConstVs , mapConstVsC , unconstVs , consts2variants ,
8+ runEvalM , runEvalMWithOpts , reset , reset1 , stdPredef , globals , withState ,
89 PredefImpl , Predef (.. ), ($\) ,
910 pdCanonicalArgs , pdArity ,
1011 normalForm , normalFlatForm ,
1112 eval , apply , value2term , value2termM , bubble , patternMatch , vtableSelect , State (.. ),
1213 newResiduation , getMeta , setMeta , MetaState (.. ), variants , try ,
13- evalError , evalWarn , ppValue , Choice (.. ), unit , poison , split , split3 , split4 , mapC , mapCM ) where
14+ evalError , evalWarn , ppValue , Choice (.. ), unit , poison , split , split3 , split4 ,
15+ mapC , forC , mapCM , forCM ) where
1416
1517import Prelude hiding ((<>) ) -- GHC 8.4.1 clash with Text.PrettyPrint
1618import GF.Infra.Ident
1719import GF.Infra.CheckM
1820import GF.Data.Operations (Err (.. ))
19- import GF.Data.Utilities (maybeAt ,splitAt' ,(<||>) ,anyM )
21+ import GF.Data.Utilities (maybeAt ,splitAt' ,(<||>) ,anyM , secondM , bimapM )
2022import GF.Grammar.Lookup (lookupResDef ,lookupOrigInfo )
2123import GF.Grammar.Grammar
2224import GF.Grammar.Macros
@@ -94,17 +96,23 @@ data Value
9496 | VCRecType [(Label , Bool , Value )]
9597 | VCInts (Maybe Integer ) (Maybe Integer )
9698
99+ third f (a,b,c) = (a, b, f c)
100+
97101data Variants
98102 = VarFree [Value ]
99- | VarOpts Value [( Value , Value )]
103+ | VarOpts Value Value [( Value , Value , Value )]
100104
101105mapVariants :: (Value -> Value ) -> Variants -> Variants
102- mapVariants f (VarFree vs) = VarFree (f <$> vs)
103- mapVariants f (VarOpts n cs) = VarOpts n (second f <$> cs)
106+ mapVariants f (VarFree vs) = VarFree (f <$> vs)
107+ mapVariants f (VarOpts nty n cs) = VarOpts nty n (third f <$> cs)
108+
109+ mapVariantsC :: (Choice -> Value -> Value ) -> Choice -> Variants -> Variants
110+ mapVariantsC f c (VarFree vs) = VarFree (mapC f c vs)
111+ mapVariantsC f c (VarOpts nty n cs) = VarOpts nty n (mapC (third . f) c cs)
104112
105113unvariants :: Variants -> [Value ]
106- unvariants (VarFree vs) = vs
107- unvariants (VarOpts n cs) = snd <$> cs
114+ unvariants (VarFree vs) = vs
115+ unvariants (VarOpts nty n cs) = cs <&> \ (_,_,v) -> v
108116
109117isCanonicalForm :: Bool -> Value -> Bool
110118isCanonicalForm flat (VClosure {}) = True
@@ -136,15 +144,19 @@ data ConstValue a
136144
137145data ConstVariants a
138146 = ConstFree [ConstValue a ]
139- | ConstOpts Value [( Value , ConstValue a )]
147+ | ConstOpts Value Value [( Value , Value , ConstValue a )]
140148
141149mapConstVs :: (ConstValue a -> ConstValue b ) -> ConstVariants a -> ConstVariants b
142- mapConstVs f (ConstFree vs) = ConstFree (f <$> vs)
143- mapConstVs f (ConstOpts n cs) = ConstOpts n (second f <$> cs)
150+ mapConstVs f (ConstFree vs) = ConstFree (f <$> vs)
151+ mapConstVs f (ConstOpts nty n cs) = ConstOpts nty n (third f <$> cs)
152+
153+ mapConstVsC :: (Choice -> ConstValue a -> ConstValue b ) -> Choice -> ConstVariants a -> ConstVariants b
154+ mapConstVsC f c (ConstFree vs) = ConstFree (mapC f c vs)
155+ mapConstVsC f c (ConstOpts nty n cs) = ConstOpts nty n (mapC (third . f) c cs)
144156
145157unconstVs :: ConstVariants a -> [ConstValue a ]
146- unconstVs (ConstFree vs) = vs
147- unconstVs (ConstOpts n cs) = snd <$> cs
158+ unconstVs (ConstFree vs) = vs
159+ unconstVs (ConstOpts nty n cs) = cs <&> \ (_,_,v) -> v
148160
149161instance Functor ConstValue where
150162 fmap f (Const c) = Const (f c)
@@ -167,12 +179,12 @@ instance Applicative ConstValue where
167179 _ <*> RunTime = RunTime
168180
169181variants2consts :: (Value -> ConstValue a ) -> Variants -> ConstVariants a
170- variants2consts f (VarFree vs) = ConstFree (f <$> vs)
171- variants2consts f (VarOpts n os) = ConstOpts n (second f <$> os)
182+ variants2consts f (VarFree vs) = ConstFree (f <$> vs)
183+ variants2consts f (VarOpts nty n os) = ConstOpts nty n (third f <$> os)
172184
173185consts2variants :: (ConstValue a -> Value ) -> ConstVariants a -> Variants
174- consts2variants f (ConstFree vs) = VarFree (f <$> vs)
175- consts2variants f (ConstOpts n os) = VarOpts n (second f <$> os)
186+ consts2variants f (ConstFree vs) = VarFree (f <$> vs)
187+ consts2variants f (ConstOpts nty n os) = VarOpts nty n (third f <$> os)
176188
177189normalForm :: Globals -> Term -> Check Term
178190normalForm g t = value2term g [] (bubble (eval g [] unit t [] ))
@@ -326,14 +338,17 @@ eval g env c (Markup tag as ts) [] =
326338 in (VMarkup tag vas vs)
327339eval g env c (Reset ctl mb_ct t qid) [] = VReset ctl (fmap (\ t -> eval g env c t [] ) mb_ct) (eval g env c t [] ) qid
328340eval g env c (TSymCat d r rs) [] = VSymCat d r [(i,(fromJust (lookup pv env),ty)) | (i,(pv,ty)) <- rs]
329- eval g env c t@ (Opts n cs) vs = if null cs
330- then VError (" No options in expression:" $$ ppTerm Unqualified 0 t)
331- else let (c1,c2,c3) = split3 c
332- vn = eval g env c1 n []
333- vcs = mapC evalOpt c cs
334- in VFV c3 (VarOpts vn vcs)
335- where evalOpt c' (l,t) = let (c1,c2) = split c' in (eval g env c1 l [] , eval g env c2 t vs)
336- eval g env c t vs = VError (" Cannot reduce term" <+> pp t)
341+ eval g env c t@ (Opts (nty,n) cs) vs = if null cs
342+ then VError (" No options in expression:" $$ ppTerm Unqualified 0 t)
343+ else let (c1,c2,c3) = split3 c
344+ (c1ty,c1t) = split c1
345+ vnty = eval g env c1ty (fromJust nty) []
346+ vn = eval g env c1t n []
347+ vcs = mapC evalOpt c2 cs
348+ in VFV c3 (VarOpts vnty vn vcs)
349+ where evalOpt c' ((lty,l),t) = let (c1,c2,c3) = split3 c'
350+ in (eval g env c1 (fromJust lty) [] , eval g env c2 l [] , eval g env c3 t vs)
351+ eval g env c t vs = VError (" Cannot reduce term" <+> pp t)
337352
338353evalPredef :: Globals -> Choice -> Ident -> [Value ] -> Value
339354evalPredef g@ (Gl gr pds) c n args =
@@ -381,7 +396,7 @@ apply g v [] = v
381396
382397data BubbleVariants
383398 = BubbleFree Int
384- | BubbleOpts Value [ Value ]
399+ | BubbleOpts Value Value [( Value , Value ) ]
385400
386401bubble v = snd (bubble v)
387402 where
@@ -411,11 +426,15 @@ bubble v = snd (bubble v)
411426 bubble v@ (VFV c (VarFree vs))
412427 | null vs = (Map. empty, v)
413428 | otherwise = let (union,vs') = mapAccumL descend Map. empty vs
414- in (Map. insert c (BubbleFree (length vs),1 ) union, addVariants (VFV c (VarFree vs')) union)
415- bubble v@ (VFV c (VarOpts n os))
429+ b = BubbleFree (length vs)
430+ v' = addVariants (VFV c (VarFree vs')) union
431+ in (Map. insert c (b,1 ) union, v')
432+ bubble v@ (VFV c (VarOpts nty n os))
416433 | null os = (Map. empty, v)
417- | otherwise = let (union,os') = mapAccumL (\ acc (k,v) -> second (k,) $ descend acc v) Map. empty os
418- in (Map. insert c (BubbleOpts n (fst <$> os),1 ) union, addVariants (VFV c (VarOpts n os')) union)
434+ | otherwise = let (union,os') = mapAccumL (\ acc (lty,l,v) -> second (lty,l,) $ descend acc v) Map. empty os
435+ b = BubbleOpts nty n (os <&> \ (lty,l,_) -> (lty,l))
436+ v' = addVariants (VFV c (VarOpts nty n os')) union
437+ in (Map. insert c (b,1 ) union, v')
419438 bubble (VAlts v vs) = lift1L2 VAlts v vs
420439 bubble (VStrs vs) = liftL VStrs vs
421440 bubble (VMarkup tag attrs vs) =
@@ -500,8 +519,8 @@ bubble v = snd (bubble v)
500519 where
501520 addVariant c (bvs,cnt) v
502521 | cnt > 1 = VFV c $ case bvs of
503- BubbleFree k -> VarFree (replicate k v)
504- BubbleOpts n os -> VarOpts n ((,v) <$> os )
522+ BubbleFree k -> VarFree (replicate k v)
523+ BubbleOpts nty n os -> VarOpts nty n (os <&> \ (lty,l) -> (lty,l,v) )
505524 | otherwise = v
506525
507526 unitfy = fmap (\ (n,_) -> (n,1 ))
@@ -669,9 +688,10 @@ data MetaState
669688 | Residuation Scope (Maybe Constraint )
670689data OptionInfo
671690 = OptionInfo
672- { optChoice :: Choice
673- , optLabel :: Value
674- , optChoices :: [Value ]
691+ { optChoice :: Choice
692+ , optLabelType :: Value
693+ , optLabel :: Value
694+ , optChoices :: [(Value , Value )]
675695 }
676696type ChoiceMap = Map. Map Choice Int
677697data State
@@ -738,6 +758,12 @@ reset (EvalM f) = EvalM $ \g k state r ws ->
738758 Fail msg ws -> Fail msg ws
739759 Success xs ws -> k (reverse xs) state r ws
740760
761+ reset1 :: EvalM a -> EvalM (Maybe a )
762+ reset1 (EvalM f) = EvalM $ \ g k state r ws ->
763+ case f g (\ x' state x ws -> Success (x <|> Just x') ws) state Nothing ws of
764+ Fail msg ws -> Fail msg ws
765+ Success x ws -> k x state r ws
766+
741767globals :: EvalM Globals
742768globals = EvalM (\ g k -> k g)
743769
@@ -907,13 +933,13 @@ value2termM True xs (VFV i (VarFree vs)) = do
907933 v <- variants i vs
908934 value2termM True xs v
909935value2termM False xs (VFV i (VarFree vs)) = variants' i (value2termM False xs) vs
910- value2termM flat xs (VFV i (VarOpts n os)) =
936+ value2termM flat xs (VFV i (VarOpts nty n os)) =
911937 EvalM $ \ g k (State choices metas opts) r msgs ->
912938 let j = fromMaybe 0 (Map. lookup i choices)
913939 in case os `maybeAt` j of
914- Just (l,t) -> case value2termM flat xs t of
915- EvalM f -> let oi = OptionInfo i n (fst <$> os )
916- in f g k (State choices metas (oi: opts)) r msgs
940+ Just (lty, l,t) -> case value2termM flat xs t of
941+ EvalM f -> let oi = OptionInfo i nty n (os <&> \ (lty,l,_) -> (lty,l) )
942+ in f g k (State choices metas (oi: opts)) r msgs
917943 Nothing -> Fail (" Index" <+> j <+> " out of bounds for option:" $$ ppValue Unqualified 0 n) msgs
918944value2termM flat xs (VPatt min max p) = return (EPatt min max p)
919945value2termM flat xs (VPattType v) = do t <- value2termM flat xs v
@@ -1020,7 +1046,9 @@ ppValue q d (VC v1 v2) = prec d 1 (hang (ppValue q 2 v1) 2 ("++" <+> ppValue q 1
10201046ppValue q d (VGlue v1 v2) = prec d 2 (ppValue q 3 v1 <+> ' +' <+> ppValue q 2 v2)
10211047ppValue q d (VPatt _ _ _) = pp " VPatt"
10221048ppValue q d (VPattType _) = pp " VPattType"
1023- ppValue q d (VFV i vs) = prec d 4 (" variants" <+> pp i <+> braces (fsep (punctuate ' ;' (map (ppValue q 0 ) (unvariants vs)))))
1049+ ppValue q d (VFV i (VarFree vs)) = prec d 4 (" variants" <+> pp i <+> braces (fsep (punctuate ' ;' (map (ppValue q 0 ) vs))))
1050+ ppValue q d (VFV i (VarOpts _ n os)) = prec d 4 (" option" <+> ppValue q 0 n <+> " of" <+> pp i <+> braces (fsep (punctuate ' ;'
1051+ (map (\ (_,l,v) -> parens (ppValue q 0 l) <+> " =>" <+> ppValue q 0 v) os))))
10241052ppValue q d (VAlts e xs) = prec d 4 (" pre" <+> braces (ppValue q 0 e <> ' ;' <+> fsep (punctuate ' ;' (map (ppAltern q) xs))))
10251053ppValue q d (VStrs _) = pp " VStrs"
10261054ppValue q d (VMarkup _ _ _) = pp " VMarkup"
@@ -1129,6 +1157,9 @@ mapC f c (x:xs) =
11291157 let (! c1,! c2) = split c
11301158 in f c1 x : mapC f c2 xs
11311159
1160+ forC :: Choice -> [a ] -> (Choice -> a -> b ) -> [b ]
1161+ forC c xs f = mapC f c xs
1162+
11321163mapCM :: Monad m => (Choice -> a -> m b ) -> Choice -> [a ] -> m [b ]
11331164mapCM f c [] = return []
11341165mapCM f c [x] = do y <- f c x
@@ -1138,3 +1169,6 @@ mapCM f c (x:xs) = do
11381169 y <- f c1 x
11391170 ys <- mapCM f c2 xs
11401171 return (y: ys)
1172+
1173+ forCM :: Monad m => Choice -> [a ] -> (Choice -> a -> m b ) -> m [b ]
1174+ forCM c xs f = mapCM f c xs
0 commit comments