@@ -6,10 +6,13 @@ import Core.CoreParser
66import Core.TT
77
88import Text.ParserCombinators.Parsec
9+import Text.Parsec.Prim(Parsec)
910import Text.ParserCombinators.Parsec.Expr
1011import Text.ParserCombinators.Parsec.Language
1112import qualified Text.ParserCombinators.Parsec.Token as PTok
1213
14+import Data.List
15+import Control.Monad.State
1316import Debug.Trace
1417
1518type TokenParser a = PTok.TokenParser a
@@ -22,7 +25,9 @@ idrisDef = haskellDef {
2225 "using", "params", "namespace"]
2326 }
2427
25−lexer :: TokenParser ()
28+type IParser = Parsec String IState
29+
30+lexer :: TokenParser IState
2631lexer = PTok.makeTokenParser idrisDef
2732
2833whiteSpace= PTok.whiteSpace lexer
@@ -38,17 +43,48 @@ operator = PTok.operator lexer
3843reservedOp= PTok.reservedOp lexer
3944lchar = lexeme.char
4045
41−parseExpr = parse pFullExpr "(input)"
46+parseExpr i = runParser pFullExpr i "(input)"
47+
48+parseProg :: String -> Idris [PDecl]
49+parseProg fname = do file <- lift $ readFile fname
50+ i <- get
51+ case (runParser (do ps <- many1 pDecl
52+ i' <- getState
53+ return (ps, i')) i fname file) of
54+ Left err -> fail (show err)
55+ Right (x, i) -> do put i
56+ return x
57+
4258
4359pFullExpr = do x <- pExpr; eof; return x
4460
45−pExpr' :: Parser PTerm
61+pDecl :: IParser PDecl
62+pDecl = do d <- pDecl'; lchar ';'; return d
63+
64+pDecl' :: IParser PDecl
65+pDecl' = try (do f <- fixity; i <- natural; ops <- sepBy1 operator (lchar ',')
66+ let prec = fromInteger i
67+ istate <- getState
68+ let fs = map (Fix (f prec)) ops
69+ setState (istate {
70+ idris_infixes = sort (fs ++ idris_infixes istate) })
71+ return (PFix (f prec) ops))
72+ <|> try (do n <- iName; ty <- pTSig
73+ return (PTy n ty))
74+
75+fixity :: IParser (Int -> Fixity)
76+fixity = try (do reserved "infixl"; return Infixl)
77+ <|> try (do reserved "infixr"; return Infixr)
78+ <|> try (do reserved "infix"; return InfixN)
79+
80+pExpr = do i <- getState
81+ buildExpressionParser (table (idris_infixes i)) pExpr'
82+
83+pExpr' :: IParser PTerm
4684pExpr' = try pApp
47− <|> pSimpleExpr
48− <|> try pLambda
49− <|> try pPi
50−
51−pExpr = buildExpressionParser table pExpr'
85+ <|> pSimpleExpr
86+ <|> try pLambda
87+ <|> try pPi
5288
5389pSimpleExpr =
5490 try (do symbol "!["; t <- pTerm; lchar ']'
@@ -79,8 +115,18 @@ pPi = do lchar '('; x <- iName; t <- pTSig; lchar ')'
79115 sc <- pExpr
80116 return (PPi Imp x t sc)
81117
82−table = [[binary "=" (\x y -> PApp (PRef (UN ["="])) [] [x,y]) AssocLeft],
83− [binary "->" (PPi Exp (MN 0 "X")) AssocRight]]
118+table fixes
119+ = toTable (reverse fixes) ++
120+ [[binary "=" (\x y -> PApp (PRef (UN ["="])) [] [x,y]) AssocLeft],
121+ [binary "->" (PPi Exp (MN 0 "X")) AssocRight]]
122+
123+toTable fs = map (map toBin)
124+ (groupBy (\ (Fix x _) (Fix y _) -> prec x == prec y) fs)
125+ where toBin (Fix f op) = binary op
126+ (\x y -> PApp (PRef (UN [op])) [] [x,y]) (assoc f)
127+ assoc (Infixl _) = AssocLeft
128+ assoc (Infixr _) = AssocRight
129+ assoc (InfixN _) = AssocNone
84130
85131binary name f assoc = Infix (do { reservedOp name; return f }) assoc
86132