Download src/Assertica/Backend/Emit.hs from Snapkitty/assertica: direct link, hf CLI and curl.
- Browser
- Download file 6.03 kB
-
https://huggingface.co/Snapkitty/assertica/resolve/main/src/Assertica/Backend/Emit.hs
- Command line
-
hf download hf://Snapkitty/assertica/src/Assertica/Backend/Emit.hs
-
curl -L -o Emit.hs https://huggingface.co/Snapkitty/assertica/resolve/main/src/Assertica/Backend/Emit.hs
6.03 kB
| {-| | |
| Module : Assertica.Backend.Emit | |
| Description : Emit syntactically valid Haskell source code | |
| Copyright : (c) 2026 Ahmad Ali Parr | |
| License : BSL-1.0 | |
| Converts compiled intermediate representations (from CodeGen, TermCompiler, etc.) | |
| into syntactically valid Haskell 2010 source code that can be processed by GHC. | |
| RESPONSIBILITIES: | |
| 1. **Module Headers**: Generate correct module declaration with exports | |
| 2. **Imports**: Produce valid import statements with proper syntax | |
| 3. **Definitions**: Format term and type definitions with correct syntax | |
| 4. **Type Signatures**: Generate type declarations with proper indentation | |
| 5. **Comments**: Add source location hints and documentation | |
| 6. **Pretty-Printing**: Consistent, readable formatting | |
| HASKELL SYNTAX REQUIREMENTS: | |
| - Module header: "module Name (exports) where" | |
| - Imports: "import [qualified] Module [(selective)]" | |
| - Type signature: "name :: type" | |
| - Definition: "name = body" or "name pattern = body" | |
| - Indentation: 2 spaces (configurable) | |
| PRINCIPLES: | |
| 1. **Determinism**: Same input produces identical Haskell source | |
| 2. **Validity**: All generated code must parse as Haskell 2010 + GHC extensions | |
| 3. **Readability**: Human-readable formatting for debugging | |
| 4. **Completeness**: All AST nodes properly formatted | |
| -} | |
| module Assertica.Backend.Emit | |
| ( -- * Main emission functions | |
| emitHaskellModule | |
| , emitHaskellDefinition | |
| , emitHaskellExpression | |
| -- * Formatting utilities | |
| , prettyPrint | |
| , formatModuleHeader | |
| , formatImports | |
| , formatDefinition | |
| , formatTypeSignature | |
| -- * Configuration | |
| , EmitConfig(..) | |
| , defaultEmitConfig | |
| ) where | |
| import Data.Text (Text) | |
| import qualified Data.Text as T | |
| import Data.List (intercalate) | |
| import GHC.Generics (Generic) | |
| import Assertica.Backend.CodeGen | |
| ( HaskellModule(..) | |
| , HaskellDefinition(..) | |
| , HaskellExpr(..) | |
| ) | |
| -- ============================================================================ | |
| -- EMIT CONFIGURATION | |
| -- ============================================================================ | |
| {-| Configuration for Haskell code emission -} | |
| data EmitConfig = EmitConfig | |
| { ecIndentSize :: Int -- ^ Spaces per indentation level (default: 2) | |
| , ecLineLength :: Int -- ^ Target line length (default: 80) | |
| , ecAddComments :: Bool -- ^ Include source comments (default: True) | |
| , ecPreludeImports :: Bool -- ^ Auto-import Prelude (default: True) | |
| } | |
| deriving (Show, Generic) | |
| {-| Default emission configuration -} | |
| defaultEmitConfig :: EmitConfig | |
| defaultEmitConfig = EmitConfig | |
| { ecIndentSize = 2 | |
| , ecLineLength = 80 | |
| , ecAddComments = True | |
| , ecPreludeImports = True | |
| } | |
| -- ============================================================================ | |
| -- MAIN EMISSION FUNCTIONS | |
| -- ============================================================================ | |
| {-| Emit a complete Haskell module as source code. | |
| This is the primary interface for generating output .hs files. | |
| Takes a HaskellModule and produces a complete, syntactically valid Haskell | |
| program that can be compiled with GHC. | |
| -} | |
| emitHaskellModule :: EmitConfig -> HaskellModule -> Text | |
| emitHaskellModule config (HaskellModule modName imports defs comments) = | |
| T.unlines $ | |
| -- Comments | |
| map (T.cons '-') comments ++ | |
| [""] | |
| -- Module header | |
| ++ [formatModuleHeader modName] | |
| -- Imports | |
| ++ (if null imports then [] else [""] ++ formatImports config imports) | |
| -- Definitions | |
| ++ (if null defs then [] else [""] ++ map (emitHaskellDefinition config) defs) | |
| {-| Emit a single Haskell definition -} | |
| emitHaskellDefinition :: EmitConfig -> HaskellDefinition -> Text | |
| emitHaskellDefinition config (HaskellDefinition name typeSig body sourceLocation) = | |
| let | |
| -- Type signature (if present) | |
| sigLines = case typeSig of | |
| Nothing -> [] | |
| Just sig -> [formatTypeSignature name sig] | |
| -- Definition line | |
| defLine = formatDefinition name body | |
| -- Source location comment | |
| commentLines = case sourceLocation of | |
| Nothing -> [] | |
| Just loc | ecAddComments config -> ["-- Source: " <> loc] | |
| _ -> [] | |
| in | |
| T.unlines $ commentLines ++ sigLines ++ [defLine] | |
| {-| Emit a single Haskell expression -} | |
| emitHaskellExpression :: EmitConfig -> HaskellExpr -> Text | |
| emitHaskellExpression _config (HaskellExpr expr _mtype) = | |
| expr | |
| -- ============================================================================ | |
| -- FORMATTING FUNCTIONS | |
| -- ============================================================================ | |
| {-| Format module header -} | |
| formatModuleHeader :: [Text] -> Text | |
| formatModuleHeader modName = | |
| "module " <> T.intercalate "." modName <> " where" | |
| {-| Format import statements -} | |
| formatImports :: EmitConfig -> [Text] -> [Text] | |
| formatImports _config imports = | |
| map ("import " <>) imports | |
| {-| Format a type signature -} | |
| formatTypeSignature :: Text -> Text -> Text | |
| formatTypeSignature name typeSig = | |
| name <> " :: " <> typeSig | |
| {-| Format a definition with name and body -} | |
| formatDefinition :: Text -> Text -> Text | |
| formatDefinition name body = | |
| name <> " = " <> body | |
| -- ============================================================================ | |
| -- PRETTY-PRINTING | |
| -- ============================================================================ | |
| {-| Pretty-print a piece of code with proper indentation and formatting. | |
| This takes raw code (possibly from a compiler) and formats it nicely | |
| for human consumption and debugging. | |
| -} | |
| prettyPrint :: EmitConfig -> Text -> Text | |
| prettyPrint config code = | |
| -- Add proper indentation, line wrapping, etc. | |
| -- For now, return as-is | |
| code | |
| {-| Indent a text block by n levels -} | |
| indent :: Int -> Text -> Text | |
| indent n txt = | |
| let spaces = T.replicate n " " | |
| lines_ = T.lines txt | |
| in T.unlines $ map (spaces <>) lines_ | |
| {-| Wrap text to specified line length -} | |
| wrap :: Int -> Text -> Text | |
| wrap _lineLen txt = | |
| -- Simple implementation: just return as-is | |
| -- A full implementation would break at spaces | |
| txt | |