summaryrefslogtreecommitdiff
path: root/src/Language/Fiddle/Compiler/Qualification.hs
blob: 27c0911e453f8949015bf3736b931a4872c25000 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
-- | Qualification compilation phase.
--
-- The qualification phase is responsible for resolving all type references in
-- the AST to their fully-qualified counterparts. This process involves
-- replacing unqualified references with their fully-qualified names and
-- attaching the necessary metadata to each reference. This enriched information
-- is then available for use in later stages of the compilation pipeline.
--
-- In this phase, symbol resolution statements (such as 'using' statements) are
-- removed, as they become unnecessary once references are fully qualified.
module Language.Fiddle.Compiler.Qualification (qualificationPhase) where

import Control.Monad (forM)
import Control.Monad.Identity
import Data.Foldable (foldlM)
import Data.Maybe (catMaybes)
import Data.Word
import Language.Fiddle.Ast
import Language.Fiddle.Compiler
import Language.Fiddle.Compiler.ConsistencyCheck
import Language.Fiddle.Internal.Scopes
import Language.Fiddle.Internal.UnitInterface
import Language.Fiddle.Types

type CurrentStage = Expanded

data GlobalState = GlobalState
  { globalScope :: Scope String (Either SizeBits SizeBytes),
    fileDependencies :: [FilePath],
    unitInterface :: UnitInterface
  }

newtype LocalState = LocalState (ScopePath String)

type I = Identity

type Annot = Commented SourceSpan

type SizeBits = Word32

type SizeBytes = Word32

instance CompilationStage Expanded where
  type StageAfter Expanded = Qualified
  type StageMonad Expanded = Compile GlobalState
  type StageState Expanded = LocalState
  type StageFunctor Expanded = Identity
  type StageAnnotation Expanded = Commented SourceSpan

qualificationPhase :: CompilationPhase Expanded Qualified
qualificationPhase =
  pureCompilationPhase $
    fmap snd
      . subCompile (GlobalState mempty mempty mempty)
      . advanceStage (LocalState mempty)

deriving instance AdvanceStage CurrentStage ObjTypeBody

deriving instance AdvanceStage CurrentStage DeferredRegisterBody

deriving instance AdvanceStage CurrentStage RegisterBody

deriving instance AdvanceStage CurrentStage AnonymousBitsType

deriving instance AdvanceStage CurrentStage ImportStatement

deriving instance AdvanceStage CurrentStage BitType

deriving instance AdvanceStage CurrentStage EnumBody

deriving instance AdvanceStage CurrentStage EnumConstantDecl

deriving instance AdvanceStage CurrentStage RegisterBitsDecl

deriving instance AdvanceStage CurrentStage ObjTypeDecl

deriving instance AdvanceStage CurrentStage Expression

instance AdvanceStage CurrentStage RegisterBitsTypeRef where
  advanceStage = undefined

instance AdvanceStage CurrentStage ObjType where
  advanceStage = undefined

deriving instance (AdvanceStage CurrentStage t) => AdvanceStage CurrentStage (Directed t)

instance AdvanceStage CurrentStage PackageBody where
  advanceStage localState (PackageBody decls annot) =
    PackageBody <$> advanceFiddleDecls localState decls <*> pure annot

instance AdvanceStage CurrentStage FiddleUnit where
  advanceStage localState (FiddleUnit () decls annot) =
    FiddleUnit () <$> advanceFiddleDecls localState decls <*> pure annot

advanceFiddleDecls ::
  LocalState ->
  [TreeType (Directed FiddleDecl) CurrentStage] ->
  (StageMonad CurrentStage)
    [TreeType (Directed FiddleDecl) Qualified]
advanceFiddleDecls (LocalState scopePath) decls = fmap (reverse . fst) $ do
  foldlM
    ( \(declsRet, scopePath') -> \case
        Directed {directedSubtree = UsingDecl {usingName = name}} ->
          return (declsRet, addUsingPath (nameToList name) scopePath')
    )
    ([], scopePath)
    decls