import TargetMapping
import Text.PrettyPrint
import Data.List (foldl')
-import Data.Map as Map (Map, lookup, insertWithKey, assocs, empty)
+import Data.Map (Map)
+import qualified Data.Map as Map
+import Data.Set (Set)
+import qualified Data.Set as Set
-- The top-level types
data BaseType =
data OFL = OFL {
symbols :: SymbolTable,
+ internalSymbols :: Set String,
assignments :: [Assignment],
targetMappings :: MappingTable,
outputFunction :: FortranFunction
toDoc ofl = vcat [symbolDoc, assignmentsDoc, targetMappingsDoc, outputFunctionDoc]
where
symbolDoc = text "Symbol table:"
- $$ nest 1 (vcat [text $ show x | x <- assocs $ symbols ofl])
+ $$ nest 1 (vcat [text $ show x | x <- Map.assocs $ symbols ofl])
assignmentsDoc = text "Assignments: "
$$ nest 1 (vcat [text $ show x | x <- assignments ofl])
targetMappingsDoc = text "Target properties: "
- $$ nest 1 (vcat [text $ show x | x <- assocs $ targetMappings ofl])
+ $$ nest 1 (vcat [text $ show x | x <- Map.assocs $ targetMappings ofl])
outputFunctionDoc = text "OutputFunction:"
$$ nest 1 (text $ show $ outputFunction ofl)
-- Symbol table manipulators
addValueDeclaration :: OFL -> String -> BaseType -> [IndexType] -> OFL
addValueDeclaration ofl name baseType indices = ofl { symbols = symbols' }
- where symbols' = insertWithKey errorOnDuplicate name (ValueTag baseType indices) (symbols ofl)
+ where symbols' = Map.insertWithKey errorOnDuplicate name (ValueTag baseType indices) (symbols ofl)
addTargetMapping :: OFL -> String -> TargetType -> OFL
-addTargetMapping ofl name properties = ofl { targetMappings = targetMappings' }
- where targetMappings' = insertWithKey errorOnDuplicate name properties (targetMappings ofl)
+addTargetMapping ofl name properties = result where
+ ofl' = ofl { targetMappings = targetMappings' }
+ targetMappings' = Map.insertWithKey errorOnDuplicate name properties (targetMappings ofl)
+ result = if isInternalSymbol ofl name
+ then error $ "error: target binding " ++ show name ++ " conflicts with internally generated identifer."
+ else ofl'
addIndexDeclaration :: OFL -> String -> IndexType -> OFL
addIndexDeclaration ofl name indexType = ofl { symbols = symbols' }
- where symbols' = insertWithKey errorOnDuplicate name (IndexTag indexType) (symbols ofl)
+ where symbols' = Map.insertWithKey errorOnDuplicate name (IndexTag indexType) (symbols ofl)
+
+addInternalIndexDeclaration :: OFL -> String -> IndexType -> OFL
+addInternalIndexDeclaration ofl name indexType = ofl'' where
+ ofl' = addIndexDeclaration ofl name indexType
+ internalSymbols' = Set.insert name (internalSymbols ofl)
+ ofl'' = ofl' { internalSymbols = internalSymbols' }
findUniqueName :: OFL -> String -> String
findUniqueName ofl candidate = head [n | n <- generateSuffixed, not $ hasSymbol ofl n]
Just _ -> True
_ -> False
+isInternalSymbol :: OFL -> String -> Bool
+isInternalSymbol ofl ident = Set.member ident (internalSymbols ofl)
+
hasValue :: OFL -> String -> Bool
hasValue ofl name = case Map.lookup name (symbols ofl) of
Just (ValueTag _ _) -> True
emptyOFL = OFL {
assignments = [],
symbols = Map.empty,
+ internalSymbols = Set.empty,
targetMappings = Map.empty,
outputFunction = error "Output function not defined"
}