Merge branch 'majestic' of github.com:krangelov/gf-core into majestic

This commit is contained in:
Krasimir Angelov
2025-08-21 14:25:28 +02:00
9 changed files with 645 additions and 332 deletions
+4 -4
View File
@@ -232,12 +232,12 @@ checkInfo opts cwd sgr sm (c,info) = checkInModule cwd (snd sm) NoLoc empty $ do
ResOverload os tysts -> chIn NoLoc "overloading" $ do ResOverload os tysts -> chIn NoLoc "overloading" $ do
tysts' <- mapM (uncurry $ flip (\(L loc1 t) (L loc2 ty) -> checkLType g t ty >>= \(t,ty) -> return (L loc1 t, L loc2 ty))) tysts -- return explicit ones tysts' <- mapM (uncurry $ flip (\(L loc1 t) (L loc2 ty) -> checkLType g t ty >>= \(t,ty) -> return (L loc1 t, L loc2 ty))) tysts -- return explicit ones
tysts0 <- lookupOverload gr (fst sm,c) -- check against inherited ones too tysts0 <- lookupOverload gr (fst sm,c) -- check against inherited ones too
tysts1 <- mapM (uncurry $ flip (checkLType g)) tysts1 <- sequence
[(mkFunType args val,tr) | (args,(val,tr)) <- tysts0] [checkLType g tr (mkFunType args val) | (args,(val,tr)) <- tysts0]
--- this can only be a partial guarantee, since matching --- this can only be a partial guarantee, since matching
--- with value type is only possible if expected type is given --- with value type is only possible if expected type is given
checkUniq $ --checkUniq $
sort [let (xs,t) = typeFormCnc x in t : map (\(b,x,t) -> t) xs | (_,x) <- tysts1] -- sort [let (xs,t) = typeFormCnc x in t : map (\(b,x,t) -> t) xs | (_,x) <- tysts1]
update sm c (ResOverload os [(y,x) | (x,y) <- tysts']) update sm c (ResOverload os [(y,x) | (x,y) <- tysts'])
ResParam (Just (L loc pcs)) _ -> do ResParam (Just (L loc pcs)) _ -> do
+103 -43
View File
@@ -3,13 +3,13 @@
module GF.Compile.Compute.Concrete2 module GF.Compile.Compute.Concrete2
(Env, Scope, Value(..), Variants(..), OptionInfo(..), ChoiceMap, cleanOptions, (Env, Scope, Value(..), Variants(..), OptionInfo(..), ChoiceMap, cleanOptions,
ConstValue(..), ConstVariants(..), Globals(..), PredefTable, EvalM, ConstValue(..), ConstVariants(..), Globals(..), PredefTable, EvalM,
mapVariants, unvariants, variants2consts, consts2variants, mapVariants, mapVariantsC, unvariants, variants2consts, consts2variants,
runEvalM, runEvalMWithOpts, stdPredef, globals, withState, runEvalM, runEvalMWithOpts, stdPredef, globals,
PredefImpl, Predef(..), ($\), PredefImpl, Predef(..), ($\),
pdCanonicalArgs, pdArity, pdCanonicalArgs, pdArity,
normalForm, normalFlatForm, normalForm, normalFlatForm,
eval, apply, value2term, value2termM, bubble, patternMatch, vtableSelect, State(..), eval, apply, value2term, value2termM, value2int, value2float, bubble, patternMatch, vtableSelect, State(..),
newResiduation, getMeta, setMeta, MetaState(..), variants, try, newResiduation, checkpoint, getMeta, setMeta, MetaState(..), variants, try,
evalError, evalWarn, ppValue, Choice(..), unit, poison, split, split3, split4, mapC, mapCM) where evalError, evalWarn, ppValue, Choice(..), unit, poison, split, split3, split4, mapC, mapCM) where
import Prelude hiding ((<>)) -- GHC 8.4.1 clash with Text.PrettyPrint import Prelude hiding ((<>)) -- GHC 8.4.1 clash with Text.PrettyPrint
@@ -24,6 +24,7 @@ import GF.Grammar.Predef
import GF.Grammar.Printer hiding (ppValue) import GF.Grammar.Printer hiding (ppValue)
import GF.Grammar.Lockfield(lockLabel) import GF.Grammar.Lockfield(lockLabel)
import GF.Text.Pretty hiding (empty) import GF.Text.Pretty hiding (empty)
import qualified GF.Text.Pretty as PP
import Control.Monad import Control.Monad
import Control.Applicative hiding (Const) import Control.Applicative hiding (Const)
import qualified Control.Applicative as A import qualified Control.Applicative as A
@@ -65,7 +66,7 @@ data Value
| VGen {-# UNPACK #-} !Int [Value] | VGen {-# UNPACK #-} !Int [Value]
| VClosure Env Choice Term | VClosure Env Choice Term
| VProd BindType Ident Value Value | VProd BindType Ident Value Value
| VRecType [(Label, Bool, Value)] | VRecType [(Label, Bool, Value)] Bool
| VR [(Label, Value)] | VR [(Label, Value)]
| VP Value Label [Value] | VP Value Label [Value]
| VExtR Value Value | VExtR Value Value
@@ -89,16 +90,20 @@ data Value
| VReset Ident (Maybe Value) Value (Maybe QIdent) | VReset Ident (Maybe Value) Value (Maybe QIdent)
| VSymCat Int LIndex [(LIndex, (Value, Type))] | VSymCat Int LIndex [(LIndex, (Value, Type))]
| VError Doc | VError Doc
| VInts (Maybe Integer) (Maybe Integer) | VInts Integer Bool
data Variants data Variants
= VarFree [Value] = VarFree [Value]
| VarOpts Value [(Value, Value)] | VarOpts Value [(Maybe Value, Value)]
mapVariants :: (Value -> Value) -> Variants -> Variants mapVariants :: (Value -> Value) -> Variants -> Variants
mapVariants f (VarFree vs) = VarFree (f <$> vs) mapVariants f (VarFree vs) = VarFree (f <$> vs)
mapVariants f (VarOpts n cs) = VarOpts n (second f <$> cs) mapVariants f (VarOpts n cs) = VarOpts n (second f <$> cs)
mapVariantsC :: (Choice -> Value -> Value) -> Choice -> Variants -> Variants
mapVariantsC f c (VarFree vs) = VarFree (mapC f c vs)
mapVariantsC f c (VarOpts n cs) = VarOpts n (mapC (\c (x,y) -> (x,f c y)) c cs)
unvariants :: Variants -> [Value] unvariants :: Variants -> [Value]
unvariants (VarFree vs) = vs unvariants (VarFree vs) = vs
unvariants (VarOpts n cs) = snd <$> cs unvariants (VarOpts n cs) = snd <$> cs
@@ -106,7 +111,7 @@ unvariants (VarOpts n cs) = snd <$> cs
isCanonicalForm :: Bool -> Value -> Bool isCanonicalForm :: Bool -> Value -> Bool
isCanonicalForm flat (VClosure {}) = True isCanonicalForm flat (VClosure {}) = True
isCanonicalForm flat (VProd b x d cod) = isCanonicalForm flat d && isCanonicalForm flat cod isCanonicalForm flat (VProd b x d cod) = isCanonicalForm flat d && isCanonicalForm flat cod
isCanonicalForm flat (VRecType fs) = all (\(l,_,ty) -> isCanonicalForm flat ty) fs isCanonicalForm flat (VRecType fs _) = all (\(l,_,ty) -> isCanonicalForm flat ty) fs
isCanonicalForm flat (VR {}) = True isCanonicalForm flat (VR {}) = True
isCanonicalForm flat (VTable d cod) = isCanonicalForm flat d && isCanonicalForm flat cod isCanonicalForm flat (VTable d cod) = isCanonicalForm flat d && isCanonicalForm flat cod
isCanonicalForm flat (VT {}) = True isCanonicalForm flat (VT {}) = True
@@ -133,7 +138,7 @@ data ConstValue a
data ConstVariants a data ConstVariants a
= ConstFree [ConstValue a] = ConstFree [ConstValue a]
| ConstOpts Value [(Value, ConstValue a)] | ConstOpts Value [(Maybe Value, ConstValue a)]
mapConstVs :: (ConstValue a -> ConstValue b) -> ConstVariants a -> ConstVariants b mapConstVs :: (ConstValue a -> ConstValue b) -> ConstVariants a -> ConstVariants b
mapConstVs f (ConstFree vs) = ConstFree (f <$> vs) mapConstVs f (ConstFree vs) = ConstFree (f <$> vs)
@@ -200,7 +205,7 @@ eval g env s (Prod b x t1 t2)[]
| otherwise = let (s1,s2) = split s | otherwise = let (s1,s2) = split s
in VProd b x (eval g env s1 t1 []) (VClosure env s2 t2) in VProd b x (eval g env s1 t1 []) (VClosure env s2 t2)
eval g env s (Typed t ty) vs = eval g env s t vs eval g env s (Typed t ty) vs = eval g env s t vs
eval g env s (RecType lbls) [] = VRecType (mapC (\s (lbl,ty) -> (lbl, True, eval g env s ty [])) s lbls) eval g env s (RecType lbls) [] = VRecType (mapC (\s (lbl,ty) -> (lbl, True, eval g env s ty [])) s lbls) False
eval g env s (R as) [] = VR (mapC (\s (lbl,(ty,t)) -> (lbl, eval g env s t [])) s as) eval g env s (R as) [] = VR (mapC (\s (lbl,(ty,t)) -> (lbl, eval g env s t [])) s as)
eval g env s (P t lbl) vs = let project (VR as) = case lookup lbl as of eval g env s (P t lbl) vs = let project (VR as) = case lookup lbl as of
Nothing -> VError ("Missing value for label" <+> pp lbl $$ Nothing -> VError ("Missing value for label" <+> pp lbl $$
@@ -214,7 +219,7 @@ eval g env s (P t lbl) vs = let project (VR as) = case lookup lbl a
eval g env s (ExtR t1 t2) [] = let (s1,s2) = split s eval g env s (ExtR t1 t2) [] = let (s1,s2) = split s
extend (VR as1) (VR as2) = VR (foldl (\as (lbl,v) -> update lbl v as) as1 as2) extend (VR as1) (VR as2) = VR (foldl (\as (lbl,v) -> update lbl v as) as1 as2)
extend (VRecType as1) (VRecType as2) = VRecType (foldl (\as (lbl,o,v) -> update3 lbl o v as) as1 as2) extend (VRecType as1 e1) (VRecType as2 e2)=VRecType (foldl (\as (lbl,o,v) -> update3 lbl o v as) as1 as2) (e1 || e2)
extend (VFV i fvs) v2 = VFV i (mapVariants (`extend` v2) fvs) extend (VFV i fvs) v2 = VFV i (mapVariants (`extend` v2) fvs)
extend v1 (VFV i fvs) = VFV i (mapVariants (v1 `extend`) fvs) extend v1 (VFV i fvs) = VFV i (mapVariants (v1 `extend`) fvs)
extend (VMeta i vs) v2 = VSusp i (\v -> extend (apply g v vs) v2) [] extend (VMeta i vs) v2 = VSusp i (\v -> extend (apply g v vs) v2) []
@@ -332,7 +337,8 @@ eval g env c t@(Opts n cs) vs = if null cs
vn = eval g env c1 n [] vn = eval g env c1 n []
vcs = mapC evalOpt c cs vcs = mapC evalOpt c cs
in VFV c3 (VarOpts vn vcs) in VFV c3 (VarOpts vn vcs)
where evalOpt c' (l,t) = let (c1,c2) = split c' in (eval g env c1 l [], eval g env c2 t vs) where evalOpt c' (Just l, t) = let (c1,c2) = split c' in (Just (eval g env c1 l []), eval g env c2 t vs)
evalOpt c' (Nothing,t) = let (c1,c2) = split c' in (Nothing, eval g env c2 t vs)
eval g env c t vs = VError ("Cannot reduce term" <+> pp t) eval g env c t vs = VError ("Cannot reduce term" <+> pp t)
evalPredef :: Globals -> Choice -> Ident -> [Value] -> Value evalPredef :: Globals -> Choice -> Ident -> [Value] -> Value
@@ -348,7 +354,7 @@ evalPredef g@(Gl gr pds) c n args =
stdPredef :: Globals -> PredefTable stdPredef :: Globals -> PredefTable
stdPredef g = Map.fromList stdPredef g = Map.fromList
[(cInts, pdArity 1 $\ \g c vs -> Const (case vs of {[VInt i] -> VInts (Just i) (Just i); vs -> VApp c (cPredef,cInts) vs})) [(cInts, pdArity 1 $\ \g c vs -> Const (case vs of {[VInt i] -> VInts i False; vs -> VApp c (cPredef,cInts) vs}))
,(cLength, pdArity 1 $\ \g c [v] -> fmap (VInt . genericLength) (value2string g v)) ,(cLength, pdArity 1 $\ \g c [v] -> fmap (VInt . genericLength) (value2string g v))
,(cTake, pdArity 2 $\ \g c [v1,v2] -> fmap string2value (liftA2 genericTake (value2int g v1) (value2string g v2))) ,(cTake, pdArity 2 $\ \g c [v1,v2] -> fmap string2value (liftA2 genericTake (value2int g v1) (value2string g v2)))
,(cDrop, pdArity 2 $\ \g c [v1,v2] -> fmap string2value (liftA2 genericDrop (value2int g v1) (value2string g v2))) ,(cDrop, pdArity 2 $\ \g c [v1,v2] -> fmap string2value (liftA2 genericDrop (value2int g v1) (value2string g v2)))
@@ -392,9 +398,9 @@ bubble v = snd (bubble v)
bubble (VGen i vs) = liftL (VGen i) vs bubble (VGen i vs) = liftL (VGen i) vs
bubble (VClosure env c t) = liftL' (\env -> VClosure env c t) env bubble (VClosure env c t) = liftL' (\env -> VClosure env c t) env
bubble (VProd bt x v1 v2) = lift2 (VProd bt x) v1 v2 bubble (VProd bt x v1 v2) = lift2 (VProd bt x) v1 v2
bubble v@(VRecType lbls) = bubble v@(VRecType lbls ext) =
let (union,lbls') = mapAccumL descendR Map.empty lbls let (union,lbls') = mapAccumL descendR Map.empty lbls
in (union, addVariants (VRecType lbls') union) in (union, addVariants (VRecType lbls' ext) union)
bubble (VR as) = liftL' VR as bubble (VR as) = liftL' VR as
bubble (VP v l vs) = lift1L (\v vs -> VP v l vs) v vs bubble (VP v l vs) = lift1L (\v vs -> VP v l vs) v vs
bubble (VExtR v1 v2) = lift2 VExtR v1 v2 bubble (VExtR v1 v2) = lift2 VExtR v1 v2
@@ -414,18 +420,20 @@ bubble v = snd (bubble v)
bubble v@(VFV c (VarFree vs)) bubble v@(VFV c (VarFree vs))
| null vs = (Map.empty, v) | null vs = (Map.empty, v)
| otherwise = let (union,vs') = mapAccumL descend Map.empty vs | otherwise = let (union,vs') = mapAccumL descend Map.empty vs
in (Map.insert c (BubbleFree (length vs),1) union, addVariants (VFV c (VarFree vs')) union) in (Map.insert c (BubbleFree (length vs),1) union, VFV c (VarFree vs'))
bubble v@(VFV c (VarOpts n os)) bubble v@(VFV c (VarOpts n os))
| null os = (Map.empty, v) | null os = (Map.empty, v)
| otherwise = let (union,os') = mapAccumL (\acc (k,v) -> second (k,) $ descend acc v) Map.empty os | otherwise = let (union,os') = mapAccumL (\acc (k,v) -> second (k,) $ descend acc v) Map.empty os
in (Map.insert c (BubbleOpts n (fst <$> os),1) union, addVariants (VFV c (VarOpts n os')) union) in (Map.insert c (BubbleOpts n (map (\(l,t) -> fromMaybe t l) os),1) union, VFV c (VarOpts n os'))
bubble (VAlts v vs) = lift1L2 VAlts v vs bubble (VAlts v vs) = lift1L2 VAlts v vs
bubble (VStrs vs) = liftL VStrs vs bubble (VStrs vs) = liftL VStrs vs
bubble (VMarkup tag attrs vs) = bubble (VMarkup tag attrs vs) =
let (union1,attrs') = mapAccumL descend' Map.empty attrs let (union1,attrs') = mapAccumL descend' Map.empty attrs
(union2,vs') = mapAccumL descend union1 vs (union2,vs') = mapAccumL descend union1 vs
in (union2, VMarkup tag attrs' vs') in (union2, VMarkup tag attrs' vs')
bubble (VReset ctl mb_cv v id) = lift1 (\v -> VReset ctl mb_cv v id) v bubble (VReset ctl mb_cv v id) =
let (union,v') = bubble v
in (Map.empty,VReset ctl mb_cv v' id)
bubble (VSymCat d i0 vs) = bubble (VSymCat d i0 vs) =
let (union,vs') = mapAccumL descendC Map.empty vs let (union,vs') = mapAccumL descendC Map.empty vs
in (union, addVariants (VSymCat d i0 vs') union) in (union, addVariants (VSymCat d i0 vs') union)
@@ -501,7 +509,7 @@ bubble v = snd (bubble v)
addVariant c (bvs,cnt) v addVariant c (bvs,cnt) v
| cnt > 1 = VFV c $ case bvs of | cnt > 1 = VFV c $ case bvs of
BubbleFree k -> VarFree (replicate k v) BubbleFree k -> VarFree (replicate k v)
BubbleOpts n os -> VarOpts n ((,v) <$> os) BubbleOpts n os -> VarOpts n (map (\l -> (Just l,v)) os)
| otherwise = v | otherwise = v
unitfy = fmap (\(n,_) -> (n,1)) unitfy = fmap (\(n,_) -> (n,1))
@@ -733,9 +741,6 @@ runEvalMWithOpts g cs (EvalM f) = Check $ \(es,ws) ->
where where
init = State cs Map.empty [] init = State cs Map.empty []
withState :: State -> EvalM a -> EvalM a
withState state (EvalM f) = EvalM $ \g k _ r ws -> f g k state r ws
reset :: EvalM a -> EvalM [a] reset :: EvalM a -> EvalM [a]
reset (EvalM f) = EvalM $ \g k state r ws -> reset (EvalM f) = EvalM $ \g k state r ws ->
case f g (\x state xs ws -> Success (x:xs) ws) state [] ws of case f g (\x state xs ws -> Success (x:xs) ws) state [] ws of
@@ -773,24 +778,36 @@ variants' c f xs = EvalM (\g k state@(State choices metas opts) r msgs ->
Fail msg msgs -> Fail msg msgs Fail msg msgs -> Fail msg msgs
Success ts msgs -> backtrack g (j+1) xs choices metas opts ts msgs Success ts msgs -> backtrack g (j+1) xs choices metas opts ts msgs
try :: (a -> EvalM b) -> ([(b,State)] -> EvalM b) -> [a] -> EvalM b try :: Int -> (a -> EvalM b) -> ([b] -> EvalM b) -> [a] -> EvalM b
try f select xs = EvalM (\g k state r msgs -> try sz f select xs = EvalM (\g k state r msgs ->
let (res,msgs') = backtrack g xs state [] msgs let (state',res,msgs') = backtrack sz g xs state [] msgs
in case select res of in case select res of
EvalM f' -> f' g k state r msgs') EvalM f' -> f' g k state' r msgs')
where where
backtrack g [] state res msgs = (res,msgs) backtrack sz g [] state res msgs = (state,res,msgs)
backtrack g (x:xs) state res msgs = backtrack sz g (x:xs) state res msgs =
case f x of case f x of
EvalM f -> case f g (\x state res msgs -> Success ((x,state):res) msgs) state res msgs of EvalM f -> case f g (\y state' (_,ys) msgs -> Success (cut sz state state',y:ys) msgs) state (state,res) msgs of
Fail msg _ -> backtrack g xs state res msgs Fail msg _ -> backtrack sz g xs state res msgs
Success res msgs -> backtrack g xs state res msgs Success (state,res) msgs -> backtrack sz g xs state res msgs
cut sz state state' = state'{metaVars=Map.mapWithKey select (metaVars state')}
where
select k ms
| k <= sz = ms
| otherwise = case Map.lookup k (metaVars state) of
Just ms -> ms
Nothing -> ms
newResiduation :: Scope -> EvalM MetaId newResiduation :: Scope -> EvalM MetaId
newResiduation scope = EvalM (\g k (State choices metas opts) r msgs -> newResiduation scope = EvalM (\g k (State choices metas opts) r msgs ->
let meta_id = Map.size metas+1 let meta_id = Map.size metas+1
in k meta_id (State choices (Map.insert meta_id (Residuation scope) metas) opts) r msgs) in k meta_id (State choices (Map.insert meta_id (Residuation scope) metas) opts) r msgs)
checkpoint :: EvalM Int
checkpoint = EvalM (\g k state r msgs ->
k (Map.size (metaVars state)) state r msgs)
getMeta :: MetaId -> EvalM MetaState getMeta :: MetaId -> EvalM MetaState
getMeta i = EvalM (\g k state r msgs -> getMeta i = EvalM (\g k state r msgs ->
case Map.lookup i (metaVars state) of case Map.lookup i (metaVars state) of
@@ -833,7 +850,7 @@ value2termM flat xs (VProd b x v1 v2) = do
t1 <- value2termM flat xs v1 t1 <- value2termM flat xs v1
t2 <- value2termM flat xs v2 t2 <- value2termM flat xs v2
return (Prod b x t1 t2) return (Prod b x t1 t2)
value2termM flat xs (VRecType lbls) = do value2termM flat xs (VRecType lbls _) = do
lbls <- mapM (\(lbl,_,v) -> fmap ((,) lbl) (value2termM flat xs v)) lbls lbls <- mapM (\(lbl,_,v) -> fmap ((,) lbl) (value2termM flat xs v)) lbls
return (RecType lbls) return (RecType lbls)
value2termM flat xs (VR as) = do value2termM flat xs (VR as) = do
@@ -908,7 +925,7 @@ value2termM flat xs (VFV i (VarOpts n os)) =
let j = fromMaybe 0 (Map.lookup i choices) let j = fromMaybe 0 (Map.lookup i choices)
in case os `maybeAt` j of in case os `maybeAt` j of
Just (l,t) -> case value2termM flat xs t of Just (l,t) -> case value2termM flat xs t of
EvalM f -> let oi = OptionInfo i n (fst <$> os) EvalM f -> let oi = OptionInfo i n (map (\(l,t) -> fromMaybe t l) os)
in f g k (State choices metas (oi:opts)) r msgs in f g k (State choices metas (oi:opts)) r msgs
Nothing -> Fail ("Index" <+> j <+> "out of bounds for option:" $$ ppValue Unqualified 0 n) msgs Nothing -> Fail ("Index" <+> j <+> "out of bounds for option:" $$ ppValue Unqualified 0 n) msgs
value2termM flat xs (VPatt min max p) = return (EPatt min max p) value2termM flat xs (VPatt min max p) = return (EPatt min max p)
@@ -941,11 +958,36 @@ value2termM flat xs (VReset ctl mb_cv v mb_qid) = do
case ts of case ts of
[t] -> return t [t] -> return t
ts -> return (Markup identW [] ts) ts -> return (Markup identW [] ts)
| ctl == cConcat' = do
ts <- case mb_cv of
Just (VInt n) -> return (genericTake n ts)
Nothing -> return ts
_ -> evalError (pp "[concat: .. | ..] requires an integer constant")
case ts of
[] -> mzero
[t] -> return t
ts -> return (Markup identW [] ts)
| ctl == cOne = | ctl == cOne =
case (ts,mb_cv) of case (ts,mb_cv) of
([] ,Nothing) -> mzero ([] ,Nothing) -> mzero
([] ,Just v) -> value2termM flat xs v ([] ,Just v) -> value2termM flat xs v
(t:ts,_) -> return t (t:ts,_) -> return t
| ctl == cSelect =
case mb_cv of
Just (VInt n) | n >= 0 -> select n ts'
| otherwise -> select (-n-1) (reverse ts')
where
ts' = sortBy compareKey ts
select _ [] = mzero
select 0 (t:ts) =
case t of
R rs -> case lookup (ident2label cp1) rs of
Just (_,t) -> return t
Nothing -> evalError (pp "Missing label p1")
_ -> evalError (pp "The term must be a record")
select n (t:ts) = select (n-1) ts
_ -> evalError (pp "[select: .. | ..] requires an integer constant")
| ctl == cDefault = | ctl == cDefault =
case (ts,mb_cv) of case (ts,mb_cv) of
([] ,Nothing) -> mzero ([] ,Nothing) -> mzero
@@ -962,15 +1004,23 @@ value2termM flat xs (VReset ctl mb_cv v mb_qid) = do
t <- listify mn cat ts t <- listify mn cat ts
return (App (App (QC (mn,identS ("Conj"++cat))) ct) t) return (App (App (QC (mn,identS ("Conj"++cat))) ct) t)
_ -> evalError (pp "[list: .. | ..] requires an argument") _ -> evalError (pp "[list: .. | ..] requires an argument")
| ctl == cLen =
case mb_cv of
Just cv -> do g <- globals
value2termM True xs (apply g cv [VInt (genericLength ts)])
Nothing -> return (EInt (genericLength ts))
| otherwise = evalError (pp "Operator" <+> pp ctl <+> pp "is not defined") | otherwise = evalError (pp "Operator" <+> pp ctl <+> pp "is not defined")
listify mn cat [t1,t2] = do return (App (App (QC (mn,identS ("Base"++cat))) t1) t2) listify mn cat [t1,t2] = do return (App (App (QC (mn,identS ("Base"++cat))) t1) t2)
listify mn cat (t1:ts) = do t2 <- listify mn cat ts listify mn cat (t1:ts) = do t2 <- listify mn cat ts
return (App (App (QC (mn,identS ("Cons"++cat))) t1) t2) return (App (App (QC (mn,identS ("Cons"++cat))) t1) t2)
compareKey (R rs1) (R rs2) =
case (lookup (ident2label cp2) rs1, lookup (ident2label cp2) rs2) of
(Just (_,K s1), Just (_,K s2)) -> compare s1 s2
value2termM flat xs (VError msg) = evalError msg value2termM flat xs (VError msg) = evalError msg
value2termM flat xs (VInts Nothing Nothing) = return (App (Q (cPredef,cInts)) (Meta 0)) value2termM flat xs (VInts n _) = return (App (Q (cPredef,cInts)) (EInt n))
value2termM flat xs (VInts (Just min) Nothing) = return (App (Q (cPredef,cInts)) (EInt min))
value2termM flat xs (VInts _ (Just max)) = return (App (Q (cPredef,cInts)) (EInt max))
value2termM flat xs v = evalError ("value2termM" <+> ppValue Unqualified 5 v) value2termM flat xs v = evalError ("value2termM" <+> ppValue Unqualified 5 v)
@@ -986,6 +1036,7 @@ pattVars st (PSeq _ _ p1 _ _ p2) = pattVars (pattVars st p1) p2
pattVars st _ = st pattVars st _ = st
ppValue q d (VApp c f vs) = prec d 4 (hsep (ppQIdent q f : map (ppValue q 5) vs)) ppValue q d (VApp c f vs) = prec d 4 (hsep (ppQIdent q f : map (ppValue q 5) vs))
ppValue q d (VMeta i vs) = prec d 4 (hsep ((if i > 0 then pp "?" <> pp i else pp "?") : map (ppValue q 5) vs)) ppValue q d (VMeta i vs) = prec d 4 (hsep ((if i > 0 then pp "?" <> pp i else pp "?") : map (ppValue q 5) vs))
ppValue q d (VSusp i k vs) = prec d 4 (hsep (pp "#susp" : (if i > 0 then pp "?" <> pp i else pp "?") : map (ppValue q 5) vs)) ppValue q d (VSusp i k vs) = prec d 4 (hsep (pp "#susp" : (if i > 0 then pp "?" <> pp i else pp "?") : map (ppValue q 5) vs))
@@ -995,13 +1046,13 @@ ppValue q d (VProd bt x a b) =
if x == identW && bt == Explicit if x == identW && bt == Explicit
then prec d 0 (ppValue q 4 a <+> "->" <+> ppValue q 0 b) then prec d 0 (ppValue q 4 a <+> "->" <+> ppValue q 0 b)
else prec d 0 (parens (ppBind (bt,x) <+> ':' <+> ppValue q 0 a) <+> "->" <+> ppValue q 0 b) else prec d 0 (parens (ppBind (bt,x) <+> ':' <+> ppValue q 0 a) <+> "->" <+> ppValue q 0 b)
ppValue q d (VRecType xs) ppValue q d (VRecType xs ext)
| q == Terse = case [cat | (l,_,_) <- xs, let (p,cat) = splitAt 5 (showIdent (label2ident l)), p == "lock_"] of | q == Terse = case [cat | (l,_,_) <- xs, let (p,cat) = splitAt 5 (showIdent (label2ident l)), p == "lock_"] of
[cat] -> pp cat [cat] -> pp cat
_ -> doc _ -> doc
| otherwise = doc | otherwise = doc
where where
doc = braces (fsep (punctuate ';' [l <+> (if o then ":" else ":?") <+> ppValue q 0 v | (l,o,v) <- xs])) doc = braces (fsep (punctuate ';' ([l <+> (if o then ":" else ":?") <+> ppValue q 0 v | (l,o,v) <- xs] ++ [pp ".." | ext])))
ppValue q d (VR _) = pp "VR" ppValue q d (VR _) = pp "VR"
ppValue q d (VP v l vs) = prec d 5 (hsep (ppValue q 5 v <> '.' <> l : map (ppValue q 5) vs)) ppValue q d (VP v l vs) = prec d 5 (hsep (ppValue q 5 v <> '.' <> l : map (ppValue q 5) vs))
ppValue q d (VExtR _ _) = pp "VExtR" ppValue q d (VExtR _ _) = pp "VExtR"
@@ -1021,17 +1072,20 @@ ppValue q d VEmpty = pp "[]"
ppValue q d (VC v1 v2) = prec d 1 (hang (ppValue q 2 v1) 2 ("++" <+> ppValue q 1 v2)) ppValue q d (VC v1 v2) = prec d 1 (hang (ppValue q 2 v1) 2 ("++" <+> ppValue q 1 v2))
ppValue q d (VGlue v1 v2) = prec d 2 (ppValue q 3 v1 <+> '+' <+> ppValue q 2 v2) ppValue q d (VGlue v1 v2) = prec d 2 (ppValue q 3 v1 <+> '+' <+> ppValue q 2 v2)
ppValue q d (VPatt _ _ _) = pp "VPatt" ppValue q d (VPatt _ _ _) = pp "VPatt"
ppValue q d (VPattType _) = pp "VPattType" ppValue q d (VPattType v) = prec d 4 ("pattern" <+> ppValue q 0 v)
ppValue q d (VFV i vs) = prec d 4 ("variants" <+> pp i <+> braces (fsep (punctuate ';' (map (ppValue q 0) (unvariants vs))))) ppValue q d (VFV i vs) = prec d 4 ("variants" <+> pp i <+> braces (fsep (punctuate ';' (map (ppValue q 0) (unvariants vs)))))
ppValue q d (VAlts e xs) = prec d 4 ("pre" <+> braces (ppValue q 0 e <> ';' <+> fsep (punctuate ';' (map (ppAltern q) xs)))) ppValue q d (VAlts e xs) = prec d 4 ("pre" <+> braces (ppValue q 0 e <> ';' <+> fsep (punctuate ';' (map (ppAltern q) xs))))
ppValue q d (VStrs _) = pp "VStrs" ppValue q d (VStrs _) = pp "VStrs"
ppValue q d (VMarkup _ _ _) = pp "VMarkup" ppValue q d (VMarkup _ _ _) = pp "VMarkup"
ppValue q d (VReset ctl ct t _) = pp "[" <> pp ctl <>
maybe PP.empty (\v -> pp ':' <+> ppValue q 6 v) ct <>
pp "|" <> ppValue q 0 t <>
pp "]"
ppValue q d (VSymCat i r rs) = pp '<' <> pp i <> pp ',' <> pp r <> pp '>' ppValue q d (VSymCat i r rs) = pp '<' <> pp i <> pp ',' <> pp r <> pp '>'
ppValue q d (VError msg) = prec d 4 (pp "error" <+> ppTerm q 5 (K (show msg))) ppValue q d (VError msg) = prec d 4 (pp "error" <+> ppTerm q 5 (K (show msg)))
ppValue q d (VInts Nothing Nothing) = prec d 4 (pp "Ints ?") ppValue q d (VInts n ext)
ppValue q d (VInts (Just min) Nothing) = prec d 4 (pp "Ints" <+> brackets (pp min <> "..")) | ext = prec d 4 (pp "Ints" <+> brackets (pp n <> ".."))
ppValue q d (VInts Nothing (Just max)) = prec d 4 (pp "Ints" <+> brackets (".." <> pp max)) | otherwise = prec d 4 (pp "Ints" <+> pp n)
ppValue q d (VInts (Just min) (Just max)) = prec d 4 (pp "Ints" <+> brackets (pp min <> ".." <> pp max))
ppAltern q (x,y) = ppValue q 0 x <+> '/' <+> ppValue q 0 y ppAltern q (x,y) = ppValue q 0 x <+> '/' <+> ppValue q 0 y
@@ -1103,6 +1157,12 @@ value2int g (VInt n) = Const n
value2int g (VFV s vs) = CFV s (variants2consts (value2int g) vs) value2int g (VFV s vs) = CFV s (variants2consts (value2int g) vs)
value2int g _ = RunTime value2int g _ = RunTime
value2float g (VMeta i vs) = CSusp i (\v -> value2float g (apply g v vs))
value2float g (VSusp i k vs) = CSusp i (\v -> value2float g (apply g (k v) vs))
value2float g (VFlt f) = Const f
value2float g (VFV s vs) = CFV s (variants2consts (value2float g) vs)
value2float g _ = RunTime
newtype Choice = Choice { unchoice :: Integer } newtype Choice = Choice { unchoice :: Integer }
deriving (Eq,Ord,Pretty,Show) deriving (Eq,Ord,Pretty,Show)
+21 -4
View File
@@ -214,11 +214,28 @@ str2lin (VSymCat d r rs) = do (r, rs) <- compute r rs
str2lin (VSymVar d r) = return [SymVar d r] str2lin (VSymVar d r) = return [SymVar d r]
str2lin VEmpty = return [] str2lin VEmpty = return []
str2lin (VC v1 v2) = liftM2 (++) (str2lin v1) (str2lin v2) str2lin (VC v1 v2) = liftM2 (++) (str2lin v1) (str2lin v2)
str2lin (VAlts def alts) = do def <- str2lin def str2lin v0@(VAlts def alts)
alts <- forM alts $ \(v,VStrs vs) -> do = do def <- str2lin def
lin <- str2lin v alts <- forM alts $ \(v1,v2) -> do
return (lin,[s | VStr s <- vs]) lin <- str2lin v1
ss <- to_strs v2
return (lin,ss)
return [SymKP def alts] return [SymKP def alts]
where
to_strs (VStrs vs) = mapM to_str vs
to_strs (VPatt _ _ p) = from_patt p
to_strs v = fail
to_str (VStr s) = return s
to_str _ = fail
from_patt (PAlt p1 p2) = liftM2 (++) (from_patt p1) (from_patt p2)
from_patt (PSeq _ _ p1 _ _ p2) = liftM2 (liftM2 (++)) (from_patt p1) (from_patt p2)
from_patt (PString s) = return [s]
from_patt (PChars cs) = return (map (:[]) cs)
from_patt _ = fail
fail = evalError ("Complex patterns are not supported in:" $$ nest 2 (pp (showValue v0)))
str2lin v = do t <- value2term False [] v str2lin v = do t <- value2term False [] v
evalError ("the string:" <+> ppTerm Unqualified 0 t $$ evalError ("the string:" <+> ppTerm Unqualified 0 t $$
"cannot be evaluated at compile time.") "cannot be evaluated at compile time.")
+441 -226
View File
@@ -14,7 +14,7 @@ import GF.Compile.Compute.Concrete2
import GF.Infra.CheckM import GF.Infra.CheckM
import GF.Data.ErrM ( Err(Ok, Bad) ) import GF.Data.ErrM ( Err(Ok, Bad) )
import Control.Applicative(Applicative(..),(<|>)) import Control.Applicative(Applicative(..),(<|>))
import Control.Monad(ap,liftM,mplus,foldM,zipWithM,forM,filterM,unless) import Control.Monad(ap,liftM,liftM2,mplus,foldM,zipWithM,forM,filterM,unless)
import Control.Monad.ST import Control.Monad.ST
import GF.Text.Pretty import GF.Text.Pretty
import Data.STRef import Data.STRef
@@ -75,7 +75,7 @@ vtypePType = VSort cPType
vtypeMarkup= VApp poison (cPredef,cMarkup) [] vtypeMarkup= VApp poison (cPredef,cMarkup) []
tcRho :: Scope -> Choice -> Term -> Maybe Rho -> EvalM (Term, Rho) tcRho :: Scope -> Choice -> Term -> Maybe Rho -> EvalM (Term, Rho)
tcRho scope s t@(EInt i) mb_ty = instSigma scope s t (VInts (Just i) Nothing) mb_ty -- INT tcRho scope s t@(EInt i) mb_ty = instSigma scope s t (VInts i True) mb_ty -- INT
tcRho scope s t@(EFloat _) mb_ty = instSigma scope s t vtypeFloat mb_ty -- FLOAT tcRho scope s t@(EFloat _) mb_ty = instSigma scope s t vtypeFloat mb_ty -- FLOAT
tcRho scope s t@(K _) mb_ty = instSigma scope s t vtypeStr mb_ty -- STR tcRho scope s t@(K _) mb_ty = instSigma scope s t vtypeStr mb_ty -- STR
tcRho scope s t@(Empty) mb_ty = instSigma scope s t vtypeStr mb_ty tcRho scope s t@(Empty) mb_ty = instSigma scope s t vtypeStr mb_ty
@@ -117,7 +117,7 @@ tcRho scope c (Abs bt var body) Nothing = do -- ABS1
VClosure env c t -> do g <- globals VClosure env c t -> do g <- globals
check m (n+1) (b,x:xs) (eval g ((x,VGen n []):env) c t []) check m (n+1) (b,x:xs) (eval g ((x,VGen n []):env) c t [])
v2 -> check m n st v2 v2 -> check m n st v2
check m n st (VRecType as) = foldM (\st (l,_,v) -> check m n st v) st as check m n st (VRecType as _) = foldM (\st (l,_,v) -> check m n st v) st as
check m n st (VR as) = check m n st (VR as) =
foldM (\st (lbl,tnk) -> check m n st tnk) st as foldM (\st (lbl,tnk) -> check m n st tnk) st as
check m n st (VP v l vs) = check m n st (VP v l vs) =
@@ -200,7 +200,7 @@ tcRho scope c (FV ts) mb_ty = do
tcRho scope s t@(Sort _) mb_ty = do tcRho scope s t@(Sort _) mb_ty = do
instSigma scope s t vtypeType mb_ty instSigma scope s t vtypeType mb_ty
tcRho scope c t@(RecType rs) Nothing = do tcRho scope c t@(RecType rs) Nothing = do
(rs,mb_ty) <- tcRecTypeFields scope c rs Nothing (rs,mb_ty) <- tcRecTypeFields scope c [] rs Nothing
return (RecType rs,fromMaybe vtypePType mb_ty) return (RecType rs,fromMaybe vtypePType mb_ty)
tcRho scope c t@(RecType rs) (Just ty) = do tcRho scope c t@(RecType rs) (Just ty) = do
(scope,f,ty') <- skolemise scope ty (scope,f,ty') <- skolemise scope ty
@@ -214,7 +214,7 @@ tcRho scope c t@(RecType rs) (Just ty) = do
ty -> do ty <- value2termM False (scopeVars scope) ty ty -> do ty <- value2termM False (scopeVars scope) ty
evalError ("The record type" <+> ppTerm Unqualified 0 t $$ evalError ("The record type" <+> ppTerm Unqualified 0 t $$
"cannot be of type" <+> ppTerm Unqualified 0 ty) "cannot be of type" <+> ppTerm Unqualified 0 ty)
(rs,mb_ty) <- tcRecTypeFields scope c rs (Just ty') (rs,mb_ty) <- tcRecTypeFields scope c [] rs (Just ty')
return (f (RecType rs),ty) return (f (RecType rs),ty)
tcRho scope s t@(Table p res) mb_ty = do tcRho scope s t@(Table p res) mb_ty = do
let (s1,s23) = split s let (s1,s23) = split s
@@ -241,15 +241,13 @@ tcRho scope c (S t p) mb_ty = do
return (S t p, res_ty) return (S t p, res_ty)
tcRho scope c (T tt ps) Nothing = do -- ABS1/AABS1 for tables tcRho scope c (T tt ps) Nothing = do -- ABS1/AABS1 for tables
let (c1,c2) = split c let (c1,c2) = split c
let mk_val i = VMeta i [] mb_p_ty <- case tt of
p_ty <- case tt of TRaw -> return Nothing
TRaw -> fmap mk_val $ newResiduation scope
TTyped ty -> do let (c3,c4) = split c1 TTyped ty -> do let (c3,c4) = split c1
(ty, _) <- tcRho scope c3 ty (Just vtypeType) (ty, _) <- tcRho scope c3 ty (Just vtypeType)
g <- globals g <- globals
return (eval g (scopeEnv scope) c4 ty []) return (Just (eval g (scopeEnv scope) c4 ty []))
res_ty <- fmap mk_val $ newResiduation scope (ps,p_ty,res_ty) <- tcCases scope c2 ps mb_p_ty Nothing
ps <- tcCases scope c2 ps p_ty res_ty
p_ty_t <- value2termM True [] p_ty p_ty_t <- value2termM True [] p_ty
return (T (TTyped p_ty_t) ps, VTable p_ty res_ty) return (T (TTyped p_ty_t) ps, VTable p_ty res_ty)
tcRho scope c (T tt ps) (Just ty) = do -- ABS2/AABS2 for tables tcRho scope c (T tt ps) (Just ty) = do -- ABS2/AABS2 for tables
@@ -262,8 +260,9 @@ tcRho scope c (T tt ps) (Just ty) = do -- ABS2/AABS2 for
TTyped ty -> do let (c1,c2) = split c12 TTyped ty -> do let (c1,c2) = split c12
(ty, _) <- tcRho scope c1 ty (Just vtypeType) (ty, _) <- tcRho scope c1 ty (Just vtypeType)
g <- globals g <- globals
unify scope (eval g (scopeEnv scope) c2 ty []) p_ty subsCheckRho scope (Meta 0) (eval g (scopeEnv scope) c2 ty []) p_ty
ps <- tcCases scope c3 ps p_ty res_ty return ()
(ps,p_ty,res_ty) <- tcCases scope c3 ps (Just p_ty) (Just res_ty)
p_ty_t <- value2termM True (scopeVars scope) p_ty p_ty_t <- value2termM True (scopeVars scope) p_ty
return (f (T (TTyped p_ty_t) ps), VTable p_ty res_ty) return (f (T (TTyped p_ty_t) ps), VTable p_ty res_ty)
tcRho scope c (V p_ty ts) Nothing = do tcRho scope c (V p_ty ts) Nothing = do
@@ -290,22 +289,22 @@ tcRho scope c (V p_ty0 ts) (Just ty) = do
ts <- mapCM (\c t -> fmap fst $ tcRho scope c t (Just res_ty)) c3 ts ts <- mapCM (\c t -> fmap fst $ tcRho scope c t (Just res_ty)) c3 ts
return (V p_ty0 ts, VTable p_ty res_ty) return (V p_ty0 ts, VTable p_ty res_ty)
tcRho scope c (R rs) Nothing = do tcRho scope c (R rs) Nothing = do
lttys <- inferRecFields scope c rs lttys <- inferRecFields scope c [] rs
rs <- mapM (\(l,t,ty) -> value2termM True (scopeVars scope) ty >>= \ty -> return (l, (Just ty, t))) lttys rs <- mapM (\(l,t,ty) -> value2termM True (scopeVars scope) ty >>= \ty -> return (l, (Just ty, t))) lttys
return (R rs, return (R rs,
VRecType [(l,True,ty) | (l,t,ty) <- lttys] VRecType [(l,True,ty) | (l,t,ty) <- lttys] False
) )
tcRho scope c (R rs) (Just ty) = do tcRho scope c (R rs) (Just ty) = do
(scope,f,ty') <- skolemise scope ty (scope,f,ty') <- skolemise scope ty
case ty' of case ty' of
(VRecType ltys) -> do lttys <- checkRecFields scope c rs ltys (VRecType ltys _)->do lttys <- checkRecFields scope c [] rs ltys
rs <- mapM (\(l,t,ty) -> value2termM True (scopeVars scope) ty >>= \ty -> return (l, (Just ty, t))) lttys rs <- mapM (\(l,t,ty) -> value2termM True (scopeVars scope) ty >>= \ty -> return (l, (Just ty, t))) lttys
return ((f . R) rs, return ((f . R) rs,
VRecType [(l,True,ty) | (l,t,ty) <- lttys] VRecType [(l,True,ty) | (l,t,ty) <- lttys] False
) )
ty -> do lttys <- inferRecFields scope c rs ty -> do lttys <- inferRecFields scope c [] rs
t <- liftM (f . R) (mapM (\(l,t,ty) -> value2termM True (scopeVars scope) ty >>= \ty -> return (l, (Just ty, t))) lttys) t <- liftM (f . R) (mapM (\(l,t,ty) -> value2termM True (scopeVars scope) ty >>= \ty -> return (l, (Just ty, t))) lttys)
let ty' = VRecType [(l,True,ty) | (l,t,ty) <- lttys] let ty' = VRecType [(l,True,ty) | (l,t,ty) <- lttys] False
(t,_,_) <- subsCheckRho scope t ty' ty (t,_,_) <- subsCheckRho scope t ty' ty
return (t, ty') return (t, ty')
tcRho scope c (P t l) mb_ty = do tcRho scope c (P t l) mb_ty = do
@@ -313,7 +312,7 @@ tcRho scope c (P t l) mb_ty = do
Just ty -> return ty Just ty -> return ty
Nothing -> do i <- newResiduation scope Nothing -> do i <- newResiduation scope
return (VMeta i []) return (VMeta i [])
(t,t_ty) <- tcRho scope c t (Just (VRecType [(l,True,l_ty)])) (t,t_ty) <- tcRho scope c t (Just (VRecType [(l,True,l_ty)] True))
return (P t l,l_ty) return (P t l,l_ty)
tcRho scope c (C t1 t2) mb_ty = do tcRho scope c (C t1 t2) mb_ty = do
let (c1,c2,c3,c4) = split4 c let (c1,c2,c3,c4) = split4 c
@@ -325,33 +324,83 @@ tcRho scope c (Glue t1 t2) mb_ty = do
(t1,t1_ty) <- tcRho scope c1 t1 (Just vtypeStr) (t1,t1_ty) <- tcRho scope c1 t1 (Just vtypeStr)
(t2,t2_ty) <- tcRho scope c2 t2 (Just vtypeStr) (t2,t2_ty) <- tcRho scope c2 t2 (Just vtypeStr)
instSigma scope c3 (Glue t1 t2) vtypeStr mb_ty instSigma scope c3 (Glue t1 t2) vtypeStr mb_ty
tcRho scope c t@(ExtR t1 t2) mb_ty = do tcRho scope c t@(ExtR t1 t2) mb_ty =
case (t2,mb_ty) of
(R rs,Just (VRecType ltys ext)) -> do
let ll2 = map fst rs
(c1,c2) = split c
(t1,ty1@(VRecType ltys1 ext)) <- tcRho scope c1 t1 (Just (VRecType [field | field@(l,_,_) <- ltys, not (elem l ll2)] ext))
let (scope',proj1,wrap) = access scope t1 ty1
lttys2 <- checkRecFields scope' c2 [] rs [field | field@(l,_,_) <- ltys, elem l ll2]
let proj2 l =
case [(Nothing,t) | (l',t,_) <- lttys2, l'==l] of
[] -> Nothing
(x:_) -> Just x
return (wrap (R [(l,t) | (l,_,_) <- ltys, Just t <- [if elem l ll2 then proj2 l else proj1 l]]),
VRecType ltys False
)
_ -> do
let (c1,c2,c3,c4) = split4 c let (c1,c2,c3,c4) = split4 c
(t1,t1_ty) <- tcRho scope c1 t1 Nothing (t1,t1_ty) <- tcRho scope c1 t1 Nothing
(t2,t2_ty) <- tcRho scope c2 t2 Nothing (t2,t2_ty) <- tcRho scope c2 t2 Nothing
ty <- join t1_ty t2_ty ty <- join t1_ty t2_ty
instSigma scope c3 (ExtR t1 t2) ty mb_ty let (scope1,proj1,wrap1) = access scope t1 t1_ty
(scope2,proj2,wrap2) = access scope1 t2 t2_ty
let t = case (mb_ty,ty,t2_ty) of
(Just (VRecType ltys False), _, VRecType ltys2 False) ->
let ll2 = [l | (l,_,_) <- ltys2]
in (wrap1 . wrap2) (R [(l,t) | (l,_,_) <- ltys, Just t <- [if elem l ll2 then proj2 l else proj1 l]])
(_, VRecType ltys False, VRecType ltys2 False) ->
let ll2 = [l | (l,_,_) <- ltys2]
in (wrap1 . wrap2) (R [(l,t) | (l,_,_) <- ltys, Just t <- [if elem l ll2 then proj2 l else proj1 l]])
_ -> ExtR t1 t2
return (t,ty)
where where
access scope (R rs) ty = (scope
,\l -> lookup l rs
,id
)
access scope (RecType rs) ty
= (scope
,\l -> fmap ((,) Nothing) (lookup l rs)
,id
)
access scope t@(Vr x) ty
= (scope
,\l -> return (Nothing,P t l)
,id
)
access scope t ty = let x = newVar scope
in (((x,ty):scope)
,\l -> return (Nothing,P (Vr x) l)
,Let (x, (Nothing, t))
)
join (VMeta i vs) ty2 = do join (VMeta i vs) ty2 = do
mv <- getMeta i mv <- getMeta i
case mv of case mv of
Bound _ v -> do Bound _ v -> do
g <- globals g <- globals
join (apply g v vs) ty2 join (apply g v vs) ty2
_ -> evalError (pp "Cannot type check record extensions when one of the types is a meta variable")
join ty1 (VMeta j vs) = do join ty1 (VMeta j vs) = do
mv <- getMeta j mv <- getMeta j
case mv of case mv of
Bound _ v -> do Bound _ v -> do
g <- globals g <- globals
join ty1 (apply g v vs) join ty1 (apply g v vs)
_ -> evalError (pp "Cannot type check record extensions when one of the types is a meta variable")
join (VSort s1) (VSort s2) join (VSort s1) (VSort s2)
| (s1 == cType || s1 == cPType) && | (s1 == cType || s1 == cPType) &&
(s2 == cType || s2 == cPType) = let sort | s1 == cPType && s2 == cPType = cPType (s2 == cType || s2 == cPType) = let sort | s1 == cPType && s2 == cPType = cPType
| otherwise = cType | otherwise = cType
in return (VSort sort) in return (VSort sort)
join (VRecType rs1) (VRecType rs2) = do join (VRecType rs1 ext1) (VRecType rs2 ext2) = do
rs <- foldM (\rs (l,o,ctr) -> extend l o ctr rs) rs1 rs2 rs <- foldM (\rs (l,o,ctr) -> extend l o ctr rs) rs1 rs2
return (VRecType rs) return (VRecType rs (ext1 || ext2))
where where
extend l o1 ty1 [] = do return [(l,o1,ty1)] extend l o1 ty1 [] = do return [(l,o1,ty1)]
extend l o1 ty1 ((l',o2,ty2):rs) extend l o1 ty1 ((l',o2,ty2):rs)
@@ -387,16 +436,16 @@ tcRho scope c (EPattType ty) mb_ty = do
let (c1,c2) = split c let (c1,c2) = split c
(ty, _) <- tcRho scope c1 ty (Just vtypeType) (ty, _) <- tcRho scope c1 ty (Just vtypeType)
instSigma scope c2 (EPattType ty) vtypeType mb_ty instSigma scope c2 (EPattType ty) vtypeType mb_ty
tcRho scope c t@(EPatt min max p) mb_ty = do tcRho scope c t@(EPatt _ _ p) mb_ty = do
(scope,f,ty) <- case mb_ty of (scope,f,mb_ty) <- case mb_ty of
Nothing -> do i <- newResiduation scope Nothing -> return (scope,id,Nothing)
return (scope,id,VMeta i [])
Just ty -> do (scope,f,ty) <- skolemise scope ty Just ty -> do (scope,f,ty) <- skolemise scope ty
case ty of case ty of
VPattType ty -> return (scope,f,ty) VPattType ty -> return (scope,f,Just ty)
_ -> evalError (ppTerm Unqualified 0 t <+> "must be of pattern type but" <+> ppTerm Unqualified 0 t <+> "is expected") _ -> evalError (ppTerm Unqualified 0 t <+> "must be of pattern type but" <+> ppTerm Unqualified 0 t <+> "is expected")
tcPatt scope c p ty (_,ty) <- tcPatt scope c p mb_ty
return (f (EPatt min max p), ty) (min,max,p) <- measurePatt p
return (f (EPatt min max p), VPattType ty)
tcRho scope c (Markup tag attrs children) mb_ty = do tcRho scope c (Markup tag attrs children) mb_ty = do
let (c1,c2,c3,c4) = split4 c let (c1,c2,c3,c4) = split4 c
attrs <- mapCM (\c (id,t) -> do attrs <- mapCM (\c (id,t) -> do
@@ -406,7 +455,7 @@ tcRho scope c (Markup tag attrs children) mb_ty = do
res <- mapCM (\c child -> tcRho scope c child Nothing) c2 children res <- mapCM (\c child -> tcRho scope c child Nothing) c2 children
instSigma scope c3 (Markup tag attrs (map fst res)) vtypeMarkup mb_ty instSigma scope c3 (Markup tag attrs (map fst res)) vtypeMarkup mb_ty
tcRho scope c (Reset ctl mb_ct t qid) mb_ty tcRho scope c (Reset ctl mb_ct t qid) mb_ty
| ctl == cConcat = do | ctl == cConcat || ctl == cConcat' = do
let (c1,c23) = split c let (c1,c23) = split c
(c2,c3 ) = split c23 (c2,c3 ) = split c23
(t,_) <- tcRho scope c1 t Nothing (t,_) <- tcRho scope c1 t Nothing
@@ -423,6 +472,21 @@ tcRho scope c (Reset ctl mb_ct t qid) mb_ty
return (Just ct,ty) return (Just ct,ty)
Nothing -> return (Nothing,ty) Nothing -> return (Nothing,ty)
return (Reset ctl mb_ct t qid,ty) return (Reset ctl mb_ct t qid,ty)
| ctl == cSelect = do
let (c1,c2) = split c
ty <- case mb_ty of
Just ty -> return ty
Nothing -> do i <- newResiduation scope
return (VMeta i [])
let rec_ty = VRecType [ (ident2label cp1, True, ty)
, (ident2label cp2, True, VSort cStr)
] False
mb_ct <- case mb_ct of
Just ct -> do (ct,_) <- tcRho scope c2 ct (Just vtypeInt)
return (Just ct)
Nothing -> evalError (pp "[select: .. | ..] requires an integer argument")
(t,_) <- tcRho scope c1 t (Just rec_ty)
return (Reset ctl mb_ct t qid,ty)
| ctl == cDefault = do | ctl == cDefault = do
let (c1,c2) = split c let (c1,c2) = split c
(t,ty) <- tcRho scope c1 t mb_ty (t,ty) <- tcRho scope c1 t mb_ty
@@ -441,11 +505,22 @@ tcRho scope c (Reset ctl mb_ct t qid) mb_ty
case ty of case ty of
VApp c qid [] -> return (Reset ctl mb_ct t (Just qid), ty) VApp c qid [] -> return (Reset ctl mb_ct t (Just qid), ty)
_ -> evalError (pp "Needs atomic type"<+>ppValue Unqualified 0 ty) _ -> evalError (pp "Needs atomic type"<+>ppValue Unqualified 0 ty)
| ctl == cLen = do
do let (c1,c2) = split c
(t,_) <- tcRho scope c1 t Nothing
case mb_ct of
Just ct -> do res_ty <- case mb_ty of
Just ty -> return ty
Nothing -> do i <- newResiduation scope
return (VMeta i [])
(ct,_) <- tcRho scope c2 ct (Just (VProd Explicit identW vtypeInt res_ty))
return (Reset ctl (Just ct) t Nothing, res_ty)
Nothing -> instSigma scope c2 (Reset ctl Nothing t Nothing) vtypeInt mb_ty
| otherwise = evalError (pp "Operator" <+> pp ctl <+> pp "is not defined") | otherwise = evalError (pp "Operator" <+> pp ctl <+> pp "is not defined")
tcRho scope s (Opts n cs) mb_ty = do tcRho scope s (Opts n cs) mb_ty = do
let (s1,s2,s3) = split3 s let (s1,s2,s3) = split3 s
(n,_) <- tcRho scope s1 n Nothing (n,_) <- tcRho scope s1 n Nothing
(ls,_) <- tcUnifying scope s2 (fst <$> cs) Nothing (ls,_) <- tcUnifyingMaybe scope s2 (fst <$> cs) Nothing
(ts,ty) <- tcUnifying scope s3 (snd <$> cs) mb_ty (ts,ty) <- tcUnifying scope s3 (snd <$> cs) mb_ty
return (Opts n (zip ls ts), ty) return (Opts n (zip ls ts), ty)
tcRho scope s t _ = unimplemented ("tcRho "++show t) tcRho scope s t _ = unimplemented ("tcRho "++show t)
@@ -471,13 +546,30 @@ tcUnifying scope c ts mb_ty = do
ts <- mapCM go c ts ts <- mapCM go c ts
return (ts,ty) return (ts,ty)
tcCases scope c [] p_ty res_ty = return [] tcUnifyingMaybe :: Scope -> Choice -> [Maybe Term] -> Maybe Rho -> EvalM ([Maybe Term], Value)
tcCases scope c ((p,t):cs) p_ty res_ty = do tcUnifyingMaybe scope c ts mb_ty = do
(ty,subsume) <-
case mb_ty of
Just ty -> do return (ty, \t ty' -> return t)
Nothing -> do i <- newResiduation scope
let ty = VMeta i []
return (ty, \t ty' -> subsCheckRho scope t ty' ty >>= \(t,_,_) -> return t)
let go c (Just t) = do (t, ty) <- tcRho scope c t mb_ty
fmap Just $ subsume t ty
go c Nothing = do return Nothing
ts <- mapCM go c ts
return (ts,ty)
tcCases scope c [] (Just p_ty) (Just res_ty) = return ([],p_ty,res_ty)
tcCases scope c ((p,t):cs) mb_p_ty mb_res_ty = do
let (c1,c2,c3,c4) = split4 c let (c1,c2,c3,c4) = split4 c
scope' <- tcPatt scope c1 p p_ty (scope',p_ty) <- tcPatt scope c1 p mb_p_ty
(t,_) <- tcRho scope' c2 t (Just res_ty) (t,res_ty) <- tcRho scope' c2 t mb_res_ty
cs <- tcCases scope c3 cs p_ty res_ty (cs,p_ty,res_ty) <- tcCases scope c3 cs (Just p_ty) (Just res_ty)
return ((p,t):cs) (_,_,p) <- measurePatt p
return ((p,t):cs,p_ty,res_ty)
tcApp scope c t0 (App fun arg) args mb_ty = tcApp scope c t0 fun (arg:args) mb_ty -- APP tcApp scope c t0 (App fun arg) args mb_ty = tcApp scope c t0 fun (arg:args) mb_ty -- APP
tcApp scope c t0 t@(Q id) args mb_ty = resolveOverloads scope c t0 id args mb_ty -- VAR (global) tcApp scope c t0 t@(Q id) args mb_ty = resolveOverloads scope c t0 id args mb_ty -- VAR (global)
@@ -521,9 +613,11 @@ resolveOverloads scope c t0 q args mb_ty = do
instSigma scope c3 t ty mb_ty instSigma scope c3 t ty mb_ty
Ok ttys -> do let (c1,c23) = split c Ok ttys -> do let (c1,c23) = split c
(c2,c3) = split c23 (c2,c3) = split c23
sz <- checkpoint
arg_tys <- mapCM (checkArg g) c1 args arg_tys <- mapCM (checkArg g) c1 args
let v_ttys = mapC (\c (t,ty) -> (t,eval g [] c ty [])) c2 ttys let v_ttys = mapC (\c (t,ty) -> (t,eval g [] c ty [])) c2 ttys
try (\(fun,fun_ty) -> reapply2 scope c3 fun fun_ty arg_tys mb_ty) try sz
(\(fun,fun_ty) -> reapply2 scope c3 fun fun_ty arg_tys mb_ty)
(\ttys -> fmap (\(ts,ty) -> (mkFV ts,ty)) (snd (minimum g ttys))) (\ttys -> fmap (\(ts,ty) -> (mkFV ts,ty)) (snd (minimum g ttys)))
v_ttys v_ttys
where where
@@ -544,43 +638,31 @@ resolveOverloads scope c t0 q args mb_ty = do
minimum g [] = (maxBound,err) minimum g [] = (maxBound,err)
where where
err = evalError (pp "Overload resolution failed") err = evalError (pp "Overload resolution failed")
minimum g (tty@((t,ty),state):ttys) = minimum g (tty@(t,ty):ttys) =
let ty' = zonk ty let a = arity ty
a = arity ty'
(a',res) = minimum g ttys (a',res) = minimum g ttys
in case compare a a' of in case compare a a' of
GT -> (a',res) GT -> (a',res)
EQ -> (a',join t ty' state res) EQ -> (a',join t ty res)
LT -> (a ,one t ty' state) LT -> (a ,one t ty)
where where
arity :: Value -> Int arity :: Value -> Int
arity (VProd _ _ _ ty) = 1 + arity ty arity (VProd _ _ _ ty) = 1 + arity ty
arity _ = 0 arity _ = 0
zonk :: Value -> Value one t ty = do
zonk (VProd bt x ty1 ty2) = VProd bt x (zonk ty1) (zonk ty2)
zonk (VMeta i vs) =
case Map.lookup i (metaVars state) of
Just (Bound _ v) -> zonk (apply g v vs)
_ -> VMeta i (map zonk vs)
zonk (VSusp i k vs) =
case Map.lookup i (metaVars state) of
Just (Bound _ v) -> zonk (apply g (k v) vs)
_ -> VSusp i k (map zonk vs)
zonk v = v
one t ty state = do
t <- withState state (zonkTerm [] t)
return ([t],ty) return ([t],ty)
join t ty state res = do join t ty res = do
t <- withState state (zonkTerm [] t)
(ts,ty') <- res (ts,ty') <- res
ty <- supertype scope (Just ty) ty' ty <- supertype scope (Just ty) ty'
return (t:ts,ty) return (t:ts,ty)
reapply2 :: Scope -> Choice -> Term -> Value -> [(Term,Value,Value)] -> Maybe Rho -> EvalM (Term,Rho) reapply2 :: Scope -> Choice -> Term -> Value -> [(Term,Value,Value)] -> Maybe Rho -> EvalM (Term,Rho)
reapply2 scope c fun fun_ty [] mb_ty = instSigma scope c fun fun_ty mb_ty reapply2 scope c fun fun_ty [] mb_ty = do
(fun,fun_ty) <- instSigma scope c fun fun_ty mb_ty
fun <- zonkTerm (scopeVars scope) fun
return (fun,fun_ty)
reapply2 scope c fun fun_ty ((ImplArg arg,arg_v,arg_ty):args) mb_ty = do -- Implicit arg case reapply2 scope c fun fun_ty ((ImplArg arg,arg_v,arg_ty):args) mb_ty = do -- Implicit arg case
(bt, x, arg_ty', res_ty) <- unifyFun scope fun_ty (bt, x, arg_ty', res_ty) <- unifyFun scope fun_ty
unless (bt == Implicit) $ unless (bt == Implicit) $
@@ -596,11 +678,18 @@ reapply2 scope c fun fun_ty ((arg,arg_v,arg_ty):args) mb_ty = do -- Explicit arg
res_ty <- evalCodomain x arg_v res_ty res_ty <- evalCodomain x arg_v res_ty
reapply2 scope c (App fun arg) res_ty args mb_ty reapply2 scope c (App fun arg) res_ty args mb_ty
tcPatt scope c PW ty0 = tcPatt scope c PW Nothing = do
return scope i <- newResiduation scope
tcPatt scope c (PV x) ty0 = return (scope,VMeta i [])
return ((x,ty0):scope) tcPatt scope c PW (Just ty0) =
tcPatt scope c (PP q ps) ty0 = do return (scope,ty0)
tcPatt scope c (PV x) Nothing = do
i <- newResiduation scope
let ty = VMeta i []
return ((x,ty):scope,ty)
tcPatt scope c (PV x) (Just ty) =
return ((x,ty):scope,ty)
tcPatt scope c (PP q ps) mb_ty = do
g@(Gl gr _) <- globals g@(Gl gr _) <- globals
ty <- case lookupResType gr q of ty <- case lookupResType gr q of
Ok ty -> return ty Ok ty -> return ty
@@ -608,110 +697,196 @@ tcPatt scope c (PP q ps) ty0 = do
let go scope c ty [] = return (scope,ty) let go scope c ty [] = return (scope,ty)
go scope c ty (p:ps) = do (_,_,arg_ty,res_ty) <- unifyFun scope ty go scope c ty (p:ps) = do (_,_,arg_ty,res_ty) <- unifyFun scope ty
let (c1,c2) = split c let (c1,c2) = split c
scope <- tcPatt scope c1 p arg_ty (scope,arg_ty) <- tcPatt scope c1 p (Just arg_ty)
go scope c2 res_ty ps go scope c2 res_ty ps
let (c1,c2) = split c let (c1,c2) = split c
(scope,ty) <- go scope c1 (eval g [] c2 ty []) ps (scope,res_ty) <- go scope c1 (eval g [] c2 ty []) ps
unify scope ty0 ty case mb_ty of
return scope Just ty -> unify scope ty res_ty
tcPatt scope c p@(PInt i) ty0 = Nothing -> return ()
case ty0 of return (scope,res_ty)
VInts min max tcPatt scope c p@(PInt i) mb_ty =
| i <= fromMaybe i max -> return scope case mb_ty of
Just ty0@(VInts n ext)
| i <= n -> return (scope,ty0)
| ext -> return (scope,VInts i ext)
| otherwise -> evalError ("Ints" <+> i <+> "is not a subtype of" <+> ppValue Unqualified 0 ty0) | otherwise -> evalError ("Ints" <+> i <+> "is not a subtype of" <+> ppValue Unqualified 0 ty0)
VMeta k vs -> do Just ty0@(VMeta k vs) -> do
mv <- getMeta k mv <- getMeta k
case mv of case mv of
Bound _ v -> do Bound scope1 v -> do
g <- globals g <- globals
tcPatt scope c p (apply g v vs) (scope,ty) <- tcPatt scope c p (Just (apply g v vs))
setMeta k (Bound scope1 ty)
return (scope,ty0)
Residuation scope1 -> do Residuation scope1 -> do
setMeta k (Bound scope1 (VInts (Just i) Nothing)) setMeta k (Bound scope1 (VInts i True))
return scope return (scope,ty0)
Nothing -> return (scope,VInts i True)
_ -> evalError (pp "An integer must have an Int or Ints n type") _ -> evalError (pp "An integer must have an Int or Ints n type")
tcPatt scope c (PString s) ty0 = do tcPatt scope c (PString s) mb_ty = do
unify scope ty0 vtypeStr case mb_ty of
return scope Just ty -> unify scope ty vtypeStr
tcPatt scope c PChar ty0 = do Nothing -> return ()
unify scope ty0 vtypeStr return (scope,vtypeStr)
return scope tcPatt scope c PChar mb_ty = do
tcPatt scope c (PChars cs) ty0 = do case mb_ty of
unify scope ty0 vtypeStr Just ty -> unify scope ty vtypeStr
return scope Nothing -> return ()
tcPatt scope c (PSeq _ _ p1 _ _ p2) ty0 = do return (scope,vtypeStr)
unify scope ty0 vtypeStr tcPatt scope c (PChars cs) mb_ty = do
case mb_ty of
Just ty -> unify scope ty vtypeStr
Nothing -> return ()
return (scope,vtypeStr)
tcPatt scope c (PSeq _ _ p1 _ _ p2) mb_ty = do
case mb_ty of
Just ty -> unify scope ty vtypeStr
Nothing -> return ()
let (c1,c2) = split c let (c1,c2) = split c
scope <- tcPatt scope c1 p1 vtypeStr (scope,_) <- tcPatt scope c1 p1 (Just vtypeStr)
scope <- tcPatt scope c2 p2 vtypeStr (scope,_) <- tcPatt scope c2 p2 (Just vtypeStr)
return scope return (scope,vtypeStr)
tcPatt scope c (PRep _ _ p) ty0 = do tcPatt scope c (PRep _ _ p) mb_ty = do
unify scope ty0 vtypeStr case mb_ty of
tcPatt scope c p vtypeStr Just ty -> unify scope ty vtypeStr
tcPatt scope c (PAs x p) ty0 = do Nothing -> return ()
tcPatt ((x,ty0):scope) c p ty0 tcPatt scope c p (Just vtypeStr)
tcPatt scope c p@(PR rs) ty0 = tcPatt scope c (PAs x p) mb_ty = do
case ty0 of ty <- case mb_ty of
VRecType ltys -> Just ty -> return ty
let go scope c [] = return scope Nothing -> do i <- newResiduation scope
go scope c ((l,p):rs) = return (VMeta i [])
case lookup3 l ltys of tcPatt ((x,ty):scope) c p (Just ty)
Just ty -> do let (c1,c2) = split c tcPatt scope c p@(PR rs) mb_ty =
scope <- tcPatt scope c1 p ty case mb_ty of
go scope c2 rs Just (VRecType ltys ext) -> check scope c rs ltys ext
Nothing -> do ty <- value2termM False (scopeVars scope) ty0 Just ty0@(VMeta i vs) -> do
evalError (pp "Label" <+> pp l <+> " is not defined in the type of the pattern:" $$
nest 4 (ppTerm Unqualified 0 ty))
in go scope c rs
VMeta i vs -> do
g <- globals
mv <- getMeta i mv <- getMeta i
case mv of case mv of
Bound _ v -> Bound scope1 v ->
tcPatt scope c p (apply g v vs) do g <- globals
(scope,ty) <- tcPatt scope c p (Just (apply g v vs))
setMeta i (Bound scope1 ty)
return (scope,ty0)
Residuation scope1 -> Residuation scope1 ->
let go scope c [] = return (scope,[]) do (scope,ltys) <- infer scope c rs
go scope c ((l,p):rs) = do setMeta i (Bound scope1 (VRecType ltys True))
i <- newResiduation scope return (scope,ty0)
let ty = VMeta i [] Nothing ->do (scope,ltys) <- infer scope c rs
(c1,c2) = split c return (scope,VRecType ltys True)
scope <- tcPatt scope c1 p ty
(scope,ltys) <- go scope c2 rs
return (scope,(l,True,ty):ltys)
in do (scope,ltys) <- go scope c rs
setMeta i (Bound scope1 (VRecType ltys))
return scope
_ -> evalError (pp "An record must have an record type") _ -> evalError (pp "An record must have an record type")
tcPatt scope c (PAlt p1 p2) ty0 = do where
check scope c [] ltys ext = return (scope,VRecType ltys ext)
check scope c ((l,p):rs) ltys ext =
case lookup3 l ltys of
Just ty -> do let (c1,c2) = split c
(scope,ty) <- tcPatt scope c1 p (Just ty)
check scope c2 rs (update3 l True ty ltys) ext
Nothing
| ext -> do let (c1,c2) = split c
(scope,ty) <- tcPatt scope c1 p Nothing
check scope c2 rs (ltys++[(l,True,ty)]) ext
| otherwise
-> do ty <- value2termM False (scopeVars scope) (VRecType ltys ext)
evalError (pp "Label" <+> pp l <+> " is not defined in the type of the pattern:" $$
nest 4 (ppTerm Unqualified 0 ty))
infer scope c [] = return (scope,[])
infer scope c ((l,p):rs) = do
let (c1,c2) = split c let (c1,c2) = split c
tcPatt scope c1 p1 ty0 (scope,ty) <- tcPatt scope c1 p Nothing
tcPatt scope c2 p2 ty0 (scope,ltys) <- infer scope c2 rs
return scope return (scope,(l,True,ty):ltys)
tcPatt scope c (PM q) ty0 = do tcPatt scope c (PNeg p) mb_ty = do
(_,ty) <- tcPatt scope c p mb_ty
return (scope, ty)
tcPatt scope c (PAlt p1 p2) mb_ty = do
let (c1,c2) = split c
(_,ty) <- tcPatt scope c1 p1 mb_ty
(_,ty) <- tcPatt scope c2 p2 (Just ty)
return (scope,ty)
tcPatt scope c (PM q) mb_ty = do
g@(Gl gr _) <- globals g@(Gl gr _) <- globals
ty <- case lookupResType gr q of ty <- case lookupResType gr q of
Ok ty -> return ty Ok ty -> return ty
Bad msg -> evalError (pp msg) Bad msg -> evalError (pp msg)
case ty of case ty of
EPattType ty EPattType ty
-> do unify scope ty0 (eval g [] c ty []) -> do let vty = eval g [] c ty []
return scope case mb_ty of
Just ty0 -> unify scope ty0 vty
Nothing -> return ()
return (scope,vty)
ty -> evalError ("Pattern type expected but " <+> pp ty <+> " found.") ty -> evalError ("Pattern type expected but " <+> pp ty <+> " found.")
tcPatt scope c p ty = unimplemented ("tcPatt "++show p) tcPatt scope c p ty = unimplemented ("tcPatt "++show p)
inferRecFields scope c rs = measurePatt p =
mapCM (\c (l,r) -> tcRecField scope c l r Nothing) c rs case p of
PM q -> do g <- globals
case eval g [] unit (Q q) [] of
VPatt minp maxp _ -> return (minp,maxp,p)
v -> evalError ("Expected pattern macro, but found:" $$ nest 2 (ppValue Unqualified 0 v))
PR ass -> do ass <- mapM (\(lbl,p) -> measurePatt p >>= \(_,_,p') -> return (lbl,p')) ass
return (0,Nothing,PR ass)
PString s -> do let len=length s
return (len,Just len,p)
PT t p -> do (min,max,p') <- measurePatt p
return (min,max,PT t p')
PAs x p -> do (min,max,p) <- measurePatt p
case p of
PW -> return (0,Nothing,PV x)
_ -> return (min,max,PAs x p)
PImplArg p -> do (min,max,p') <- measurePatt p
return (min,max,PImplArg p')
PNeg p -> do (_,_,p') <- measurePatt p
return (0,Nothing,PNeg p')
PAlt p1 p2 -> do (min1,max1,p1) <- measurePatt p1
(min2,max2,p2) <- measurePatt p2
case (p1,p2) of
(PString [c1],PString [c2]) -> return (1,Just 1,PChars [c1,c2])
(PString [c], PChars cs) -> return (1,Just 1,PChars ([c]++cs))
(PChars cs, PString [c]) -> return (1,Just 1,PChars (cs++[c]))
(PChars cs1, PChars cs2) -> return (1,Just 1,PChars (cs1++cs2))
_ -> return (min min1 min2,liftM2 max max1 max2,PAlt p1 p2)
PSeq _ _ p1 _ _ p2
-> do (min1,max1,p1) <- measurePatt p1
(min2,max2,p2) <- measurePatt p2
case (p1,p2) of
(PW, PW ) -> return (0,Nothing,PW)
(PString s1,PString s2) -> return (min1+min2,liftM2 (+) max1 max2,PString (s1++s2))
_ -> return (min1+min2,liftM2 (+) max1 max2,PSeq min1 max1 p1 min2 max2 p2)
PRep _ _ p -> do (minp,maxp,p) <- measurePatt p
case p of
PW -> return (0,Nothing,PW)
PChar -> return (0,Nothing,PW)
_ -> return (0,Nothing,PRep minp maxp p)
PChar -> return (1,Just 1,p)
PChars _ -> return (1,Just 1,p)
_ -> return (0,Nothing,p)
checkRecFields scope c [] ltys inferRecFields scope c ls [] = return []
inferRecFields scope c ls ((l,t):lts)
| elem l ls = evalError ("Repeated definition for field" <+> l)
| otherwise = do
let (c1,c2) = split c
lt <- tcRecField scope c1 l t Nothing
lts <- inferRecFields scope c2 (l:ls) lts
return (lt:lts)
checkRecFields scope c ls [] ltys
| null ltys = return [] | null ltys = return []
| otherwise = evalError ("Missing fields:" <+> hsep [l | (l,_,_) <- ltys]) | otherwise = evalError ("Missing fields:" <+> hsep [l | (l,_,_) <- ltys])
checkRecFields scope c ((l,t):lts) ltys = checkRecFields scope c ls ((l,t):lts) ltys
| elem l ls = evalError ("Repeated definition for field" <+> l)
| otherwise =
case takeIt l ltys of case takeIt l ltys of
(Just ty,ltys) -> do let (c1,c2) = split c (Just ty,ltys) -> do let (c1,c2) = split c
ltty <- tcRecField scope c1 l t (Just ty) ltty <- tcRecField scope c1 l t (Just ty)
lttys <- checkRecFields scope c2 lts ltys lttys <- checkRecFields scope c2 ls lts ltys
return (ltty : lttys) return (ltty : lttys)
(Nothing,ltys) -> do evalWarn ("Discarded field:" <+> l) (Nothing,ltys) -> do evalWarn ("Discarded field:" <+> l)
lttys <- checkRecFields scope c lts ltys lttys <- checkRecFields scope c ls lts ltys
return lttys -- ignore the field return lttys -- ignore the field
where where
takeIt l1 [] = (Nothing, []) takeIt l1 [] = (Nothing, [])
@@ -731,8 +906,10 @@ tcRecField scope c l (mb_ann_ty,t) mb_ty = do
Nothing -> tcRho scope c t mb_ty Nothing -> tcRho scope c t mb_ty
return (l,t,ty) return (l,t,ty)
tcRecTypeFields scope c [] mb_ty = return ([],mb_ty) tcRecTypeFields scope c ls [] mb_ty = return ([],mb_ty)
tcRecTypeFields scope c ((l,ty):rs) mb_ty = do tcRecTypeFields scope c ls ((l,ty):rs) mb_ty
| elem l ls = evalError ("Repeated definition for field" <+> l)
| otherwise = do
let (c1,c2) = split c let (c1,c2) = split c
(ty,sort) <- tcRho scope c1 ty mb_ty (ty,sort) <- tcRho scope c1 ty mb_ty
mb_ty <- case sort of mb_ty <- case sort of
@@ -743,7 +920,7 @@ tcRecTypeFields scope c ((l,ty):rs) mb_ty = do
_ -> do sort <- value2termM False (scopeVars scope) sort _ -> do sort <- value2termM False (scopeVars scope) sort
evalError ("The record type field" <+> l <+> ':' <+> ppTerm Unqualified 0 ty $$ evalError ("The record type field" <+> l <+> ':' <+> ppTerm Unqualified 0 ty $$
"cannot be of type" <+> ppTerm Unqualified 0 sort) "cannot be of type" <+> ppTerm Unqualified 0 sort)
(rs,mb_ty) <- tcRecTypeFields scope c2 rs mb_ty (rs,mb_ty) <- tcRecTypeFields scope c2 (l:ls) rs mb_ty
return ((l,ty):rs,mb_ty) return ((l,ty):rs,mb_ty)
-- | Invariant: if the third argument is (Just rho), -- | Invariant: if the third argument is (Just rho),
@@ -839,26 +1016,12 @@ subsCheckRho scope t ty1@(VApp _ p _) ty2@(VInts _ _) -- This is not cor
| p == (cPredef,cInt) = return (t,ty1,ty2) -- Should be only a temporary hack. | p == (cPredef,cInt) = return (t,ty1,ty2) -- Should be only a temporary hack.
subsCheckRho scope t ty1@(VInts _ _) ty2@(VApp _ p _) -- Rule INT1 subsCheckRho scope t ty1@(VInts _ _) ty2@(VApp _ p _) -- Rule INT1
| p == (cPredef,cInt) = return (t,ty1,ty2) | p == (cPredef,cInt) = return (t,ty1,ty2)
subsCheckRho scope t ty1@(VInts i1 j1) ty2@(VInts i2 j2) -- Rule INT2 subsCheckRho scope t ty1@(VInts n1 ext1) ty2@(VInts n2 ext2) -- Rule INT2
| j1 `less1` i2 = return (t,ty1,ty2) | n1 <= n2 = return (t,ty1,ty2)
| j1' `less1` i2' = return (t,VInts i1 j1',VInts i2' j2) | ext2 = return (t,ty1,VInts n1 ext2)
| otherwise = evalError ("In the term" <+> ppTerm Unqualified 0 t $$ | otherwise = evalError ("In the term" <+> ppTerm Unqualified 0 t $$
ppValue Terse 0 ty1 <+> "is not a subtype of" <+> ppValue Terse 0 ty2) ppValue Terse 0 ty1 <+> "is not a subtype of" <+> ppValue Terse 0 ty2)
where subsCheckRho scope t ty1@(VRecType rs1 ext1) ty2@(VRecType rs2 ext2) = do -- Rule REC
less1 (Just x) (Just y) = x <= y
less1 _ _ = False
less2 (Just x) (Just y) = x <= y
less2 Nothing (Just y) = True
less2 _ _ = False
less3 (Just x) (Just y) = x <= y
less3 (Just x) Nothing = True
less3 _ _ = False
j1' = if i1 `less2` i2 then i2 else j1
i2' = if j1 `less3` j2 then j1 else i2
subsCheckRho scope t ty1@(VRecType rs1) ty2@(VRecType rs2) = do -- Rule REC
let mkAccess scope t = let mkAccess scope t =
case t of case t of
ExtR t1 (R rs) -> ExtR t1 (R rs) ->
@@ -873,80 +1036,115 @@ subsCheckRho scope t ty1@(VRecType rs1) ty2@(VRecType rs2) = do -- Rule REC
,\l -> lookup l rs ,\l -> lookup l rs
,id ,id
) )
Vr x -> return (scope
,\l -> return (Nothing,P t l)
,\t' -> if is_trivial x t' then t else t'
)
t -> let x = newVar scope t -> let x = newVar scope
in return (((x,ty1):scope) in return (((x,ty1):scope)
,\l -> return (Nothing,P (Vr x) l) ,\l -> return (Nothing,P (Vr x) l)
,Let (x, (Nothing, t)) ,\t' -> if is_trivial x t' then t else Let (x, (Nothing, t)) t'
) )
mkField scope l (mb_ty,t) ty1 ty2 = do is_trivial x (R rs) = all is_selection rs
(t,_,_) <- subsCheckRho scope t ty1 ty2 where
return (l, (mb_ty,t)) is_selection (l, (_, P (Vr u) l'))
| l == l' && u == x = True
is_selection _ = False
is_trivial x _ = False
(scope,mkProj,mkWrap) <- mkAccess scope t mkField scope l (mb_ty,t) (Just ty1) ty2 = do
(t,ty1,ty2) <- subsCheckRho scope t ty1 ty2
return ((l, (mb_ty,t)), (l, True, ty1))
mkField scope l (mb_ty,t) Nothing ty2
| isLockLabel l = return ((l, (Just (RecType []),R [])), (l, True, ty2))
| otherwise = return ((l, (mb_ty,t)), (l, True, ty2))
let fields = [(l,ty2,lookup3 l rs1) | (l,o2,ty2) <- rs2] (scope,mkProj,wrap) <- mkAccess scope t
case [l | (l,_,Nothing) <- fields, not (isLockLabel l)] of
let fields = [(l,o2,ty2,lookup3 l rs1) | (l,o2,ty2) <- rs2]
case [l | (l,_,_,Nothing) <- fields, not ext1 && not (isLockLabel l)] of
[] -> return () [] -> return ()
missing -> evalError ("In the term" <+> pp t $$ missing -> evalError ("In the term" <+> pp t $$
"there are no values for fields:" <+> hsep missing) "there are no values for fields:" <+> hsep missing)
rs <- sequence [mkField scope l t ty1 ty2 | (l,ty2,Just ty1) <- fields, Just t <- [mkProj l]] rs <- sequence [mkField scope l t mb_ty1 ty2 | (l,_,ty2,mb_ty1) <- fields, Just t <- [mkProj l]]
return (mkWrap (R (rs++[(l, (Just (RecType []),R [])) | (l,_,Nothing) <- fields, isLockLabel l])),ty1,ty2) return (wrap (R (map fst rs)),VRecType (foldl (\rs (_,(l,o,ty)) -> update3 l o ty rs) rs1 rs) ext2,ty2)
subsCheckRho scope t ty1 (VFV c (VarFree vs)) = do subsCheckRho scope t ty1 (VFV c (VarFree vs)) = do
ty2 <- variants c vs ty2 <- variants c vs
subsCheckRho scope t ty1 ty2 subsCheckRho scope t ty1 ty2
subsCheckRho scope t (VFV c (VarFree vs)) ty2 = do subsCheckRho scope t (VFV c (VarFree vs)) ty2 = do
ty1 <- variants c vs ty1 <- variants c vs
subsCheckRho scope t ty1 ty2 subsCheckRho scope t ty1 ty2
subsCheckRho scope t ty1@(VPattType (VSort s1)) ty2@(VSort s2) -- for backwards compatibility
| s1 == cStr && s2 == cStrs = return (t,ty1,ty2)
subsCheckRho scope t ty1 ty2 = do -- Rule EQ subsCheckRho scope t ty1 ty2 = do -- Rule EQ
unify scope ty1 ty2 -- Revert to ordinary unification unify scope ty1 ty2 -- Revert to ordinary unification
return (t,ty1,ty2) return (t,ty1,ty2)
subsCheckFun :: Scope -> Term -> Sigma -> Value -> Sigma -> Value -> EvalM (Term,Value,Value) subsCheckFun :: Scope -> Term -> Sigma -> Value -> Sigma -> Value -> EvalM (Term,Value,Value)
subsCheckFun scope t a1 r1 a2 r2 = do subsCheckFun scope t a1 r1 a2 r2 = do
let v = newVar scope let x = newVar scope
(vt,a2,a1) <- subsCheckRho ((v,a2):scope) (Vr v) a2 a1 (xt,a2,a1) <- subsCheckRho ((x,a2):scope) (Vr x) a2 a1
g <- globals g <- globals
let (v1',r1') = case r1 of let (x1',r1') = case r1 of
VClosure env c r1 -> (v,eval g ((v,(VGen (length scope) [])):env) c r1 []) VClosure env c r1 -> (x,eval g ((x,(VGen (length scope) [])):env) c r1 [])
r1 -> (identW,r1) r1 -> (identW,r1)
(v2',r2') = case r2 of (x2',r2') = case r2 of
VClosure env c r2 -> (v,eval g ((v,(VGen (length scope) [])):env) c r2 []) VClosure env c r2 -> (x,eval g ((x,(VGen (length scope) [])):env) c r2 [])
r2 -> (identW,r2) r2 -> (identW,r2)
(t,r1,r2) <- subsCheckRho ((v,vtypeType):scope) (App t vt) r1' r2' (t,r1,r2) <- subsCheckRho ((x,a2):scope) (App t xt) r1' r2'
return (Abs Explicit v t, VProd Explicit v1' a1 r1, VProd Explicit v2' a2 r2) case t of
App t (Vr u) | u == x -> return (t, VProd Explicit x1' a1 r1, VProd Explicit x2' a2 r2)
_ -> return (Abs Explicit x t, VProd Explicit x1' a1 r1, VProd Explicit x2' a2 r2)
subsCheckTbl :: Scope -> Term -> Sigma -> Rho -> Sigma -> Rho -> EvalM (Term,Value,Value) subsCheckTbl :: Scope -> Term -> Sigma -> Rho -> Sigma -> Rho -> EvalM (Term,Value,Value)
subsCheckTbl scope t p1 r1 p2 r2 = do subsCheckTbl scope t p1 r1 p2 r2 = do
let x = newVar scope (scope,y,sel,wrap) <-
(xt,p2,p1) <- subsCheckRho ((x,p2):scope) (Vr x) p2 p1 case t of
(t,r1,r2) <- subsCheckRho ((x,p2):scope) (S t xt) r1 r2 Vr x -> let y = newVar scope
in return ((y,p2):scope
,y
,\t -> S (Vr x) t
,\p2 t' -> case t' of
S (Vr u) (Vr v) | u == x && v == y -> t
_ -> T (TTyped p2) [(PV y,t')]
)
T _ [(PV x,t')] ->
let scope' = (x,p1):scope
y = newVar scope'
in return (((y,p2):scope')
,y
,\t -> Let (x, (Nothing, t)) t'
,\p2 t -> case t of
Let (u, (Nothing, Vr v)) t | u == x && v == y -> T (TTyped p2) [(PV x,t)]
_ -> T (TTyped p2) [(PV y,t)]
)
t -> let x = newVar scope
scope' = (x,VTable p1 r1):scope
y = newVar scope'
in return (((y,VTable p1 r1):scope')
,y
,\t -> S (Vr x) t
,\p2 t' -> case t' of
S (Vr u) (Vr v) | u == x && v == y -> t
_ -> Let (x, (Nothing, t)) (T (TTyped p2) [(PV y,t')])
)
(yt,p2,p1) <- subsCheckRho scope (Vr y) p2 p1
(t,r1,r2) <- subsCheckRho scope (sel yt) r1 r2
p2_t <- value2termM True (scopeVars scope) p2 p2_t <- value2termM True (scopeVars scope) p2
return (T (TTyped p2_t) [(PV x,t)],VTable p1 r1,VTable p2 r2) return (wrap p2_t t,VTable p1 r1,VTable p2 r2)
{-subtype scope Nothing (VInts i2 j2) =
return (VInts Nothing j2) subtype scope Nothing (VInts i2 _) =
subtype scope (Just (VMeta i vs)) ty2 = do return (VInts i2 True)
g <- globals subtype scope (Just (VInts n1 _)) (VInts n2 _) =
mv <- getMeta i return (VInts (min n1 n2) False)
case mv of subtype scope Nothing (VRecType ltys ext) = do
Bound _ v -> subtype scope (Just (apply g v vs)) ty2-}
subtype scope (Just (VInts i1 j1)) (VInts i2 j2) =
case VInts (lift max i1 i2) (lift min j1 j2) of
ty@(VInts (Just i) (Just j))
| i > j -> evalError (ppValue Unqualified 0 ty <+> "is an empty type")
ty -> return ty
where
lift f Nothing Nothing = Nothing
lift f (Just x) Nothing = Just x
lift f Nothing (Just y) = Just y
lift f (Just x) (Just y) = Just (f x y)
subtype scope Nothing (VRecType ltys) = do
lctrs <- mapM (\(l,o,ty) -> subtype scope Nothing ty >>= \ctr -> return (l,o,ctr)) ltys lctrs <- mapM (\(l,o,ty) -> subtype scope Nothing ty >>= \ctr -> return (l,o,ctr)) ltys
return (VRecType lctrs) return (VRecType lctrs ext)
subtype scope (Just (VRecType lctrs1)) (VRecType lctrs2) = do subtype scope (Just (VRecType lctrs1 ext1)) (VRecType lctrs2 ext2) = do
lctrs <- foldM (\lctrs (l,o,ctr) -> union l o ctr lctrs) lctrs1 lctrs2 lctrs <- foldM (\lctrs (l,o,ctr) -> union l o ctr lctrs) lctrs1 lctrs2
return (VRecType lctrs) return (VRecType lctrs (ext1 || ext2))
where where
union l o1 ctr1 [] = do ctr <- subtype scope Nothing ctr1 union l o1 ctr1 [] = do ctr <- subtype scope Nothing ctr1
return [(l,True,ctr)] return [(l,True,ctr)]
@@ -973,24 +1171,16 @@ subtype scope (Just ctr) ty = do
unify scope ctr ty unify scope ctr ty
return ty return ty
supertype scope Nothing (VInts i2 j2) = supertype scope Nothing (VInts n2 _) =
return (VInts i2 Nothing) return (VInts n2 True)
supertype scope (Just (VInts i1 j1)) (VInts i2 j2) = supertype scope (Just (VInts n1 _)) (VInts n2 _) =
case VInts (lift min i1 i2) (lift max j1 j2) of return (VInts (max n1 n2) True)
ty@(VInts (Just i) (Just j)) supertype scope Nothing (VRecType ltys ext) = do
| i > j -> evalError (ppValue Unqualified 0 ty <+> "is an empty type")
ty -> return ty
where
lift f Nothing Nothing = Nothing
lift f (Just x) Nothing = Nothing
lift f Nothing (Just y) = Nothing
lift f (Just x) (Just y) = Just (f x y)
supertype scope Nothing (VRecType ltys) = do
lctrs <- mapM (\(l,o,ty) -> supertype scope Nothing ty >>= \ctr -> return (l,False,ctr)) ltys lctrs <- mapM (\(l,o,ty) -> supertype scope Nothing ty >>= \ctr -> return (l,False,ctr)) ltys
return (VRecType lctrs) return (VRecType lctrs ext)
supertype scope (Just (VRecType lctrs1)) (VRecType lctrs2) = do supertype scope (Just (VRecType lctrs1 ext1)) (VRecType lctrs2 ext2) = do
lctrs <- foldM (\lctrs (l,o,ctr) -> intersect l o ctr lctrs lctrs2) [] lctrs1 lctrs <- foldM (\lctrs (l,o,ctr) -> intersect l o ctr lctrs lctrs2) [] lctrs1
return (VRecType lctrs) return (VRecType lctrs (ext1 || ext2))
where where
intersect l o1 ctr1 lctrs [] = return lctrs intersect l o1 ctr1 lctrs [] = return lctrs
intersect l o1 ctr1 lctrs ((l',o2,ctr2):lctrs2) intersect l o1 ctr1 lctrs ((l',o2,ctr2):lctrs2)
@@ -1092,9 +1282,7 @@ unify scope (VFlt x) (VFlt y)
unify scope (VStr s1) (VStr s2) unify scope (VStr s1) (VStr s2)
| s1 == s2 = return () | s1 == s2 = return ()
unify scope VEmpty VEmpty = return () unify scope VEmpty VEmpty = return ()
unify scope v1 v2 = do unify scope v1 v2 =
t1 <- value2termM False (scopeVars scope) v1
t2 <- value2termM False (scopeVars scope) v2
evalError ("Cannot unify:" <+> ppValue Qualified 0 v1 $$ evalError ("Cannot unify:" <+> ppValue Qualified 0 v1 $$
" with:" <+> ppValue Qualified 0 v2) " with:" <+> ppValue Qualified 0 v2)
@@ -1139,7 +1327,7 @@ occursCheck scope' i0 scope v =
VClosure env c t -> do g <- globals VClosure env c t -> do g <- globals
check (m+1) (n+1) (eval g ((x,VGen n []):env) c t []) check (m+1) (n+1) (eval g ((x,VGen n []):env) c t [])
_ -> check m n ty2 _ -> check m n ty2
check m n (VRecType as) = check m n (VRecType as _) =
mapM_ (\(_,_,v) -> check m n v) as mapM_ (\(_,_,v) -> check m n v) as
check m n (VR as) = check m n (VR as) =
mapM_ (\(lbl,v) -> check m n v) as mapM_ (\(lbl,v) -> check m n v) as
@@ -1246,9 +1434,9 @@ quantify scope t tvs ty = do
return (x:xs,VProd bt x v1 (VClosure env c t)) return (x:xs,VProd bt x v1 (VClosure env c t))
v2 -> do (xs,v2) <- check m (n+1) xs v2 v2 -> do (xs,v2) <- check m (n+1) xs v2
return (x:xs,VProd bt x v1 v2) return (x:xs,VProd bt x v1 v2)
check m n xs (VRecType as) = do check m n xs (VRecType as ext) = do
(xs,as) <- mapAccumM (\xs (l,o,v) -> check m n xs v >>= \(xs,v) -> return (xs,(l,o,v))) xs as (xs,as) <- mapAccumM (\xs (l,o,v) -> check m n xs v >>= \(xs,v) -> return (xs,(l,o,v))) xs as
return (xs,VRecType as) return (xs,VRecType as ext)
check m n xs (VR as) = do check m n xs (VR as) = do
(xs,as) <- mapAccumM (\xs (lbl,tnk) -> check m n xs tnk >>= \(xs,tnk) -> return (xs,(lbl,tnk))) xs as (xs,as) <- mapAccumM (\xs (lbl,tnk) -> check m n xs tnk >>= \(xs,tnk) -> return (xs,(lbl,tnk))) xs as
return (xs,VR as) return (xs,VR as)
@@ -1339,6 +1527,11 @@ lookup3 l ((l',_,v):rs)
| l == l' = Just v | l == l' = Just v
| otherwise = lookup3 l rs | otherwise = lookup3 l rs
update3 l o v [] = [(l,o,v)]
update3 l o v (r@(l',_,_):rs)
| l == l' = (l,o,v) : rs
| otherwise = r : update3 l o v rs
newVar :: Scope -> Ident newVar :: Scope -> Ident
newVar scope = head [x | i <- [1..], newVar scope = head [x | i <- [1..],
let x = identS ('v':show i), let x = identS ('v':show i),
@@ -1360,7 +1553,7 @@ getMetaVars sc_tys = foldM (\acc (scope,ty) -> go acc ty) [] sc_tys
go acc (VGen i args) = foldM go acc args go acc (VGen i args) = foldM go acc args
go acc (VSort s) = return acc go acc (VSort s) = return acc
go acc (VInt _) = return acc go acc (VInt _) = return acc
go acc (VRecType vs) = foldM (\acc (lbl,_,v) -> go acc v) acc vs go acc (VRecType vs _) = foldM (\acc (lbl,_,v) -> go acc v) acc vs
go acc (VClosure _ _ _) = return acc go acc (VClosure _ _ _) = return acc
go acc (VProd b x v1 v2) = go acc v2 >>= \acc -> go acc v1 go acc (VProd b x v1 v2) = go acc v2 >>= \acc -> go acc v1
go acc (VTable v1 v2) = go acc v2 >>= \acc -> go acc v1 go acc (VTable v1 v2) = go acc v2 >>= \acc -> go acc v1
@@ -1373,6 +1566,7 @@ getMetaVars sc_tys = foldM (\acc (scope,ty) -> go acc ty) [] sc_tys
go acc (VApp c f args) = foldM go acc args go acc (VApp c f args) = foldM go acc args
go acc (VFV c vs) = foldM go acc (unvariants vs) go acc (VFV c vs) = foldM go acc (unvariants vs)
go acc (VInts _ _) = return acc go acc (VInts _ _) = return acc
go acc (VPattType v) = go acc v
go acc v = unimplemented ("go "++show (ppValue Unqualified 5 v)) go acc v = unimplemented ("go "++show (ppValue Unqualified 5 v))
-- | Eliminate any substitutions in a term -- | Eliminate any substitutions in a term
@@ -1393,3 +1587,24 @@ zonkTerm xs (Meta i) = do
Bound _ v -> zonkTerm xs =<< value2termM False xs v Bound _ v -> zonkTerm xs =<< value2termM False xs v
_ -> return (Meta i) _ -> return (Meta i)
zonkTerm xs t = composOp (zonkTerm xs) t zonkTerm xs t = composOp (zonkTerm xs) t
zonkValue :: Value -> EvalM Value
zonkValue (VProd bt x ty1 ty2) = do
ty1 <- zonkValue ty1
ty2 <- zonkValue ty2
return (VProd bt x ty1 ty2)
zonkValue (VMeta i vs) = do
g <- globals
st <- getMeta i
case st of
Bound _ v -> zonkValue (apply g v vs)
_ -> do vs <- mapM zonkValue vs
return (VMeta i vs)
zonkValue (VSusp i k vs) = do
g <- globals
st <- getMeta i
case st of
Bound _ v -> zonkValue (apply g (k v) vs)
_ -> do vs <- mapM zonkValue vs
return (VSusp i k vs)
zonkValue v = return v
+1 -1
View File
@@ -466,7 +466,7 @@ type Equation = ([Patt],Term)
type Labelling = (Label, Type) type Labelling = (Label, Type)
type Assign = (Label, (Maybe Type, Term)) type Assign = (Label, (Maybe Type, Term))
type Option = (Term, Term) type Option = (Maybe Term, Term)
type Case = (Patt, Term) type Case = (Patt, Term)
--type Cases = ([Patt], Term) --type Cases = ([Patt], Term)
type LocalDef = (Ident, (Maybe Type, Term)) type LocalDef = (Ident, (Maybe Type, Term))
+2 -1
View File
@@ -404,6 +404,7 @@ composOp co trm =
RecType r -> liftM RecType (mapPairsM co r) RecType r -> liftM RecType (mapPairsM co r)
P t i -> liftM2 P (co t) (return i) P t i -> liftM2 P (co t) (return i)
ExtR a c -> liftM2 ExtR (co a) (co c) ExtR a c -> liftM2 ExtR (co a) (co c)
Opts t os -> liftM2 Opts (co t) (mapM (\(t1,t2) -> liftM2 (,) (maybe (return Nothing) (liftM Just . co) t1) (co t2)) os)
T i cc -> liftM2 (flip T) (mapPairsM co cc) (changeTableType co i) T i cc -> liftM2 (flip T) (mapPairsM co cc) (changeTableType co i)
V ty vs -> liftM2 V (co ty) (mapM co vs) V ty vs -> liftM2 V (co ty) (mapM co vs)
Let (x,(mt,a)) b -> liftM3 let' (co a) (T.mapM co mt) (co b) Let (x,(mt,a)) b -> liftM3 let' (co a) (T.mapM co mt) (co b)
@@ -450,7 +451,7 @@ collectOp co trm = case trm of
S c a -> co c <> co a S c a -> co c <> co a
Table a c -> co a <> co c Table a c -> co a <> co c
ExtR a c -> co a <> co c ExtR a c -> co a <> co c
Opts t os -> co t <> mconcatMap (\(a,b) -> co a <> co b) os Opts t os -> co t <> mconcatMap (\(a,b) -> maybe mempty co a <> co b) os
R r -> mconcatMap (\ (_,(mt,a)) -> maybe mempty co mt <> co a) r R r -> mconcatMap (\ (_,(mt,a)) -> maybe mempty co mt <> co a) r
RecType r -> mconcatMap (co . snd) r RecType r -> mconcatMap (co . snd) r
P t i -> co t P t i -> co t
+26 -18
View File
@@ -276,9 +276,9 @@ ParamDef
OperDef :: { [(Ident,Info)] } OperDef :: { [(Ident,Info)] }
OperDef OperDef
: Posn LhsNames ':' Exp ';' Posn { [(i, info) | i <- $2, info <- mkOverload (Just (mkL $1 $6 $4)) Nothing ] } : Posn LhsNames ':' Exp ';' Posn { [(i, info) | i <- $2, info <- mkOverload (Just (mkL $1 $6 $4)) Nothing ] }
| Posn LhsNames '=' Markup Posn { [(i, info) | i <- $2, info <- mkOverload Nothing (Just (mkL $1 $5 $4))] } | Posn LhsNames '=' Exp ';' Posn { [(i, info) | i <- $2, info <- mkOverload Nothing (Just (mkL $1 $6 $4))] }
| Posn LhsName ListArg '=' Markup Posn { [(i, info) | i <- [$2], info <- mkOverload Nothing (Just (mkL $1 $6 (mkAbs $3 $5)))] } | Posn LhsName ListArg '=' Exp ';' Posn { [(i, info) | i <- [$2], info <- mkOverload Nothing (Just (mkL $1 $7 (mkAbs $3 $5)))] }
| Posn LhsNames ':' Exp '=' Markup Posn { [(i, info) | i <- $2, info <- mkOverload (Just (mkL $1 $7 $4)) (Just (mkL $1 $7 $6))] } | Posn LhsNames ':' Exp '=' Exp ';' Posn { [(i, info) | i <- $2, info <- mkOverload (Just (mkL $1 $8 $4)) (Just (mkL $1 $8 $6))] }
LinDef :: { [(Ident,Info)] } LinDef :: { [(Ident,Info)] }
LinDef LinDef
@@ -452,7 +452,11 @@ Exp4 :: { Term }
Exp4 Exp4
: Exp4 Exp5 { App $1 $2 } : Exp4 Exp5 { App $1 $2 }
| Exp4 '{' Exp '}' { App $1 (ImplArg $3) } | Exp4 '{' Exp '}' { App $1 (ImplArg $3) }
| 'option' Exp 'of' '{' ListOpt '}' { Opts $2 $5 } | 'option' Exp 'of' '{' ListExp '}' { let toOption t =
case t of
Table x y -> (Just x, y)
y -> (Nothing, y)
in Opts $2 (map toOption $5) }
| 'case' Exp 'of' '{' ListCase '}' { let annot = case $2 of | 'case' Exp 'of' '{' ListCase '}' { let annot = case $2 of
Typed _ t -> TTyped t Typed _ t -> TTyped t
_ -> TRaw _ -> TRaw
@@ -487,8 +491,7 @@ Exp6
| '{' ListLocDef '}' {% mkR $2 } | '{' ListLocDef '}' {% mkR $2 }
| '<' ListTupleComp '>' { R (tuple2record $2) } | '<' ListTupleComp '>' { R (tuple2record $2) }
| '<' Exp ':' Exp '>' { Typed $2 $4 } | '<' Exp ':' Exp '>' { Typed $2 $4 }
| '[' Control '|' Tag ']' { Reset (fst $2) (snd $2) $4 Nothing } | '[' Control '|' ListMarkup ']' { Reset (fst $2) (snd $2) (mkMarkup $4) Nothing }
| '[' Control '|' Exp ']' { Reset (fst $2) (snd $2) $4 Nothing }
| '(' Exp ')' { $2 } | '(' Exp ')' { $2 }
ListExp :: { [Term] } ListExp :: { [Term] }
@@ -609,15 +612,6 @@ ListPattTupleComp
| Patt { [$1] } | Patt { [$1] }
| Patt ',' ListPattTupleComp { $1 : $3 } | Patt ',' ListPattTupleComp { $1 : $3 }
Opt :: { Option }
Opt
: '(' Exp ')' '=>' Exp { ($2,$5) }
ListOpt :: { [Option] }
ListOpt
: Opt { [$1] }
| Opt ';' ListOpt { $1 : $3 }
Case :: { Case } Case :: { Case }
Case Case
: Patt '=>' Exp { ($1,$3) } : Patt '=>' Exp { ($1,$3) }
@@ -721,13 +715,20 @@ ERHS3 :: { ERHS }
NLG :: { Map.Map Ident Info } NLG :: { Map.Map Ident Info }
: ListNLGDef { Map.fromList $1 } : ListNLGDef { Map.fromList $1 }
| Posn Tag Posn { Map.singleton (identS "main") (ResOper Nothing (Just (mkL $1 $3 $2))) }
| Posn Exp Posn { Map.singleton (identS "main") (ResOper Nothing (Just (mkL $1 $3 $2))) } | Posn Exp Posn { Map.singleton (identS "main") (ResOper Nothing (Just (mkL $1 $3 $2))) }
| Posn ListMarkup2 Posn { Map.singleton (identS "main") (ResOper Nothing (Just (mkL $1 $3 (mkMarkup $2)))) }
ListNLGDef :: { [(Ident,Info)] } ListNLGDef :: { [(Ident,Info)] }
ListNLGDef ListNLGDef
: {- empty -} { [] } : 'oper' NLGDef { [] }
| 'oper' OperDef ListNLGDef { $2 ++ $3 } | 'oper' NLGDef ListNLGDef { $2 ++ $3 }
NLGDef :: { [(Ident,Info)] }
NLGDef
: Posn LhsNames ':' Exp ';' Posn { [(i, info) | i <- $2, info <- mkOverload (Just (mkL $1 $6 $4)) Nothing ] }
| Posn LhsNames '=' ListMarkup2 Posn { [(i, info) | i <- $2, info <- mkOverload Nothing (Just (mkL $1 $5 (mkMarkup $4)))] }
| Posn LhsName ListArg '=' ListMarkup2 Posn { [(i, info) | i <- [$2], info <- mkOverload Nothing (Just (mkL $1 $6 (mkAbs $3 (mkMarkup $5))))] }
| Posn LhsNames ':' Exp '=' ListMarkup2 Posn { [(i, info) | i <- $2, info <- mkOverload (Just (mkL $1 $7 $4)) (Just (mkL $1 $7 (mkMarkup $6)))] }
Markup :: { Term } Markup :: { Term }
Markup Markup
@@ -746,6 +747,10 @@ ListMarkup :: { [Term] }
| Exp { [$1] } | Exp { [$1] }
| Markup ListMarkup { $1 : $2 } | Markup ListMarkup { $1 : $2 }
ListMarkup2 :: { [Term] }
: Markup { [$1] }
| Markup ListMarkup2 { $1 : $2 }
Control :: { (Ident,Maybe Term) } Control :: { (Ident,Maybe Term) }
: Ident { ($1, Nothing) } : Ident { ($1, Nothing) }
| Ident ':' Exp6 { ($1, Just $3) } | Ident ':' Exp6 { ($1, Just $3) }
@@ -884,4 +889,7 @@ mkAlts cs = case cs of
mkL :: Posn -> Posn -> x -> L x mkL :: Posn -> Posn -> x -> L x
mkL (Pn l1 _) (Pn l2 _) x = L (Local l1 l2) x mkL (Pn l1 _) (Pn l2 _) x = L (Local l1 l2) x
mkMarkup [t] = t
mkMarkup ts = Markup identW [] ts
} }
+6
View File
@@ -63,9 +63,15 @@ cError = identS "error"
-- * Used in the delimited continuations -- * Used in the delimited continuations
cConcat = identS "concat" cConcat = identS "concat"
cConcat' = identS "concat'"
cOne = identS "one" cOne = identS "one"
cSelect = identS "select"
cDefault = identS "default" cDefault = identS "default"
cList = identS "list" cList = identS "list"
cLen = identS "len"
cp1 = identS "p1"
cp2 = identS "p2"
-- * Hacks: dummy identifiers used in various places. -- * Hacks: dummy identifiers used in various places.
-- Not very nice! -- Not very nice!
+6
View File
@@ -218,6 +218,9 @@ ppTerm q d (S x y) = case x of
'}' '}'
_ -> prec d 3 (hang (ppTerm q 3 x) 2 ("!" <+> ppTerm q 4 y)) _ -> prec d 3 (hang (ppTerm q 3 x) 2 ("!" <+> ppTerm q 4 y))
ppTerm q d (ExtR x y) = prec d 3 (ppTerm q 3 x <+> "**" <+> ppTerm q 4 y) ppTerm q d (ExtR x y) = prec d 3 (ppTerm q 3 x <+> "**" <+> ppTerm q 4 y)
ppTerm q d (Opts t opts) = "option" <+> ppTerm q 0 t <+>"of" <+> '{' $$
nest 2 (vcat (punctuate ';' (map (ppOpt q) opts))) $$
'}'
ppTerm q d (App x y) = prec d 4 (ppTerm q 4 x <+> ppTerm q 5 y) ppTerm q d (App x y) = prec d 4 (ppTerm q 4 x <+> ppTerm q 5 y)
ppTerm q d (V e es) = hang "table" 2 (sep [ppTerm q 6 e,brackets (fsep (punctuate ';' (map (ppTerm q 0) es)))]) ppTerm q d (V e es) = hang "table" 2 (sep [ppTerm q 6 e,brackets (fsep (punctuate ';' (map (ppTerm q 0) es)))])
ppTerm q d (FV es) = prec d 4 ("variants" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es)))) ppTerm q d (FV es) = prec d 4 ("variants" <+> braces (fsep (punctuate ';' (map (ppTerm q 0) es))))
@@ -269,6 +272,9 @@ ppEquation q (ps,e) = hcat (map (ppPatt q 2) ps) <+> "->" <+> ppTerm q 0 e
ppCase q (p,e) = ppPatt q 0 p <+> "=>" <+> ppTerm q 0 e ppCase q (p,e) = ppPatt q 0 p <+> "=>" <+> ppTerm q 0 e
ppOpt q (Just p, e) = ppTerm q 0 p <+> "=>" <+> ppTerm q 0 e
ppOpt q (Nothing,e) = ppTerm q 0 e
ppControl q (id,Nothing) = pp id ppControl q (id,Nothing) = pp id
ppControl q (id,Just t ) = pp id <> ':' <+> ppTerm q 6 t ppControl q (id,Just t ) = pp id <> ':' <+> ppTerm q 6 t