on master help sign in
Properly parse all user-defined infix declarations
c2eecc2Evan Czaplicki
compiler/Parse/Binop.hs+1−25
@@ -1,4 +1,4 @@
1−module Parse.Binop (binops, infixStmt, OpTable) where
1+module Parse.Binop (binops, OpTable) where
2
2
3import Control.Applicative ((<$>))
3import Control.Applicative ((<$>))
4import Control.Monad.Error
4import Control.Monad.Error
@@ -11,20 +11,6 @@ import SourceSyntax.Declaration (Assoc(..))
11import Text.Parsec
11import Text.Parsec
12import Parse.Helpers
12import Parse.Helpers
13
13
14−preludeTable =
15− [ (9, R, ".")
16− , (8, R, "^")
17− , (7, L, "*"), (7, L, "/"), (7, L, "mod"), (7, L, "div"), (7, L, "rem")
18− , (6, L, "+"), (6, L, "-")
19− , (5, R, "::"), (5, R, "++")
20− , (4, N, "<="), (4, N, ">="), (4, N, "<")
21− , (4, N, "=="), (4, N, "/="), (4, N, ">")
22− , (4, L, "~"), (4, L, "<~")
23− , (3, R, "&&")
24− , (2, R, "||")
25− , (0, R, "<|"), (0, L, "|>")
26− ]
27−
28opLevel :: OpTable -> String -> Int
14opLevel :: OpTable -> String -> Int
29opLevel table op = fst $ Map.findWithDefault (9,L) op table
15opLevel table op = fst $ Map.findWithDefault (9,L) op table
30
16
@@ -96,13 +82,3 @@ getAssoc table n eops
96 concat [ "Conflicting " ++ problem ++ " for binary operators ("
82 concat [ "Conflicting " ++ problem ++ " for binary operators ("
97 , intercalate ", " (map fst eops), "). "
83 , intercalate ", " (map fst eops), "). "
98 , "Consider adding parentheses to disambiguate." ]
84 , "Consider adding parentheses to disambiguate." ]
99−
100−infixStmt :: IParser (Int, Assoc, String)
101−infixStmt =
102− let infx str assoc = try (reserved ("infix" ++ str) >> return assoc) in
103− do assoc <- choice [ infx "l" L, infx "r" R, infx "" N ]
104− whitespace
105− prec <- do n <- digit ; return (read [n] :: Int)
106− whitespace
107− op <- anyOp
108− return (prec, assoc, op)
compiler/Parse/Parse.hs+9−14
@@ -9,9 +9,11 @@ import Text.Parsec hiding (newline,spaces)
9import qualified Text.PrettyPrint as P
9import qualified Text.PrettyPrint as P
10
10
11import qualified SourceSyntax.Module as S
11import qualified SourceSyntax.Module as S
12+import SourceSyntax.Declaration (Declaration(Fixity))
12import Parse.Helpers
13import Parse.Helpers
13−import Parse.Binop (infixStmt, OpTable)
14+import Parse.Binop (OpTable)
14import Parse.Expression
15import Parse.Expression
16+import Parse.Declaration (infixDecl)
15import Parse.Type
17import Parse.Type
16import Parse.Module
18import Parse.Module
17import qualified Parse.Declaration as Decl
19import qualified Parse.Declaration as Decl
@@ -59,22 +61,15 @@ setupParserWithTable table p source =
59
61
60parseFixities = infixes []
62parseFixities = infixes []
61 where
63 where
62− nil p = const () <$> p
64+ eatLine = anyThen (const False <$> simpleNewline <|> const True <$> eof)
63− manyTil p end = end <|> (p >> manyTil p end)
64
65
65− eatLine = manyTil (nil multiComment <|> nil anyChar)
66− (const False <$> simpleNewline <|> const True <$> eof)
67−
68− infixes stmts = do
66+ infixes ops = do
69− next <- Left <$> infixStmt <|> Right <$> eatLine
67+ next <- Left <$> infixDecl <|> Right <$> eatLine
70 case next of
68 case next of
71− Left stmt -> infixes (stmt:stmts)
69+ Left (Fixity assoc lvl op) -> infixes ((op,(lvl,assoc)) : ops)
72− Right True -> return $ format stmts
70+ Right True -> return $ Map.fromList ops
73− Right False -> infixes stmts
71+ Right False -> infixes ops
74
72
75− format = Map.fromList . map (\(lvl,assoc,op) -> (op, (lvl,assoc)))
76−
77−
78setupParser :: IParser a -> String -> Either [P.Doc] a
73setupParser :: IParser a -> String -> Either [P.Doc] a
79setupParser p source =
74setupParser p source =
80 case iParse p source of
75 case iParse p source of
libraries/Basics.elm+4
@@ -96,6 +96,10 @@ infixl 7 *
96infixl 7 /
96infixl 7 /
97infixl 8 ^
97infixl 8 ^
98
98
99+infixl 7 `div`
100+infixl 7 `mod`
101+infixl 7 `rem`
102+
99{-| Integer division, remainder is discarded. -}
103{-| Integer division, remainder is discarded. -}
100div : Int -> Int -> Int
104div : Int -> Int -> Int
101div = Native.Basics.div
105div = Native.Basics.div