summaryrefslogtreecommitdiff
path: root/src/Language/Fiddle/Compiler/ConsistencyCheck.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Language/Fiddle/Compiler/ConsistencyCheck.hs')
-rw-r--r--src/Language/Fiddle/Compiler/ConsistencyCheck.hs134
1 files changed, 111 insertions, 23 deletions
diff --git a/src/Language/Fiddle/Compiler/ConsistencyCheck.hs b/src/Language/Fiddle/Compiler/ConsistencyCheck.hs
index 908db52..abfbb9b 100644
--- a/src/Language/Fiddle/Compiler/ConsistencyCheck.hs
+++ b/src/Language/Fiddle/Compiler/ConsistencyCheck.hs
@@ -23,7 +23,7 @@ import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NonEmpty
import Data.Map (Map)
import qualified Data.Map as Map
-import Data.Maybe (fromMaybe)
+import Data.Maybe (fromMaybe, mapMaybe)
import qualified Data.Set as Set
import qualified Data.Text as Text
import Data.Void
@@ -33,8 +33,8 @@ import GHC.TypeLits
import Language.Fiddle.Ast
import Language.Fiddle.Compiler
import Language.Fiddle.Internal.Scopes
-import Language.Fiddle.Internal.UnitInterface
-import Language.Fiddle.Types (Commented (unCommented), SourceSpan)
+import Language.Fiddle.Internal.UnitInterface as UnitInterface
+import Language.Fiddle.Types (Comment (DocComment), Commented (Commented, unCommented), SourceSpan)
import Text.Printf (printf)
import Prelude hiding (unzip)
@@ -57,14 +57,14 @@ type SizeBytes = Word32
consistencyCheckPhase ::
CompilationPhase Expanded Checked
consistencyCheckPhase =
- CompilationPhase (pure ()) (\_ _ -> return ()) (\_ _ -> checkConsistency)
+ CompilationPhase (pure ()) (\_ _ -> return ([], Just ())) (\_ _ -> checkConsistency)
checkConsistency ::
FiddleUnit Expanded I Annot ->
Compile () (FiddleUnit Checked I Annot)
checkConsistency =
fmap snd
- . subCompile (GlobalState mempty mempty)
+ . subCompile (GlobalState mempty mempty mempty)
. advanceStage (LocalState mempty)
instance CompilationStage Checked where
@@ -81,7 +81,11 @@ instance CompilationStage Expanded where
type StageFunctor Expanded = Identity
type StageAnnotation Expanded = Commented SourceSpan
-instance AdvanceStage Expanded FiddleUnit
+instance AdvanceStage Expanded FiddleUnit where
+ advanceStage localState (FiddleUnit _ decls a) = do
+ decls' <- mapM (advanceStage localState) decls
+ intf <- gets unitInterface
+ return $ FiddleUnit intf decls' a
-- advanceStage localState (FiddleUnit decls _ annot) = do
@@ -107,7 +111,41 @@ deriving instance AdvanceStage Expanded EnumConstantDecl
deriving instance AdvanceStage Expanded PackageBody
-deriving instance AdvanceStage Expanded ImportStatement
+instance AdvanceStage Expanded ImportStatement where
+ modifyState
+ ( ImportStatement
+ { importInterface =
+ ( UnitInterface
+ { rootScope = unitScope,
+ dependencies = importDependencies
+ }
+ )
+ }
+ )
+ ls = do
+ modify'
+ ( \s@GlobalState
+ { globalScope = globalScope,
+ unitInterface = unitInterface
+ } ->
+ s
+ { globalScope =
+ unitInterfaceScopeToGlobalScope unitScope <> globalScope,
+ unitInterface =
+ unitInterface
+ { dependencies =
+ importDependencies ++ dependencies unitInterface
+ }
+ }
+ )
+ return ls
+ where
+ unitInterfaceScopeToGlobalScope =
+ fmap
+ ( \(Annotated _ _ exportedValue) -> case exportedValue of
+ ExportedBitsType sz -> Left sz
+ ExportedObjType sz -> Right sz
+ )
deriving instance (AdvanceStage Expanded t) => AdvanceStage Expanded (Directed t)
@@ -119,9 +157,9 @@ instance AdvanceStage Expanded ObjTypeBody where
instance AdvanceStage Expanded FiddleDecl where
modifyState t s = case t of
- (BitsDecl id typ a) -> do
+ (BitsDecl id typ annotation) -> do
typeSize <- getTypeSize typ
- insertTypeSize s id typeSize
+ insertTypeSize annotation s id typeSize
return s
(PackageDecl n _ _) -> do
let strs = nameToList n
@@ -139,6 +177,22 @@ instance AdvanceStage Expanded FiddleDecl where
}
_ -> return s
+ customAdvanceStage t (LocalState scopePath) = case t of
+ (ObjTypeDecl ident (Identity body) annot) -> do
+ (body', size) <- objTypeBodyToStage3 (LocalState scopePath) body 0
+
+ let fullName =
+ NonEmpty.prependList
+ (currentScope scopePath)
+ (NonEmpty.singleton (Text.unpack (identifierName ident)))
+
+ ui <- gets unitInterface
+ let ui' = insertIntoUnitInterface fullName ui annot (ExportedObjType size)
+ modify' $ \gs -> gs {unitInterface = ui'}
+
+ return $ Just $ ObjTypeDecl ident (Identity body') annot
+ _ -> return Nothing
+
nameToList :: Name f a -> [String]
nameToList (Name idents _) = map (\(Identifier (Text.unpack -> s) _) -> s) (toList idents)
@@ -444,9 +498,9 @@ lookupTypeSize (LocalState scopePath) (Name idents a) = do
case results of
-- Successfully resolved to a unique size
- [(_, Right sz)] -> return sz
+ [(_, Left sz)] -> return sz
-- Multiple ambiguous results found
- matches@(_ : _) -> do
+ matches@(_ : _ : _) -> do
-- Generate a list of ambiguous paths for error reporting
let ambiguousPaths =
map
@@ -467,7 +521,7 @@ lookupTypeSize (LocalState scopePath) (Name idents a) = do
compilationFailure
-- No matches found
- _ -> do
+ [] -> do
tell
[ Diagnostic
Error
@@ -528,23 +582,57 @@ getTypeSize (EnumBitType expr (Identity (EnumBody constants _)) ann) = do
diagnosticError :: String -> Annot -> Compile a ()
diagnosticError str a = tell [Diagnostic Error str (unCommented a)]
+diagnosticInfo :: String -> Annot -> Compile a ()
+diagnosticInfo str a = tell [Diagnostic Info str (unCommented a)]
+
+insertIntoUnitInterface path ui (Commented comments srcspan) val =
+ let docComments =
+ mconcat
+ ( mapMaybe
+ ( \com -> do
+ (DocComment txt) <- Just com
+ return txt
+ )
+ comments
+ )
+ in ui
+ { rootScope =
+ insertScope path (Annotated srcspan docComments val) (rootScope ui)
+ }
+
insertTypeSize ::
+ Annot ->
LocalState ->
Identifier f Annot ->
SizeBits ->
Compile GlobalState ()
-insertTypeSize (LocalState scopePath) (Identifier s annot) size = do
+insertTypeSize annot (LocalState scopePath) (Identifier s idannot) size = do
modifyM $
- \state@GlobalState {globalScope = globalScope} ->
- let fullName =
- NonEmpty.prependList
- (currentScope scopePath)
- (NonEmpty.singleton (Text.unpack s))
- in case upsertScope fullName (Right size) globalScope of
- (Just _, _) -> do
- diagnosticError (printf "Duplicate type %s" s) annot
- compilationFailure
- (Nothing, n) -> return $ state {globalScope = n}
+ \state@GlobalState
+ { globalScope = globalScope,
+ unitInterface = unitInterface
+ } ->
+ let fullName =
+ NonEmpty.prependList
+ (currentScope scopePath)
+ (NonEmpty.singleton (Text.unpack s))
+ in case upsertScope fullName (Left size) globalScope of
+ (Just _, _) -> do
+ diagnosticError (printf "Duplicate type %s" s) idannot
+
+ compilationFailure
+ (Nothing, n) ->
+ let unitInterface' =
+ insertIntoUnitInterface
+ fullName
+ unitInterface
+ annot
+ (ExportedBitsType size)
+ in return $
+ state
+ { globalScope = n,
+ unitInterface = unitInterface'
+ }
where
modifyM fn = do
s <- get