summaryrefslogtreecommitdiff
path: root/src/Language/Fiddle/Internal/UnitInterface.hs
blob: b18b98b49ea9906886373045bab2bc7365b7ea89 (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
{-# LANGUAGE OverloadedStrings #-}

module Language.Fiddle.Internal.UnitInterface where

import Data.Aeson
import Data.Text
import Data.Word
import Language.Fiddle.Internal.Scopes (Scope)
import Language.Fiddle.Types (SourceSpan)

data Annotated a = Annotated
  { sourceSpan :: SourceSpan,
    docComment :: Text,
    internal :: a
  }
  deriving (Eq, Ord, Show)

-- | 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 (Annotated ExportedValue),
      dependencies :: [FilePath]
    } ->
    UnitInterface
  deriving (Eq, Ord, Show)

instance Semigroup UnitInterface where
  (<>) (UnitInterface s d) (UnitInterface s1 d1) =
    UnitInterface (s <> s1) (d <> d1)

instance Monoid UnitInterface where
  mempty = UnitInterface mempty mempty

data ExportedValue where
  ExportedBitsType ::
    {exportBitsTypeSize :: Word32} ->
    ExportedValue
  ExportedObjType ::
    {exportObjTypeSize :: Word32} ->
    ExportedValue
  deriving (Show, Eq, Ord)

instance (ToJSON a) => ToJSON (Annotated a) where
  toJSON (Annotated span doc internal) =
    object
      [ "sourceSpan" .= span,
        "docComment" .= doc,
        "internal" .= internal
      ]

instance (FromJSON a) => FromJSON (Annotated a) where
  parseJSON = withObject "Annotated" $ \v ->
    Annotated
      <$> v .: "sourceSpan"
      <*> v .: "docComment"
      <*> v .: "internal"

instance ToJSON UnitInterface where
  toJSON (UnitInterface rootScope dependencies) =
    object
      [ "rootScope" .= rootScope,
        "dependencies" .= dependencies
      ]

instance FromJSON UnitInterface where
  parseJSON = withObject "UnitInterface" $ \v ->
    UnitInterface
      <$> v .: "rootScope"
      <*> v .: "dependencies"

instance ToJSON ExportedValue where
  toJSON (ExportedBitsType size) =
    object
      [ "type" .= String "ExportedBitsType",
        "size" .= size
      ]
  toJSON (ExportedObjType size) =
    object
      [ "type" .= String "ExportedObjType",
        "size" .= size
      ]

instance FromJSON ExportedValue where
  parseJSON = withObject "ExportedValue" $ \v -> do
    typ <- v .: "type"
    case typ of
      String "ExportedBitsType" -> ExportedBitsType <$> v .: "size"
      String "ExportedObjType" -> ExportedObjType <$> v .: "size"
      _ -> fail "Unknown ExportedValue type"