crude but effective stratification

This commit is contained in:
rhiannon morris 2023-05-21 20:09:34 +02:00
parent e4a20cc632
commit 42aa07c9c8
31 changed files with 817 additions and 582 deletions

View file

@ -83,15 +83,16 @@ avoidDim ds loc x =
fromName (const $ throw $ DimNameInTerm loc x.base) (pure . fromPName) ds x
private
resolveName : Mods -> Loc -> Name -> Eff FromParserPure (Term d n)
resolveName ns loc x =
resolveName : Mods -> Loc -> Name -> Maybe Universe ->
Eff FromParserPure (Term d n)
resolveName ns loc x u =
let here = addMods ns x in
if isJust $ lookup here !(getAt DEFS) then
pure $ FT here loc
pure $ FT here (fromMaybe 0 u) loc
else do
let ns :< _ = ns
| _ => throw $ TermNotInScope loc x
resolveName ns loc x
resolveName ns loc x u
export
fromPatVar : PatVar -> BindName
@ -107,6 +108,17 @@ fromPTagVal : PTagVal -> TagVal
fromPTagVal (PT t _) = t
private
fromV : Context' PatVar d -> Context' PatVar n ->
PName -> Maybe Universe -> Loc -> Eff FromParserPure (Term d n)
fromV ds ns x u loc = fromName bound free ns x where
bound : Var n -> Eff FromParserPure (Term d n)
bound i = do whenJust u $ \u => throw $ DisplacedBoundVar loc x
pure $ E $ B i loc
free : PName -> Eff FromParserPure (Term d n)
free x = do x <- avoidDim ds loc x
resolveName !(getAt NS) loc x u
mutual
export
fromPTermWith : Context' PatVar d -> Context' PatVar n ->
@ -199,9 +211,7 @@ mutual
<*> fromPTermTScope ds ns [< b] body
<*> pure loc
V x loc =>
fromName (\i => pure $ E $ B i loc)
(resolveName !(getAt NS) loc <=< avoidDim ds loc) ns x
V x u loc => fromV ds ns x u loc
Ann s a loc =>
map E $ Ann

View file

@ -24,6 +24,7 @@ data Error =
| DimNotInScope Loc PBaseName
| QtyNotGlobal Loc Qty
| DimNameInTerm Loc PBaseName
| DisplacedBoundVar Loc PName
| WrapTypeError TypeError
| LoadError Loc String FileError
| WrapParseError String ParseError
@ -89,6 +90,11 @@ parameters (showContext : Bool)
(sep ["dimension" <++> !(hl DVar $ text i),
"used in a term context"])
prettyError (DisplacedBoundVar loc x) = pure $
vappend !(prettyLoc loc)
(sep ["local variable" <++> !(hl TVar $ text $ toDotsP x),
"cannot be displaced"])
prettyError (WrapTypeError err) =
Typing.prettyError showContext $ trimContext 2 err

View file

@ -21,7 +21,8 @@ import Derive.Prelude
||| @ Nat nat literal
||| @ String string literal
||| @ Tag tag literal
||| @ TYPE "Type" or "★" with subscript
||| @ TYPE "Type" or "★" with ascii nat directly after
||| @ Sup superscript or ^ number (displacement, or universe for ★)
public export
data Token =
Reserved String
@ -30,6 +31,7 @@ data Token =
| Str String
| Tag String
| TYPE Nat
| Sup Nat
%runElab derive "Token" [Eq, Ord, Show]
-- token or whitespace
@ -94,21 +96,33 @@ fromSub c = case c of
'' => '0'; '' => '1'; '' => '2'; '' => '3'; '' => '4'
'' => '5'; '' => '6'; '' => '7'; '' => '8'; '' => '9'; _ => c
private %inline
fromSup : Char -> Char
fromSup c = case c of
'' => '0'; '¹' => '1'; '²' => '2'; '³' => '3'; '' => '4'
'' => '5'; '' => '6'; '' => '7'; '' => '8'; '' => '9'; _ => c
private %inline
subToNat : String -> Nat
subToNat = cast . pack . map fromSub . unpack
private %inline
supToNat : String -> Nat
supToNat = cast . pack . map fromSup . unpack
-- ★0, Type0. base ★/Type is a Reserved
private
universe : Tokenizer TokenW
universe = universeWith "" <|> universeWith "Type" where
universeWith : String -> Tokenizer TokenW
universeWith pfx =
let len = length pfx in
match (exact pfx <+> some (range '0' '9'))
(TYPE . cast . drop len) <|>
match (exact pfx <+> some (range '' ''))
(TYPE . subToNat . drop len)
match (exact pfx <+> digits) (TYPE . cast . drop len)
private
sup : Tokenizer TokenW
sup = match (some $ pred isSupDigit) (Sup . supToNat)
<|> match (is '^' <+> digits) (Sup . cast . drop 1)
private %inline
@ -219,7 +233,7 @@ tokens = choice $
blockComment (exact "{-") (exact "-}")] <+>
[universe] <+> -- ★ᵢ takes precedence over bare ★
map resTokenizer reserved <+>
[nat, string, tag, name]
[sup, nat, string, tag, name]
export
lex : String -> Either Error (List (WithBounds Token))

