Optional type annotation on case scrutinee

This commit is contained in:
2025-12-29 10:24:15 -08:00
parent 7d262d9930
commit f4d1e86319
4 changed files with 26 additions and 17 deletions

View File

@@ -1,6 +1,7 @@
## TODO ## TODO
- [x] add optional types to case `case xxx : Maybe Int of ...`
- [ ] "Expected keyword" at `\ a ->` should be error at the `->` - [ ] "Expected keyword" at `\ a ->` should be error at the `->`
- [x] Show Either - [x] Show Either
- [ ] `local` for `where`-like `let` clauses? (I want a `where` that closes over more stuff) - [ ] `local` for `where`-like `let` clauses? (I want a `where` that closes over more stuff)

View File

@@ -1358,7 +1358,7 @@ undo prev ((DoArrow fc left@(RVar fc' nm) right Nil) :: xs) = do
Just _ => do Just _ => do
let nm = "$sc" let nm = "$sc"
xs' <- undo fc xs xs' <- undo fc xs
rest <- pure $ RCase fc (RVar fc nm) (MkAlt left (Just xs') :: Nil) rest <- pure $ RCase fc (RVar fc nm) Nothing (MkAlt left (Just xs') :: Nil)
pure $ RApp fc (RApp fc (RVar fc "_>>=_") right Explicit) pure $ RApp fc (RApp fc (RVar fc "_>>=_") right Explicit)
(RLam fc (BI fc nm Explicit Many) rest) Explicit (RLam fc (BI fc nm Explicit Many) rest) Explicit
Nothing => do Nothing => do
@@ -1368,7 +1368,7 @@ undo prev ((DoArrow fc left@(RVar fc' nm) right Nil) :: xs) = do
undo prev ((DoArrow fc left right alts) :: xs) = do undo prev ((DoArrow fc left right alts) :: xs) = do
let nm = "$sc" let nm = "$sc"
xs' <- undo fc xs xs' <- undo fc xs
rest <- pure $ RCase fc (RVar fc nm) (MkAlt left (Just xs') :: alts) rest <- pure $ RCase fc (RVar fc nm) Nothing (MkAlt left (Just xs') :: alts)
pure $ RApp fc (RApp fc (RVar fc "_>>=_") right Explicit) pure $ RApp fc (RApp fc (RVar fc "_>>=_") right Explicit)
(RLam fc (BI fc nm Explicit Many) rest) Explicit (RLam fc (BI fc nm Explicit Many) rest) Explicit
@@ -1426,13 +1426,20 @@ check ctx tm ty = do
(RUpdateRec fc clauses arg, ty) => updateRec ctx fc clauses arg ty (RUpdateRec fc clauses arg, ty) => updateRec ctx fc clauses arg ty
(RWhere fc decls body, ty) => checkWhere ctx (collectDecl decls) body ty (RWhere fc decls body, ty) => checkWhere ctx (collectDecl decls) body ty
(RIf fc a b c, ty) => (RIf fc a b c, ty) =>
let tm' = RCase fc a ( MkAlt (RVar (getFC b) "True") (Just b) :: MkAlt (RVar (getFC c) "False") (Just c) :: Nil) in -- REVIEW maybe stuff Bool in here?
let tm' = RCase fc a Nothing (MkAlt (RVar (getFC b) "True") (Just b) :: MkAlt (RVar (getFC c) "False") (Just c) :: Nil) in
check ctx tm' ty check ctx tm' ty
(RDo fc stmts, ty) => do (RDo fc stmts, ty) => do
stmts' <- undo fc stmts stmts' <- undo fc stmts
check ctx stmts' ty check ctx stmts' ty
(RCase fc rsc alts, ty) => do (RCase fc rsc mty alts, ty) => do
(sc, scty) <- infer ctx rsc (sc, scty) <- case mty of
Nothing => infer ctx rsc
Just ty => do
scty <- check ctx ty (VU emptyFC)
vscty <- eval ctx.env scty
sc <- check ctx rsc vscty
pure (sc, vscty)
scty <- forceMeta scty scty <- forceMeta scty
debug $ \ _ => "SCTM \{rpprint (names ctx) sc}" debug $ \ _ => "SCTM \{rpprint (names ctx) sc}"
debug $ \ _ => "SCTY \{show scty}" debug $ \ _ => "SCTY \{show scty}"

View File

@@ -273,7 +273,6 @@ letExpr = do
letAssign = do letAssign = do
fc <- getPos fc <- getPos
name <- ident name <- ident
-- TODO type assertion
ty <- optional (keyword ":" *> typeExpr) ty <- optional (keyword ":" *> typeExpr)
keyword "=" keyword "="
t <- typeExpr t <- typeExpr
@@ -329,16 +328,17 @@ caseExpr = do
fc <- getPos fc <- getPos
keyword "case" keyword "case"
sc <- term sc <- term
ty <- optional (keyword ":" *> typeExpr)
keyword "of" keyword "of"
alts <- startBlock $ someSame $ caseAlt alts <- startBlock $ someSame $ caseAlt
pure $ RCase fc sc alts pure $ RCase fc sc ty alts
caseLamExpr : Parser Raw caseLamExpr : Parser Raw
caseLamExpr = do caseLamExpr = do
fc <- getPos fc <- getPos
try ((keyword "\\" <|> keyword "λ") *> keyword "case") try ((keyword "\\" <|> keyword "λ") *> keyword "case")
alts <- startBlock $ someSame $ caseAlt alts <- startBlock $ someSame $ caseAlt
pure $ RLam fc (BI fc "$case" Explicit Many) $ RCase fc (RVar fc "$case") alts pure $ RLam fc (BI fc "$case" Explicit Many) $ RCase fc (RVar fc "$case") Nothing alts
doExpr : Parser Raw doExpr : Parser Raw
doStmt : Parser DoStmt doStmt : Parser DoStmt
@@ -355,7 +355,7 @@ caseLet = do
alts <- startBlock $ manySame $ symbol "|" *> caseAlt alts <- startBlock $ manySame $ symbol "|" *> caseAlt
keyword "in" keyword "in"
body <- term body <- term
pure $ RCase fc sc (MkAlt pat (Just body) :: alts) pure $ RCase fc sc Nothing (MkAlt pat (Just body) :: alts)
doCaseLet : Parser DoStmt doCaseLet : Parser DoStmt
doCaseLet = do doCaseLet = do
@@ -370,7 +370,7 @@ doCaseLet = do
alts <- startBlock $ manySame $ symbol "|" *> caseAlt alts <- startBlock $ manySame $ symbol "|" *> caseAlt
bodyFC <- getPos bodyFC <- getPos
body <- RDo <$> getPos <*> someSame doStmt body <- RDo <$> getPos <*> someSame doStmt
pure $ DoExpr fc (RCase fc sc (MkAlt pat (Just body) :: alts)) pure $ DoExpr fc (RCase fc sc Nothing (MkAlt pat (Just body) :: alts))
doArrow : Parser DoStmt doArrow : Parser DoStmt
doArrow = do doArrow = do

View File

@@ -45,7 +45,7 @@ data Raw : U where
RLet : (fc : FC) -> (nm : Name) -> (ty : Raw) -> (v : Raw) -> (sc : Raw) -> Raw RLet : (fc : FC) -> (nm : Name) -> (ty : Raw) -> (v : Raw) -> (sc : Raw) -> Raw
RAnn : (fc : FC) -> (tm : Raw) -> (ty : Raw) -> Raw RAnn : (fc : FC) -> (tm : Raw) -> (ty : Raw) -> Raw
RLit : (fc : FC) -> Literal -> Raw RLit : (fc : FC) -> Literal -> Raw
RCase : (fc : FC) -> (scrut : Raw) -> (alts : List RCaseAlt) -> Raw RCase : (fc : FC) -> (scrut : Raw) -> (mty : Maybe Raw) -> (alts : List RCaseAlt) -> Raw
RImplicit : (fc : FC) -> Raw RImplicit : (fc : FC) -> Raw
RHole : (fc : FC) -> Raw RHole : (fc : FC) -> Raw
RDo : (fc : FC) -> List DoStmt -> Raw RDo : (fc : FC) -> List DoStmt -> Raw
@@ -65,7 +65,7 @@ instance HasFC Raw where
getFC (RLet fc nm ty v sc) = fc getFC (RLet fc nm ty v sc) = fc
getFC (RAnn fc tm ty) = fc getFC (RAnn fc tm ty) = fc
getFC (RLit fc y) = fc getFC (RLit fc y) = fc
getFC (RCase fc scrut alts) = fc getFC (RCase fc scrut mty alts) = fc
getFC (RImplicit fc) = fc getFC (RImplicit fc) = fc
getFC (RHole fc) = fc getFC (RHole fc) = fc
getFC (RDo fc stmts) = fc getFC (RDo fc stmts) = fc
@@ -171,7 +171,8 @@ instance Show Raw where
show (RPi _ bi y z) = foo ( "Pi" :: show bi :: show y :: show z :: Nil) show (RPi _ bi y z) = foo ( "Pi" :: show bi :: show y :: show z :: Nil)
show (RApp _ x y z) = foo ( "App" :: show x :: show y :: show z :: Nil) show (RApp _ x y z) = foo ( "App" :: show x :: show y :: show z :: Nil)
show (RLam _ bi y) = foo ( "Lam" :: show bi :: show y :: Nil) show (RLam _ bi y) = foo ( "Lam" :: show bi :: show y :: Nil)
show (RCase _ x xs) = foo ( "Case" :: show x :: show xs :: Nil) show (RCase _ x Nothing xs) = foo ( "Case" :: show x :: " of " :: show xs :: Nil)
show (RCase _ x (Just ty) xs) = foo ( "Case" :: show x :: " : " :: show ty :: " of " :: show xs :: Nil)
show (RDo _ stmts) = foo ( "DO" :: "FIXME" :: Nil) show (RDo _ stmts) = foo ( "DO" :: "FIXME" :: Nil)
show (RU _) = "U" show (RU _) = "U"
show (RIf _ x y z) = foo ( "If" :: show x :: show y :: show z :: Nil) show (RIf _ x y z) = foo ( "If" :: show x :: show y :: show z :: Nil)
@@ -224,15 +225,15 @@ instance Pretty Raw where
<+> text "=" <+> asDoc p v <+> text "=" <+> asDoc p v
<+/> text "in" <+> asDoc p scope <+/> text "in" <+> asDoc p scope
-- does this exist? -- does this exist?
asDoc p (RAnn _ x y) = text "TODO - RAnn" asDoc p (RAnn _ x y) = text "TODO - Pretty RAnn"
asDoc p (RLit _ lit) = pretty lit asDoc p (RLit _ lit) = pretty lit
asDoc p (RCase _ x xs) = text "TODO - RCase" asDoc p (RCase _ x _ xs) = text "TODO - Pretty RCase"
asDoc p (RImplicit _) = text "_" asDoc p (RImplicit _) = text "_"
asDoc p (RImpossible _) = text "()" asDoc p (RImpossible _) = text "()"
asDoc p (RHole _) = text "?" asDoc p (RHole _) = text "?"
asDoc p (RDo _ stmts) = text "TODO - RDo" asDoc p (RDo _ stmts) = text "TODO - Pretty RDo"
asDoc p (RIf _ x y z) = par p 0 $ text "if" <+> asDoc 0 x <+/> text "then" <+> asDoc 0 y <+/> text "else" <+> asDoc 0 z asDoc p (RIf _ x y z) = par p 0 $ text "if" <+> asDoc 0 x <+/> text "then" <+> asDoc 0 y <+/> text "else" <+> asDoc 0 z
asDoc p (RWhere _ dd b) = text "TODO pretty where" asDoc p (RWhere _ dd b) = text "TODO pretty RWhere"
asDoc p (RAs _ nm x) = text nm ++ text "@(" ++ asDoc 0 x ++ text ")" asDoc p (RAs _ nm x) = text nm ++ text "@(" ++ asDoc 0 x ++ text ")"
asDoc p (RUpdateRec _ clauses tm) = text "{" <+> text "TODO RUpdateRec" <+> text "}" asDoc p (RUpdateRec _ clauses tm) = text "{" <+> text "TODO RUpdateRec" <+> text "}"