drop commit/mustWork for parsec approach. allow mixfix constructors

This commit is contained in:
2024-09-14 14:46:04 -07:00
parent 647d8d8728
commit 331d966ef3
5 changed files with 49 additions and 62 deletions

View File

@@ -3,7 +3,8 @@
I may be done with `U` - I keep typing `Type`. I may be done with `U` - I keep typing `Type`.
- [ ] type constructors are no longer generated? And seem to have 0 arity. - [x] switch from commit/mustWork to checking progress
- [x] type constructors are no longer generated? And seem to have 0 arity.
- [ ] raw let is not yet implemented (although define used by case tree building) - [ ] raw let is not yet implemented (although define used by case tree building)
- [x] there is some zero argument application in generated code - [x] there is some zero argument application in generated code
- [x] get equality.newt to work - [x] get equality.newt to work

View File

@@ -38,4 +38,8 @@ data Pair : U -> U -> U where
_,_ : {A B : U} -> A -> B -> Pair A B _,_ : {A B : U} -> A -> B -> Pair A B
blah : Int -> Int -> Int -> Pair Int (Pair Int Int) 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 (_,_ a b) = a + b
-- curryPlus (a , b) = a + b

View File

@@ -94,9 +94,9 @@ parseOp = parseApp >>= go 0
where where
go : Int -> Raw -> Parser Raw go : Int -> Raw -> Parser Raw
go prec left = go prec left =
do try (do
fc <- getPos
op <- token Oper op <- token Oper
fc <- getPos
ops <- getOps ops <- getOps
let op' = "_" ++ op ++ "_" let op' = "_" ++ op ++ "_"
let Just (p,fix) = lookup op' ops let Just (p,fix) = lookup op' ops
@@ -108,14 +108,13 @@ parseOp = parseApp >>= go 0
if p >= prec then pure () else fail "" if p >= prec then pure () else fail ""
let pr = case fix of InfixR => p; _ => p + 1 let pr = case fix of InfixR => p; _ => p + 1
right <- go pr !(parseApp) right <- go pr !(parseApp)
go prec (RApp fc (RApp fc (RVar fc op') left Explicit) right Explicit) go prec (RApp fc (RApp fc (RVar fc op') left Explicit) right Explicit))
<|> pure left <|> pure left
export export
letExpr : Parser Raw letExpr : Parser Raw
letExpr = do letExpr = do
keyword "let" keyword "let"
commit
alts <- startBlock $ someSame $ letAssign alts <- startBlock $ someSame $ letAssign
keyword' "in" keyword' "in"
scope <- typeExpr scope <- typeExpr
@@ -142,7 +141,6 @@ export
lamExpr : Parser Raw lamExpr : Parser Raw
lamExpr = do lamExpr = do
keyword "\\" <|> keyword "λ" keyword "\\" <|> keyword "λ"
commit
args <- some pLetArg args <- some pLetArg
keyword "=>" keyword "=>"
scope <- typeExpr scope <- typeExpr
@@ -163,19 +161,18 @@ patAtom = do
fc <- getPos fc <- getPos
PatWild fc Explicit <$ keyword "_" PatWild fc Explicit <$ keyword "_"
<|> PatVar fc Explicit <$> ident <|> PatVar fc Explicit <$> ident
<|> PatCon fc Explicit <$> uident <*> pure [] <|> PatCon fc Explicit <$> (uident <|> token MixFix) <*> pure []
<|> braces (PatVar fc Implicit <$> ident) <|> braces (PatVar fc Implicit <$> ident)
<|> braces (PatWild fc Implicit <$ keyword "_") <|> braces (PatWild fc Implicit <$ keyword "_")
<|> braces (PatCon fc Implicit <$> uident <*> many patAtom) <|> braces (PatCon fc Implicit <$> (uident <|> token MixFix) <*> many patAtom)
<|> parens pPattern <|> parens pPattern
pPattern = PatCon (!getPos) Explicit <$> uident <*> many patAtom <|> patAtom pPattern = PatCon (!getPos) Explicit <$> (uident <|> token MixFix) <*> many patAtom <|> patAtom
caseAlt : Parser RCaseAlt caseAlt : Parser RCaseAlt
caseAlt = do caseAlt = do
pat <- pPattern pat <- pPattern
keyword "=>" keyword "=>"
commit
t <- term t <- term
pure $ MkAlt pat t pure $ MkAlt pat t
@@ -183,7 +180,6 @@ export
caseExpr : Parser Raw caseExpr : Parser Raw
caseExpr = do caseExpr = do
keyword "case" keyword "case"
commit
sc <- term sc <- term
keyword "of" keyword "of"
alts <- startBlock $ someSame $ caseAlt alts <- startBlock $ someSame $ caseAlt
@@ -208,13 +204,11 @@ ebind = do
ibind : Parser (List (String, Icit, Raw)) ibind : Parser (List (String, Icit, Raw))
ibind = do ibind = do
sym "{" sym "{"
mustWork $ do names <- some (ident <|> uident)
names <- some (ident <|> uident) ty <- optional (sym ":" >> typeExpr)
ty <- optional (sym ":" >> typeExpr) pos <- getPos
pos <- getPos sym "}"
sym "}" pure $ map (\name => (name, Implicit, fromMaybe (RImplicit pos) ty)) names
-- getPos is a hack here, I would like to position at the name...
pure $ map (\name => (name, Implicit, fromMaybe (RImplicit pos) ty)) names
arrow : Parser Unit arrow : Parser Unit
arrow = sym "->" <|> sym "" arrow = sym "->" <|> sym ""
@@ -222,9 +216,8 @@ arrow = sym "->" <|> sym "→"
-- Collect a bunch of binders (A : U) {y : A} -> ... -- Collect a bunch of binders (A : U) {y : A} -> ...
binders : Parser Raw binders : Parser Raw
binders = do binders = do
binds <- many (ibind <|> ebind) binds <- many (ibind <|> try ebind)
arrow arrow
commit
scope <- typeExpr scope <- typeExpr
fc <- getPos fc <- getPos
pure $ foldr (mkBind fc) scope (join binds) pure $ foldr (mkBind fc) scope (join binds)
@@ -235,7 +228,7 @@ binders = do
typeExpr = binders typeExpr = binders
<|> do <|> do
exp <- term exp <- term
scope <- optional (arrow *> mustWork typeExpr) scope <- optional (arrow *> typeExpr)
case scope of case scope of
Nothing => pure exp Nothing => pure exp
-- consider Maybe String to represent missing -- consider Maybe String to represent missing
@@ -247,10 +240,10 @@ typeExpr = binders
export export
parseSig : Parser Decl parseSig : Parser Decl
parseSig = TypeSig <$> getPos <*> (ident <|> uident) <* keyword ":" <*> mustWork typeExpr parseSig = TypeSig <$> getPos <*> (ident <|> uident) <* keyword ":" <*> typeExpr
parseImport : Parser Decl parseImport : Parser Decl
parseImport = DImport <$> getPos <* keyword "import" <* commit <*> uident parseImport = DImport <$> getPos <* keyword "import" <*> uident
-- Do we do pattern stuff now? or just name = lambda? -- Do we do pattern stuff now? or just name = lambda?
@@ -260,11 +253,10 @@ parseMixfix = do
fix <- InfixL <$ keyword "infixl" fix <- InfixL <$ keyword "infixl"
<|> InfixR <$ keyword "infixr" <|> InfixR <$ keyword "infixr"
<|> Infix <$ keyword "infix" <|> Infix <$ keyword "infix"
mustWork $ do prec <- token Number
prec <- token Number op <- token MixFix
op <- token MixFix addOp op (cast prec) fix
addOp op (cast prec) fix pure $ PMixFix fc op (cast prec) fix
pure $ PMixFix fc op (cast prec) fix
export export
parseDef : Parser Decl parseDef : Parser Decl
@@ -273,7 +265,7 @@ parseDef = do
nm <- ident <|> uident nm <- ident <|> uident
pats <- many patAtom pats <- many patAtom
keyword "=" keyword "="
body <- mustWork typeExpr body <- typeExpr
-- these get collected later -- these get collected later
pure $ Def fc nm [MkClause fc [] pats body] pure $ Def fc nm [MkClause fc [] pats body]
@@ -285,7 +277,7 @@ parsePType = do
id <- uident id <- uident
ty <- optional $ do ty <- optional $ do
keyword ":" keyword ":"
mustWork typeExpr typeExpr
pure $ PType fc id ty pure $ PType fc id ty
parsePFunc : Parser Decl parsePFunc : Parser Decl
@@ -296,7 +288,7 @@ parsePFunc = do
keyword ":" keyword ":"
ty <- typeExpr ty <- typeExpr
keyword ":=" keyword ":="
src <- mustWork (cast <$> token StringKind) src <- cast <$> token StringKind
pure $ PFunc fc nm ty src pure $ PFunc fc nm ty src
export export
@@ -304,16 +296,12 @@ parseData : Parser Decl
parseData = do parseData = do
fc <- getPos fc <- getPos
keyword "data" keyword "data"
-- FIXME - switch from mustWork / commit to checking if we've consumed tokens name <- uident
mustWork $ do keyword ":"
name <- uident ty <- typeExpr
keyword ":" keyword "where"
ty <- typeExpr decls <- startBlock $ manySame $ parseSig
keyword "where" pure $ Data fc name ty decls
commit
decls <- startBlock $ manySame $ parseSig
-- TODO - turn decls into something more useful
pure $ Data fc name ty decls
-- Not sure what I want here. -- Not sure what I want here.
-- I can't get a Tm without a type, and then we're covered by the other stuff -- I can't get a Tm without a type, and then we're covered by the other stuff
@@ -322,7 +310,7 @@ parseNorm = DCheck <$> getPos <* keyword "#check" <*> typeExpr <* keyword ":" <*
export export
parseDecl : Parser Decl parseDecl : Parser Decl
parseDecl = parseMixfix <|> parsePType <|> parsePFunc <|> parseImport <|> parseNorm <|> parseData <|> parseSig <|> parseDef parseDecl = parseMixfix <|> parsePType <|> parsePFunc <|> parseImport <|> parseNorm <|> parseData <|> (try $ parseSig) <|> parseDef
export export
parseMod : Parser Module parseMod : Parser Module

