A strongly typed functional programming language compiler that compiles to JavaScript with advanced type system features and IDE integration
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
CoreFn is the core functional intermediate representation used in the PureScript compiler. It serves as the bridge between the high-level Abstract Syntax Tree (AST) and the imperative CoreImp representation, providing a simplified functional language that eliminates syntactic sugar while preserving semantic information.
The fundamental expression types in the CoreFn representation, covering all functional constructs after desugaring.
-- | Core functional expressions
data Expr a
= Literal a (Literal (Expr a)) -- Literal values
| Constructor a (ProperName 'TypeName) (ProperName 'ConstructorName) [Ident] -- Data constructors
| Accessor a PSString (Expr a) -- Record property access
| ObjectUpdate a (Expr a) (Maybe [PSString]) [(PSString, Expr a)] -- Record updates
| Abs a Ident (Expr a) -- Lambda abstractions
| App a (Expr a) (Expr a) -- Function application
| Var a (Qualified Ident) -- Variables
| Case a [Expr a] [CaseAlternative a] -- Pattern matching
| Let a [Bind a] (Expr a) -- Let bindings
-- | Case alternatives with pattern matching
data CaseAlternative a = CaseAlternative
{ caseAlternativeBinders :: [Binder a] -- Pattern binders
, caseAlternativeResult :: Either [(Guard a, Expr a)] (Expr a) -- Guarded or simple result
}
-- | Guards for conditional expressions
type Guard a = Expr aBinding forms for let expressions and module-level definitions.
-- | Let and module bindings
data Bind a
= NonRec a Ident (Expr a) -- Non-recursive binding
| Rec [((a, Ident), Expr a)] -- Recursive binding groupComplete module structure in CoreFn form with imports, exports, and declarations.
-- | CoreFn module representation
data Module a = Module
{ moduleSourceSpan :: SourceSpan -- Source location
, moduleComments :: [Comment] -- Module comments
, moduleName :: ModuleName -- Module name
, modulePath :: FilePath -- Source file path
, moduleImports :: [(a, ModuleName)] -- Import list with annotations
, moduleExports :: [Ident] -- Exported identifiers
, moduleReExports :: Map ModuleName [Ident] -- Re-exported identifiers
, moduleForeign :: [Ident] -- Foreign function imports
, moduleDecls :: [Bind a] -- Module declarations
}Functions for converting high-level AST to CoreFn representation, performing desugaring and simplification.
-- | Convert a module from AST to CoreFn
moduleToCoreFn :: Module -> m (Module CoreFn.Ann)
-- | Convert expressions from AST to CoreFn
exprToCoreFn :: Expr -> m (CoreFn.Expr CoreFn.Ann)
-- | Convert declarations to CoreFn bindings
declToCoreFn :: Declaration -> m [CoreFn.Bind CoreFn.Ann]Optimization passes that operate on the CoreFn representation to improve performance and eliminate dead code.
-- | Optimize a CoreFn module
optimizeCoreFn :: Module CoreFn.Ann -> Module CoreFn.Ann
-- | Inline simple bindings and constants
inlineCoreFn :: Module CoreFn.Ann -> Module CoreFn.Ann
-- | Remove unused bindings and expressions
eliminateDeadCodeCoreFn :: Module CoreFn.Ann -> Module CoreFn.AnnSerialization functions for persisting and loading CoreFn modules in JSON format.
-- | Convert CoreFn module to JSON
moduleToJSON :: Module CoreFn.Ann -> Value
-- | Parse CoreFn module from JSON
moduleFromJSON :: Value -> Either String (Module CoreFn.Ann)
-- | Convert CoreFn expression to JSON
exprToJSON :: Expr CoreFn.Ann -> Value
-- | Parse CoreFn expression from JSON
exprFromJSON :: Value -> Either String (Expr CoreFn.Ann)Generic traversal and analysis functions for working with CoreFn structures.
-- | Transform all expressions in a module
everywhereOnValues :: (Bind a -> Bind a) -> (Expr a -> Expr a) -> (Binder a -> Binder a) -> Module a -> Module a
-- | Collect information from all expressions in a module
everythingOnValues :: Monoid r => (Bind a -> r) -> (Expr a -> r) -> (Binder a -> r) -> Module a -> r
-- | Transform expressions with context
transformCoreFn :: (Expr a -> Expr a) -> Module a -> Module aAnnotation types used throughout CoreFn to preserve source information and metadata.
-- | CoreFn annotations with source positions and metadata
data Ann = Ann
{ annSourceSpan :: SourceSpan -- Source location
, annComments :: [Comment] -- Associated comments
, annType :: Maybe Type -- Type information
, annMeta :: Maybe Meta -- Compiler metadata
}
-- | Metadata for CoreFn expressions
data Meta
= IsConstructor -- Constructor application
| IsNewtype -- Newtype constructor
| IsTypeClassConstructor -- Type class dictionary
| IsForeign -- Foreign function
| IsWhere -- Where clause binding
| ConstructorType [Ident] [Ident] -- Constructor field infoimport Language.PureScript.CoreFn
-- Create a simple lambda expression: \x -> x
identityExpr :: Expr Ann
identityExpr = Abs ann (Ident "x") (Var ann (Qualified Nothing (Ident "x")))
where ann = Ann defaultSourceSpan [] Nothing Nothing
-- Create a function application: f x
appExpr :: Expr Ann -> Expr Ann -> Expr Ann
appExpr f x = App ann f x
where ann = Ann defaultSourceSpan [] Nothing Nothing-- Extract all variable references from a module
extractVars :: Module Ann -> [Qualified Ident]
extractVars = everythingOnValues (const mempty) getVars (const mempty)
where
getVars (Var _ name) = [name]
getVars _ = []
-- Transform all lambdas in a module
transformLambdas :: (Ident -> Expr Ann -> Expr Ann) -> Module Ann -> Module Ann
transformLambdas f = everywhereOnValues id transformExpr id
where
transformExpr (Abs ann ident body) = f ident (Abs ann ident body)
transformExpr expr = expr-- Save a CoreFn module to a file
saveCoreFnModule :: FilePath -> Module Ann -> IO ()
saveCoreFnModule path modul = do
let json = moduleToJSON modul
encodeFile path json
-- Load a CoreFn module from a file
loadCoreFnModule :: FilePath -> IO (Either String (Module Ann))
loadCoreFnModule path = do
result <- eitherDecodeFileStrict path
return $ result >>= moduleFromJSON