on master help sign in
Namespace parsing improvements (for qualified operator names)

thanks to Dirk Ullrich

commit517acc13589079c51b36adad2f1999c2e3388593 authorEdwin Brady <eb@cs.st-andrews.ac.uk> dateTue 4 Sep 2012, 09:14 (14 years ago) parent3812df8
3 files changed+62−12
src/Core/CoreParser.hs+35−9 src/IRTS/Defunctionalise.hs+20 src/Idris/Parser.hs+7−3
src/Core/CoreParser.hs+35−9
@@ -1,6 +1,7 @@
11{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
22
3−module Core.CoreParser(parseTerm, parseFile, parseDef, pTerm, iName, idrisDef) where
3+module Core.CoreParser(parseTerm, parseFile, parseDef, pTerm, iName, idrisDef,
4+ maybeWithNS) where
45
56import Core.TT
67
@@ -60,15 +61,40 @@ pTestFile = do p <- many1 pDef ; eof
6061 return p
6162
6263iName :: [String] -> CParser a Name
63−iName bad = do x <- identifier
64− when (x `elem` bad) $ fail "Reserved identifier"
65− return $ mkNS (reverse (parseName x))
64+iName bad = maybeWithNS identifier False bad
65+
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
71+ i <- option "" (lookAhead identifier)
72+ when (i `elem` bad) $ fail "Reserved identifier"
73+ let transf = if ascend then id else reverse
74+ (x, xs) <- choice $ transf (parserNoNS : parsersNS i)
75+ return $ mkName (x, xs)
6676 where
67− mkNS [x] = UN x
68− mkNS (x:xs) = NS (UN x) xs
69− parseName x = case span (/= '.') x of
70− (x, "") -> [x]
71− (x, '.':y) -> x : parseName y
77+ parserNoNS = do x <- parser; return (x, "")
78+ parserNS ns = do xs <- string ns; lchar '.'; x <- parser; return (x, xs)
79+ parsersNS i = [try (parserNS ns) | ns <- (initsEndAt (=='.') i)]
80+
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
83+-- condition.
84+initsEndAt :: (a -> Bool) -> [a] -> [[a]]
85+initsEndAt p [] = []
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]
89+
90+-- Create a `Name' from a pair of strings representing a base name and its
91+-- namespace.
92+mkName :: (String, String) -> Name
93+mkName (n, "") = UN n
94+mkName (n, ns) = NS (UN n) (reverse (parseNS ns))
95+ where parseNS x = case span (/= '.') x of
96+ (x, "") -> [x]
97+ (x, '.':y) -> x : parseNS y
7298
7399pDef :: CParser a (Name, RDef)
74100pDef = try (do x <- iName []; lchar ':'; ty <- pTerm
src/IRTS/Defunctionalise.hsnew file+20
@@ -0,0 +1,20 @@
1+module IRTS.Defunctionalise where
2+
3+import IRTS.Lang
4+import Core.TT
5+
6+defunctionalise :: [(Name, LDecl)] -> [(Name, LDecl)]
7+defunctionalise defs = defs -- TODO!
8+
9+-- To defunctionalise:
10+--
11+-- 1 Create a data constructor for each function
12+-- 2 Create a data constructor for each underapplication of a function
13+-- 3 Convert underapplications to their corresponding constructors
14+-- 4 Create an EVAL function which calls the appropriate function for data constructors
15+-- created as part of step 1
16+-- 5 Create an APPLY function which adds an argument to each underapplication (or calls
17+-- APPLY again for an exact application)
18+-- 6 Wrap overapplications in chains of APPLY
19+
20+
src/Idris/Parser.hs+7−3
@@ -613,10 +613,14 @@ pName = do i <- getState
613613 i <- getState
614614 UN n <- iName (syntax_keywords i)
615615 return (UN ('@':n))
616−
617616
618−pfName = try pName
619− <|> do lchar '('; o <- operator; lchar ')'; return (UN o)
617+-- Parser for an operator in function position, i.e. enclosed by `()', with an
618+-- optional namespace.
619+pOpFront = maybeWithNS pOpFrontNoNS False []
620+ where pOpFrontNoNS = do lchar '('; o <- operator; lchar ')'; return o
621+
622+pfName = try pOpFront
623+ <|> pName
620624
621625pAccessibility' :: IParser Accessibility
622626pAccessibility'