View File

@@ -1,13 +1,5 @@
module Lib.Parser.Impl module Lib.Parser.Impl
-- This follows Idris, not sure why I did that because commit / mustWork is messy
-- and painful to work with. I _think_ a commit on consumption of anything, like parsec
-- would work better.
-- Perhaps we can set the commit flag on consumption and get that with minor changes.
-- TODO see what Kovacs' flatparse does for error handling / <|>
import Lib.Token import Lib.Token
import Data.String import Data.String
import Data.Nat import Data.Nat
@@ -101,6 +93,12 @@ parse pa toks = case runP pa toks False [] (-1,-1) of
-- I think I want to drop the typeclasses for v1 -- I think I want to drop the typeclasses for v1
export
try : Parser a -> Parser a
try (P pa) = P $ \toks,com,ops,col => case pa toks com ops col of
(Fail x err toks com ops) => Fail x err toks False ops
res => res
export export
fail : String -> Parser a fail : String -> Parser a
fail msg = P $ \toks,com,ops,col => Fail False (error toks msg) toks com ops fail msg = P $ \toks,com,ops,col => Fail False (error toks msg) toks com ops
@@ -109,13 +107,6 @@ export
fatal : String -> Parser a fatal : String -> Parser a
fatal msg = P $ \toks,com,ops,col => Fail True (error toks msg) toks com ops fatal msg = P $ \toks,com,ops,col => Fail True (error toks msg) toks com ops
-- mustWork / commit copied from Idris, but I may switch to the parsec consumption thing.
export
mustWork : Parser a -> Parser a
mustWork (P pa) = P $ \ toks, com, ops, col => case (pa toks com ops col) of
Fail x err xs y ops => Fail True err xs y ops
res => res
export export
getOps : Parser (List (String, Int, Fixity)) getOps : Parser (List (String, Int, Fixity))
getOps = P $ \ toks, com, ops, col => OK ops toks com ops getOps = P $ \ toks, com, ops, col => OK ops toks com ops
@@ -147,7 +138,7 @@ export
case pa toks False ops col of case pa toks False ops col of
OK a toks' _ ops => OK a toks' com ops OK a toks' _ ops => OK a toks' com ops
Fail True err toks' com ops => Fail True err toks' com ops Fail True err toks' com ops => Fail True err toks' com ops
Fail fatal err toks' True ops => Fail fatal err toks' com ops Fail fatal err toks' True ops => Fail fatal err toks' True ops
Fail fatal err toks' False ops => pb toks com ops col Fail fatal err toks' False ops => pb toks com ops col
export export
@@ -161,7 +152,7 @@ Monad Parser where
pred : (BTok -> Bool) -> String -> Parser String pred : (BTok -> Bool) -> String -> Parser String
pred f msg = P $ \toks,com,ops,col => pred f msg = P $ \toks,com,ops,col =>
case toks of case toks of
(t :: ts) => if f t then OK (value t) ts com ops else Fail False (error toks "\{msg} at \{show $ kind t}:\{value t}") toks com ops (t :: ts) => if f t then OK (value t) ts True ops else Fail False (error toks "\{msg} at \{show $ kind t}:\{value t}") toks com ops
[] => Fail False (error toks "\{msg} at EOF") toks com ops [] => Fail False (error toks "\{msg} at EOF") toks com ops
export export

