summaryrefslogtreecommitdiff
path: root/src/Language/Fiddle/Ast/Internal/SyntaxTree.hs
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2024-10-11 16:19:21 -0600
committerJosh Rahm <joshuarahm@gmail.com>2024-10-11 16:19:21 -0600
commit1e820e50668631a239cfc3188137cc90c34cf738 (patch)
treec2f2271d17199d97b91b397be46da075a569b21c /src/Language/Fiddle/Ast/Internal/SyntaxTree.hs
parent8082f91fd9fd1bdcbde5ebf74ed4710cdbb0c6c5 (diff)
downloadfiddle-1e820e50668631a239cfc3188137cc90c34cf738.tar.gz
fiddle-1e820e50668631a239cfc3188137cc90c34cf738.tar.bz2
fiddle-1e820e50668631a239cfc3188137cc90c34cf738.zip
Further implement C backend.
There is a problem where I'm mixing up bits and bytes. I think I'll try to resolve that using more type-level constraints.
Diffstat (limited to 'src/Language/Fiddle/Ast/Internal/SyntaxTree.hs')
-rw-r--r--src/Language/Fiddle/Ast/Internal/SyntaxTree.hs52
1 files changed, 44 insertions, 8 deletions
diff --git a/src/Language/Fiddle/Ast/Internal/SyntaxTree.hs b/src/Language/Fiddle/Ast/Internal/SyntaxTree.hs
index 610fdb2..f467141 100644
--- a/src/Language/Fiddle/Ast/Internal/SyntaxTree.hs
+++ b/src/Language/Fiddle/Ast/Internal/SyntaxTree.hs
@@ -1,9 +1,10 @@
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE IncoherentInstances #-}
-{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
@@ -12,7 +13,10 @@ module Language.Fiddle.Ast.Internal.SyntaxTree
NumberType,
RegisterOffset,
BitsOffset,
- QMd (..),
+ QMd,
+ N (..),
+ Unit (..),
+ FieldSpan (..),
-- Witness Types
Witness (..),
-- AST Types
@@ -48,11 +52,12 @@ module Language.Fiddle.Ast.Internal.SyntaxTree
mapDirectedM,
asDirected,
undirected,
+ bitsToBytes,
)
where
import Control.Monad (forM_)
-import Data.Aeson (ToJSON (..))
+import Data.Aeson (FromJSON (..), ToJSON (..))
import Data.Kind (Type)
import Data.List.NonEmpty hiding (map)
import Data.Text (Text)
@@ -69,6 +74,33 @@ import Language.Fiddle.Internal.UnitInterface
type QMd s t = When (s .>= Qualified) t
+-- | Phantom type used to ensure Bits and Bytes don't get mixed up in the code.
+data Unit = Bits | Bytes
+
+-- | An integer with a unit.
+newtype N (u :: Unit) = N Word32
+ deriving newtype (Real, Enum, Num, Eq, Ord, Integral)
+
+instance (Show (N u)) where
+ show (N b) = show b
+
+instance (ToJSON (N u)) where
+ toJSON (N b) = toJSON b
+
+instance (FromJSON (N u)) where
+ parseJSON v = N <$> parseJSON v
+
+bitsToBytes :: N Bits -> (N Bytes, N Bits)
+bitsToBytes (N a) = let (y, i) = divMod a 8 in (N y, N i)
+
+data FieldSpan (u :: Unit) where
+ FieldSpan ::
+ { offset :: N u,
+ size :: N u
+ } ->
+ FieldSpan u
+ deriving (Eq, Ord, Show, Generic, ToJSON, FromJSON)
+
type BitsOffset stage = RegisterOffset stage
-- | Type used for the RegisterOffset type. This is populated in the check
@@ -449,7 +481,7 @@ data ObjTypeDecl stage f a where
RegisterDecl ::
{ -- | Offset within the register. Calculated during the consistency check.
-- The offset is calculated from the top-level structure.
- regOffset :: RegisterOffset stage,
+ regSpan :: When (stage .>= Checked) (FieldSpan Bytes),
-- | Optional register modifier.
regModifier :: Maybe (Modifier f a),
-- | Optional register identifier. This is guaranteed to exist after
@@ -466,7 +498,11 @@ data ObjTypeDecl stage f a where
ObjTypeDecl stage f a
-- | A reserved declaration for padding or alignment.
ReservedDecl ::
- { -- | The expression for reserved space.
+ { -- | Offset and size of this reserved block.
+ regSpan :: When (stage .>= Checked) (FieldSpan Bytes),
+ -- | Generated identifier for this reserved field.
+ reservedIdent :: When (stage .>= Qualified) String,
+ -- | The expression for reserved space.
reservedExpr :: Expression stage f a,
-- | Annotation for the reserved declaration.
reservedAnnot :: a
@@ -503,8 +539,7 @@ data ModifierKeyword = Rw | Ro | Wo
-- declarations.
data DeferredRegisterBody stage f a where
DeferredRegisterBody ::
- { -- | Bit declarations.
- deferredBits :: [Directed RegisterBitsDecl stage f a],
+ { deferredBits :: [Directed RegisterBitsDecl stage f a],
-- | Annotation for the deferred register body.
deferredAnnot :: a
} ->
@@ -553,7 +588,8 @@ data RegisterBitsDecl stage f a where
DefinedBits ::
{ -- | The offset for these bits. This is calculated during the
-- ConsistencyCheck phase, so until this phase it's just ().
- definedBitsOffset :: BitsOffset stage,
+ definedBitsSpan :: When (stage .>= Checked) (FieldSpan Bits),
+ -- | Bit declarations.
-- | Optional modifier for the bits.
definedBitsModifier :: Maybe (Modifier f a),
-- | Identifier for the bits.