diff options
author | Greg Brown <greg.brown01@ed.ac.uk> | 2024-09-17 17:09:41 +0100 |
---|---|---|
committer | Greg Brown <greg.brown01@ed.ac.uk> | 2024-09-17 17:09:41 +0100 |
commit | 974717f0aa46bb295d44e239594b38f63f39ceab (patch) | |
tree | 73eaa9501f4c79328d98bf5257529d8495f6c756 /src/Inky/Parser.idr | |
parent | b2d6c85d420992270c37eba055cdc3952985c70e (diff) |
Introduce names in contexts.
Introduce rows for n-ary sums and products.
Remove union types.
Diffstat (limited to 'src/Inky/Parser.idr')
-rw-r--r-- | src/Inky/Parser.idr | 183 |
1 files changed, 45 insertions, 138 deletions
diff --git a/src/Inky/Parser.idr b/src/Inky/Parser.idr index 047165c..1ad48d8 100644 --- a/src/Inky/Parser.idr +++ b/src/Inky/Parser.idr @@ -7,116 +7,9 @@ import Data.List.Elem import Data.List1 import Data.Nat import Data.So +import Inky.Context +import Text.Lexer --- Contexts -------------------------------------------------------------------- - -export -infix 2 :- - -export -prefix 2 %% - -public export -record Assoc (a : Type) where - constructor (:-) - 0 name : String - value : a - -public export -data Context : Type -> Type where - Lin : Context a - (:<) : Context a -> Assoc a -> Context a - -%name Context ctx - -public export -data Length : Context a -> Type where - Z : Length [<] - S : Length ctx -> Length (ctx :< x) - -%name Length len - -public export -(++) : Context a -> Context a -> Context a -ctx ++ [<] = ctx -ctx ++ ctx' :< x = (ctx ++ ctx') :< x - -lengthAppend : Length ctx1 -> Length ctx2 -> Length (ctx1 ++ ctx2) -lengthAppend len1 Z = len1 -lengthAppend len1 (S len2) = S (lengthAppend len1 len2) - --- Variableents - -public export -data VariablePos : Context a -> (0 x : String) -> a -> Type where - [search x] - Here : VariablePos (ctx :< (x :- v)) x v - There : VariablePos ctx x v -> VariablePos (ctx :< y) x v - -public export -record Variable (ctx : Context a) (v : a) where - constructor (%%) - 0 name : String - {auto pos : VariablePos ctx name v} - -toVar : VariablePos ctx x v -> Variable ctx v -toVar pos = (%%) x {pos} - -wknLPos : VariablePos ctx1 x v -> Length ctx2 -> VariablePos (ctx1 ++ ctx2) x v -wknLPos x Z = x -wknLPos x (S len) = There (wknLPos x len) - -wknRPos : VariablePos ctx2 x v -> VariablePos (ctx1 ++ ctx2) x v -wknRPos Here = Here -wknRPos (There x) = There (wknRPos x) - -splitPos : Length ctx2 -> VariablePos (ctx1 ++ ctx2) x v -> Either (VariablePos ctx1 x v) (VariablePos ctx2 x v) -splitPos Z x = Left x -splitPos (S len) Here = Right Here -splitPos (S len) (There x) = mapSnd There $ splitPos len x - -wknL : {auto len : Length ctx2} -> Variable ctx1 v -> Variable (ctx1 ++ ctx2) v -wknL x = (%%) x.name {pos = wknLPos x.pos len} - -wknR : Variable ctx2 v -> Variable (ctx1 ++ ctx2) v -wknR x = (%%) x.name {pos = wknRPos x.pos} - -split : {auto len : Length ctx2} -> Variable (ctx1 ++ ctx2) x -> Either (Variable ctx1 x) (Variable ctx2 x) -split x = bimap toVar toVar $ splitPos len x.pos - -lift : - {auto len : Length ctx} -> - (forall x. Variable ctx1 x -> Variable ctx2 x) -> - Variable (ctx1 ++ ctx) x -> Variable (ctx2 ++ ctx) x -lift f = either (wknL {len} . f) wknR . split {len} - --- Environments - -namespace Quantifier - public export - data All : (0 p : a -> Type) -> Context a -> Type where - Lin : All p [<] - (:<) : All p ctx -> (px : p x.value) -> All p (ctx :< x) - - %name Quantifier.All env - - indexAllPos : VariablePos ctx x v -> All p ctx -> p v - indexAllPos Here (env :< px) = px - indexAllPos (There x) (env :< px) = indexAllPos x env - - export - indexAll : Variable ctx v -> All p ctx -> p v - indexAll x env = indexAllPos x.pos env - - export - mapProperty : ({0 x : a} -> p x -> q x) -> All p ctx -> All q ctx - mapProperty f [<] = [<] - mapProperty f (env :< px) = mapProperty f env :< f px - - export - (++) : All p ctx1 -> All p ctx2 -> All p (ctx1 ++ ctx2) - env1 ++ [<] = env1 - env1 ++ env2 :< px = (env1 ++ env2) :< px -- Parser Expressions ---------------------------------------------------------- @@ -131,10 +24,10 @@ linUnless True ctx = ctx public export data Parser : (i : Type) -> (nil : Bool) -> (locked, free : Context (Bool, Type)) -> Type -> Type where - Var : (f : a -> b) -> Variable free (nil, a) -> Parser i nil locked free b + Var : (f : a -> b) -> Var free (nil, a) -> Parser i nil locked free b Fail : (msg : String) -> Parser i False locked free a Empty : (x : a) -> Parser i True locked free a - Lit : (text : i) -> (x : a) -> Parser i False locked free a + Lit : (text : i) -> (x : String -> a) -> Parser i False locked free a (<**>) : {nil1, nil2 : Bool} -> Parser i nil1 locked free (a -> b) -> @@ -158,7 +51,7 @@ Functor (Parser i nil locked free) where map f (Var g x) = Var (f . g) x map f (Fail msg) = Fail msg map f (Empty x) = Empty (f x) - map f (Lit text x) = Lit text (f x) + map f (Lit text g) = Lit text (f . g) map f ((<**>) {nil1 = True} p q) = map (f .) p <**> q map f ((<**>) {nil1 = False} p q) = map (f .) p <**> q map f (p <|> q) = map f p <|> map f q @@ -209,7 +102,7 @@ follow penv1 penv2 fenv1 fenv2 (Fix x f p) = -- Proof: -- - we always add information -- - no step depends on existing information - follow (penv1 :< peek penv2 p) penv2 (fenv1 :< empty) fenv2 p + follow (penv1 :< (x :- peek penv2 p)) penv2 (fenv1 :< (x :- empty)) fenv2 p export WellTyped : @@ -246,8 +139,8 @@ WellTyped penv1 penv2 fenv1 fenv2 (p <|> q) = ) WellTyped penv1 penv2 fenv1 fenv2 (Fix x f p) = let fst = peek penv2 p in - let flw = follow (penv1 :< fst) penv2 (fenv1 :< empty) fenv2 p in - WellTyped (penv1 :< fst) penv2 (fenv1 :< flw) fenv2 p + let flw = follow (penv1 :< (x :- fst)) penv2 (fenv1 :< (x :- empty)) fenv2 p in + WellTyped (penv1 :< (x :- fst)) penv2 (fenv1 :< (x :- flw)) fenv2 p -- Parsing Function ------------------------------------------------------------ @@ -320,9 +213,9 @@ parser : (fenv1 : _) -> (fenv2 : _) -> {auto 0 wf : WellTyped penv1 penv2 fenv1 fenv2 p} -> - (xs : List i) -> - All (\x => (ys : List i) -> (0 _ : SmallerX False ys xs) -> uncurry (M ys) x) locked -> - All (\x => (ys : List i) -> (0 _ : SmallerX True ys xs) -> uncurry (M ys) x) free -> + (xs : List (WithBounds (Token i))) -> + All (\x => (ys : List (WithBounds (Token i))) -> (0 _ : SmallerX False ys xs) -> uncurry (M ys) x) locked -> + All (\x => (ys : List (WithBounds (Token i))) -> (0 _ : SmallerX True ys xs) -> uncurry (M ys) x) free -> M xs nil a parser (Var f x) penv1 penv2 fenv1 fenv2 xs env1 env2 = f <$> indexAll x env2 xs (Lax reflexive) @@ -330,13 +223,13 @@ parser (Fail msg) penv1 penv2 fenv1 fenv2 xs env1 env2 = Err msg parser (Empty x) penv1 penv2 fenv1 fenv2 xs env1 env2 = Ok x xs (Lax reflexive) -parser (Lit text x) penv1 penv2 fenv1 fenv2 xs env1 env2 = +parser (Lit text f) penv1 penv2 fenv1 fenv2 xs env1 env2 = case xs of [] => Err "expected \{text}, got end of file" y :: ys => - if y == text - then Ok x ys (Strict reflexive) - else Err "expected \{text}, got \{y}" + if y.val.kind == text + then Ok (f y.val.text) ys (Strict reflexive) + else Err "\{show y.bounds}: expected \{text}, got \{y.val.kind}" parser ((<**>) {nil1 = False, nil2} p q) penv1 penv2 fenv1 fenv2 xs env1 env2 = case parser p penv1 penv2 fenv1 fenv2 xs env1 env2 of Err msg => Err msg @@ -372,15 +265,15 @@ parser ((<|>) {nil1, nil2} p q) penv1 penv2 fenv1 fenv2 xs env1 env2 = then parser q penv1 penv2 fenv1 fenv2 [] env1 env2 else Err "unexpected end of input" x :: xs => - if elem x (peek penv2 p) + if elem x.val.kind (peek penv2 p) then wknL (parser p penv1 penv2 fenv1 fenv2 (x :: xs) env1 env2) nil2 - else if elem x (peek penv2 q) + else if elem x.val.kind (peek penv2 q) then wknR nil1 (parser q penv1 penv2 fenv1 fenv2 (x :: xs) env1 env2) else if nil1 then parser p penv1 penv2 fenv1 fenv2 (x :: xs) env1 env2 else if nil2 then parser q penv1 penv2 fenv1 fenv2 (x :: xs) env1 env2 - else Err "unexpected token \{x}" + else Err "\{show x.bounds}: unexpected \{x.val.kind}" parser (Fix {a, b, nil} x f p) penv1 penv2 fenv1 fenv2 xs env1 env2 = let g = parser p _ _ _ _ {wf} in let @@ -390,7 +283,7 @@ parser (Fix {a, b, nil} x f p) penv1 penv2 fenv1 fenv2 xs env1 env2 = (\ys, rec, lte => g ys ( mapProperty (\f, zs, 0 prf => f zs $ transX prf lte) env1 - :< (\zs, prf => rec zs (toSmaller prf) (forget $ transX prf lte)) + :< (x :- (\zs, prf => rec zs (toSmaller prf) (forget $ transX prf lte))) ) (mapProperty (\f, zs, prf => f zs $ transX prf lte) env2)) xs @@ -403,7 +296,7 @@ parse : Eq i => Interpolation i => (p : Parser i nil [<] [<] a) -> {auto 0 wf : WellTyped [<] [<] [<] [<] p} -> - (xs : List i) -> M xs nil a + (xs : List (WithBounds (Token i))) -> M xs nil a parse p xs = parser p [<] [<] [<] [<] xs [<] [<] -- Weakening ------------------------------------------------------------------- @@ -412,8 +305,8 @@ public export rename : (len1 : Length locked1) -> (len2 : Length locked2) -> - (forall x. Variable locked1 x -> Variable locked2 x) -> - (forall x. Variable free1 x -> Variable free2 x) -> + (forall x. Var locked1 x -> Var locked2 x) -> + (forall x. Var free1 x -> Var free2 x) -> Parser i nil locked1 free1 a -> Parser i nil locked2 free2 a rename len1 len2 ren1 ren2 (Var f x) = Var f (ren2 x) rename len1 len2 ren1 ren2 (Fail msg) = Fail msg @@ -430,6 +323,27 @@ rename len1 len2 ren1 ren2 (Fix x f p) = Fix x f (rename (S len1) (S len2) (lift {len = S Z} ren1) ren2 p) public export +weaken : + (len1 : Length free2) -> + {auto len2 : Length locked} -> + Parser i nil (free2 ++ locked) free1 a -> Parser i nil locked (free1 ++ free2) a +weaken len1 (Var f x) = Var f (wknL x) +weaken len1 (Fail msg) = Fail msg +weaken len1 (Empty x) = Empty x +weaken len1 (Lit text x) = Lit text x +weaken len1 ((<**>) {nil1 = False} p q) = + weaken len1 p <**> + rename Z Z + id + ( either (wknL . wknL) (either (wknL . wknR) wknR . split) + . split {len = lengthAppend len1 len2} + ) + q +weaken len1 ((<**>) {nil1 = True} p q) = weaken len1 p <**> weaken len1 q +weaken len1 (p <|> q) = weaken len1 p <|> weaken len1 q +weaken len1 (Fix x f p) = Fix x f (weaken len1 p) + +public export shift : {auto len1 : Length locked1} -> (len2 : Length locked2) -> @@ -465,15 +379,8 @@ public export p <** q = const <$> p <**> q public export -match : i -> Parser i False locked free () -match x = Lit x () - -public export -oneOf : (xs : List i) -> {auto 0 _ : NonEmpty xs} -> Parser i False locked free (x ** Elem x xs) -oneOf [x] = (x ** Here) <$ match x -oneOf (x :: xs@(_ :: _)) = - (x ** Here) <$ match x <|> - (\y => (y.fst ** There y.snd)) <$> oneOf xs +match : TokenKind i => (kind : i) -> Parser i False locked free (TokType kind) +match kind = Lit kind (tokValue kind) public export option : Parser i False locked free a -> Parser i True locked free (Maybe a) |