mirror of
https://github.com/GaloisInc/cryptol.git
synced 2024-12-18 05:21:57 +03:00
Plumb through primitive declarations
This commit is contained in:
parent
e4258b4d2c
commit
b1bbd41f83
@ -123,7 +123,11 @@ evalDeclGroup dg env = env'
|
|||||||
NonRecursive d -> evalDecl env d env
|
NonRecursive d -> evalDecl env d env
|
||||||
|
|
||||||
evalDecl :: ReadEnv -> Decl -> EvalEnv -> EvalEnv
|
evalDecl :: ReadEnv -> Decl -> EvalEnv -> EvalEnv
|
||||||
evalDecl renv d = bindVar (dName d) (evalExpr renv (dDefinition d))
|
evalDecl renv d = bindVar (dName d) (evalDef renv (dDefinition d))
|
||||||
|
|
||||||
|
evalDef :: ReadEnv -> DeclDef -> Value
|
||||||
|
evalDef renv (DExpr e) = evalExpr renv e
|
||||||
|
evalDef _ DPrim = panic "Eval" [ "unimplemented primitive" ]
|
||||||
|
|
||||||
|
|
||||||
-- Selectors -------------------------------------------------------------------
|
-- Selectors -------------------------------------------------------------------
|
||||||
|
@ -419,6 +419,10 @@ instance Rename Bind where
|
|||||||
, bPragmas = p'
|
, bPragmas = p'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance Rename BindDef where
|
||||||
|
rename DPrim = return DPrim
|
||||||
|
rename (DExpr e) = DExpr <$> rename e
|
||||||
|
|
||||||
-- NOTE: this only renames types within the pattern.
|
-- NOTE: this only renames types within the pattern.
|
||||||
instance Rename Pattern where
|
instance Rename Pattern where
|
||||||
rename p = case p of
|
rename p = case p of
|
||||||
|
@ -70,6 +70,8 @@ import Paths_cryptol
|
|||||||
'max' { Located $$ (Token (KW KW_max ) _)}
|
'max' { Located $$ (Token (KW KW_max ) _)}
|
||||||
'x' { Located $$ (Token (KW KW_x) _)}
|
'x' { Located $$ (Token (KW KW_x) _)}
|
||||||
|
|
||||||
|
'primitive' { Located $$ (Token (KW KW_primitive) _)}
|
||||||
|
|
||||||
'[' { Located $$ (Token (Sym BracketL) _)}
|
'[' { Located $$ (Token (Sym BracketL) _)}
|
||||||
']' { Located $$ (Token (Sym BracketR) _)}
|
']' { Located $$ (Token (Sym BracketR) _)}
|
||||||
'<-' { Located $$ (Token (Sym ArrL ) _)}
|
'<-' { Located $$ (Token (Sym ArrL ) _)}
|
||||||
@ -236,10 +238,35 @@ vtop_decl :: { [TopDecl] }
|
|||||||
| 'property' name apats '=' expr { [exportDecl Public (mkProperty $2 $3 $5)]}
|
| 'property' name apats '=' expr { [exportDecl Public (mkProperty $2 $3 $5)]}
|
||||||
| 'property' name '=' expr { [exportDecl Public (mkProperty $2 [] $4)]}
|
| 'property' name '=' expr { [exportDecl Public (mkProperty $2 [] $4)]}
|
||||||
| newtype { [exportNewtype Public $1] }
|
| newtype { [exportNewtype Public $1] }
|
||||||
|
| 'primitive' prim_bind { [exportDecl Public $ at ($1,$2) $ DBind $2]}
|
||||||
|
|
||||||
top_decl :: { TopDecl }
|
top_decl :: { TopDecl }
|
||||||
: decl { Decl (TopLevel {tlExport = Public, tlValue = $1}) }
|
: decl { Decl (TopLevel {tlExport = Public, tlValue = $1}) }
|
||||||
| 'include' STRLIT {% Include `fmap` fromStrLit $2 }
|
| 'include' STRLIT {% Include `fmap` fromStrLit $2 }
|
||||||
|
| 'primitive' prim_bind { exportDecl Public $ at ($1,$2) $ DBind $2 }
|
||||||
|
|
||||||
|
prim_bind :: { Bind }
|
||||||
|
: name ':' schema { Bind { bName = fmap mkUnqual $1
|
||||||
|
, bParams = []
|
||||||
|
, bDef = at $3 (Located emptyRange DPrim)
|
||||||
|
, bSignature = Just $3
|
||||||
|
, bPragmas = []
|
||||||
|
, bMono = False
|
||||||
|
, bInfix = False
|
||||||
|
, bFixity = Nothing
|
||||||
|
} }
|
||||||
|
|
||||||
|
| '(' op ')' ':' schema { Bind { bName = $2
|
||||||
|
, bParams = []
|
||||||
|
, bDef = at $5 (Located emptyRange DPrim)
|
||||||
|
, bSignature = Just $5
|
||||||
|
, bPragmas = []
|
||||||
|
, bMono = False
|
||||||
|
, bInfix = True
|
||||||
|
, bFixity = Nothing
|
||||||
|
} }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
decl :: { Decl }
|
decl :: { Decl }
|
||||||
: vars_comma ':' schema { at (head $1,$3) $ DSignature (map (fmap mkUnqual) (reverse $1)) $3 }
|
: vars_comma ':' schema { at (head $1,$3) $ DSignature (map (fmap mkUnqual) (reverse $1)) $3 }
|
||||||
@ -247,7 +274,7 @@ decl :: { Decl }
|
|||||||
| name apats '=' expr { at ($1,$4) $
|
| name apats '=' expr { at ($1,$4) $
|
||||||
DBind $ Bind { bName = fmap mkUnqual $1
|
DBind $ Bind { bName = fmap mkUnqual $1
|
||||||
, bParams = reverse $2
|
, bParams = reverse $2
|
||||||
, bDef = $4
|
, bDef = at $4 (Located emptyRange (DExpr $4))
|
||||||
, bSignature = Nothing
|
, bSignature = Nothing
|
||||||
, bPragmas = []
|
, bPragmas = []
|
||||||
, bMono = False
|
, bMono = False
|
||||||
@ -258,7 +285,7 @@ decl :: { Decl }
|
|||||||
| apat op apat '=' expr { at ($1,$5) $
|
| apat op apat '=' expr { at ($1,$5) $
|
||||||
DBind $ Bind { bName = $2
|
DBind $ Bind { bName = $2
|
||||||
, bParams = [$1,$3]
|
, bParams = [$1,$3]
|
||||||
, bDef = $5
|
, bDef = at $5 (Located emptyRange (DExpr $5))
|
||||||
, bSignature = Nothing
|
, bSignature = Nothing
|
||||||
, bPragmas = []
|
, bPragmas = []
|
||||||
, bMono = False
|
, bMono = False
|
||||||
@ -279,7 +306,7 @@ let_decl :: { Decl }
|
|||||||
| 'let' name apats '=' expr { at ($2,$5) $
|
| 'let' name apats '=' expr { at ($2,$5) $
|
||||||
DBind $ Bind { bName = fmap mkUnqual $2
|
DBind $ Bind { bName = fmap mkUnqual $2
|
||||||
, bParams = reverse $3
|
, bParams = reverse $3
|
||||||
, bDef = $5
|
, bDef = at $5 (Located emptyRange (DExpr $5))
|
||||||
, bSignature = Nothing
|
, bSignature = Nothing
|
||||||
, bPragmas = []
|
, bPragmas = []
|
||||||
, bMono = False
|
, bMono = False
|
||||||
@ -298,11 +325,12 @@ newtype_body :: { [Named Type] }
|
|||||||
| '{' field_types '}' { $2 }
|
| '{' field_types '}' { $2 }
|
||||||
|
|
||||||
vars_comma :: { [ LName ] }
|
vars_comma :: { [ LName ] }
|
||||||
: name { [ $1] }
|
: var { [ $1] }
|
||||||
| vars_comma ',' name { $3 : $1 }
|
| vars_comma ',' var { $3 : $1 }
|
||||||
|
|
||||||
| '(' op ')' { [fmap unqual $2] }
|
var :: { LName }
|
||||||
| vars_comma ',' '(' op ')' { fmap unqual $4 : $1 }
|
: name { $1 }
|
||||||
|
| '(' op ')' { fmap unqual $2 }
|
||||||
|
|
||||||
apats :: { [Pattern] }
|
apats :: { [Pattern] }
|
||||||
: apat { [$1] }
|
: apat { [$1] }
|
||||||
|
@ -33,6 +33,7 @@ module Cryptol.Parser.AST
|
|||||||
, Fixity(..), defaultFixity
|
, Fixity(..), defaultFixity
|
||||||
, TySyn(..)
|
, TySyn(..)
|
||||||
, Bind(..)
|
, Bind(..)
|
||||||
|
, BindDef(..), LBindDef
|
||||||
, Pragma(..)
|
, Pragma(..)
|
||||||
, ExportType(..)
|
, ExportType(..)
|
||||||
, ExportSpec(..), exportBind, exportType
|
, ExportSpec(..), exportBind, exportType
|
||||||
@ -152,7 +153,7 @@ data TySyn = TySyn LQName [TParam] Type
|
|||||||
-}
|
-}
|
||||||
data Bind = Bind { bName :: LQName -- ^ Defined thing
|
data Bind = Bind { bName :: LQName -- ^ Defined thing
|
||||||
, bParams :: [Pattern] -- ^ Parameters
|
, bParams :: [Pattern] -- ^ Parameters
|
||||||
, bDef :: Expr -- ^ Definition
|
, bDef :: LBindDef -- ^ Definition
|
||||||
, bSignature :: Maybe Schema -- ^ Optional type sig
|
, bSignature :: Maybe Schema -- ^ Optional type sig
|
||||||
, bInfix :: Bool -- ^ Infix operator?
|
, bInfix :: Bool -- ^ Infix operator?
|
||||||
, bFixity :: Maybe Fixity -- ^ Optional fixity info
|
, bFixity :: Maybe Fixity -- ^ Optional fixity info
|
||||||
@ -160,6 +161,12 @@ data Bind = Bind { bName :: LQName -- ^ Defined thing
|
|||||||
, bMono :: Bool -- ^ Is this a monomorphic binding
|
, bMono :: Bool -- ^ Is this a monomorphic binding
|
||||||
} deriving (Eq,Show)
|
} deriving (Eq,Show)
|
||||||
|
|
||||||
|
type LBindDef = Located BindDef
|
||||||
|
|
||||||
|
data BindDef = DPrim
|
||||||
|
| DExpr Expr
|
||||||
|
deriving (Eq,Show)
|
||||||
|
|
||||||
data Fixity = Fixity { fAssoc :: !Assoc
|
data Fixity = Fixity { fAssoc :: !Assoc
|
||||||
, fLevel :: !Int
|
, fLevel :: !Int
|
||||||
} deriving (Eq,Show)
|
} deriving (Eq,Show)
|
||||||
@ -533,7 +540,7 @@ ppPragma xs p =
|
|||||||
|
|
||||||
instance PP Bind where
|
instance PP Bind where
|
||||||
ppPrec _ b = sig $$ vcat [ ppPragma [f] p | p <- bPragmas b ] $$
|
ppPrec _ b = sig $$ vcat [ ppPragma [f] p | p <- bPragmas b ] $$
|
||||||
hang (def <+> eq) 4 (pp (bDef b))
|
hang (def <+> eq) 4 (pp (thing (bDef b)))
|
||||||
where def | bInfix b = lhsOp
|
where def | bInfix b = lhsOp
|
||||||
| otherwise = lhs
|
| otherwise = lhs
|
||||||
f = bName b
|
f = bName b
|
||||||
@ -548,6 +555,11 @@ instance PP Bind where
|
|||||||
_ -> panic "AST" [ "Malformed infix operator", show b ]
|
_ -> panic "AST" [ "Malformed infix operator", show b ]
|
||||||
|
|
||||||
|
|
||||||
|
instance PP BindDef where
|
||||||
|
ppPrec _ DPrim = text "<primitive>"
|
||||||
|
ppPrec p (DExpr e) = ppPrec p e
|
||||||
|
|
||||||
|
|
||||||
instance PP TySyn where
|
instance PP TySyn where
|
||||||
ppPrec _ (TySyn x xs t) = text "type" <+> ppL x <+> fsep (map (ppPrec 1) xs)
|
ppPrec _ (TySyn x xs t) = text "type" <+> ppL x <+> fsep (map (ppPrec 1) xs)
|
||||||
<+> text "=" <+> pp t
|
<+> text "=" <+> pp t
|
||||||
|
@ -108,6 +108,8 @@ $white+ { emit $ White Space }
|
|||||||
"infixr" { emit $ KW KW_infixr }
|
"infixr" { emit $ KW KW_infixr }
|
||||||
"infix" { emit $ KW KW_infix }
|
"infix" { emit $ KW KW_infix }
|
||||||
|
|
||||||
|
"primitive" { emit $ KW KW_primitive }
|
||||||
|
|
||||||
@num2 { emitS (numToken 2 . drop 2) }
|
@num2 { emitS (numToken 2 . drop 2) }
|
||||||
@num8 { emitS (numToken 8 . drop 2) }
|
@num8 { emitS (numToken 8 . drop 2) }
|
||||||
@num10 { emitS (numToken 10 . drop 0) }
|
@num10 { emitS (numToken 10 . drop 0) }
|
||||||
|
@ -342,6 +342,7 @@ data TokenKW = KW_Arith
|
|||||||
| KW_infixl
|
| KW_infixl
|
||||||
| KW_infixr
|
| KW_infixr
|
||||||
| KW_infix
|
| KW_infix
|
||||||
|
| KW_primitive
|
||||||
deriving (Eq,Show)
|
deriving (Eq,Show)
|
||||||
|
|
||||||
-- | The named operators are a special case for parsing types, and 'Other' is
|
-- | The named operators are a special case for parsing types, and 'Other' is
|
||||||
|
@ -71,7 +71,12 @@ tsName (TySyn lqn _ _) = lqn
|
|||||||
|
|
||||||
-- | The names defined and used by a single binding.
|
-- | The names defined and used by a single binding.
|
||||||
namesB :: Bind -> ([Located QName], Set QName)
|
namesB :: Bind -> ([Located QName], Set QName)
|
||||||
namesB b = ([bName b], boundNames (namesPs (bParams b)) (namesE (bDef b)))
|
namesB b = ([bName b], boundNames (namesPs (bParams b)) (namesDef (thing (bDef b))))
|
||||||
|
|
||||||
|
|
||||||
|
namesDef :: BindDef -> Set QName
|
||||||
|
namesDef DPrim = Set.empty
|
||||||
|
namesDef (DExpr e) = namesE e
|
||||||
|
|
||||||
|
|
||||||
-- | The names used by an expression.
|
-- | The names used by an expression.
|
||||||
@ -186,7 +191,11 @@ tnamesB b = Set.unions [setS, setP, setE]
|
|||||||
where
|
where
|
||||||
setS = maybe Set.empty tnamesS (bSignature b)
|
setS = maybe Set.empty tnamesS (bSignature b)
|
||||||
setP = Set.unions (map tnamesP (bParams b))
|
setP = Set.unions (map tnamesP (bParams b))
|
||||||
setE = tnamesE (bDef b)
|
setE = tnamesDef (thing (bDef b))
|
||||||
|
|
||||||
|
tnamesDef :: BindDef -> Set QName
|
||||||
|
tnamesDef DPrim = Set.empty
|
||||||
|
tnamesDef (DExpr e) = tnamesE e
|
||||||
|
|
||||||
-- | The type names used by an expression.
|
-- | The type names used by an expression.
|
||||||
tnamesE :: Expr -> Set QName
|
tnamesE :: Expr -> Set QName
|
||||||
|
@ -16,7 +16,7 @@ module Cryptol.Parser.NoPat (RemovePatterns(..),Error(..)) where
|
|||||||
|
|
||||||
import Cryptol.Prims.Syntax
|
import Cryptol.Prims.Syntax
|
||||||
import Cryptol.Parser.AST
|
import Cryptol.Parser.AST
|
||||||
import Cryptol.Parser.Position(Range(..),start)
|
import Cryptol.Parser.Position(Range(..),emptyRange,start,at)
|
||||||
import Cryptol.Utils.PP
|
import Cryptol.Utils.PP
|
||||||
import Cryptol.Utils.Panic(panic)
|
import Cryptol.Utils.Panic(panic)
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ import Data.Either(partitionEithers)
|
|||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
|
|
||||||
#if __GLASGOW_HASKELL__ < 710
|
#if __GLASGOW_HASKELL__ < 710
|
||||||
import Control.Applicative(Applicative(..),(<$>))
|
import Control.Applicative(Applicative(..),(<$>)(<$))
|
||||||
import Data.Traversable(traverse)
|
import Data.Traversable(traverse)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -47,7 +47,8 @@ instance RemovePatterns [Decl] where
|
|||||||
removePatterns ds = runNoPatM (noPatDs ds)
|
removePatterns ds = runNoPatM (noPatDs ds)
|
||||||
|
|
||||||
simpleBind :: Located QName -> Expr -> Bind
|
simpleBind :: Located QName -> Expr -> Bind
|
||||||
simpleBind x e = Bind { bName = x, bParams = [], bDef = e
|
simpleBind x e = Bind { bName = x, bParams = []
|
||||||
|
, bDef = at e (Located emptyRange (DExpr e))
|
||||||
, bSignature = Nothing, bPragmas = []
|
, bSignature = Nothing, bPragmas = []
|
||||||
, bMono = True, bInfix = False, bFixity = Nothing
|
, bMono = True, bInfix = False, bFixity = Nothing
|
||||||
}
|
}
|
||||||
@ -190,8 +191,15 @@ noPatM (MatchLet b) = (return . MatchLet) <$> noMatchB b
|
|||||||
|
|
||||||
noMatchB :: Bind -> NoPatM Bind
|
noMatchB :: Bind -> NoPatM Bind
|
||||||
noMatchB b =
|
noMatchB b =
|
||||||
do (ps,e) <- noPatFun (bParams b) (bDef b)
|
case thing (bDef b) of
|
||||||
return b { bParams = ps, bDef = e }
|
|
||||||
|
DPrim | null (bParams b) -> return b
|
||||||
|
| otherwise -> panic "NoPat" [ "noMatchB: primitive with params"
|
||||||
|
, show b ]
|
||||||
|
|
||||||
|
DExpr e ->
|
||||||
|
do (ps,e') <- noPatFun (bParams b) e
|
||||||
|
return b { bParams = ps, bDef = DExpr e' <$ bDef b }
|
||||||
|
|
||||||
noMatchD :: Decl -> NoPatM [Decl]
|
noMatchD :: Decl -> NoPatM [Decl]
|
||||||
noMatchD decl =
|
noMatchD decl =
|
||||||
@ -209,7 +217,7 @@ noMatchD decl =
|
|||||||
let e2 = foldl ETyped e1 ts
|
let e2 = foldl ETyped e1 ts
|
||||||
return $ DBind Bind { bName = x
|
return $ DBind Bind { bName = x
|
||||||
, bParams = []
|
, bParams = []
|
||||||
, bDef = e2
|
, bDef = at e (Located emptyRange (DExpr e2))
|
||||||
, bSignature = Nothing
|
, bSignature = Nothing
|
||||||
, bPragmas = []
|
, bPragmas = []
|
||||||
, bMono = False
|
, bMono = False
|
||||||
|
@ -319,7 +319,7 @@ mkPoly rng terms = mk 0 (map fromInteger bits)
|
|||||||
mkProperty :: LName -> [Pattern] -> Expr -> Decl
|
mkProperty :: LName -> [Pattern] -> Expr -> Decl
|
||||||
mkProperty f ps e = DBind Bind { bName = fmap mkUnqual f
|
mkProperty f ps e = DBind Bind { bName = fmap mkUnqual f
|
||||||
, bParams = reverse ps
|
, bParams = reverse ps
|
||||||
, bDef = ETyped e TBit
|
, bDef = at e (Located emptyRange (DExpr (ETyped e TBit)))
|
||||||
, bSignature = Nothing
|
, bSignature = Nothing
|
||||||
, bPragmas = [PragmaProperty]
|
, bPragmas = [PragmaProperty]
|
||||||
, bMono = False
|
, bMono = False
|
||||||
|
@ -781,7 +781,7 @@ bindItVariable ty expr = do
|
|||||||
}
|
}
|
||||||
decl = T.Decl { T.dName = freshIt
|
decl = T.Decl { T.dName = freshIt
|
||||||
, T.dSignature = schema
|
, T.dSignature = schema
|
||||||
, T.dDefinition = expr
|
, T.dDefinition = T.DExpr expr
|
||||||
, T.dPragmas = []
|
, T.dPragmas = []
|
||||||
, T.dInfix = False
|
, T.dInfix = False
|
||||||
, T.dFixity = Nothing
|
, T.dFixity = Nothing
|
||||||
|
@ -398,7 +398,12 @@ evalDeclGroup env dg =
|
|||||||
in env'
|
in env'
|
||||||
|
|
||||||
evalDecl :: Env -> Decl -> (QName, Value)
|
evalDecl :: Env -> Decl -> (QName, Value)
|
||||||
evalDecl env d = (dName d, evalExpr env (dDefinition d))
|
evalDecl env d = (dName d, evalDeclDef env (dDefinition d))
|
||||||
|
|
||||||
|
evalDeclDef :: Env -> DeclDef -> Value
|
||||||
|
evalDeclDef env (DExpr e) = evalExpr env e
|
||||||
|
evalDeclDef _ DPrim = panic "Cryptol.Symbolic.evalDeclDef"
|
||||||
|
[ "Unimplemented primitive" ]
|
||||||
|
|
||||||
-- | Make a copy of the given value, building the spine based only on
|
-- | Make a copy of the given value, building the spine based only on
|
||||||
-- the type without forcing the value argument. This lets us avoid
|
-- the type without forcing the value argument. This lets us avoid
|
||||||
|
@ -212,9 +212,13 @@ rewM rews ma =
|
|||||||
|
|
||||||
|
|
||||||
rewD :: RewMap -> Decl -> M Decl
|
rewD :: RewMap -> Decl -> M Decl
|
||||||
rewD rews d = do e <- rewE rews (dDefinition d)
|
rewD rews d = do e <- rewDef rews (dDefinition d)
|
||||||
return d { dDefinition = e }
|
return d { dDefinition = e }
|
||||||
|
|
||||||
|
rewDef :: RewMap -> DeclDef -> M DeclDef
|
||||||
|
rewDef rews (DExpr e) = DExpr <$> rewE rews e
|
||||||
|
rewDef _ DPrim = return DPrim
|
||||||
|
|
||||||
rewDeclGroup :: RewMap -> DeclGroup -> M DeclGroup
|
rewDeclGroup :: RewMap -> DeclGroup -> M DeclGroup
|
||||||
rewDeclGroup rews dg =
|
rewDeclGroup rews dg =
|
||||||
case dg of
|
case dg of
|
||||||
@ -231,9 +235,12 @@ rewDeclGroup rews dg =
|
|||||||
sameTParams (_,tps1,x,_) (_,tps2,y,_) = tps1 == tps2 && x == y
|
sameTParams (_,tps1,x,_) (_,tps2,y,_) = tps1 == tps2 && x == y
|
||||||
compareTParams (_,tps1,x,_) (_,tps2,y,_) = compare (x,tps1) (y,tps2)
|
compareTParams (_,tps1,x,_) (_,tps2,y,_) = compare (x,tps1) (y,tps2)
|
||||||
|
|
||||||
consider d = let (tps,props,e) = splitTParams (dDefinition d)
|
consider d =
|
||||||
in if not (null tps) && notFun e
|
case dDefinition d of
|
||||||
then Right (d, tps, props, e)
|
DPrim -> Left d
|
||||||
|
DExpr e -> let (tps,props,e') = splitTParams e
|
||||||
|
in if not (null tps) && notFun e'
|
||||||
|
then Right (d, tps, props, e')
|
||||||
else Left d
|
else Left d
|
||||||
|
|
||||||
rewSame ds =
|
rewSame ds =
|
||||||
@ -252,7 +259,7 @@ rewDeclGroup rews dg =
|
|||||||
, d { dName = newN
|
, d { dName = newN
|
||||||
, dSignature = (dSignature d)
|
, dSignature = (dSignature d)
|
||||||
{ sVars = [], sProps = [] }
|
{ sVars = [], sProps = [] }
|
||||||
, dDefinition = e1
|
, dDefinition = DExpr e1
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -262,7 +269,7 @@ rewDeclGroup rews dg =
|
|||||||
let newBody = EVar (dName f')
|
let newBody = EVar (dName f')
|
||||||
newE = EWhere newBody
|
newE = EWhere newBody
|
||||||
[ Recursive [f'] ]
|
[ Recursive [f'] ]
|
||||||
in foldr ETAbs
|
in DExpr $ foldr ETAbs
|
||||||
(foldr EProofAbs newE props) tps
|
(foldr EProofAbs newE props) tps
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -285,6 +292,7 @@ rewDeclGroup rews dg =
|
|||||||
(map (sType . dSignature) monoDs)
|
(map (sType . dSignature) monoDs)
|
||||||
|
|
||||||
, dDefinition =
|
, dDefinition =
|
||||||
|
DExpr $
|
||||||
addTPs $
|
addTPs $
|
||||||
EWhere (ETuple [ EVar (dName d) | d <- monoDs ])
|
EWhere (ETuple [ EVar (dName d) | d <- monoDs ])
|
||||||
[ Recursive monoDs ]
|
[ Recursive monoDs ]
|
||||||
@ -301,6 +309,7 @@ rewDeclGroup rews dg =
|
|||||||
|
|
||||||
mkFunDef n f =
|
mkFunDef n f =
|
||||||
f { dDefinition =
|
f { dDefinition =
|
||||||
|
DExpr $
|
||||||
addTPs $ ESel ( flip (foldl mkProof) props
|
addTPs $ ESel ( flip (foldl mkProof) props
|
||||||
$ flip (foldl ETApp) tys
|
$ flip (foldl ETApp) tys
|
||||||
$ EVar tupName
|
$ EVar tupName
|
||||||
|
@ -187,7 +187,10 @@ specializeConst e0 = do
|
|||||||
qname' <- freshName qname ts -- New type instance, record new name
|
qname' <- freshName qname ts -- New type instance, record new name
|
||||||
sig' <- instantiateSchema ts n (dSignature decl)
|
sig' <- instantiateSchema ts n (dSignature decl)
|
||||||
modifySpecCache (Map.adjust (fmap (insertTM ts (qname', Nothing))) qname)
|
modifySpecCache (Map.adjust (fmap (insertTM ts (qname', Nothing))) qname)
|
||||||
rhs' <- specializeExpr =<< instantiateExpr ts n (dDefinition decl)
|
rhs' <- case dDefinition decl of
|
||||||
|
DExpr e -> do e' <- specializeExpr =<< instantiateExpr ts n e
|
||||||
|
return (DExpr e')
|
||||||
|
DPrim -> return DPrim
|
||||||
let decl' = decl { dName = qname', dSignature = sig', dDefinition = rhs' }
|
let decl' = decl { dName = qname', dSignature = sig', dDefinition = rhs' }
|
||||||
modifySpecCache (Map.adjust (fmap (insertTM ts (qname', Just decl'))) qname)
|
modifySpecCache (Map.adjust (fmap (insertTM ts (qname', Just decl'))) qname)
|
||||||
return (EVar qname')
|
return (EVar qname')
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
-- Maintainer : cryptol@galois.com
|
-- Maintainer : cryptol@galois.com
|
||||||
-- Stability : provisional
|
-- Stability : provisional
|
||||||
-- Portability : portable
|
-- Portability : portable
|
||||||
|
{-# LANGUAGE PatternGuards #-}
|
||||||
|
|
||||||
module Cryptol.TypeCheck
|
module Cryptol.TypeCheck
|
||||||
( tcModule
|
( tcModule
|
||||||
@ -71,7 +72,7 @@ tcExpr e0 inp = runInferM inp
|
|||||||
{ P.bName = P.Located (inpRange inp)
|
{ P.bName = P.Located (inpRange inp)
|
||||||
$ mkUnqual (P.Name "(expression)")
|
$ mkUnqual (P.Name "(expression)")
|
||||||
, P.bParams = []
|
, P.bParams = []
|
||||||
, P.bDef = expr
|
, P.bDef = P.Located (inpRange inp) (P.DExpr expr)
|
||||||
, P.bPragmas = []
|
, P.bPragmas = []
|
||||||
, P.bSignature = Nothing
|
, P.bSignature = Nothing
|
||||||
, P.bMono = False
|
, P.bMono = False
|
||||||
@ -80,7 +81,12 @@ tcExpr e0 inp = runInferM inp
|
|||||||
} ]
|
} ]
|
||||||
|
|
||||||
case res of
|
case res of
|
||||||
[d] -> return (dDefinition d, dSignature d)
|
[d] | DExpr e <- dDefinition d -> return (e, dSignature d)
|
||||||
|
| otherwise ->
|
||||||
|
panic "Cryptol.TypeCheck.tcExpr"
|
||||||
|
[ "Expected an expression in definition"
|
||||||
|
, show d ]
|
||||||
|
|
||||||
_ -> panic "Cryptol.TypeCheck.tcExpr"
|
_ -> panic "Cryptol.TypeCheck.tcExpr"
|
||||||
( "Multiple declarations when check expression:"
|
( "Multiple declarations when check expression:"
|
||||||
: map show res
|
: map show res
|
||||||
|
@ -258,12 +258,16 @@ groupDecls dg = case dg of
|
|||||||
|
|
||||||
data Decl = Decl { dName :: QName
|
data Decl = Decl { dName :: QName
|
||||||
, dSignature :: Schema
|
, dSignature :: Schema
|
||||||
, dDefinition :: Expr
|
, dDefinition :: DeclDef
|
||||||
, dPragmas :: [Pragma]
|
, dPragmas :: [Pragma]
|
||||||
, dInfix :: !Bool
|
, dInfix :: !Bool
|
||||||
, dFixity :: Maybe Fixity
|
, dFixity :: Maybe Fixity
|
||||||
} deriving (Show)
|
} deriving (Show)
|
||||||
|
|
||||||
|
data DeclDef = DPrim
|
||||||
|
| DExpr Expr
|
||||||
|
deriving (Show)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
@ -875,6 +879,10 @@ instance PP (WithNames Decl) where
|
|||||||
) $$
|
) $$
|
||||||
pp dName <+> text "=" <+> ppWithNames nm dDefinition
|
pp dName <+> text "=" <+> ppWithNames nm dDefinition
|
||||||
|
|
||||||
|
instance PP (WithNames DeclDef) where
|
||||||
|
ppPrec _ (WithNames DPrim _) = text "<primitive>"
|
||||||
|
ppPrec _ (WithNames (DExpr e) nm) = ppWithNames nm e
|
||||||
|
|
||||||
instance PP Decl where
|
instance PP Decl where
|
||||||
ppPrec = ppWithNamesPrec IntMap.empty
|
ppPrec = ppWithNamesPrec IntMap.empty
|
||||||
|
|
||||||
|
@ -567,7 +567,10 @@ inferCArm armNum (m : ms) =
|
|||||||
-- be unaffected.
|
-- be unaffected.
|
||||||
inferBinds :: Bool -> Bool -> [P.Bind] -> InferM [Decl]
|
inferBinds :: Bool -> Bool -> [P.Bind] -> InferM [Decl]
|
||||||
inferBinds isTopLevel isRec binds =
|
inferBinds isTopLevel isRec binds =
|
||||||
mdo let exprMap = Map.fromList [ (x,inst (EVar x) (dDefinition b))
|
mdo let dExpr (DExpr e) = e
|
||||||
|
dExpr DPrim = panic "[TypeCheck]" [ "primitive in a recursive group" ]
|
||||||
|
|
||||||
|
exprMap = Map.fromList [ (x,inst (EVar x) (dExpr (dDefinition b)))
|
||||||
| b <- genBs, let x = dName b ] -- REC.
|
| b <- genBs, let x = dName b ] -- REC.
|
||||||
|
|
||||||
inst e (ETAbs x e1) = inst (ETApp e (TVar (tpVar x))) e1
|
inst e (ETAbs x e1) = inst (ETApp e (TVar (tpVar x))) e1
|
||||||
@ -647,7 +650,9 @@ simpBind d =
|
|||||||
case simpTypeMaybe t of
|
case simpTypeMaybe t of
|
||||||
Nothing -> d
|
Nothing -> d
|
||||||
Just t1 -> d { dSignature = Forall as qs t1
|
Just t1 -> d { dSignature = Forall as qs t1
|
||||||
, dDefinition = castUnder t1 (dDefinition d)
|
, dDefinition = case dDefinition d of
|
||||||
|
DPrim -> DPrim
|
||||||
|
DExpr e -> DExpr (castUnder t1 e)
|
||||||
}
|
}
|
||||||
where
|
where
|
||||||
-- Assumes the quantifiers match
|
-- Assumes the quantifiers match
|
||||||
@ -715,7 +720,9 @@ generalize bs0 gs0 =
|
|||||||
qs = map (apSubst su) here
|
qs = map (apSubst su) here
|
||||||
|
|
||||||
genE e = foldr ETAbs (foldr EProofAbs (apSubst su e) qs) asPs
|
genE e = foldr ETAbs (foldr EProofAbs (apSubst su e) qs) asPs
|
||||||
genB d = d { dDefinition = genE (dDefinition d)
|
genB d = d { dDefinition = case dDefinition d of
|
||||||
|
DExpr e -> DExpr (genE e)
|
||||||
|
DPrim -> DPrim
|
||||||
, dSignature = Forall asPs qs
|
, dSignature = Forall asPs qs
|
||||||
$ apSubst su $ sType $ dSignature d
|
$ apSubst su $ sType $ dSignature d
|
||||||
}
|
}
|
||||||
@ -725,27 +732,55 @@ generalize bs0 gs0 =
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
checkMonoB :: P.Bind -> Type -> InferM Decl
|
checkMonoB :: P.Bind -> Type -> InferM Decl
|
||||||
checkMonoB b t =
|
checkMonoB b t =
|
||||||
inRangeMb (getLoc b) $
|
inRangeMb (getLoc b) $
|
||||||
do e1 <- checkFun (pp (thing (P.bName b))) (P.bParams b) (P.bDef b) t
|
case thing (P.bDef b) of
|
||||||
let f = thing (P.bName b)
|
|
||||||
return Decl { dName = f
|
P.DPrim ->
|
||||||
, dSignature = Forall [] [] t
|
return Decl { dName = thing (P.bName b)
|
||||||
, dDefinition = e1
|
, dSignature = Forall [] [] t
|
||||||
, dPragmas = P.bPragmas b
|
, dDefinition = DPrim
|
||||||
, dInfix = P.bInfix b
|
, dPragmas = P.bPragmas b
|
||||||
, dFixity = P.bFixity b
|
, dInfix = P.bInfix b
|
||||||
}
|
, dFixity = P.bFixity b
|
||||||
|
}
|
||||||
|
|
||||||
|
P.DExpr e ->
|
||||||
|
do e1 <- checkFun (pp (thing (P.bName b))) (P.bParams b) e t
|
||||||
|
let f = thing (P.bName b)
|
||||||
|
return Decl { dName = f
|
||||||
|
, dSignature = Forall [] [] t
|
||||||
|
, dDefinition = DExpr e1
|
||||||
|
, dPragmas = P.bPragmas b
|
||||||
|
, dInfix = P.bInfix b
|
||||||
|
, dFixity = P.bFixity b
|
||||||
|
}
|
||||||
|
|
||||||
-- XXX: Do we really need to do the defaulting business in two different places?
|
-- XXX: Do we really need to do the defaulting business in two different places?
|
||||||
checkSigB :: P.Bind -> (Schema,[Goal]) -> InferM Decl
|
checkSigB :: P.Bind -> (Schema,[Goal]) -> InferM Decl
|
||||||
checkSigB b (Forall as asmps0 t0, validSchema) =
|
checkSigB b (Forall as asmps0 t0, validSchema) = case thing (P.bDef b) of
|
||||||
|
|
||||||
|
-- XXX what should we do with validSchema in this case?
|
||||||
|
P.DPrim
|
||||||
|
| not (null validSchema) ->
|
||||||
|
return Decl
|
||||||
|
{ dName = thing (P.bName b)
|
||||||
|
, dSignature = Forall as asmps0 t0
|
||||||
|
, dDefinition = DPrim
|
||||||
|
, dPragmas = P.bPragmas b
|
||||||
|
, dInfix = P.bInfix b
|
||||||
|
, dFixity = P.bFixity b
|
||||||
|
}
|
||||||
|
|
||||||
|
| otherwise ->
|
||||||
|
panic "[TypeCheck]" [ "invalid primitive schema", show b, show validSchema ]
|
||||||
|
|
||||||
|
P.DExpr e0 ->
|
||||||
inRangeMb (getLoc b) $
|
inRangeMb (getLoc b) $
|
||||||
withTParams as $
|
withTParams as $
|
||||||
do (e1,cs0) <- collectGoals $
|
do (e1,cs0) <- collectGoals $
|
||||||
do e1 <- checkFun (pp (thing (P.bName b))) (P.bParams b) (P.bDef b) t0
|
do e1 <- checkFun (pp (thing (P.bName b))) (P.bParams b) e0 t0
|
||||||
() <- simplifyAllConstraints -- XXX: using `asmps` also...
|
() <- simplifyAllConstraints -- XXX: using `asmps` also...
|
||||||
return e1
|
return e1
|
||||||
cs <- applySubst cs0
|
cs <- applySubst cs0
|
||||||
@ -792,7 +827,7 @@ checkSigB b (Forall as asmps0 t0, validSchema) =
|
|||||||
return Decl
|
return Decl
|
||||||
{ dName = thing (P.bName b)
|
{ dName = thing (P.bName b)
|
||||||
, dSignature = Forall as asmps t
|
, dSignature = Forall as asmps t
|
||||||
, dDefinition = foldr ETAbs (foldr EProofAbs e2 asmps) as
|
, dDefinition = DExpr (foldr ETAbs (foldr EProofAbs e2 asmps) as)
|
||||||
, dPragmas = P.bPragmas b
|
, dPragmas = P.bPragmas b
|
||||||
, dInfix = P.bInfix b
|
, dInfix = P.bInfix b
|
||||||
, dFixity = P.bFixity b
|
, dFixity = P.bFixity b
|
||||||
|
@ -356,12 +356,19 @@ convertible t1 t2 = go t1 t2
|
|||||||
-- | Check a declaration. The boolean indicates if we should check the siganture
|
-- | Check a declaration. The boolean indicates if we should check the siganture
|
||||||
checkDecl :: Bool -> Decl -> TcM (QName, Schema)
|
checkDecl :: Bool -> Decl -> TcM (QName, Schema)
|
||||||
checkDecl checkSig d =
|
checkDecl checkSig d =
|
||||||
do let s = dSignature d
|
case dDefinition d of
|
||||||
when checkSig $ checkSchema s
|
|
||||||
s1 <- exprSchema (dDefinition d)
|
DPrim ->
|
||||||
unless (same s s1) $
|
do when checkSig $ checkSchema $ dSignature d
|
||||||
reportError $ TypeMismatch s s1
|
return (dName d, dSignature d)
|
||||||
return (dName d, s)
|
|
||||||
|
DExpr e ->
|
||||||
|
do let s = dSignature d
|
||||||
|
when checkSig $ checkSchema s
|
||||||
|
s1 <- exprSchema e
|
||||||
|
unless (same s s1) $
|
||||||
|
reportError $ TypeMismatch s s1
|
||||||
|
return (dName d, s)
|
||||||
|
|
||||||
checkDeclGroup :: DeclGroup -> TcM [(QName, Schema)]
|
checkDeclGroup :: DeclGroup -> TcM [(QName, Schema)]
|
||||||
checkDeclGroup dg =
|
checkDeclGroup dg =
|
||||||
|
@ -236,6 +236,10 @@ instance TVars Decl where
|
|||||||
, dDefinition = apSubst su (dDefinition d)
|
, dDefinition = apSubst su (dDefinition d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance TVars DeclDef where
|
||||||
|
apSubst su (DExpr e) = DExpr (apSubst su e)
|
||||||
|
apSubst _ DPrim = DPrim
|
||||||
|
|
||||||
instance TVars Module where
|
instance TVars Module where
|
||||||
apSubst su m = m { mDecls = apSubst su (mDecls m) }
|
apSubst su m = m { mDecls = apSubst su (mDecls m) }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user