Show instances, fixed a bunch of bugs in parsing
- The case / let / indent stuff actually works - Needed a bunch of defers - Idris silently builds loops in immediate definitions
This commit is contained in:
@@ -4,6 +4,7 @@ module Lib.Parser
|
||||
import Lib.Token
|
||||
import Lib.Parser.Impl
|
||||
import Syntax
|
||||
import Data.List
|
||||
|
||||
-- There is the whole core vs surface thing here.
|
||||
-- might be best to do core first/ Technically don't
|
||||
@@ -19,27 +20,130 @@ import Syntax
|
||||
|
||||
ident = token Ident
|
||||
|
||||
term : Parser Term
|
||||
|
||||
parens : Parser a -> Parser a
|
||||
parens pa = do
|
||||
sym "("
|
||||
t <- pa
|
||||
sym ")"
|
||||
pure t
|
||||
|
||||
lit : Parser Term
|
||||
lit = do
|
||||
t <- token Number
|
||||
pure $ Lit (LInt (cast t))
|
||||
|
||||
|
||||
|
||||
export
|
||||
term : (Parser Term)
|
||||
|
||||
|
||||
-- ( t : ty ), (t , u) (t)
|
||||
-- Or do we want (x : ty) I think we may need to annotate any term
|
||||
parenThinger : Parser Term
|
||||
parenThinger = do
|
||||
keyword "("
|
||||
t <- term
|
||||
-- And now we want ) : or ,
|
||||
-- we could do this with backtracing, but it'd kinda suck?
|
||||
fail "todo"
|
||||
|
||||
-- the inside of term
|
||||
atom : Parser Term
|
||||
atom = lit
|
||||
<|> Var <$> ident
|
||||
<|> parens term
|
||||
-- <|> sym "(" *> term <* sym ")"
|
||||
|
||||
--
|
||||
-- atom is lit or ident
|
||||
|
||||
data Fixity = InfixL | InfixR | Infix
|
||||
|
||||
-- starter pack, but we'll move some to prelude
|
||||
operators : List (String, Int, Fixity)
|
||||
operators = [
|
||||
("->", 1, InfixR),
|
||||
("=", 2, InfixL), -- REVIEW
|
||||
("+",4,InfixL),
|
||||
("-",4,InfixL),
|
||||
("*",5,InfixL),
|
||||
("/",5,InfixL)
|
||||
]
|
||||
parseApp : Parser Term
|
||||
parseApp = do
|
||||
hd <- atom
|
||||
rest <- many atom
|
||||
pure $ foldl App hd rest
|
||||
|
||||
|
||||
parseOp : Lazy (Parser Term)
|
||||
parseOp = parseApp >>= go 0
|
||||
where
|
||||
go : Int -> Term -> Parser Term
|
||||
go prec left =
|
||||
do
|
||||
op <- token Oper
|
||||
let Just (p,fix) = lookup op operators
|
||||
| Nothing => fail "expected operator"
|
||||
-- if p >= prec then pure () else fail ""
|
||||
guard $ p >= prec
|
||||
-- commit
|
||||
let pr = case fix of InfixR => p; _ => p + 1
|
||||
-- commit?
|
||||
right <- go pr !(parseApp)
|
||||
go prec (App (App (Var op) left) right)
|
||||
<|> pure left
|
||||
|
||||
|
||||
export
|
||||
letExpr : Parser Term
|
||||
letExpr = Let <$ keyword "let" <*> ident <* keyword "=" <*> term <* keyword "in" <*> term
|
||||
letExpr = do
|
||||
keyword "let"
|
||||
commit
|
||||
alts <- startBlock $ someSame $ letAssign
|
||||
keyword' "in"
|
||||
scope <- term
|
||||
pure $ Let alts scope
|
||||
-- Let <$ keyword "let" <*> ident <* keyword "=" <*> term <* keyword "in" <*> term
|
||||
|
||||
pattern : Parser Pattern
|
||||
where
|
||||
letAssign : Parser (Name,Term)
|
||||
letAssign = do
|
||||
name <- ident
|
||||
keyword "="
|
||||
t <- term
|
||||
pure (name,t)
|
||||
|
||||
pPattern : Parser Pattern
|
||||
pPattern
|
||||
= PatWild <$ keyword "_"
|
||||
<|> [| PatVar ident |]
|
||||
|
||||
export
|
||||
lamExpr : Parser Term
|
||||
lamExpr = do
|
||||
keyword "\\"
|
||||
commit
|
||||
name <- pattern
|
||||
name <- pPattern
|
||||
keyword "."
|
||||
scope <- term
|
||||
pure $ Lam name scope
|
||||
|
||||
caseAlt : Parser CaseAlt
|
||||
|
||||
caseAlt : Parser CaseAlt
|
||||
caseAlt = do
|
||||
pat <- pPattern -- Term and sort it out later?
|
||||
keyword "=>"
|
||||
commit
|
||||
t <- term
|
||||
pure $ MkAlt pat t
|
||||
|
||||
export
|
||||
caseExpr : Parser Term
|
||||
caseExpr = do
|
||||
_ <- keyword "case"
|
||||
keyword "case"
|
||||
commit
|
||||
sc <- term
|
||||
keyword "of"
|
||||
@@ -47,10 +151,10 @@ caseExpr = do
|
||||
pure $ Case sc alts
|
||||
|
||||
|
||||
|
||||
-- TODO - get this up and running with a case expr to test it
|
||||
|
||||
|
||||
term = defer $ \_ =>
|
||||
caseExpr
|
||||
<|> letExpr
|
||||
<|> parseOp
|
||||
|
||||
{-
|
||||
so lets say we wanted to do the indent, the hard way.
|
||||
|
||||
Reference in New Issue
Block a user