module FreeC.Test.Environment
( renameAndAddTestEntry
, defineTestTypeVar
, defineTestTypeSyn
, defineTestTypeCon
, defineTestCon
, defineTestVar
, defineTestFunc
, definePartialTestFunc
, defineStrictTestFunc
, definePartialStrictTestFunc
) where
import Data.Maybe ( fromJust )
import qualified FreeC.Backend.Coq.Syntax as Coq
import FreeC.Environment.Entry
import FreeC.Environment.Renamer
import FreeC.IR.Reference
import FreeC.IR.SrcSpan
import qualified FreeC.IR.Syntax as IR
import FreeC.LiftedIR.Effect
import FreeC.Monad.Converter
import FreeC.Monad.Reporter
import FreeC.Test.Parser
renameAndAddTestEntry :: EnvEntry -> Converter String
renameAndAddTestEntry entry = do
entry' <- renameAndAddTestEntry' entry
return (fromJust (Coq.unpackQualid (entryIdent entry')))
renameAndAddTestEntry' :: EnvEntry -> Converter EnvEntry
renameAndAddTestEntry' = renameAndAddEntry
defineTestTypeVar :: String -> Converter String
defineTestTypeVar nameStr = do
name <- parseTestQName nameStr
renameAndAddTestEntry TypeVarEntry
{ entrySrcSpan = NoSrcSpan
, entryName = name
, entryIdent = undefined
, entryAgdaIdent = undefined
}
defineTestTypeSyn :: String -> [String] -> String -> Converter String
defineTestTypeSyn nameStr typeArgs typeStr = do
name <- parseTestQName nameStr
typeExpr <- parseTestType typeStr
renameAndAddTestEntry TypeSynEntry
{ entrySrcSpan = NoSrcSpan
, entryArity = length typeArgs
, entryTypeArgs = typeArgs
, entryTypeSyn = typeExpr
, entryName = name
, entryIdent = undefined
, entryAgdaIdent = undefined
}
defineTestTypeCon :: String -> Int -> [String] -> Converter String
defineTestTypeCon nameStr arity consNameStrs = do
name <- parseTestQName nameStr
consNames <- mapM parseTestQName consNameStrs
renameAndAddTestEntry DataEntry
{ entrySrcSpan = NoSrcSpan
, entryArity = arity
, entryName = name
, entryConsNames = consNames
, entryIdent = undefined
, entryAgdaIdent = undefined
}
defineTestCon :: String -> Int -> String -> Converter (String, String)
defineTestCon nameStr arity typeStr = do
name <- parseTestQName nameStr
IR.TypeScheme _ typeArgs typeExpr <- parseExplicitTestTypeScheme typeStr
let (argTypes, returnType) = IR.splitFuncType typeExpr arity
entry <- renameAndAddTestEntry' ConEntry
{ entrySrcSpan = NoSrcSpan
, entryArity = arity
, entryTypeArgs = map IR.typeVarDeclIdent typeArgs
, entryArgTypes = argTypes
, entryReturnType = returnType
, entryName = name
, entryIdent = undefined
, entryAgdaIdent = undefined
, entrySmartIdent = undefined
, entryAgdaSmartIdent = undefined
}
let (Just ident') = Coq.unpackQualid (entryIdent entry)
(Just smartIdent') = Coq.unpackQualid (entrySmartIdent entry)
return (ident', smartIdent')
defineTestVar :: String -> Converter String
defineTestVar nameStr = do
name <- parseTestQName nameStr
renameAndAddTestEntry VarEntry
{ entrySrcSpan = NoSrcSpan
, entryIsPure = False
, entryName = name
, entryIdent = undefined
, entryAgdaIdent = undefined
, entryType = Nothing
}
defineTestFunc :: String -> Int -> String -> Converter String
defineTestFunc nameStr arity = defineTestFunc' False (replicate arity False)
nameStr arity
defineTestFunc'
:: Bool -> [Bool] -> String -> Int -> String -> Converter String
defineTestFunc' partial areStrict nameStr arity typeStr = do
name <- parseTestQName nameStr
IR.TypeScheme _ typeArgs typeExpr <- parseExplicitTestTypeScheme typeStr
let (argTypes, returnType) = IR.splitFuncType typeExpr arity
renameAndAddTestEntry FuncEntry
{ entrySrcSpan = NoSrcSpan
, entryArity = arity
, entryTypeArgs = map IR.typeVarDeclIdent typeArgs
, entryArgTypes = argTypes
, entryStrictArgs = areStrict
, entryReturnType = returnType
, entryNeedsFreeArgs = True
, entryEncapsulatesEffects = False
, entryEffects = [Partiality | partial]
, entryName = name
, entryIdent = undefined
, entryAgdaIdent = undefined
}
definePartialTestFunc :: String -> Int -> String -> Converter String
definePartialTestFunc nameStr arity = defineTestFunc' True
(replicate arity False) nameStr arity
defineStrictTestFunc :: String -> [Bool] -> String -> Converter String
defineStrictTestFunc nameStr areStrict = defineTestFunc' False areStrict nameStr
(length areStrict)
definePartialStrictTestFunc :: String -> [Bool] -> String -> Converter String
definePartialStrictTestFunc nameStr areStrict = defineTestFunc' True areStrict
nameStr (length areStrict)
parseExplicitTestTypeScheme :: String -> Converter IR.TypeScheme
parseExplicitTestTypeScheme input = do
typeScheme <- parseTestTypeScheme input
if not (null (freeTypeVars typeScheme)) && take 7 input /= "forall."
then reportFatal
$ Message NoSrcSpan Internal
$ "Type signatures in environment entries should not contain any free"
++ "type variables, but got `"
++ input
++ "`. Write `forall. "
++ input
++ "` if you really intended to do this."
else return typeScheme