matching on mixfix
This commit is contained in:
11
TODO.md
11
TODO.md
@@ -14,14 +14,17 @@ I may be done with `U` - I keep typing `Type`.
|
|||||||
- [x] operators
|
- [x] operators
|
||||||
- [x] pair syntax (via comma operator)
|
- [x] pair syntax (via comma operator)
|
||||||
- [ ] matching on operators
|
- [ ] matching on operators
|
||||||
|
- [x] top level
|
||||||
|
- [ ] case statements ********
|
||||||
- [x] SKIP list syntax
|
- [x] SKIP list syntax
|
||||||
- Agda doesn't have it, clashes with pair syntax
|
- Agda doesn't have it, clashes with pair syntax
|
||||||
- [ ] import
|
- [ ] import
|
||||||
- [ ] autos / typeclass resolution
|
- [ ] autos / typeclass resolution
|
||||||
- keep as implicit and do auto if the type constructor is flagged auto
|
|
||||||
- keep as implicit and mark auto, behavior overlaps a lot with implicit
|
|
||||||
- have separate type of implict with `{{}}`
|
|
||||||
- Can we solve right away when creating the implicit, or do we need postpone?
|
- Can we solve right away when creating the implicit, or do we need postpone?
|
||||||
|
- options
|
||||||
|
- keep as implicit and do auto if the type constructor is flagged auto
|
||||||
|
- keep as implicit and mark auto, behavior overlaps a lot with implicit
|
||||||
|
- have separate type of implict with `{{}}`
|
||||||
- [ ] do blocks
|
- [ ] do blocks
|
||||||
- [ ] some solution for `+` problem (classes? ambiguity?)
|
- [ ] some solution for `+` problem (classes? ambiguity?)
|
||||||
- [ ] show compiler failure in the editor (exit code != 0)
|
- [ ] show compiler failure in the editor (exit code != 0)
|
||||||
@@ -38,3 +41,5 @@ I may be done with `U` - I keep typing `Type`.
|
|||||||
- [ ] magic tuple? (codegen as array)
|
- [ ] magic tuple? (codegen as array)
|
||||||
- [ ] magic newtype? (drop in codegen)
|
- [ ] magic newtype? (drop in codegen)
|
||||||
- [ ] records / copatterns
|
- [ ] records / copatterns
|
||||||
|
|
||||||
|
- [ ] Read Ulf Norell thesis
|
||||||
|
|||||||
@@ -41,5 +41,4 @@ blah : Int -> Int -> Int -> Pair Int (Pair Int Int)
|
|||||||
blah x y z = (x, y, z)
|
blah x y z = (x, y, z)
|
||||||
|
|
||||||
curryPlus : Pair Int Int -> Int
|
curryPlus : Pair Int Int -> Int
|
||||||
curryPlus (_,_ a b) = a + b
|
curryPlus (a, b) = a + b
|
||||||
-- curryPlus (a , b) = a + b
|
|
||||||
|
|||||||
@@ -520,7 +520,7 @@ check ctx tm ty = case (tm, !(forceType ty)) of
|
|||||||
(RHole fc, ty) => do
|
(RHole fc, ty) => do
|
||||||
ty' <- quote ctx.lvl ty
|
ty' <- quote ctx.lvl ty
|
||||||
let names = (toList $ map fst ctx.types)
|
let names = (toList $ map fst ctx.types)
|
||||||
-- I want to know which ones are defines. I should skip the `=` bit if they match
|
-- I want to know which ones are defines. I should skip the `=` bit if they match, I'll need indices in here too.
|
||||||
env <- for (zip ctx.env (toList ctx.types)) $ \(v, n, ty) => pure " \{n} : \{pprint names !(quote ctx.lvl ty)} = \{pprint names !(quote ctx.lvl v)}"
|
env <- for (zip ctx.env (toList ctx.types)) $ \(v, n, ty) => pure " \{n} : \{pprint names !(quote ctx.lvl ty)} = \{pprint names !(quote ctx.lvl v)}"
|
||||||
let msg = unlines (toList $ reverse env) ++ " -----------\n" ++ " goal \{pprint names ty'}"
|
let msg = unlines (toList $ reverse env) ++ " -----------\n" ++ " goal \{pprint names ty'}"
|
||||||
putStrLn "INFO at \{show fc}: "
|
putStrLn "INFO at \{show fc}: "
|
||||||
|
|||||||
@@ -258,16 +258,41 @@ parseMixfix = do
|
|||||||
addOp op (cast prec) fix
|
addOp op (cast prec) fix
|
||||||
pure $ PMixFix fc op (cast prec) fix
|
pure $ PMixFix fc op (cast prec) fix
|
||||||
|
|
||||||
|
-- We can be much more precise with a context
|
||||||
|
raw2pat : Raw -> SnocList Pattern -> M Pattern
|
||||||
|
raw2pat (RVar x nm) sp = ?rhs_1
|
||||||
|
raw2pat (RApp x t u icit) sp = ?rhs_3
|
||||||
|
raw2pat (RHole x) sp = ?rhs_11
|
||||||
|
raw2pat (RU x) sp = ?rhs_4
|
||||||
|
raw2pat (RLit x y) sp = ?rhs_8
|
||||||
|
|
||||||
|
raw2pat (RLam x nm icit ty) sp = ?rhs_2
|
||||||
|
raw2pat (RPi x nm icit ty sc) sp = ?rhs_5
|
||||||
|
raw2pat (RLet x nm ty v sc) sp = ?rhs_6
|
||||||
|
raw2pat (RAnn x tm ty) sp = ?rhs_7
|
||||||
|
raw2pat (RCase x scrut alts) sp = ?rhs_9
|
||||||
|
raw2pat (RImplicit x) sp = ?rhs_10
|
||||||
|
raw2pat (RParseError x str) sp = ?rhs_12
|
||||||
|
|
||||||
|
|
||||||
|
getName : Raw -> Parser String
|
||||||
|
getName (RVar x nm) = pure nm
|
||||||
|
getName (RApp x t u icit) = getName t
|
||||||
|
getName tm = fail "bad LHS"
|
||||||
|
|
||||||
|
|
||||||
export
|
export
|
||||||
parseDef : Parser Decl
|
parseDef : Parser Decl
|
||||||
parseDef = do
|
parseDef = do
|
||||||
fc <- getPos
|
fc <- getPos
|
||||||
nm <- ident <|> uident
|
t <- typeExpr
|
||||||
|
nm <- getName t
|
||||||
|
-- nm <- ident <|> uident
|
||||||
pats <- many patAtom
|
pats <- many patAtom
|
||||||
keyword "="
|
keyword "="
|
||||||
body <- typeExpr
|
body <- typeExpr
|
||||||
-- these get collected later
|
-- these get collected later
|
||||||
pure $ Def fc nm [MkClause fc [] pats body]
|
pure $ Def fc nm [(t, body)] -- [MkClause fc [] t body]
|
||||||
|
|
||||||
export
|
export
|
||||||
parsePType : Parser Decl
|
parsePType : Parser Decl
|
||||||
|
|||||||
@@ -27,6 +27,33 @@ collectDecl ((Def fc nm cl) :: rest@(Def _ nm' cl' :: xs)) =
|
|||||||
else (Def fc nm cl :: collectDecl rest)
|
else (Def fc nm cl :: collectDecl rest)
|
||||||
collectDecl (x :: xs) = x :: collectDecl xs
|
collectDecl (x :: xs) = x :: collectDecl xs
|
||||||
|
|
||||||
|
makeClause : TopContext -> (Raw, Raw) -> M Clause
|
||||||
|
makeClause top (lhs, rhs) = do
|
||||||
|
let (nm, args) = splitArgs lhs []
|
||||||
|
pats <- traverse mkPat args
|
||||||
|
pure $ MkClause (getFC lhs) [] pats rhs
|
||||||
|
where
|
||||||
|
|
||||||
|
splitArgs : Raw -> List (Raw, Icit) -> (Raw, List (Raw, Icit))
|
||||||
|
splitArgs (RApp fc t u icit) args = splitArgs t ((u, icit) :: args)
|
||||||
|
splitArgs tm args = (tm, args)
|
||||||
|
|
||||||
|
mkPat : (Raw, Icit) -> M Pattern
|
||||||
|
mkPat (tm, icit) = do
|
||||||
|
case splitArgs tm [] of
|
||||||
|
((RVar fc nm), b) => case lookup nm top of
|
||||||
|
(Just (MkEntry name type (DCon k str))) =>
|
||||||
|
-- TODO check arity, also figure out why we need reverse
|
||||||
|
pure $ PatCon fc icit nm !(traverse mkPat b)
|
||||||
|
Just _ => error (getFC tm) "not a data constructor"
|
||||||
|
Nothing => case b of
|
||||||
|
[] => pure $ PatVar fc icit nm
|
||||||
|
_ => error (getFC tm) "patvar applied to args"
|
||||||
|
((RImplicit fc), []) => pure $ PatWild fc icit
|
||||||
|
((RImplicit fc), _) => error fc "implicit pat can't be applied"
|
||||||
|
-- ((RLit x y), b) => ?rhs_19
|
||||||
|
(a,b) => error (getFC a) "expected pat var or constructor"
|
||||||
|
|
||||||
export
|
export
|
||||||
processDecl : Decl -> M ()
|
processDecl : Decl -> M ()
|
||||||
|
|
||||||
@@ -69,7 +96,9 @@ processDecl (Def fc nm clauses) = do
|
|||||||
vty <- eval empty CBN ty
|
vty <- eval empty CBN ty
|
||||||
putStrLn "vty is \{show vty}"
|
putStrLn "vty is \{show vty}"
|
||||||
|
|
||||||
tm <- buildTree (mkCtx ctx.metas fc) (MkProb clauses vty)
|
-- I can take LHS apart syntactically or elaborate it with an infer
|
||||||
|
clauses' <- traverse (makeClause ctx) clauses
|
||||||
|
tm <- buildTree (mkCtx ctx.metas fc) (MkProb clauses' vty)
|
||||||
putStrLn "Ok \{pprint [] tm}"
|
putStrLn "Ok \{pprint [] tm}"
|
||||||
tm' <- zonk ctx 0 [] tm
|
tm' <- zonk ctx 0 [] tm
|
||||||
putStrLn "NF \{pprint[] tm'}"
|
putStrLn "NF \{pprint[] tm'}"
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ data Decl : Type where
|
|||||||
|
|
||||||
data Decl
|
data Decl
|
||||||
= TypeSig FC Name Raw
|
= TypeSig FC Name Raw
|
||||||
| Def FC Name (List Clause)
|
| Def FC Name (List (Raw,Raw)) -- (List Clause)
|
||||||
| DImport FC Name
|
| DImport FC Name
|
||||||
| DCheck FC Raw Raw
|
| DCheck FC Raw Raw
|
||||||
| Data FC Name Raw (List Decl)
|
| Data FC Name Raw (List Decl)
|
||||||
@@ -231,10 +231,7 @@ Pretty Module where
|
|||||||
where
|
where
|
||||||
doDecl : Decl -> Doc
|
doDecl : Decl -> Doc
|
||||||
doDecl (TypeSig _ nm ty) = text nm <+> text ":" <+> nest 2 (pretty ty)
|
doDecl (TypeSig _ nm ty) = text nm <+> text ":" <+> nest 2 (pretty ty)
|
||||||
doDecl (Def _ nm clauses) = spread $ map doClause clauses
|
doDecl (Def _ nm clauses) = stack $ map (\(a,b) => pretty a <+> "=" <+> pretty b) clauses
|
||||||
where
|
|
||||||
doClause : Clause -> Doc
|
|
||||||
doClause (MkClause fc _ pats body) = text nm <+> spread (map pretty pats) <+> text "=" <+> nest 2 (pretty body)
|
|
||||||
doDecl (DImport _ nm) = text "import" <+> text nm ++ line
|
doDecl (DImport _ nm) = text "import" <+> text nm ++ line
|
||||||
-- the behavior of nest is kinda weird, I have to do the nest before/around the </>.
|
-- the behavior of nest is kinda weird, I have to do the nest before/around the </>.
|
||||||
doDecl (Data _ nm x xs) = text "data" <+> text nm <+> text ":" <+> pretty x <+> (nest 2 $ text "where" </> stack (map doDecl xs))
|
doDecl (Data _ nm x xs) = text "data" <+> text nm <+> text ":" <+> pretty x <+> (nest 2 $ text "where" </> stack (map doDecl xs))
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ keywords = ["let", "in", "where", "case", "of", "data", "U",
|
|||||||
"ptype", "pfunc", "module", "infixl", "infixr", "infix"]
|
"ptype", "pfunc", "module", "infixl", "infixr", "infix"]
|
||||||
|
|
||||||
specialOps : List String
|
specialOps : List String
|
||||||
specialOps = ["->", ":", "=>", ":="]
|
specialOps = ["->", ":", "=>", ":=", "="]
|
||||||
|
|
||||||
checkKW : String -> Token Kind
|
checkKW : String -> Token Kind
|
||||||
checkKW s = if elem s keywords then Tok Keyword s else Tok Ident s
|
checkKW s = if elem s keywords then Tok Keyword s else Tok Ident s
|
||||||
|
|||||||
Reference in New Issue
Block a user