module Lib.TopContext import Data.IORef import Data.SortedMap import Data.String import Prelude import Lib.Common import Lib.Types -- I want unique ids, to be able to lookup, update, and a Ref so -- I don't need good Context discipline. (I seem to have made mistakes already.) lookup : QName -> TopContext -> Maybe TopEntry lookup qn@(QN ns nm) top = if ns == top.ns then lookupMap' qn top.defs else case lookupMap' ns top.modules of Just mod => lookupMap' qn mod.modDefs Nothing => Nothing lookupImported : String → TopContext -> List TopEntry lookupImported raw top = mapMaybe (flip lookup top) $ (QN top.ns raw) :: map (flip QN raw) top.imported -- For repl / out of scope errors lookupAll : String → TopContext -> List TopEntry lookupAll raw top = mapMaybe (flip lookup top) $ (QN top.ns raw) :: map (flip QN raw) (map fst $ toList top.modules) lookupRaw : String -> TopContext -> Maybe TopEntry lookupRaw raw top = case lookupMap' (QN top.ns raw) top.defs of Just entry => Just entry Nothing => go top.imported where go : List String → Maybe TopEntry go Nil = Nothing go (ns :: nss) = case lookupMap' ns top.modules of Nothing => go nss Just mod => case lookupMap' (QN ns raw) mod.modDefs of Just entry => Just entry Nothing => go nss instance Show TopContext where show top = "\nContext:\n [\{ joinBy "\n" $ map (show ∘ snd) $ toList top.defs}]" emptyTop : TopContext emptyTop = MkTop emptyMap Nil emptyMap Nil "" emptyMap (MC emptyMap Nil 0 CheckAll) 0 Nil emptyMap setFlag : QName → FC → EFlag → M Unit setFlag name fc flag = do top <- getTop let (Just (MkEntry fc nm ty def flags)) = lookupMap' name top.defs | Nothing => error fc "\{show name} not declared" modifyTop [ defs $= (updateMap name (MkEntry fc name ty def (flag :: flags))) ] setDef : QName -> FC -> Tm -> Def → List EFlag -> M Unit setDef name fc ty def flags = do top <- getTop let (Nothing) = lookupMap' name top.defs | Just (MkEntry fc' nm' ty' def' _) => error fc "\{show name} is already defined at \{show fc'}" modifyTop $ \top => [ defs := (updateMap name (MkEntry fc name ty def flags) top.defs)] top updateDef : QName -> FC -> Tm -> Def -> M Unit updateDef name fc ty def = do top <- getTop let (Just (MkEntry fc' nm' ty' def' flags)) = lookupMap' name top.defs | Nothing => error fc "\{show name} not declared" putTop $ [ defs := updateMap name (MkEntry fc' name ty def flags) top.defs ] top typeName : Tm → Maybe QName typeName (Pi fc nm Explicit rig t u) = Nothing typeName (Pi fc name icit rig t u) = typeName u typeName (App fc t u) = typeName t typeName (Ref _ nm) = Just nm typeName _ = Nothing addHint : QName → M Unit addHint qn = do top <- getTop case lookup qn top of Just entry => do let (Just tyname) = typeName entry.type | Nothing => error entry.fc "can't find tcon name for \{show qn}" let xs = fromMaybe Nil $ lookupMap' tyname top.hints let hints = updateMap tyname ((qn, entry.type) :: xs) top.hints putTop $ [ hints := hints ] top Nothing => pure MkUnit addError : Error -> M Unit addError err = do top <- getTop modifyTop [ errors $= (err ::) ] addInfo : EditorInfo → M Unit addInfo info = do top <- getTop modifyTop [ infos $= (info ::)]