summaryrefslogtreecommitdiff
path: root/src/Language/Fiddle/Compiler/Backend.hs
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2024-10-10 16:38:51 -0600
committerJosh Rahm <joshuarahm@gmail.com>2024-10-10 16:38:51 -0600
commitc2f195a23bdb0d0dc876cc548d4c3157534082c6 (patch)
tree658954b31fd7ae55ec87b4304adf024a89c3949d /src/Language/Fiddle/Compiler/Backend.hs
parent069268394681c95e05cd74ab8bc0dd2ea6c43353 (diff)
downloadfiddle-c2f195a23bdb0d0dc876cc548d4c3157534082c6.tar.gz
fiddle-c2f195a23bdb0d0dc876cc548d4c3157534082c6.tar.bz2
fiddle-c2f195a23bdb0d0dc876cc548d4c3157534082c6.zip
Add backend support and start implementing a C backend.o
Diffstat (limited to 'src/Language/Fiddle/Compiler/Backend.hs')
-rw-r--r--src/Language/Fiddle/Compiler/Backend.hs81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/Language/Fiddle/Compiler/Backend.hs b/src/Language/Fiddle/Compiler/Backend.hs
new file mode 100644
index 0000000..ddb32c6
--- /dev/null
+++ b/src/Language/Fiddle/Compiler/Backend.hs
@@ -0,0 +1,81 @@
+module Language.Fiddle.Compiler.Backend where
+
+import Control.Monad (forM_)
+import Control.Monad.Identity (Identity)
+import Control.Monad.Writer
+import Data.Map (Map)
+import qualified Data.Text.IO
+import qualified Data.Map as Map
+import Data.Text (Text)
+import Language.Fiddle.Ast
+import Language.Fiddle.Types (Commented, SourceSpan)
+import Options.Applicative
+
+-- | Data representing the result of transpilation.
+data TranspileResult where
+ TranspileResult ::
+ { newFileContents :: Map FilePath Text
+ } ->
+ TranspileResult
+
+instance Semigroup TranspileResult where
+ (<>) (TranspileResult c1) (TranspileResult c2) =
+ TranspileResult $ Map.unionWith (<>) c1 c2
+
+instance Monoid TranspileResult where
+ mempty = TranspileResult mempty
+
+-- | "Opens" a file in the broader context of a TransplieResult, and writes the
+-- resulting bytestring to it
+withFile ::
+ (MonadWriter TranspileResult m) => FilePath -> Writer Text () -> m ()
+withFile path bsWriter =
+ tell (TranspileResult $ Map.singleton path $ execWriter bsWriter)
+
+-- | A backend for the FiddleCompiler. Takes a Checked FiddleUnit and emits
+-- generated code for that fiddle unit.
+data Backend where
+ Backend ::
+ forall privateFlags privateState.
+ { backendName :: String,
+ backendOptionsParser :: Parser privateFlags,
+ backendIOMakeState :: privateFlags -> IO privateState,
+ backendTranspile ::
+ privateFlags ->
+ privateState ->
+ FiddleUnit Checked Identity (Commented SourceSpan) ->
+ TranspileResult
+ } ->
+ Backend
+
+backendToParserFunction ::
+ Backend ->
+ Parser
+ ( FiddleUnit Checked Identity (Commented SourceSpan) -> IO TranspileResult
+ )
+backendToParserFunction
+ Backend
+ { backendOptionsParser = optionsParser,
+ backendIOMakeState = ioMakeState,
+ backendTranspile = transpile
+ } =
+ ( \opts ->
+ let ioState = ioMakeState opts
+ in \fiddleUnit -> do
+ state <- ioState
+ return $ transpile opts state fiddleUnit
+ )
+ <$> optionsParser
+
+processTranspileResult :: TranspileResult -> IO ()
+processTranspileResult (TranspileResult mp) =
+ forM_ (Map.toList mp) $ \(file, text) ->
+ Data.Text.IO.writeFile file text
+
+nullBackend :: Backend
+nullBackend = Backend {
+ backendName = "null",
+ backendOptionsParser = pure (),
+ backendIOMakeState = const $ return (),
+ backendTranspile = \_ _ _ -> mempty
+}