View File

@@ -17,6 +17,9 @@ checkKW s = if elem s keywords then Tok Keyword s else Tok Ident s
checkUKW : String -> Token Kind checkUKW : String -> Token Kind
checkUKW s = if elem s keywords then Tok Keyword s else Tok UIdent s checkUKW s = if elem s keywords then Tok Keyword s else Tok UIdent s
checkOp : String -> Token Kind
checkOp s = if elem s specialOps then Tok Keyword s else Tok Oper s
isOpChar : Char -> Bool isOpChar : Char -> Bool
isOpChar c = c `elem` (unpack ":!#$%&*+./<=>?@\\^|-~") isOpChar c = c `elem` (unpack ":!#$%&*+./<=>?@\\^|-~")
@@ -54,8 +57,8 @@ rawTokens
<|> match (quo <+> manyUntil quo ((esc any <+> any) <|> any) <+> opt quo) (Tok StringKind . unquote) <|> match (quo <+> manyUntil quo ((esc any <+> any) <|> any) <+> opt quo) (Tok StringKind . unquote)
<|> match (lineComment (exact "--")) (Tok Space) <|> match (lineComment (exact "--")) (Tok Space)
<|> match (blockComment (exact "/-") (exact "-/")) (Tok Space) <|> match (blockComment (exact "/-") (exact "-/")) (Tok Space)
<|> match (exact ",") (\s => Tok Oper s) <|> match (exact ",") (Tok Oper)
<|> match (some opChar) (\s => Tok Oper s) <|> match (some opChar) checkOp
<|> match symbol (Tok Symbol) <|> match symbol (Tok Symbol)
<|> match spaces (Tok Space) <|> match spaces (Tok Space)