summaryrefslogtreecommitdiff
path: root/source/Felix/Checking/Exact/Global.hs
diff options
context:
space:
mode:
authoradelon <22380201+adelon@users.noreply.github.com>2026-08-06 17:54:00 +0200
committeradelon <22380201+adelon@users.noreply.github.com>2026-08-06 17:54:00 +0200
commit82328890108bae64b372b8d58620ebc62699de76 (patch)
tree575404c6b425c19259c0ded296f1c8ffb7ff0e2b /source/Felix/Checking/Exact/Global.hs
parent1a25421c2a168d420581358c8733fcd8f36f379b (diff)
Migrate to `Felix` namespaceHEADhotg
Diffstat (limited to 'source/Felix/Checking/Exact/Global.hs')
-rw-r--r--source/Felix/Checking/Exact/Global.hs116
1 files changed, 116 insertions, 0 deletions
diff --git a/source/Felix/Checking/Exact/Global.hs b/source/Felix/Checking/Exact/Global.hs
new file mode 100644
index 0000000..d4040e6
--- /dev/null
+++ b/source/Felix/Checking/Exact/Global.hs
@@ -0,0 +1,116 @@
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+-- | Exact resolution of source symbols to checked semantic globals.
+module Felix.Checking.Exact.Global
+ ( ExactGlobalResolutionError(..)
+ , resolveExactSourceGlobals
+ ) where
+
+import Base
+import Felix.Checking.Core
+import Felix.Checking.Declaration qualified as Declaration
+import Felix.Checking.Exact.Vocabulary
+import Felix.Checking.Identity
+import Felix.Checking.Semantic
+import Felix.Checking.Typed.Inductive qualified as Typed
+import Felix.Syntax.Internal qualified as Internal
+
+import Control.Monad (foldM)
+import Control.Monad.Except
+ ( liftEither
+ , runExceptT
+ , throwError
+ )
+import Control.Monad.Trans.Class (lift)
+import Data.Bifunctor (first)
+import Data.Map.Strict qualified as Map
+import Data.Maybe (catMaybes)
+import Data.Set qualified as Set
+
+
+data ExactGlobalResolutionError
+ = ExactGlobalNotVisible !Internal.Symbol
+ | ExactGlobalAmbiguous !Internal.Symbol
+ | ExactGlobalUnsupported !Internal.Symbol
+ | ExactGlobalContextualUnsupported !Internal.Symbol
+ | ExactGlobalContentInvalid !CoreCheckError
+ deriving stock (Show, Eq)
+
+resolveExactSourceGlobals
+ :: Set.Set Internal.Symbol
+ -> Declaration.LoweringDriver
+ (Either
+ ExactGlobalResolutionError
+ ( Map.Map
+ Internal.Symbol
+ (Typed.SourceGlobal ObjectId)
+ , Map.Map ObjectId CoreType
+ ))
+resolveExactSourceGlobals symbols =
+ runExceptT
+ (foldM resolve (Map.empty, Map.empty)
+ (Set.toAscList symbols))
+ where
+ resolve (resolved, types) symbol =
+ case classifyExactSymbol symbol of
+ ExactClosedLiteral ->
+ pure (resolved, types)
+ ExactFixedPrimitive _meaning ->
+ pure (resolved, types)
+ ExactUnsupportedSymbol ->
+ throwError (ExactGlobalUnsupported symbol)
+ ExactSourceGlobal keys -> do
+ matches <-
+ catMaybes
+ <$> traverse
+ (lift
+ . Declaration.resolveVisibleGlobalContentLowering)
+ (toList keys)
+ case matches of
+ [] ->
+ throwError (ExactGlobalNotVisible symbol)
+ [match] -> do
+ (source, sourceTypes) <-
+ liftEither (prepareSourceGlobal symbol match)
+ pure
+ ( Map.insert symbol source resolved
+ , Map.union sourceTypes types
+ )
+ _ ->
+ throwError (ExactGlobalAmbiguous symbol)
+
+prepareSourceGlobal
+ :: Internal.Symbol
+ -> ( SemanticGlobalTarget
+ , ObjectContent
+ , Map.Map ObjectId CoreType
+ )
+ -> Either
+ ExactGlobalResolutionError
+ (Typed.SourceGlobal ObjectId, Map.Map ObjectId CoreType)
+prepareSourceGlobal symbol (target, content, dependencies) = do
+ body <-
+ case target of
+ GlobalReference _identity ->
+ Right Nothing
+ TransparentExpansion _identity ->
+ case content of
+ TransparentObjectContent _theory _coreType canonical ->
+ Just
+ <$> first ExactGlobalContentInvalid
+ (checkCanonicalCore
+ (`Map.lookup` dependencies)
+ canonical)
+ _ ->
+ impossible
+ "validated transparent expansion has opaque content"
+ ContextualTransparentExpansion _identity _requirements ->
+ Left (ExactGlobalContextualUnsupported symbol)
+ let identity = semanticGlobalTargetObject target
+ types =
+ Map.insert
+ identity
+ (objectContentType content)
+ dependencies
+ pure (Typed.SourceGlobal identity body, types)