@@ -1,6 +1,7 @@
1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
1{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
3−module Core.CoreParser(parseTerm, parseFile, parseDef, pTerm, iName, idrisDef) where
3+module Core.CoreParser(parseTerm, parseFile, parseDef, pTerm, iName, idrisDef,
5import Core.TT
6import Core.TT
@@ -60,15 +61,40 @@ pTestFile = do p <- many1 pDef ; eof
62iName :: [String] -> CParser a Name
63iName :: [String] -> CParser a Name
64+iName bad = maybeWithNS identifier False bad
66+-- Enhances a given parser to accept an optional namespace. All possible
67+-- namespace prefixes are tried in ascending / descending order, and
68+-- identifiers of a given list fail.
69+maybeWithNS :: CParser a String -> Bool -> [String] -> CParser a Name
70+maybeWithNS parser ascend bad = do
63−iName bad = do x <- identifier
71+ i <- option "" (lookAhead identifier)
64− when (x `elem` bad) $ fail "Reserved identifier"
72+ when (i `elem` bad) $ fail "Reserved identifier"
65− return $ mkNS (reverse (parseName x))
73+ let transf = if ascend then id else reverse
74+ (x, xs) <- choice $ transf (parserNoNS : parsersNS i)
75+ return $ mkName (x, xs)
67− mkNS [x] = UN x
77+ parserNoNS = do x <- parser; return (x, "")
68− mkNS (x:xs) = NS (UN x) xs
78+ parserNS ns = do xs <- string ns; lchar '.'; x <- parser; return (x, xs)
79+ parsersNS i = [try (parserNS ns) | ns <- (initsEndAt (=='.') i)]
81+-- List of all initial segments in ascending order of a list. Every such
82+-- initial segment ends right before an element satisfying the given
84+initsEndAt :: (a -> Bool) -> [a] -> [[a]]
86+initsEndAt p (x:xs) | p x = [] : x_inits_xs
87+ | otherwise = x_inits_xs
88+ where x_inits_xs = [x : cs | cs <- initsEndAt p xs]
90+-- Create a `Name' from a pair of strings representing a base name and its
92+mkName :: (String, String) -> Name
94+mkName (n, ns) = NS (UN n) (reverse (parseNS ns))
69− parseName x = case span (/= '.') x of
95+ where parseNS x = case span (/= '.') x of
70− (x, "") -> [x]
96+ (x, "") -> [x]
71− (x, '.':y) -> x : parseName y
97+ (x, '.':y) -> x : parseNS y
73pDef :: CParser a (Name, RDef)
99pDef :: CParser a (Name, RDef)
74pDef = try (do x <- iName []; lchar ':'; ty <- pTerm
100pDef = try (do x <- iName []; lchar ':'; ty <- pTerm