Moved the adding of direction specifiers out of the type inferrence pass into a new pass that runs before type inference
This commit is contained in:
parent
24fa36ccda
commit
6db9b221af
|
@ -39,6 +39,7 @@ import Utils
|
||||||
occamPasses :: [Pass]
|
occamPasses :: [Pass]
|
||||||
occamPasses =
|
occamPasses =
|
||||||
[ occamOnlyPass "Dummy occam pass" [] (Prop.agg_namesDone ++ [Prop.mainTagged]) return
|
[ occamOnlyPass "Dummy occam pass" [] (Prop.agg_namesDone ++ [Prop.mainTagged]) return
|
||||||
|
, addDirections
|
||||||
, inferTypes
|
, inferTypes
|
||||||
, foldConstants
|
, foldConstants
|
||||||
, fixConstructorTypes
|
, fixConstructorTypes
|
||||||
|
|
|
@ -17,7 +17,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
-- | The occam typechecker.
|
-- | The occam typechecker.
|
||||||
module OccamTypes (inferTypes, checkTypes) where
|
module OccamTypes (inferTypes, checkTypes, addDirections) where
|
||||||
|
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
import Data.Generics
|
import Data.Generics
|
||||||
|
@ -607,6 +607,46 @@ inSubscriptedContext m body
|
||||||
|
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
|
addDirections :: Pass
|
||||||
|
addDirections = occamOnlyPass "Add direction specifiers to inputs and outputs"
|
||||||
|
[] []
|
||||||
|
(applyDepthM2 doProcess doAlternative)
|
||||||
|
where
|
||||||
|
doProcess :: Transform A.Process
|
||||||
|
doProcess (A.Output m v os)
|
||||||
|
= do v' <- makeEnd m A.DirOutput v
|
||||||
|
return $ A.Output m v' os
|
||||||
|
doProcess (A.OutputCase m v n os)
|
||||||
|
= do v' <- makeEnd m A.DirOutput v
|
||||||
|
return $ A.OutputCase m v' n os
|
||||||
|
doProcess (A.Input m v im@(A.InputSimple {}))
|
||||||
|
= do v' <- makeEnd m A.DirInput v
|
||||||
|
return $ A.Input m v' im
|
||||||
|
doProcess (A.Input m v im@(A.InputCase {}))
|
||||||
|
= do v' <- makeEnd m A.DirInput v
|
||||||
|
return $ A.Input m v' im
|
||||||
|
doProcess p = return p
|
||||||
|
|
||||||
|
doAlternative :: Transform A.Alternative
|
||||||
|
doAlternative (A.Alternative m pre v im p)
|
||||||
|
= do v' <- case im of
|
||||||
|
A.InputSimple {} -> makeEnd m A.DirInput v
|
||||||
|
A.InputCase {} -> makeEnd m A.DirInput v
|
||||||
|
_ -> return v
|
||||||
|
return $ A.Alternative m pre v' im p
|
||||||
|
doAlternative a = return a
|
||||||
|
|
||||||
|
makeEnd :: Meta -> A.Direction -> Transform A.Variable
|
||||||
|
makeEnd m dir v
|
||||||
|
= do t <- astTypeOf v
|
||||||
|
case t of
|
||||||
|
A.ChanEnd {} -> return v
|
||||||
|
A.Chan {} -> return $ A.DirectedVariable m dir v
|
||||||
|
A.Array _ (A.ChanEnd {}) -> return v
|
||||||
|
A.Array _ (A.Chan {}) -> return $ A.DirectedVariable m dir v
|
||||||
|
-- If unsure (e.g. Infer), just shove a direction on it to be sure:
|
||||||
|
_ -> return $ A.DirectedVariable m dir v
|
||||||
|
|
||||||
--{{{ inferTypes
|
--{{{ inferTypes
|
||||||
|
|
||||||
-- | Infer types.
|
-- | Infer types.
|
||||||
|
@ -730,10 +770,7 @@ inferTypes = occamOnlyPass "Infer types"
|
||||||
doAlternative :: Transform A.Alternative
|
doAlternative :: Transform A.Alternative
|
||||||
doAlternative (A.Alternative m pre v im p)
|
doAlternative (A.Alternative m pre v im p)
|
||||||
= do pre' <- inTypeContext (Just A.Bool) $ recurse pre
|
= do pre' <- inTypeContext (Just A.Bool) $ recurse pre
|
||||||
v' <- recurse v >>= case im of
|
v' <- recurse v
|
||||||
A.InputSimple {} -> makeEnd m A.DirInput
|
|
||||||
A.InputCase {} -> makeEnd m A.DirInput
|
|
||||||
_ -> return
|
|
||||||
im' <- recurse im
|
im' <- recurse im
|
||||||
p' <- recurse p
|
p' <- recurse p
|
||||||
return $ A.Alternative m pre' v' im' p'
|
return $ A.Alternative m pre' v' im' p'
|
||||||
|
@ -859,17 +896,6 @@ inferTypes = occamOnlyPass "Infer types"
|
||||||
doVariable v = makeDescend ops v
|
doVariable v = makeDescend ops v
|
||||||
|
|
||||||
|
|
||||||
makeEnd :: Meta -> A.Direction -> Transform A.Variable
|
|
||||||
makeEnd m dir v
|
|
||||||
= do t <- astTypeOf v
|
|
||||||
case t of
|
|
||||||
A.ChanEnd {} -> return v
|
|
||||||
A.Chan {} -> return $ A.DirectedVariable m dir v
|
|
||||||
A.Array _ (A.ChanEnd {}) -> return v
|
|
||||||
A.Array _ (A.Chan {}) -> return $ A.DirectedVariable m dir v
|
|
||||||
_ -> dieP m "Cannot infer direction for things that are not a channel or channel-end"
|
|
||||||
|
|
||||||
|
|
||||||
doProcess :: Transform A.Process
|
doProcess :: Transform A.Process
|
||||||
doProcess p
|
doProcess p
|
||||||
= case p of
|
= case p of
|
||||||
|
@ -879,7 +905,7 @@ inferTypes = occamOnlyPass "Infer types"
|
||||||
el' <- doExpressionList ts el
|
el' <- doExpressionList ts el
|
||||||
return $ A.Assign m vs' el'
|
return $ A.Assign m vs' el'
|
||||||
A.Output m v ois ->
|
A.Output m v ois ->
|
||||||
do v' <- recurse v >>= makeEnd m A.DirOutput
|
do v' <- recurse v
|
||||||
-- At this point we must resolve the "c ! x" ambiguity:
|
-- At this point we must resolve the "c ! x" ambiguity:
|
||||||
-- we definitely know what c is, and we must know what x is
|
-- we definitely know what c is, and we must know what x is
|
||||||
-- before trying to infer its type.
|
-- before trying to infer its type.
|
||||||
|
@ -896,7 +922,7 @@ inferTypes = occamOnlyPass "Infer types"
|
||||||
else do ois' <- doOutputItems m v' Nothing ois
|
else do ois' <- doOutputItems m v' Nothing ois
|
||||||
return $ A.Output m v' ois'
|
return $ A.Output m v' ois'
|
||||||
A.OutputCase m v tag ois ->
|
A.OutputCase m v tag ois ->
|
||||||
do v' <- recurse v >>= makeEnd m A.DirOutput
|
do v' <- recurse v
|
||||||
ois' <- doOutputItems m v' (Just tag) ois
|
ois' <- doOutputItems m v' (Just tag) ois
|
||||||
return $ A.OutputCase m v' tag ois'
|
return $ A.OutputCase m v' tag ois'
|
||||||
A.If _ _ -> inTypeContext (Just A.Bool) $ descend p
|
A.If _ _ -> inTypeContext (Just A.Bool) $ descend p
|
||||||
|
@ -915,11 +941,11 @@ inferTypes = occamOnlyPass "Infer types"
|
||||||
A.IntrinsicProcCall _ _ _ -> noTypeContext $ descend p
|
A.IntrinsicProcCall _ _ _ -> noTypeContext $ descend p
|
||||||
A.Input m v im@(A.InputSimple {})
|
A.Input m v im@(A.InputSimple {})
|
||||||
-> do im' <- recurse im
|
-> do im' <- recurse im
|
||||||
v' <- recurse v >>= makeEnd m A.DirInput
|
v' <- recurse v
|
||||||
return $ A.Input m v' im'
|
return $ A.Input m v' im'
|
||||||
A.Input m v im@(A.InputCase {})
|
A.Input m v im@(A.InputCase {})
|
||||||
-> do im' <- recurse im
|
-> do im' <- recurse im
|
||||||
v' <- recurse v >>= makeEnd m A.DirInput
|
v' <- recurse v
|
||||||
return $ A.Input m v' im'
|
return $ A.Input m v' im'
|
||||||
_ -> descend p
|
_ -> descend p
|
||||||
where
|
where
|
||||||
|
|
Loading…
Reference in New Issue
Block a user