on master help sign in
Actually use infixes in parser
commit11f5f5263c1e49c769f44891625b0a8147cd2577 authorEvan Czaplicki <info@elm-lang.org> dateThu 29 Aug 2013, 02:53 (13 years ago) parent37f1be6
3 files changed+43−4
compiler/Initialize.hs+4−1 compiler/Parse/Parse.hs+38−2 compiler/Transform/Canonicalize.hs+1−1
compiler/Initialize.hs+4−1
@@ -23,7 +23,10 @@ import qualified Transform.Canonicalize as Canonical
2323buildFromSource :: Bool -> Interfaces -> String -> Either [Doc] (MetadataModule () ())
2424buildFromSource noPrelude interfaces source =
2525 do let add = if noPrelude then id else Prelude.add
26− modul@(Module _ _ _ decls') <- add `fmap` Parse.program source
26+ infixes = Map.fromList . map (\(assoc,lvl,op) -> (op,(lvl,assoc)))
27+ . concatMap iFixities $ Map.elems interfaces
28+
29+ modul@(Module _ _ _ decls') <- add `fmap` Parse.program infixes source
2730
2831 -- check for structural errors
2932 Module names exs ims decls <-
compiler/Parse/Parse.hs+38−2
@@ -4,11 +4,13 @@ import Control.Applicative ((<$>), (<*>))
44import Control.Monad
55import Data.Char (isSymbol, isDigit)
66import Data.List (foldl',intercalate)
7+import qualified Data.Map as Map
78import Text.Parsec hiding (newline,spaces)
89import qualified Text.PrettyPrint as P
910
1011import qualified SourceSyntax.Module as S
1112import Parse.Helpers
13+import Parse.Binop (infixStmt, OpTable)
1214import Parse.Expression
1315import Parse.Type
1416import Parse.Module
@@ -21,8 +23,8 @@ freshDef = commitIf (freshLine >> (letter <|> char '_')) $ do
2123decls = do d <- Decl.declaration <?> "at least one datatype or variable definition"
2224 (d:) <$> many freshDef
2325
24−program :: String -> Either [P.Doc] (S.Module t v)
25−program = setupParser $ do
26+program :: OpTable -> String -> Either [P.Doc] (S.Module t v)
27+program table = setupParserWithTable table $ do
2628 optional freshLine
2729 (names,exports) <- option (["Main"],[]) (moduleDef `followedBy` freshLine)
2830 is <- (do try (lookAhead $ reserved "import")
@@ -39,6 +41,40 @@ dependencies =
3941 (,) <$> option "Main" (getName <$> moduleDef `followedBy` freshLine)
4042 <*> option [] (map fst <$> imports `followedBy` freshLine)
4143
44+setupParserWithTable :: OpTable -> IParser a -> String -> Either [P.Doc] a
45+setupParserWithTable table p source =
46+ do localTable <- setupParser parseFixities source
47+ case Map.intersection table localTable of
48+ overlap | not (Map.null overlap) -> Left [ msg overlap ]
49+ | otherwise ->
50+ flip setupParser source $ do
51+ putState (Map.union table localTable)
52+ p
53+ where
54+ msg overlap =
55+ P.vcat [ P.text "Parse error:"
56+ , P.text $ "Overlapping definitions for infix operators: " ++
57+ intercalate " " (Map.keys overlap)
58+ ]
59+
60+parseFixities = infixes []
61+ where
62+ nil p = const () <$> p
63+ manyTil p end = end <|> (p >> manyTil p end)
64+
65+ eatLine = manyTil (nil multiComment <|> nil anyChar)
66+ (const False <$> simpleNewline <|> const True <$> eof)
67+
68+ infixes stmts = do
69+ next <- Left <$> infixStmt <|> Right <$> eatLine
70+ case next of
71+ Left stmt -> infixes (stmt:stmts)
72+ Right True -> return $ format stmts
73+ Right False -> infixes stmts
74+
75+ format = Map.fromList . map (\(lvl,assoc,op) -> (op, (lvl,assoc)))
76+
77+
4278setupParser :: IParser a -> String -> Either [P.Doc] a
4379setupParser p source =
4480 case iParse p source of
compiler/Transform/Canonicalize.hs+1−1
@@ -22,7 +22,7 @@ interface moduleName iface =
2222 { iTypes = Map.mapKeys prefix (Map.map renameType' (iTypes iface))
2323 , iAdts = map (both prefix renameCtors) (iAdts iface)
2424 , iAliases = map (both prefix renameType') (iAliases iface)
25− , iFixities = map (both id prefix) (iFixities iface)
25+ , iFixities = iFixities iface -- cannot have canonicalized operators while parsing
2626 }
2727 where
2828 both f g (a,b,c) = (f a, b, g c)