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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
module Language.Fiddle.Internal.UnitInterface where
import Data.Aeson
import Data.List.NonEmpty (NonEmpty)
import Data.Text
import Data.Word
import GHC.Generics
import Language.Fiddle.Internal.Scopes (Scope)
import qualified Language.Fiddle.Internal.Scopes as Scopes
import Language.Fiddle.Types (SourceSpan)
data InternalDirectiveExpression
= InternalDirectiveExpressionNumber String
| InternalDirectiveExpressionString String
deriving (Generic, ToJSON, FromJSON, Show, Eq, Ord)
-- | Represents a compiler directive that provides configuration for the compiler
-- or its various backends. Directives can adjust the behavior of the compiler
-- or influence the code generation in the backends.
data InternalDirective = InternalDirective
{ -- | Specifies the backend that this directive is intended for. If 'Nothing',
-- the directive applies globally across all backends.
directiveBackend :: Maybe String,
-- | The key or name of the directive. This identifies the directive's
-- purpose, such as enabling specific features or setting options.
directiveKey :: String,
-- | The optional value associated with this directive. Some directives
-- may not require a value (e.g., flags), in which case this field is 'Nothing'.
directiveValue :: Maybe InternalDirectiveExpression
}
deriving (Generic, ToJSON, FromJSON, Show, Eq, Ord)
-- | Metadata about an exported value. This includes things like the source
-- location, doc comments and compiler directives associated with the exported
-- symbol.
data Metadata = Metadata
{ -- | Fully-qualified path the the element.
metadataFullyQualifiedPath :: NonEmpty String,
-- | Source location for the exported symbol.
metadataSourceSpan :: SourceSpan,
-- | Doc comment associated with the symbol.
metadataDocComment :: Text,
-- | List of directives associated with this exported symbol.
metadataDirectives :: [InternalDirective]
}
deriving (Generic, ToJSON, FromJSON, Show, Eq, Ord)
-- | Contains a datastructure which represents a FiddleUnit.
--
-- These datastructures contain the exported symobls of a fiddle unit and it's
-- direct dependencies.
data UnitInterface where
UnitInterface ::
{ rootScope :: Scope String (Metadata, ExportedDecl),
dependencies :: [FilePath]
} ->
UnitInterface
deriving (Generic, Eq, Ord, Show, FromJSON, ToJSON)
insert :: (ExportableDecl d) => d -> UnitInterface -> UnitInterface
insert decl (UnitInterface sc deps) =
let metadata = getMetadata decl
path = metadataFullyQualifiedPath metadata
in UnitInterface (Scopes.insertScope path (metadata, toExportedDecl decl) sc) deps
singleton :: (ExportableDecl d) => d -> UnitInterface
singleton decl =
let path = metadataFullyQualifiedPath (getMetadata decl)
metadata = getMetadata decl
in UnitInterface (Scopes.singleton path (metadata, toExportedDecl decl)) []
instance Semigroup UnitInterface where
(<>) (UnitInterface s d) (UnitInterface s1 d1) =
UnitInterface (s <> s1) (d <> d1)
instance Monoid UnitInterface where
mempty = UnitInterface mempty mempty
-- | Represents an exported package declaration in the syntax tree.
-- This is a higher-level abstraction with metadata detailing the package.
data ExportedPackageDecl where
ExportedPackageDecl ::
{ -- | Metadata associated with the package.
exportedPackageMetadata :: Metadata
} ->
ExportedPackageDecl
deriving (Show, Eq, Ord, Generic, FromJSON, ToJSON)
-- | Represents an exported location declaration in the syntax tree.
-- Contains metadata and the actual integer value of the location.
data ExportedLocationDecl where
ExportedLocationDecl ::
{ -- | Metadata associated with the location.
exportedLocationMetadata :: Metadata,
-- | The value of the location as an integer.
exportedLocationValue :: Integer
} ->
ExportedLocationDecl
deriving (Show, Eq, Ord, Generic, FromJSON, ToJSON)
-- | Represents an exported bits declaration in the syntax tree.
-- Contains metadata and the size of the bits in a Word32 format.
data ExportedBitsDecl where
ExportedBitsDecl ::
{ -- | Metadata associated with the bits declaration.
exportedBitsDeclMetadata :: Metadata,
-- | The size of the bits in this declaration.
exportedBitsDeclSizeBits :: Word32
} ->
ExportedBitsDecl
deriving (Show, Eq, Ord, Generic, FromJSON, ToJSON)
-- | Represents an exported type declaration in the syntax tree.
-- Contains metadata and the size of the type in bytes.
data ExportedTypeDecl where
ExportedTypeDecl ::
{ -- | Metadata associated with the type declaration.
exportedTypeDeclMetadata :: Metadata,
-- | The size of the type in bytes.
exportedTypeDeclSizeBytes :: Word32
} ->
ExportedTypeDecl
deriving (Show, Eq, Ord, Generic, FromJSON, ToJSON)
data ReferencedObjectType where
ReferencedObjectType ::
{objectTypeReference :: String} -> ReferencedObjectType
ArrayObjectType ::
{ arrayObjectTypeType :: ReferencedObjectType,
arryObjecttTypeNumber :: Word32
} ->
ReferencedObjectType
deriving (Show, Eq, Ord, Generic, FromJSON, ToJSON)
-- | Represents an exported object declaration in the syntax tree.
-- This includes metadata, location, and the type of the object.
data ExportedObjectDecl where
ExportedObjectDecl ::
{ -- | Metadata associated with the object declaration.
exportedObjectDeclMetadata :: Metadata,
-- | The memory location of the object.
exportedObjectDeclLocation :: Integer,
-- | The type of the object as a string.
exportedObjectDeclType :: ReferencedObjectType
} ->
ExportedObjectDecl
deriving (Show, Eq, Ord, Generic, FromJSON, ToJSON)
-- | A typeclass for converting various exported declarations into the
-- generalized 'ExportedDecl' type. This allows treating different exported
-- declarations uniformly in the compilation process.
class ExportableDecl a where
toExportedDecl :: a -> ExportedDecl
fromExportedDecl :: ExportedDecl -> Maybe a
getMetadata :: a -> Metadata
-- Instances of 'ExportableDecl' to convert specific exported declaration types
-- into the generalized 'ExportedDecl' type.
instance ExportableDecl ExportedPackageDecl where
toExportedDecl = ExportedPackage
fromExportedDecl = \case
ExportedPackage x -> Just x
_ -> Nothing
getMetadata = exportedPackageMetadata
instance ExportableDecl ExportedLocationDecl where
toExportedDecl = ExportedLocation
fromExportedDecl = \case
ExportedLocation x -> Just x
_ -> Nothing
getMetadata = exportedLocationMetadata
instance ExportableDecl ExportedBitsDecl where
toExportedDecl = ExportedBits
fromExportedDecl = \case
ExportedBits x -> Just x
_ -> Nothing
getMetadata = exportedBitsDeclMetadata
instance ExportableDecl ExportedTypeDecl where
toExportedDecl = ExportedType
fromExportedDecl = \case
ExportedType x -> Just x
_ -> Nothing
getMetadata = exportedTypeDeclMetadata
instance ExportableDecl ExportedObjectDecl where
toExportedDecl = ExportedObject
fromExportedDecl = \case
ExportedObject x -> Just x
_ -> Nothing
getMetadata = exportedObjectDeclMetadata
-- | A generalized representation of different exported declarations.
-- This data type allows for a uniform way to handle various exportable
-- syntax tree elements (e.g., packages, locations, bits, types, objects).
data ExportedDecl where
ExportedPackage :: ExportedPackageDecl -> ExportedDecl
ExportedLocation :: ExportedLocationDecl -> ExportedDecl
ExportedBits :: ExportedBitsDecl -> ExportedDecl
ExportedType :: ExportedTypeDecl -> ExportedDecl
ExportedObject :: ExportedObjectDecl -> ExportedDecl
deriving (Show, Eq, Ord, Generic, FromJSON, ToJSON)
|