hssqlppp-0.1.0: Database/HsSqlPpp/AstInternals/TypeChecking/Misc.ag
{-
Copyright 2009 Jake Wheat
Contains bit and pieces of type checking which don't fit anywhere else
================================================================================
= type names
Types with type modifiers (called PrecTypeName here, to be changed),
are not supported at the moment.
-}
ATTR TypeName [||namedType : Type]
SEM TypeName
| SimpleTypeName ArrayTypeName SetOfTypeName PrecTypeName
lhs.namedType = tpeToT @loc.tpe
lhs.annotatedTree = updateAnnotation
((map TypeErrorA $ getErrors @loc.tpe) ++)
@loc.backTree
SEM TypeName
| SimpleTypeName
loc.tpe = envLookupType @lhs.env $ canonicalizeTypeName @tn
loc.backTree = SimpleTypeName @ann @tn
| ArrayTypeName
loc.tpe = dependsOnRTpe [@typ.namedType] $ Right $ ArrayType @typ.namedType
loc.backTree = ArrayTypeName @ann @typ.annotatedTree
| SetOfTypeName
loc.tpe = dependsOnRTpe [@typ.namedType] $ Right $ SetOfType @typ.namedType
loc.backTree = SetOfTypeName @ann @typ.annotatedTree
| PrecTypeName
loc.tpe = envLookupType @lhs.env $ canonicalizeTypeName @tn
loc.backTree = PrecTypeName @ann @tn @prec
{-
================================================================================
= generic node types
-}
--expression list and list list - just collect up the types
ATTR ExpressionList [||typeList : {[Type]}]
SEM ExpressionList
| Cons lhs.typeList = getTypeAnnotation @hd.annotatedTree : @tl.typeList
| Nil lhs.typeList = []
ATTR ExpressionListList [||typeListList : {[[Type]]}]
SEM ExpressionListList
| Cons lhs.typeListList = @hd.typeList : @tl.typeListList
| Nil lhs.typeListList = []
-- stringlist: collect the strings
ATTR StringList [||strings : {[String]}]
SEM StringList
| Cons lhs.strings = @hd : @tl.strings
| Nil lhs.strings = []
-- maybe bool expression: if present, then check its type is bool
SEM MaybeBoolExpression
| Just
lhs.annotatedTree =
if getTypeAnnotation @just.annotatedTree `notElem` [typeBool, TypeCheckFailed]
then Just $ updateAnnotation ((TypeErrorA ExpressionMustBeBool) :)
@just.annotatedTree
else Just $ @just.annotatedTree
{
{-
================================================================================
= couple of small utils
I think this should be alright, an identifier referenced in an
expression can only have zero or one dot in it.
-}
splitIdentifier :: String -> (String,String)
splitIdentifier s = let (a,b) = span (/= '.') s
in if b == ""
then ("", a)
else (a,tail b)
{-
helper to make adding annotations a bit easier
-}
annTypesAndErrors :: Data a => a -> Type -> [TypeError]
-> Maybe [AnnotationElement] -> a
annTypesAndErrors item nt errs add =
updateAnnotation modifier item
where
modifier = (([TypeAnnotation nt] ++ fromMaybe [] add ++
map TypeErrorA errs) ++)
}