module Language.Reflection.TTImp import Data.Maybe import Data.String import public Language.Reflection.TT %default total -- Unchecked terms and declarations in the intermediate language mutual public export data BindMode = PI Count | PATTERN | COVERAGE | NONE %name BindMode bm -- For as patterns matching linear arguments, select which side is -- consumed public export data UseSide = UseLeft | UseRight %name UseSide side public export data DotReason = NonLinearVar | VarApplied | NotConstructor | ErasedArg | UserDotted | UnknownDot | UnderAppliedCon %name DotReason dr public export data TTImp : Type where IVar : FC -> Name -> TTImp IPi : FC -> Count -> PiInfo TTImp -> Maybe Name -> (argTy : TTImp) -> (retTy : TTImp) -> TTImp ILam : FC -> Count -> PiInfo TTImp -> Maybe Name -> (argTy : TTImp) -> (lamTy : TTImp) -> TTImp ILet : FC -> (lhsFC : FC) -> Count -> Name -> (nTy : TTImp) -> (nVal : TTImp) -> (scope : TTImp) -> TTImp ICase : FC -> TTImp -> (ty : TTImp) -> List Clause -> TTImp ILocal : FC -> List Decl -> TTImp -> TTImp IUpdate : FC -> List IFieldUpdate -> TTImp -> TTImp IApp : FC -> TTImp -> TTImp -> TTImp INamedApp : FC -> TTImp -> Name -> TTImp -> TTImp IAutoApp : FC -> TTImp -> TTImp -> TTImp IWithApp : FC -> TTImp -> TTImp -> TTImp ISearch : FC -> (depth : Nat) -> TTImp IAlternative : FC -> AltType -> List TTImp -> TTImp IRewrite : FC -> TTImp -> TTImp -> TTImp -- Any implicit bindings in the scope should be bound here, using -- the given binder IBindHere : FC -> BindMode -> TTImp -> TTImp -- A name which should be implicitly bound IBindVar : FC -> String -> TTImp -- An 'as' pattern, valid on the LHS of a clause only IAs : FC -> (nameFC : FC) -> UseSide -> Name -> TTImp -> TTImp -- A 'dot' pattern, i.e. one which must also have the given value -- by unification IMustUnify : FC -> DotReason -> TTImp -> TTImp -- Laziness annotations IDelayed : FC -> LazyReason -> TTImp -> TTImp -- the type IDelay : FC -> TTImp -> TTImp -- delay constructor IForce : FC -> TTImp -> TTImp -- Quasiquotation IQuote : FC -> TTImp -> TTImp IQuoteName : FC -> Name -> TTImp IQuoteDecl : FC -> List Decl -> TTImp IUnquote : FC -> TTImp -> TTImp IPrimVal : FC -> (c : Constant) -> TTImp IType : FC -> TTImp IHole : FC -> String -> TTImp -- An implicit value, solved by unification, but which will also be -- bound (either as a pattern variable or a type variable) if unsolved -- at the end of elaborator Implicit : FC -> (bindIfUnsolved : Bool) -> TTImp IWithUnambigNames : FC -> List (FC, Name) -> TTImp -> TTImp %name TTImp s, t, u public export data IFieldUpdate : Type where ISetField : (path : List String) -> TTImp -> IFieldUpdate ISetFieldApp : (path : List String) -> TTImp -> IFieldUpdate %name IFieldUpdate upd public export data AltType : Type where FirstSuccess : AltType Unique : AltType UniqueDefault : TTImp -> AltType public export data NoMangleDirective : Type where CommonName : String -> NoMangleDirective BackendNames : List (String, String) -> NoMangleDirective public export data FnOpt : Type where Inline : FnOpt NoInline : FnOpt Deprecate : FnOpt TCInline : FnOpt -- Flag means the hint is a direct hint, not a function which might -- find the result (e.g. chasing parent interface dictionaries) Hint : Bool -> FnOpt -- Flag means to use as a default if all else fails GlobalHint : Bool -> FnOpt ExternFn : FnOpt -- Defined externally, list calling conventions ForeignFn : List TTImp -> FnOpt -- Mark for export to a foreign language, list calling conventions ForeignExport : List TTImp -> FnOpt -- assume safe to cancel arguments in unification Invertible : FnOpt Totality : TotalReq -> FnOpt Macro : FnOpt SpecArgs : List Name -> FnOpt ||| Keep the user provided name during codegen NoMangle : Maybe NoMangleDirective -> FnOpt public export data ITy : Type where MkTy : FC -> (nameFC : FC) -> (n : Name) -> (ty : TTImp) -> ITy %name ITy sig public export data DataOpt : Type where SearchBy : List Name -> DataOpt -- determining arguments NoHints : DataOpt -- Don't generate search hints for constructors UniqueSearch : DataOpt -- auto implicit search must check result is unique External : DataOpt -- implemented externally NoNewtype : DataOpt -- don't apply newtype optimisation %name DataOpt dopt public export data Data : Type where MkData : FC -> (n : Name) -> (tycon : TTImp) -> (opts : List DataOpt) -> (datacons : List ITy) -> Data MkLater : FC -> (n : Name) -> (tycon : TTImp) -> Data %name Data dt public export data IField : Type where MkIField : FC -> Count -> PiInfo TTImp -> Name -> TTImp -> IField %name IField fld public export data Record : Type where MkRecord : FC -> (n : Name) -> (params : List (Name, Count, PiInfo TTImp, TTImp)) -> (conName : Name) -> (fields : List IField) -> Record %name Record rec public export data WithFlag = Syntactic public export data Clause : Type where PatClause : FC -> (lhs : TTImp) -> (rhs : TTImp) -> Clause WithClause : FC -> (lhs : TTImp) -> (rig : Count) -> (wval : TTImp) -> -- with'd expression (& quantity) (prf : Maybe Name) -> -- optional name for the proof (flags : List WithFlag) -> List Clause -> Clause ImpossibleClause : FC -> (lhs : TTImp) -> Clause %name Clause cl public export data Decl : Type where IClaim : FC -> Count -> Visibility -> List FnOpt -> ITy -> Decl IData : FC -> Visibility -> Maybe TotalReq -> Data -> Decl IDef : FC -> Name -> (cls : List Clause) -> Decl IParameters : FC -> (params : List (Name, Count, PiInfo TTImp, TTImp)) -> (decls : List Decl) -> Decl IRecord : FC -> Maybe String -> -- nested namespace Visibility -> Maybe TotalReq -> Record -> Decl INamespace : FC -> Namespace -> (decls : List Decl) -> Decl ITransform : FC -> Name -> TTImp -> TTImp -> Decl IRunElabDecl : FC -> TTImp -> Decl ILog : Maybe (List String, Nat) -> Decl IBuiltin : FC -> BuiltinType -> Name -> Decl %name Decl decl public export getFC : TTImp -> FC getFC (IVar fc y) = fc getFC (IPi fc _ _ _ _ _) = fc getFC (ILam fc _ _ _ _ _) = fc getFC (ILet fc _ _ _ _ _ _) = fc getFC (ICase fc _ _ _) = fc getFC (ILocal fc _ _) = fc getFC (IUpdate fc _ _) = fc getFC (IApp fc _ _) = fc getFC (INamedApp fc _ _ _) = fc getFC (IAutoApp fc _ _) = fc getFC (IWithApp fc _ _) = fc getFC (ISearch fc _) = fc getFC (IAlternative fc _ _) = fc getFC (IRewrite fc _ _) = fc getFC (IBindHere fc _ _) = fc getFC (IBindVar fc _) = fc getFC (IAs fc _ _ _ _) = fc getFC (IMustUnify fc _ _) = fc getFC (IDelayed fc _ _) = fc getFC (IDelay fc _) = fc getFC (IForce fc _) = fc getFC (IQuote fc _) = fc getFC (IQuoteName fc _) = fc getFC (IQuoteDecl fc _) = fc getFC (IUnquote fc _) = fc getFC (IPrimVal fc _) = fc getFC (IType fc) = fc getFC (IHole fc _) = fc getFC (Implicit fc _) = fc getFC (IWithUnambigNames fc _ _) = fc public export Eq LazyReason where LInf == LInf = True LLazy == LLazy = True LUnknown == LUnknown = True _ == _ = False public export Eq Namespace where MkNS ns == MkNS ns' = ns == ns' public export Eq Count where M0 == M0 = True M1 == M1 = True MW == MW = True _ == _ = False public export Eq BindMode where PI c == PI c' = c == c' PATTERN == PATTERN = True NONE == NONE = True _ == _ = False public export Eq UseSide where UseLeft == UseLeft = True UseRight == UseRight = True _ == _ = False public export Eq DotReason where NonLinearVar == NonLinearVar = True VarApplied == VarApplied = True NotConstructor == NotConstructor = True ErasedArg == ErasedArg = True UserDotted == UserDotted = True UnknownDot == UnknownDot = True UnderAppliedCon == UnderAppliedCon = True _ == _ = False public export Eq WithFlag where Syntactic == Syntactic = True public export Eq UserName where Basic n == Basic n' = n == n' Field n == Field n' = n == n' Underscore == Underscore = True _ == _ = False public export Eq Name where NS ns n == NS ns' n' = ns == ns' && n == n' UN n == UN n' = n == n' MN n i == MN n' i' = n == n' && i == i' DN _ n == DN _ n' = n == n' Nested i n == Nested i' n' = i == i' && n == n' CaseBlock n i == CaseBlock n' i' = n == n' && i == i' WithBlock n i == WithBlock n' i' = n == n' && i == i' _ == _ = False public export Eq PrimType where IntType == IntType = True IntegerType == IntegerType = True Int8Type == Int8Type = True Int16Type == Int16Type = True Int32Type == Int32Type = True Int64Type == Int64Type = True Bits8Type == Bits8Type = True Bits16Type == Bits16Type = True Bits32Type == Bits32Type = True Bits64Type == Bits64Type = True StringType == StringType = True CharType == CharType = True DoubleType == DoubleType = True WorldType == WorldType = True _ == _ = False public export Eq Constant where I c == I c' = c == c' BI c == BI c' = c == c' I8 c == I8 c' = c == c' I16 c == I16 c' = c == c' I32 c == I32 c' = c == c' I64 c == I64 c' = c == c' B8 c == B8 c' = c == c' B16 c == B16 c' = c == c' B32 c == B32 c' = c == c' B64 c == B64 c' = c == c' Str c == Str c' = c == c' Ch c == Ch c' = c == c' Db c == Db c' = c == c' PrT t == PrT t' = t == t' WorldVal == WorldVal = True _ == _ = False public export Eq DataOpt where SearchBy ns == SearchBy ns' = ns == ns' NoHints == NoHints = True UniqueSearch == UniqueSearch = True External == External = True NoNewtype == NoNewtype = True _ == _ = False public export Eq NoMangleDirective where CommonName s == CommonName s' = s == s' BackendNames ns == BackendNames ns' = ns == ns' _ == _ = False public export Eq a => Eq (PiInfo a) where ImplicitArg == ImplicitArg = True ExplicitArg == ExplicitArg = True AutoImplicit == AutoImplicit = True DefImplicit t == DefImplicit t' = t == t' _ == _ = False parameters {auto eqTTImp : Eq TTImp} public export Eq Clause where PatClause _ lhs rhs == PatClause _ lhs' rhs' = lhs == lhs' && rhs == rhs' WithClause _ l r w p f cs == WithClause _ l' r' w' p' f' cs' = l == l' && r == r' && w == w' && p == p' && f == f' && (assert_total $ cs == cs') ImpossibleClause _ l == ImpossibleClause _ l' = l == l' _ == _ = False public export Eq IFieldUpdate where ISetField p t == ISetField p' t' = p == p' && t == t' ISetFieldApp p t == ISetFieldApp p' t' = p == p' && t == t' _ == _ = False public export Eq AltType where FirstSuccess == FirstSuccess = True Unique == Unique = True UniqueDefault t == UniqueDefault t' = t == t' _ == _ = False public export Eq FnOpt where Inline == Inline = True NoInline == NoInline = True Deprecate == Deprecate = True TCInline == TCInline = True Hint b == Hint b' = b == b' GlobalHint b == GlobalHint b' = b == b' ExternFn == ExternFn = True ForeignFn es == ForeignFn es' = es == es' ForeignExport es == ForeignExport es' = es == es' Invertible == Invertible = True Totality tr == Totality tr' = tr == tr' Macro == Macro = True SpecArgs ns == SpecArgs ns' = ns == ns' NoMangle nm == NoMangle nm' = nm == nm' _ == _ = False public export Eq ITy where MkTy _ _ n ty == MkTy _ _ n' ty' = n == n' && ty == ty' public export Eq Data where MkData _ n tc os dc == MkData _ n' tc' os' dc' = n == n' && tc == tc' && os == os' && dc == dc' MkLater _ n tc == MkLater _ n' tc' = n == n' && tc == tc' _ == _ = False public export Eq IField where MkIField _ c pi n e == MkIField _ c' pi' n' e' = c == c' && pi == pi' && n == n' && e == e' public export Eq Record where MkRecord _ n ps cn fs == MkRecord _ n' ps' cn' fs' = n == n' && ps == ps' && cn == cn' && fs == fs' public export Eq Decl where IClaim _ c v fos t == IClaim _ c' v' fos' t' = c == c' && v == v' && fos == fos' && t == t' IData _ v t d == IData _ v' t' d' = v == v' && t == t' && d == d' IDef _ n cs == IDef _ n' cs' = n == n' && cs == cs' IParameters _ ps ds == IParameters _ ps' ds' = ps == ps' && (assert_total $ ds == ds') IRecord _ ns v tr r == IRecord _ ns' v' tr' r' = ns == ns' && v == v' && tr == tr' && r == r' INamespace _ ns ds == INamespace _ ns' ds' = ns == ns' && (assert_total $ ds == ds') ITransform _ n f t == ITransform _ n' f' t' = n == n' && f == f' && t == t' IRunElabDecl _ e == IRunElabDecl _ e' = e == e' ILog p == ILog p' = p == p' IBuiltin _ t n == IBuiltin _ t' n' = t == t' && n == n' _ == _ = False public export Eq TTImp where IVar _ v == IVar _ v' = v == v' IPi _ c i n a r == IPi _ c' i' n' a' r' = c == c' && (assert_total $ i == i') && n == n' && a == a' && r == r' ILam _ c i n a r == ILam _ c' i' n' a' r' = c == c' && (assert_total $ i == i') && n == n' && a == a' && r == r' ILet _ _ c n ty val s == ILet _ _ c' n' ty' val' s' = c == c' && n == n' && ty == ty' && val == val' && s == s' ICase _ t ty cs == ICase _ t' ty' cs' = t == t' && ty == ty' && (assert_total $ cs == cs') ILocal _ ds e == ILocal _ ds' e' = (assert_total $ ds == ds') && e == e' IUpdate _ fs t == IUpdate _ fs' t' = (assert_total $ fs == fs') && t == t' IApp _ f x == IApp _ f' x' = f == f' && x == x' INamedApp _ f n x == INamedApp _ f' n' x' = f == f' && n == n' && x == x' IAutoApp _ f x == IAutoApp _ f' x' = f == f' && x == x' IWithApp _ f x == IWithApp _ f' x' = f == f' && x == x' ISearch _ n == ISearch _ n' = n == n' IAlternative _ t as == IAlternative _ t' as' = (assert_total $ t == t') && (assert_total $ as == as') IRewrite _ p q == IRewrite _ p' q' = p == p' && q == q' IBindHere _ m t == IBindHere _ m' t' = m == m' && t == t' IBindVar _ s == IBindVar _ s' = s == s' IAs _ _ u n t == IAs _ _ u' n' t' = u == u' && n == n' && t == t' IMustUnify _ r t == IMustUnify _ r' t' = r == r' && t == t' IDelayed _ r t == IDelayed _ r' t' = r == r' && t == t' IDelay _ t == IDelay _ t' = t == t' IForce _ t == IForce _ t' = t == t' IQuote _ tm == IQuote _ tm' = tm == tm' IQuoteName _ n == IQuoteName _ n' = n == n' IQuoteDecl _ ds == IQuoteDecl _ ds' = assert_total $ ds == ds' IUnquote _ tm == IUnquote _ tm' = tm == tm' IPrimVal _ c == IPrimVal _ c' = c == c' IType _ == IType _ = True IHole _ s == IHole _ s' = s == s' Implicit _ b == Implicit _ b' = b == b' IWithUnambigNames _ ns t == IWithUnambigNames _ ns' t' = map snd ns == map snd ns' && t == t' _ == _ = False mutual export Show IField where show (MkIField fc rig pinfo nm s) = showPiInfo {wrapExplicit=False} pinfo (showCount rig "\{show nm} : \{show s}") export Show Record where show (MkRecord fc n params conName fields) = unwords [ "record", show n , unwords (map (\ (nm, rig, pinfo, ty) => showPiInfo pinfo (showCount rig "\{show nm} : \{show ty}")) params) , "where" , "{" , "constructor", show conName, "; " , joinBy "; " (map show fields) , "}" ] export Show Data where show (MkData fc n tycon opts datacons) -- TODO: print opts = unwords [ "data", show n, ":", show tycon, "where" , "{", joinBy "; " (map show datacons), "}" ] show (MkLater fc n tycon) = unwords [ "data", show n, ":", show tycon ] export Show ITy where show (MkTy fc nameFC n ty) = "\{show n} : \{show ty}" export Show Decl where show (IClaim fc rig vis xs sig) = unwords [ show vis , showCount rig (show sig) ] show (IData fc vis treq dt) = unwords [ show vis , showTotalReq treq (show dt) ] show (IDef fc nm xs) = joinBy "; " (map show xs) show (IParameters fc params decls) = unwords [ "parameters" , unwords (map (\ (nm, rig, pinfo, ty) => showPiInfo pinfo (showCount rig "\{show nm} : \{show ty}")) params) , "{" , joinBy "; " (assert_total $ map show decls) , "}" ] show (IRecord fc x vis treq rec) = unwords [ show vis, showTotalReq treq (show rec) ] show (INamespace fc ns decls) = unwords [ "namespace", show ns , "{", joinBy "; " (assert_total $ map show decls), "}" ] show (ITransform fc nm s t) = #"%transform "\{show nm}" \{show s} = \{show t}"# show (IRunElabDecl fc s) = "%runElab \{show s}" show (ILog loglvl) = case loglvl of Nothing => "%logging off" Just ([], lvl) => "%logging \{show lvl}" Just (topic, lvl) => "%logging \{joinBy "." topic} \{show lvl}" show (IBuiltin fc bty nm) = "%builtin \{show bty} \{show nm}" export Show IFieldUpdate where show (ISetField path s) = "\{joinBy "->" path} := \{show s}" show (ISetFieldApp path s) = "\{joinBy "->" path} $= \{show s}" export Show Clause where show (PatClause fc lhs rhs) = "\{show lhs} = \{show rhs}" show (WithClause fc lhs rig wval prf flags cls) -- TODO print flags = unwords [ show lhs, "with" , showCount rig $ maybe id (\ nm => (++ " proof \{show nm}")) prf $ showParens True (show wval) , "{", joinBy "; " (assert_total $ map show cls), "}" ] show (ImpossibleClause fc lhs) = "\{show lhs} impossible" export Show TTImp where showPrec d (IVar fc nm) = show nm showPrec d (IPi fc rig pinfo x argTy retTy) = showParens (d > Open) $ let nm = fromMaybe (UN Underscore) x in assert_total (showPiInfo pinfo "\{showCount rig $ show nm} : \{show argTy}") ++ " -> \{show retTy}" showPrec d (ILam fc rig pinfo x argTy lamTy) = showParens (d > Open) $ "\\ \{showCount rig $ show (fromMaybe (UN Underscore) x)} => \{show lamTy}" showPrec d (ILet fc lhsFC rig nm nTy nVal scope) = showParens (d > Open) $ "let \{showCount rig (show nm)} : \{show nTy} = \{show nVal} in \{show scope}" showPrec d (ICase fc s ty xs) = showParens (d > Open) $ unwords [ "case", show s, ":", show ty, "of", "{" , joinBy "; " (assert_total $ map show xs) , "}" ] showPrec d (ILocal fc decls s) = showParens (d > Open) $ unwords [ "let", joinBy "; " (assert_total $ map show decls) , "in", show s ] showPrec d (IUpdate fc upds s) = showParens (d > Open) $ unwords [ "{", joinBy ", " $ assert_total (map show upds), "}" , showPrec App s ] showPrec d (IApp fc f t) = showParens (d >= App) $ "\{show f} \{showPrec App t}" showPrec d (INamedApp fc f nm t) = showParens (d >= App) $ "\{show f} {\{show nm} = \{show t}}" showPrec d (IAutoApp fc f t) = showParens (d >= App) $ "\{show f} @{\{show t}}" showPrec d (IWithApp fc f t) = showParens (d >= App) $ "\{show f} | \{showPrec App t}" showPrec d (ISearch fc depth) = "%search" showPrec d (IAlternative fc x xs) = "<\{show (length xs)} alts>" showPrec d (IRewrite fc s t) = showParens (d > Open) "rewrite \{show s} in \{show t}" showPrec d (IBindHere fc bm s) = showPrec d s showPrec d (IBindVar fc x) = x showPrec d (IAs fc nameFC side nm s) = "\{show nm}@\{showPrec App s}" showPrec d (IMustUnify fc dr s) = ".(\{show s})" showPrec d (IDelayed fc lr s) = showPrec d s showPrec d (IDelay fc s) = showCon d "Delay" $ assert_total (showArg s) showPrec d (IForce fc s) = showPrec d s showPrec d (IQuote fc s) = "`(\{show s})" showPrec d (IQuoteName fc nm) = "`{\{show nm}}" showPrec d (IQuoteDecl fc xs) = "`[\{joinBy "; " (assert_total $ map show xs)}]" showPrec d (IUnquote fc s) = "~(\{show s})" showPrec d (IPrimVal fc c) = show c showPrec d (IType fc) = "Type" showPrec d (IHole fc str) = "?" ++ str showPrec d (Implicit fc b) = ifThenElse b "_" "?" showPrec d (IWithUnambigNames fc ns s) = case ns of [] => show s [(_,x)] => "with \{show x} \{show s}" _ => "with [\{joinBy ", " $ map (show . snd) ns}] \{show s}"