View file

@ -106,10 +106,14 @@ export
strLit : Grammar True String
strLit = terminalMatch "string literal" `(Str s) `(s)
||| single-token universe, like ★ or Type1
||| single-token universe, like ★0 or Type1
export
universe1 : Grammar True Universe
universe1 = terminalMatch "universe" `(TYPE u) `(u)
universeTok : Grammar True Universe
universeTok = terminalMatch "universe" `(TYPE u) `(u)
export
super : Grammar True Nat
super = terminalMatch "superscript number or '^'" `(Sup n) `(n)
||| possibly-qualified name
export
@ -134,6 +138,11 @@ qtyVal = terminalMatchN "quantity"
[(`(Nat 0), `(Zero)), (`(Nat 1), `(One)), (`(Reserved "ω"), `(Any))]
||| optional superscript number
export
displacement : Grammar False (Maybe Universe)
displacement = optional super
||| quantity (0, 1, or ω)
export
qty : FileName -> Grammar True PQty
@ -263,6 +272,10 @@ tupleTerm fname = withLoc fname $ do
terms <- delimSep1 "(" ")" "," $ assert_total term fname
pure $ \loc => foldr1 (\s, t => Pair s t loc) terms
export
universe1 : Grammar True Universe
universe1 = universeTok <|> res "" *> super
||| argument/atomic term: single-token terms, or those with delimiters e.g.
||| `[t]`
export
@ -275,7 +288,7 @@ termArg fname = withLoc fname $
<|> Nat <$ res ""
<|> Zero <$ res "zero"
<|> [|fromNat nat|]
<|> [|V qname|]
<|> [|V qname displacement|]
<|> const <$> tupleTerm fname
export
@ -345,7 +358,10 @@ compTerm fname = withLoc fname $ do
export
splitUniverseTerm : FileName -> Grammar True PTerm
splitUniverseTerm fname = withLoc fname $ resC "" *> mustWork [|TYPE nat|]
splitUniverseTerm fname =
withLoc fname $ resC "" *> mustWork [|TYPE $ nat <|> super|]
-- having super here looks redundant, but when parsing a non-atomic term
-- this branch will be taken first
export
eqTerm : FileName -> Grammar True PTerm

View file

@ -87,7 +87,7 @@ namespace PTerm
| BOX PQty PTerm Loc
| Box PTerm Loc
| V PName Loc
| V PName (Maybe Universe) Loc
| Ann PTerm PTerm Loc
| Coe (PatVar, PTerm) PDim PDim PTerm Loc
@ -124,7 +124,7 @@ Located PTerm where
(Succ _ loc).loc = loc
(BOX _ _ loc).loc = loc
(Box _ loc).loc = loc
(V _ loc).loc = loc
(V _ _ loc).loc = loc
(Ann _ _ loc).loc = loc
(Coe _ _ _ _ loc).loc = loc
(Comp _ _ _ _ _ _ _ loc).loc = loc