add definitions to parser
This commit is contained in:
parent
ab2508e0ce
commit
757ea89b0f
9 changed files with 199 additions and 29 deletions
|
@ -215,7 +215,11 @@ reserved =
|
||||||
W "λ" `Or` W "fun",
|
W "λ" `Or` W "fun",
|
||||||
W "δ" `Or` W "dfun",
|
W "δ" `Or` W "dfun",
|
||||||
W "ω" `Or` S "#",
|
W "ω" `Or` S "#",
|
||||||
S "★" `Or` W "Type"]
|
S "★" `Or` W "Type",
|
||||||
|
W1 "def",
|
||||||
|
W1 "def0",
|
||||||
|
W "defω" `Or` W "def#",
|
||||||
|
S "≔" `Or` S ":="]
|
||||||
|
|
||||||
||| `IsReserved str` is true if `R str` might actually show up in
|
||| `IsReserved str` is true if `R str` might actually show up in
|
||||||
||| the token stream
|
||| the token stream
|
||||||
|
|
|
@ -21,18 +21,6 @@ public export
|
||||||
Grammar = Core.Grammar () Token
|
Grammar = Core.Grammar () Token
|
||||||
%hide Core.Grammar
|
%hide Core.Grammar
|
||||||
|
|
||||||
private
|
|
||||||
data PArg = T PTerm | D PDim
|
|
||||||
|
|
||||||
|
|
||||||
private
|
|
||||||
apply : PTerm -> List PArg -> PTerm
|
|
||||||
apply = foldl $ \f, x => case x of T x => f :@ x; D p => f :% p
|
|
||||||
|
|
||||||
private
|
|
||||||
annotate : PTerm -> Maybe PTerm -> PTerm
|
|
||||||
annotate s a = maybe s (s :#) a
|
|
||||||
|
|
||||||
|
|
||||||
export
|
export
|
||||||
res : (str : String) -> (0 _ : IsReserved str) => Grammar True ()
|
res : (str : String) -> (0 _ : IsReserved str) => Grammar True ()
|
||||||
|
@ -167,19 +155,15 @@ private
|
||||||
makeSig : MakeBinder 0
|
makeSig : MakeBinder 0
|
||||||
makeSig = ("×", \([], x, s) => Sig x s)
|
makeSig = ("×", \([], x, s) => Sig x s)
|
||||||
|
|
||||||
private
|
|
||||||
plural : Nat -> a -> a -> a
|
|
||||||
plural 1 s p = s
|
|
||||||
plural _ s p = p
|
|
||||||
|
|
||||||
private
|
private
|
||||||
makeBinder : {m, n : Nat} -> MakeBinder m -> PBinderHead n -> PTerm ->
|
makeBinder : {m, n : Nat} -> MakeBinder m -> PBinderHead n -> PTerm ->
|
||||||
Grammar False PTerm
|
Grammar False PTerm
|
||||||
makeBinder (str, f) h t =
|
makeBinder (str, f) h t =
|
||||||
case decEq m n of
|
case decEq m n of
|
||||||
Yes Refl => pure $ f h t
|
Yes Refl => pure $ f h t
|
||||||
No _ => fatalError
|
No _ =>
|
||||||
"'\{str}' expects \{show m} quantit\{plural m "y" "ies"}, got \{show n}"
|
let q = if m == 1 then "quantity" else "quantities" in
|
||||||
|
fatalError "'\{str}' expects \{show m} \{q}, got \{show n}"
|
||||||
|
|
||||||
private
|
private
|
||||||
binderInfix : Grammar True (n ** MakeBinder n)
|
binderInfix : Grammar True (n ** MakeBinder n)
|
||||||
|
@ -208,6 +192,9 @@ mutual
|
||||||
<|> caseTerm
|
<|> caseTerm
|
||||||
<|> bindTerm
|
<|> bindTerm
|
||||||
<|> [|annotate infixEqTerm (optional $ resC "∷" *> term)|]
|
<|> [|annotate infixEqTerm (optional $ resC "∷" *> term)|]
|
||||||
|
where
|
||||||
|
annotate : PTerm -> Maybe PTerm -> PTerm
|
||||||
|
annotate s a = maybe s (s :#) a
|
||||||
|
|
||||||
private covering
|
private covering
|
||||||
lamTerm : Grammar True PTerm
|
lamTerm : Grammar True PTerm
|
||||||
|
@ -248,11 +235,15 @@ mutual
|
||||||
appTerm = resC "★" *> [|TYPE nat|]
|
appTerm = resC "★" *> [|TYPE nat|]
|
||||||
<|> resC "Eq" *> [|Eq (bracks optBinderTerm) aTerm aTerm|]
|
<|> resC "Eq" *> [|Eq (bracks optBinderTerm) aTerm aTerm|]
|
||||||
<|> [|apply aTerm (many appArg)|]
|
<|> [|apply aTerm (many appArg)|]
|
||||||
|
where
|
||||||
|
data PArg = T PTerm | D PDim
|
||||||
|
|
||||||
private covering
|
appArg : Grammar True PArg
|
||||||
appArg : Grammar True PArg
|
appArg = [|D $ resC "@" *> dim|]
|
||||||
appArg = [|D $ resC "@" *> dim|]
|
<|> [|T aTerm|]
|
||||||
<|> [|T aTerm|]
|
|
||||||
|
apply : PTerm -> List PArg -> PTerm
|
||||||
|
apply = foldl $ \f, x => case x of T x => f :@ x; D p => f :% p
|
||||||
|
|
||||||
private covering
|
private covering
|
||||||
aTerm : Grammar True PTerm
|
aTerm : Grammar True PTerm
|
||||||
|
@ -269,8 +260,24 @@ mutual
|
||||||
name <- bname
|
name <- bname
|
||||||
resC ":"
|
resC ":"
|
||||||
ty <- term
|
ty <- term
|
||||||
pure (_ ** (qs.snd, name, ty))
|
pure (qs.fst ** (qs.snd, name, ty))
|
||||||
|
|
||||||
private covering
|
private covering
|
||||||
optBinderTerm : Grammar True (BName, PTerm)
|
optBinderTerm : Grammar True (BName, PTerm)
|
||||||
optBinderTerm = [|MkPair optNameBinder term|]
|
optBinderTerm = [|MkPair optNameBinder term|]
|
||||||
|
|
||||||
|
|
||||||
|
export covering
|
||||||
|
defIntro : Grammar True PQty
|
||||||
|
defIntro = Zero <$ resC "def0"
|
||||||
|
<|> Any <$ resC "defω"
|
||||||
|
<|> resC "def" *> option Any (qty <* resC "·")
|
||||||
|
|
||||||
|
export covering
|
||||||
|
definition : Grammar True PDefinition
|
||||||
|
definition =
|
||||||
|
[|MkPDef defIntro name (resC ":" *> term) (resC "≔" *> term)|] <* resC ";"
|
||||||
|
|
||||||
|
export covering
|
||||||
|
input : Grammar False (List PDefinition)
|
||||||
|
input = many definition
|
||||||
|
|
|
@ -2,6 +2,7 @@ module Quox.Parser.Syntax
|
||||||
|
|
||||||
import public Quox.Syntax
|
import public Quox.Syntax
|
||||||
import public Quox.Syntax.Qty.Three
|
import public Quox.Syntax.Qty.Three
|
||||||
|
import public Quox.Definition
|
||||||
|
|
||||||
import public Control.Monad.Either
|
import public Control.Monad.Either
|
||||||
|
|
||||||
|
@ -65,6 +66,17 @@ namespace PTerm
|
||||||
%runElab deriveMutual ["PTerm", "PCaseBody"] [Eq, Ord, Show]
|
%runElab deriveMutual ["PTerm", "PCaseBody"] [Eq, Ord, Show]
|
||||||
|
|
||||||
|
|
||||||
|
public export
|
||||||
|
record PDefinition where
|
||||||
|
constructor MkPDef
|
||||||
|
qty : PQty
|
||||||
|
name : Name
|
||||||
|
type : PTerm
|
||||||
|
term : PTerm
|
||||||
|
%name PDefinition def
|
||||||
|
%runElab derive "PDefinition" [Eq, Ord, Show]
|
||||||
|
|
||||||
|
|
||||||
export
|
export
|
||||||
toPDimWith : Context' BaseName d -> Dim d -> PDim
|
toPDimWith : Context' BaseName d -> Dim d -> PDim
|
||||||
toPDimWith ds (K e) = K e
|
toPDimWith ds (K e) = K e
|
||||||
|
@ -163,6 +175,7 @@ data FromPTermError =
|
||||||
AnnotationNeeded PTerm
|
AnnotationNeeded PTerm
|
||||||
| DuplicatesInEnum (List TagVal)
|
| DuplicatesInEnum (List TagVal)
|
||||||
| DimNotInScope Name
|
| DimNotInScope Name
|
||||||
|
| QtyNotGlobal PQty
|
||||||
|
|
||||||
public export
|
public export
|
||||||
FromPTerm : (Type -> Type) -> Type
|
FromPTerm : (Type -> Type) -> Type
|
||||||
|
@ -189,8 +202,8 @@ export
|
||||||
fromPDimWith : FromPTerm m =>
|
fromPDimWith : FromPTerm m =>
|
||||||
Context' BName d -> PDim -> m (Dim d)
|
Context' BName d -> PDim -> m (Dim d)
|
||||||
fromPDimWith ds (K e) = pure $ K e
|
fromPDimWith ds (K e) = pure $ K e
|
||||||
fromPDimWith ds (V i) =
|
fromPDimWith ds (V i) = fromBaseName (pure . B) (throwError . DimNotInScope) ds i
|
||||||
fromBaseName (pure . B) (throwError . DimNotInScope) ds i
|
|
||||||
|
|
||||||
mutual
|
mutual
|
||||||
export
|
export
|
||||||
|
@ -298,3 +311,22 @@ mutual
|
||||||
export %inline
|
export %inline
|
||||||
fromPTerm : FromPTerm m => PTerm -> m (Term Three 0 0)
|
fromPTerm : FromPTerm m => PTerm -> m (Term Three 0 0)
|
||||||
fromPTerm = fromPTermWith [<] [<]
|
fromPTerm = fromPTermWith [<] [<]
|
||||||
|
|
||||||
|
|
||||||
|
export
|
||||||
|
globalPQty : FromPTerm m => (q : PQty) -> m (IsGlobal q)
|
||||||
|
globalPQty Zero = pure GZero
|
||||||
|
globalPQty One = throwError $ QtyNotGlobal One
|
||||||
|
globalPQty Any = pure GAny
|
||||||
|
|
||||||
|
|
||||||
|
-- [todo] extend substitutions so they can do this injection. that's the sort of
|
||||||
|
-- thing they are for.
|
||||||
|
export
|
||||||
|
fromPDefinition : FromPTerm m => PDefinition -> m (Name, Definition Three)
|
||||||
|
fromPDefinition (MkPDef {name, qty, type, term}) =
|
||||||
|
pure (name, MkDef' {
|
||||||
|
qty, qtyGlobal = !(globalPQty qty),
|
||||||
|
type = T $ inject !(fromPTerm type),
|
||||||
|
term = Just $ T $ inject !(fromPTerm term)
|
||||||
|
})
|
||||||
|
|
|
@ -127,3 +127,9 @@ DecEq (Dim d) where
|
||||||
public export %inline
|
public export %inline
|
||||||
BV : (i : Nat) -> (0 _ : LT i d) => Dim d
|
BV : (i : Nat) -> (0 _ : LT i d) => Dim d
|
||||||
BV i = B $ V i
|
BV i = B $ V i
|
||||||
|
|
||||||
|
|
||||||
|
export
|
||||||
|
inject : {0 d' : Nat} -> Dim d -> Dim (d + d')
|
||||||
|
inject (K e) = K e
|
||||||
|
inject (B i) = B $ inject i
|
||||||
|
|
|
@ -120,6 +120,21 @@ ssDownViaNat by =
|
||||||
%transform "Shift.ssDown" ssDown = ssDownViaNat
|
%transform "Shift.ssDown" ssDown = ssDownViaNat
|
||||||
|
|
||||||
|
|
||||||
|
public export
|
||||||
|
inject : Shift from to -> Shift (from + n') (to + n')
|
||||||
|
inject SZ = SZ
|
||||||
|
inject (SS by) = SS (inject by)
|
||||||
|
|
||||||
|
public export
|
||||||
|
injectViaNat : Shift from to -> Shift (from + n') (to + n')
|
||||||
|
injectViaNat by =
|
||||||
|
rewrite shiftDiff by in
|
||||||
|
rewrite sym $ plusAssociative by.nat from n' in
|
||||||
|
fromNat by.nat
|
||||||
|
|
||||||
|
%transform "Shift.inject" Shift.inject = Shift.injectViaNat
|
||||||
|
|
||||||
|
|
||||||
public export
|
public export
|
||||||
shift : Shift from to -> Var from -> Var to
|
shift : Shift from to -> Var from -> Var to
|
||||||
shift SZ i = i
|
shift SZ i = i
|
||||||
|
|
|
@ -299,3 +299,77 @@ mutual
|
||||||
pushSubstsWith th (comp th ps ph) e
|
pushSubstsWith th (comp th ps ph) e
|
||||||
pushSubstsWith th ph (DCloE e ps) =
|
pushSubstsWith th ph (DCloE e ps) =
|
||||||
pushSubstsWith (ps . th) ph e
|
pushSubstsWith (ps . th) ph e
|
||||||
|
|
||||||
|
|
||||||
|
parameters {0 d', n' : Nat}
|
||||||
|
mutual
|
||||||
|
namespace Term
|
||||||
|
export
|
||||||
|
inject : Term q d n -> Term q (d + d') (n + n')
|
||||||
|
inject (TYPE l) = TYPE l
|
||||||
|
inject (Pi qty arg res) = Pi qty (inject arg) (inject res)
|
||||||
|
inject (Lam body) = Lam (inject body)
|
||||||
|
inject (Sig fst snd) = Sig (inject fst) (inject snd)
|
||||||
|
inject (Pair fst snd) = Pair (inject fst) (inject snd)
|
||||||
|
inject (Enum cases) = Enum cases
|
||||||
|
inject (Tag tag) = Tag tag
|
||||||
|
inject (Eq ty l r) = Eq (inject ty) (inject l) (inject r)
|
||||||
|
inject (DLam body) = DLam (inject body)
|
||||||
|
inject (E e) = E (inject e)
|
||||||
|
inject (CloT tm th) = CloT (inject tm) (inject th)
|
||||||
|
inject (DCloT tm th) = DCloT (inject tm) (inject th)
|
||||||
|
|
||||||
|
namespace Elim
|
||||||
|
export
|
||||||
|
inject : Elim q d n -> Elim q (d + d') (n + n')
|
||||||
|
inject (F x) = F x
|
||||||
|
inject (B i) = B $ inject i
|
||||||
|
inject (fun :@ arg) = (inject fun) :@ (inject arg)
|
||||||
|
inject (CasePair qty pair ret body) =
|
||||||
|
CasePair qty (inject pair) (inject ret) (inject body)
|
||||||
|
inject (CaseEnum qty tag ret arms) =
|
||||||
|
CaseEnum qty (inject tag) (inject ret)
|
||||||
|
(assert_total $ map inject arms)
|
||||||
|
inject (fun :% arg) = (inject fun) :% (inject arg)
|
||||||
|
inject (tm :# ty) = (inject tm) :# (inject ty)
|
||||||
|
inject (CloE el th) = CloE (inject el) (inject th)
|
||||||
|
inject (DCloE el th) = DCloE (inject el) (inject th)
|
||||||
|
|
||||||
|
namespace ScopeTerm
|
||||||
|
export
|
||||||
|
inject : ScopeTermN s q d n -> ScopeTermN s q (d + d') (n + n')
|
||||||
|
inject (S names (N body)) = S names (N (inject body))
|
||||||
|
inject (S names (Y body)) {s, n} =
|
||||||
|
S names $ Y $ rewrite plusAssociative s n n' in inject body
|
||||||
|
|
||||||
|
namespace DScopeTerm
|
||||||
|
export
|
||||||
|
inject : DScopeTermN s q d n -> DScopeTermN s q (d + d') (n + n')
|
||||||
|
inject (S names (N body)) = S names (N (inject body))
|
||||||
|
inject (S names (Y body)) {s, d} =
|
||||||
|
S names $ Y $ rewrite plusAssociative s d d' in inject body
|
||||||
|
|
||||||
|
namespace TSubst
|
||||||
|
export
|
||||||
|
inject : TSubst q d from to -> TSubst q (d + d') (from + n') (to + n')
|
||||||
|
inject (Shift by) = Shift $ inject by
|
||||||
|
inject (t ::: th) = inject t ::: inject th
|
||||||
|
|
||||||
|
namespace DSubst
|
||||||
|
export
|
||||||
|
inject : DSubst from to -> DSubst (from + d') (to + d')
|
||||||
|
inject (Shift by) = Shift $ inject by
|
||||||
|
inject (p ::: th) = inject p ::: inject th
|
||||||
|
|
||||||
|
|
||||||
|
-- [fixme]
|
||||||
|
-- Error: Linearity checking failed on metavar Quox.Syntax.Term.Subst.{b:7362}
|
||||||
|
-- (Int not a function type)
|
||||||
|
{-
|
||||||
|
%transform "Term.inject" Term.inject t = believe_me t
|
||||||
|
%transform "Elim.inject" Elim.inject e = believe_me e
|
||||||
|
%transform "ScopeTerm.inject" ScopeTerm.inject t = believe_me t
|
||||||
|
%transform "DScopeTerm.inject" DScopeTerm.inject t = believe_me t
|
||||||
|
%transform "TSubst.inject" TSubst.inject th = believe_me th
|
||||||
|
%transform "DSubst.inject" DSubst.inject th = believe_me th
|
||||||
|
-}
|
||||||
|
|
|
@ -111,6 +111,18 @@ toFromNat 0 (LTESucc x) = Refl
|
||||||
toFromNat (S k) (LTESucc x) = cong S $ toFromNat k x
|
toFromNat (S k) (LTESucc x) = cong S $ toFromNat k x
|
||||||
|
|
||||||
|
|
||||||
|
export
|
||||||
|
inject : Var m -> Var (m + n)
|
||||||
|
inject VZ = VZ
|
||||||
|
inject (VS i) = VS $ inject i
|
||||||
|
|
||||||
|
private
|
||||||
|
injectViaNat : Var m -> Var (m + n)
|
||||||
|
injectViaNat i = fromNatWith i.nat (toNatLT i `transitive` lteAddRight m)
|
||||||
|
|
||||||
|
%transform "Var.inject" Var.inject = injectViaNat
|
||||||
|
|
||||||
|
|
||||||
-- not using %transform like other things because weakSpec requires the proof
|
-- not using %transform like other things because weakSpec requires the proof
|
||||||
-- to be relevant. but since only `LTESucc` is ever possible that seems
|
-- to be relevant. but since only `LTESucc` is ever possible that seems
|
||||||
-- to be an instance of <https://github.com/idris-lang/Idris2/issues/1259>?
|
-- to be an instance of <https://github.com/idris-lang/Idris2/issues/1259>?
|
||||||
|
|
|
@ -54,10 +54,10 @@ tests = "lexer" :- [
|
||||||
|
|
||||||
"identifiers & keywords" :- [
|
"identifiers & keywords" :- [
|
||||||
lexes "abc" [I "abc"],
|
lexes "abc" [I "abc"],
|
||||||
lexes "abc def" [I "abc", I "def"],
|
lexes "abc def" [I "abc", R "def"],
|
||||||
lexes "abc_def" [I "abc_def"],
|
lexes "abc_def" [I "abc_def"],
|
||||||
lexes "abc-def" [I "abc-def"],
|
lexes "abc-def" [I "abc-def"],
|
||||||
lexes "abc{-comment-}def" [I "abc", I "def"],
|
lexes "abc{-comment-}def" [I "abc", R "def"],
|
||||||
lexes "λ" [R "λ"],
|
lexes "λ" [R "λ"],
|
||||||
lexes "fun" [R "λ"],
|
lexes "fun" [R "λ"],
|
||||||
lexes "δ" [R "δ"],
|
lexes "δ" [R "δ"],
|
||||||
|
|
|
@ -237,5 +237,25 @@ tests = "parser" :- [
|
||||||
Case Any (V "t") (Nothing, V "A") (CaseEnum []),
|
Case Any (V "t") (Nothing, V "A") (CaseEnum []),
|
||||||
parsesAs term "case# t return A of {}" $
|
parsesAs term "case# t return A of {}" $
|
||||||
Case Any (V "t") (Nothing, V "A") (CaseEnum [])
|
Case Any (V "t") (Nothing, V "A") (CaseEnum [])
|
||||||
|
],
|
||||||
|
|
||||||
|
"definitions" :- [
|
||||||
|
parsesAs definition "defω x : (_: {a}) × {b} ≔ ('a, 'b);" $
|
||||||
|
MkPDef Any "x" (Sig Nothing (Enum ["a"]) (Enum ["b"]))
|
||||||
|
(Pair (Tag "a") (Tag "b")),
|
||||||
|
parsesAs definition "def# x : (_: {a}) ** {b} ≔ ('a, 'b);" $
|
||||||
|
MkPDef Any "x" (Sig Nothing (Enum ["a"]) (Enum ["b"]))
|
||||||
|
(Pair (Tag "a") (Tag "b")),
|
||||||
|
parsesAs definition "def ω·x : (_: {a}) × {b} ≔ ('a, 'b);" $
|
||||||
|
MkPDef Any "x" (Sig Nothing (Enum ["a"]) (Enum ["b"]))
|
||||||
|
(Pair (Tag "a") (Tag "b")),
|
||||||
|
parsesAs definition "def x : (_: {a}) × {b} ≔ ('a, 'b);" $
|
||||||
|
MkPDef Any "x" (Sig Nothing (Enum ["a"]) (Enum ["b"]))
|
||||||
|
(Pair (Tag "a") (Tag "b")),
|
||||||
|
parsesAs definition "def0 A : ★₀ ≔ {a, b, c};" $
|
||||||
|
MkPDef Zero "A" (TYPE 0) (Enum ["a", "b", "c"]),
|
||||||
|
parsesAs input "def0 A : ★₀ ≔ {}; def0 B : ★₁ ≔ A;" $
|
||||||
|
[MkPDef Zero "A" (TYPE 0) (Enum []),
|
||||||
|
MkPDef Zero "B" (TYPE 1) (V "A")]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue