@@ -47,11 +47,14 @@ import Control.Monad
47import Control.Monad.Error (throwError, catchError)
47import Control.Monad.Error (throwError, catchError)
48import Control.Monad.State.Strict
48import Control.Monad.State.Strict
50import Data.Maybe
51import Data.Maybe
51import qualified Data.List.Split as Spl
52import qualified Data.List.Split as Spl
52import Data.List
53import Data.List
53import Data.Monoid
54import Data.Monoid
54import Data.Char
55import Data.Char
57+import qualified Data.Map as M
55import qualified Data.HashSet as HS
58import qualified Data.HashSet as HS
56import qualified Data.Text as T
59import qualified Data.Text as T
57import qualified Data.ByteString.UTF8 as UTF8
60import qualified Data.ByteString.UTF8 as UTF8
@@ -63,6 +66,7 @@ import System.FilePath
63import System.IO
66import System.IO
66 grammar shortcut notation:
70 grammar shortcut notation:
67 ~CHARSEQ = complement of char sequence (i.e. any character except CHARSEQ)
71 ~CHARSEQ = complement of char sequence (i.e. any character except CHARSEQ)
68 RULE? = optional rule (i.e. RULE or nothing)
72 RULE? = optional rule (i.e. RULE or nothing)
@@ -70,12 +74,16 @@ import System.IO
70 RULE+ = repeated rule with at least one match (i.e. RULE one or more times)
74 RULE+ = repeated rule with at least one match (i.e. RULE one or more times)
71 RULE! = invalid rule (i.e. rule that is not valid in context, report meaningful error in case)
75 RULE! = invalid rule (i.e. rule that is not valid in context, report meaningful error in case)
72 RULE{n} = rule repeated n times
76 RULE{n} = rule repeated n times
75{- * Main grammar -}
80{- * Main grammar -}
77{- | Parses module definition
82{- | Parses module definition
78 ModuleHeader ::= 'module' Identifier_t ';'?;
85 ModuleHeader ::= 'module' Identifier_t ';'?;
80moduleHeader :: IdrisParser [String]
88moduleHeader :: IdrisParser [String]
81moduleHeader = try (do reserved "module"
89moduleHeader = try (do reserved "module"
@@ -90,18 +98,26 @@ moduleHeader = try (do reserved "module"
90 (x, '.':y) -> x : moduleName y
98 (x, '.':y) -> x : moduleName y
92{- | Parses an import statement
100{- | Parses an import statement
93 Import ::= 'import' Identifier_t ';'?;
103 Import ::= 'import' Identifier_t ';'?;
95−import_ :: IdrisParser String
106+import_ :: IdrisParser (String, Maybe String, FC)
107+import_ = do fc <- getFC
96−import_ = do reserved "import"
108+ reserved "import"
97 id <- identifier
109 id <- identifier
110+ newName <- optional (reserved "as" *> identifier)
98 option ';' (lchar ';')
111 option ';' (lchar ';')
99− return (toPath id)
112+ return (toPath id, toPath <$> newName, fc)
100 <?> "import statement"
113 <?> "import statement"
101− where toPath f = foldl1' (</>) (Spl.splitOn "." f)
114+ where toPath = foldl1' (</>) . Spl.splitOn "."
103{- | Parses program source
116{- | Parses program source
104 Prog ::= Decl* EOF;
119 Prog ::= Decl* EOF;
106prog :: SyntaxInfo -> IdrisParser [PDecl]
122prog :: SyntaxInfo -> IdrisParser [PDecl]
107prog syn = do whiteSpace
123prog syn = do whiteSpace
@@ -111,7 +127,9 @@ prog syn = do whiteSpace
111 let c = (concat decls)
127 let c = (concat decls)
114−{- | Parses a top-level declaration
130+{-| Parses a top-level declaration
@@ -126,6 +144,7 @@ Decl ::=
126 | Transform
144 | Transform
127 | Import!
145 | Import!
130decl :: SyntaxInfo -> IdrisParser [PDecl]
149decl :: SyntaxInfo -> IdrisParser [PDecl]
131decl syn = do notEndBlock
150decl syn = do notEndBlock
@@ -151,6 +170,8 @@ decl syn = do notEndBlock
151 return [d']
170 return [d']
153{- | Parses a top-level declaration with possible syntax sugar
172{- | Parses a top-level declaration with possible syntax sugar
156 | FunDecl'
177 | FunDecl'
@@ -158,6 +179,7 @@ Decl' ::=
159 | SyntaxDecl
180 | SyntaxDecl
162decl' :: SyntaxInfo -> IdrisParser PDecl
184decl' :: SyntaxInfo -> IdrisParser PDecl
163decl' syn = fixity
185decl' syn = fixity
@@ -168,7 +190,10 @@ decl' syn = fixity
168 <?> "declaration"
190 <?> "declaration"
170{- | Parses a syntax extension declaration (and adds the rule to parser state)
192{- | Parses a syntax extension declaration (and adds the rule to parser state)
171 SyntaxDecl ::= SyntaxRule;
195 SyntaxDecl ::= SyntaxRule;
173syntaxDecl :: SyntaxInfo -> IdrisParser PDecl
198syntaxDecl :: SyntaxInfo -> IdrisParser PDecl
174syntaxDecl syn = do s <- syntaxRule syn
199syntaxDecl syn = do s <- syntaxRule syn
@@ -186,17 +211,24 @@ syntaxDecl syn = do s <- syntaxRule syn
186 ename (Keyword n) = Just n
211 ename (Keyword n) = Just n
187 ename _ = Nothing
212 ename _ = Nothing
189−{- | Parses a syntax extension declaration
214+{- | Parses a syntax extension declaration
190−SyntaxRuleOpts ::= 'term' | 'pattern';
217+SyntaxRuleOpts ::= 'term' | 'pattern';
192SyntaxRule ::=
221SyntaxRule ::=
193 SyntaxRuleOpts? 'syntax' SyntaxSym+ '=' TypeExpr Terminator;
222 SyntaxRuleOpts? 'syntax' SyntaxSym+ '=' TypeExpr Terminator;
195SyntaxSym ::= '[' Name_t ']'
226SyntaxSym ::= '[' Name_t ']'
196 | '{' Name_t '}'
227 | '{' Name_t '}'
198 | StringLiteral_t
229 | StringLiteral_t
201syntaxRule :: SyntaxInfo -> IdrisParser Syntax
233syntaxRule :: SyntaxInfo -> IdrisParser Syntax
202syntaxRule syn
234syntaxRule syn
@@ -232,11 +264,14 @@ syntaxRule syn
234{- | Parses a syntax symbol (either binding variable, keyword or expression)
266{- | Parses a syntax symbol (either binding variable, keyword or expression)
235SyntaxSym ::= '[' Name_t ']'
269SyntaxSym ::= '[' Name_t ']'
236 | '{' Name_t '}'
270 | '{' Name_t '}'
238 | StringLiteral_t
272 | StringLiteral_t
241syntaxSym :: IdrisParser SSymbol
276syntaxSym :: IdrisParser SSymbol
242syntaxSym = try (do lchar '['; n <- name; lchar ']'
277syntaxSym = try (do lchar '['; n <- name; lchar ']'
@@ -250,7 +285,10 @@ syntaxSym = try (do lchar '['; n <- name; lchar ']'
250 <?> "syntax symbol"
285 <?> "syntax symbol"
252{- | Parses a function declaration with possible syntax sugar
287{- | Parses a function declaration with possible syntax sugar
253 FunDecl ::= FunDecl';
290 FunDecl ::= FunDecl';
255fnDecl :: SyntaxInfo -> IdrisParser [PDecl]
293fnDecl :: SyntaxInfo -> IdrisParser [PDecl]
256fnDecl syn = try (do notEndBlock
294fnDecl syn = try (do notEndBlock
@@ -259,13 +297,16 @@ fnDecl syn = try (do notEndBlock
259 let d' = fmap (desugar syn i) d
297 let d' = fmap (desugar syn i) d
260 return [d']) <?> "function declaration"
298 return [d']) <?> "function declaration"
262−{- Parses a function declaration
300+{-| Parses a function declaration
263 FunDecl' ::=
303 FunDecl' ::=
264 DocComment_t? FnOpts* Accessibility? FnOpts* FnName TypeSig Terminator
304 DocComment_t? FnOpts* Accessibility? FnOpts* FnName TypeSig Terminator
265 | Postulate
305 | Postulate
266 | Pattern
306 | Pattern
270fnDecl' :: SyntaxInfo -> IdrisParser PDecl
311fnDecl' :: SyntaxInfo -> IdrisParser PDecl
271fnDecl' syn = checkFixity $
312fnDecl' syn = checkFixity $
@@ -309,23 +350,29 @@ fnDecl' syn = checkFixity $
309 | otherwise = return True
350 | otherwise = return True
310 fixityOK _ = return True
351 fixityOK _ = return True
312−{- Parses function options given initial options
353+{-| Parses function options given initial options
313FnOpts ::= 'total'
356FnOpts ::= 'total'
314 | 'partial'
357 | 'partial'
315 | 'implicit'
358 | 'implicit'
316 | '%' 'assert_total'
359 | '%' 'assert_total'
317 | '%' 'error_handler'
360 | '%' 'error_handler'
318− | '%' 'reflection'
361+ | '%' 'reflection'
319 | '%' 'specialise' '[' NameTimesList? ']'
362 | '%' 'specialise' '[' NameTimesList? ']'
322NameTimes ::= FnName Natural?;
367NameTimes ::= FnName Natural?;
324NameTimesList ::=
371NameTimesList ::=
325 NameTimes
372 NameTimes
326 | NameTimes ',' NameTimesList
373 | NameTimes ',' NameTimesList
330-- FIXME: Check compatability for function options (i.e. partal/total)
377-- FIXME: Check compatability for function options (i.e. partal/total)
331fnOpts :: [FnOpt] -> IdrisParser [FnOpt]
378fnOpts :: [FnOpt] -> IdrisParser [FnOpt]
@@ -356,9 +403,11 @@ fnOpts opts
357{- | Parses a postulate
404{- | Parses a postulate
359Postulate ::=
407Postulate ::=
360 DocComment_t? 'postulate' FnOpts* Accesibility? FnOpts* FnName TypeSig Terminator
408 DocComment_t? 'postulate' FnOpts* Accesibility? FnOpts* FnName TypeSig Terminator
363postulate :: SyntaxInfo -> IdrisParser PDecl
412postulate :: SyntaxInfo -> IdrisParser PDecl
364postulate syn = do doc <- try $ do doc <- option "" (docComment '|')
413postulate syn = do doc <- try $ do doc <- option "" (docComment '|')
@@ -384,9 +433,11 @@ postulate syn = do doc <- try $ do doc <- option "" (docComment '|')
385{- | Parses a using declaration
434{- | Parses a using declaration
388 'using' '(' UsingDeclList ')' OpenBlock Decl* CloseBlock
438 'using' '(' UsingDeclList ')' OpenBlock Decl* CloseBlock
391using_ :: SyntaxInfo -> IdrisParser [PDecl]
442using_ :: SyntaxInfo -> IdrisParser [PDecl]
392using_ syn =
443using_ syn =
@@ -398,11 +449,13 @@ using_ syn =
398 return (concat ds)
449 return (concat ds)
399 <?> "using declaration"
450 <?> "using declaration"
401−{- | Parses a parameters declaration
452+{- | Parses a parameters declaration
403Params ::=
455Params ::=
404 'parameters' '(' TypeDeclList ')' OpenBlock Decl* CloseBlock
456 'parameters' '(' TypeDeclList ')' OpenBlock Decl* CloseBlock
407params :: SyntaxInfo -> IdrisParser [PDecl]
460params :: SyntaxInfo -> IdrisParser [PDecl]
408params syn =
461params syn =
@@ -417,9 +470,11 @@ params syn =
418{- | Parses a mutual declaration (for mutually recursive functions)
471{- | Parses a mutual declaration (for mutually recursive functions)
420Mutual ::=
474Mutual ::=
421 'mutual' OpenBlock Decl* CloseBlock
475 'mutual' OpenBlock Decl* CloseBlock
424mutual :: SyntaxInfo -> IdrisParser [PDecl]
479mutual :: SyntaxInfo -> IdrisParser [PDecl]
425mutual syn =
480mutual syn =
@@ -432,11 +487,13 @@ mutual syn =
432 return [PMutual fc (concat ds)]
487 return [PMutual fc (concat ds)]
433 <?> "mutual block"
488 <?> "mutual block"
435−{- | Parses a namespace declaration
490+{-| Parses a namespace declaration
437Namespace ::=
493Namespace ::=
438 'namespace' identifier OpenBlock Decl+ CloseBlock
494 'namespace' identifier OpenBlock Decl+ CloseBlock
441namespace :: SyntaxInfo -> IdrisParser [PDecl]
498namespace :: SyntaxInfo -> IdrisParser [PDecl]
442namespace syn =
499namespace syn =
@@ -447,9 +504,12 @@ namespace syn =
447 return [PNamespace n (concat ds)]
504 return [PNamespace n (concat ds)]
448 <?> "namespace declaration"
505 <?> "namespace declaration"
450−{- |Parses a methods block (for instances)
507+{- | Parses a methods block (for instances)
451 InstanceBlock ::= 'where' OpenBlock FnDecl* CloseBlock
510 InstanceBlock ::= 'where' OpenBlock FnDecl* CloseBlock
453instanceBlock :: SyntaxInfo -> IdrisParser [PDecl]
513instanceBlock :: SyntaxInfo -> IdrisParser [PDecl]
454instanceBlock syn = do reserved "where"
514instanceBlock syn = do reserved "where"
455 openBlock
515 openBlock
@@ -458,16 +518,20 @@ instanceBlock syn = do reserved "where"
458 return (concat ds)
518 return (concat ds)
459 <?> "instance block"
519 <?> "instance block"
461−{- |Parses a methods and instances block (for type classes)
521+{- | Parses a methods and instances block (for type classes)
463MethodOrInstance ::=
524MethodOrInstance ::=
465 | Instance
526 | Instance
468ClassBlock ::=
531ClassBlock ::=
469 'where' OpenBlock MethodOrInstance* CloseBlock
532 'where' OpenBlock MethodOrInstance* CloseBlock
472classBlock :: SyntaxInfo -> IdrisParser [PDecl]
536classBlock :: SyntaxInfo -> IdrisParser [PDecl]
473classBlock syn = do reserved "where"
537classBlock syn = do reserved "where"
@@ -477,16 +541,20 @@ classBlock syn = do reserved "where"
477 return (concat ds)
541 return (concat ds)
478 <?> "class block"
542 <?> "class block"
480−{- |Parses a type class declaration
544+{-| Parses a type class declaration
482ClassArgument ::=
547ClassArgument ::=
484 | '(' Name ':' Expr ')'
549 | '(' Name ':' Expr ')'
488 DocComment_t? Accessibility? 'class' ConstraintList? Name ClassArgument* ClassBlock?
555 DocComment_t? Accessibility? 'class' ConstraintList? Name ClassArgument* ClassBlock?
491class_ :: SyntaxInfo -> IdrisParser [PDecl]
559class_ :: SyntaxInfo -> IdrisParser [PDecl]
492class_ syn = do (doc, acc) <- try (do
560class_ syn = do (doc, acc) <- try (do
@@ -507,13 +575,17 @@ class_ syn = do (doc, acc) <- try (do
507 <|> do i <- name;
575 <|> do i <- name;
508 return (i, PType)
576 return (i, PType)
510−{- |Parses a type class instance declaration
578+{- | Parses a type class instance declaration
512 Instance ::=
581 Instance ::=
513 'instance' InstanceName? ConstraintList? Name SimpleExpr* InstanceBlock?
582 'instance' InstanceName? ConstraintList? Name SimpleExpr* InstanceBlock?
516− InstanceName ::= '[' Name ']';
587+InstanceName ::= '[' Name ']';
518instance_ :: SyntaxInfo -> IdrisParser [PDecl]
590instance_ :: SyntaxInfo -> IdrisParser [PDecl]
519instance_ syn = do reserved "instance"; fc <- getFC
591instance_ syn = do reserved "instance"; fc <- getFC
@@ -534,20 +606,27 @@ instance_ syn = do reserved "instance"; fc <- getFC
536{- | Parses a using declaration list
608{- | Parses a using declaration list
537UsingDeclList ::=
611UsingDeclList ::=
538 UsingDeclList'
612 UsingDeclList'
539 | NameList TypeSig
613 | NameList TypeSig
542UsingDeclList' ::=
618UsingDeclList' ::=
543 UsingDecl
619 UsingDecl
544 | UsingDecl ',' UsingDeclList'
620 | UsingDecl ',' UsingDeclList'
547NameList ::=
625NameList ::=
549 | Name ',' NameList
627 | Name ',' NameList
552usingDeclList :: SyntaxInfo -> IdrisParser [Using]
631usingDeclList :: SyntaxInfo -> IdrisParser [Using]
553usingDeclList syn
632usingDeclList syn
@@ -559,10 +638,13 @@ usingDeclList syn
559 <?> "using declaration list"
638 <?> "using declaration list"
561{- |Parses a using declaration
640{- |Parses a using declaration
562UsingDecl ::=
643UsingDecl ::=
563 FnName TypeSig
644 FnName TypeSig
564 | FnName FnName+
645 | FnName FnName+
567usingDecl :: SyntaxInfo -> IdrisParser Using
649usingDecl :: SyntaxInfo -> IdrisParser Using
568usingDecl syn = try (do x <- fnName
650usingDecl syn = try (do x <- fnName
@@ -574,8 +656,11 @@ usingDecl syn = try (do x <- fnName
574 return (UConstraint c xs)
656 return (UConstraint c xs)
575 <?> "using declaration"
657 <?> "using declaration"
577−{- | Parse a clause with patterns
659+{- | Parse a clause with patterns
578Pattern ::= Clause;
662Pattern ::= Clause;
580pattern :: SyntaxInfo -> IdrisParser PDecl
665pattern :: SyntaxInfo -> IdrisParser PDecl
581pattern syn = do fc <- getFC
666pattern syn = do fc <- getFC
@@ -584,7 +669,10 @@ pattern syn = do fc <- getFC
584 <?> "pattern"
669 <?> "pattern"
586{- | Parse a constant applicative form declaration
671{- | Parse a constant applicative form declaration
587− CAF ::= 'let' FnName '=' Expr Terminator;
674+CAF ::= 'let' FnName '=' Expr Terminator;
589caf :: SyntaxInfo -> IdrisParser PDecl
677caf :: SyntaxInfo -> IdrisParser PDecl
590caf syn = do reserved "let"
678caf syn = do reserved "let"
@@ -597,7 +685,10 @@ caf syn = do reserved "let"
597 <?> "constant applicative form declaration"
685 <?> "constant applicative form declaration"
599{- | Parse an argument expression
687{- | Parse an argument expression
600− ArgExpr ::= HSimpleExpr | {- In Pattern External (User-defined) Expression -};
690+ArgExpr ::= HSimpleExpr | {- In Pattern External (User-defined) Expression -};
602argExpr :: SyntaxInfo -> IdrisParser PTerm
693argExpr :: SyntaxInfo -> IdrisParser PTerm
603argExpr syn = let syn' = syn { inPattern = True } in
694argExpr syn = let syn' = syn { inPattern = True } in
@@ -605,12 +696,17 @@ argExpr syn = let syn' = syn { inPattern = True } in
605 <?> "argument expression"
696 <?> "argument expression"
607{- | Parse a right hand side of a function
698{- | Parse a right hand side of a function
608RHS ::= '=' Expr
701RHS ::= '=' Expr
609 | '?=' RHSName? Expr
702 | '?=' RHSName? Expr
610 | 'impossible'
703 | 'impossible'
613RHSName ::= '{' FnName '}';
708RHSName ::= '{' FnName '}';
615rhs :: SyntaxInfo -> Name -> IdrisParser PTerm
711rhs :: SyntaxInfo -> Name -> IdrisParser PTerm
616rhs syn n = do lchar '='; expr syn
712rhs syn n = do lchar '='; expr syn
@@ -633,16 +729,28 @@ rhs syn n = do lchar '='; expr syn
633 addLet nm r = (PLet (sUN "value") Placeholder r (PMetavar nm))
729 addLet nm r = (PLet (sUN "value") Placeholder r (PMetavar nm))
635{- |Parses a function clause
731{- |Parses a function clause
636RHSOrWithBlock ::= RHS WhereOrTerminator
734RHSOrWithBlock ::= RHS WhereOrTerminator
637 | 'with' SimpleExpr OpenBlock FnDecl+ CloseBlock
735 | 'with' SimpleExpr OpenBlock FnDecl+ CloseBlock
639Clause ::= WExpr+ RHSOrWithBlock
740Clause ::= WExpr+ RHSOrWithBlock
640 | SimpleExpr '<==' FnName RHS WhereOrTerminator
741 | SimpleExpr '<==' FnName RHS WhereOrTerminator
641 | ArgExpr Operator ArgExpr WExpr* RHSOrWithBlock {- Except "=" and "?=" operators to avoid ambiguity -}
742 | ArgExpr Operator ArgExpr WExpr* RHSOrWithBlock {- Except "=" and "?=" operators to avoid ambiguity -}
642 | FnName ConstraintArg* ImplicitOrArgExpr* WExpr* RHSOrWithBlock
743 | FnName ConstraintArg* ImplicitOrArgExpr* WExpr* RHSOrWithBlock
644ImplicitOrArgExpr ::= ImplicitArg | ArgExpr;
748ImplicitOrArgExpr ::= ImplicitArg | ArgExpr;
645−WhereOrTerminator ::= WhereBlock | Terminator;
752+WhereOrTerminator ::= WhereBlock | Terminator;
647clause :: SyntaxInfo -> IdrisParser PClause
755clause :: SyntaxInfo -> IdrisParser PClause
648clause syn
756clause syn
@@ -771,17 +879,23 @@ clause syn
771 fillLHSD n c a (PClauses fc o fn cs) = PClauses fc o fn (map (fillLHS n c a) cs)
879 fillLHSD n c a (PClauses fc o fn cs) = PClauses fc o fn (map (fillLHS n c a) cs)
772 fillLHSD n c a x = x
880 fillLHSD n c a x = x
774−{- |Parses with pattern
882+{-| Parses with pattern
775− WExpr ::= '|' Expr';
885+WExpr ::= '|' Expr';
777wExpr :: SyntaxInfo -> IdrisParser PTerm
888wExpr :: SyntaxInfo -> IdrisParser PTerm
778wExpr syn = do lchar '|'
889wExpr syn = do lchar '|'
779 expr' syn
890 expr' syn
780 <?> "with pattern"
891 <?> "with pattern"
782−{- |Parses a where block
893+{- | Parses a where block
783WhereBlock ::= 'where' OpenBlock Decl+ CloseBlock;
896WhereBlock ::= 'where' OpenBlock Decl+ CloseBlock;
785whereBlock :: Name -> SyntaxInfo -> IdrisParser ([PDecl], [(Name, Name)])
899whereBlock :: Name -> SyntaxInfo -> IdrisParser ([PDecl], [(Name, Name)])
786whereBlock n syn
900whereBlock n syn
787 = do reserved "where"
901 = do reserved "where"
@@ -791,6 +905,8 @@ whereBlock n syn
791 <?> "where block"
905 <?> "where block"
793{- |Parses a code generation target language name
907{- |Parses a code generation target language name
794Codegen ::= 'C'
910Codegen ::= 'C'
796 | 'JavaScript'
912 | 'JavaScript'
@@ -798,6 +914,7 @@ Codegen ::= 'C'
799 | 'Bytecode'
915 | 'Bytecode'
802codegen_ :: IdrisParser Codegen
919codegen_ :: IdrisParser Codegen
803codegen_ = do reserved "C"; return ViaC
920codegen_ = do reserved "C"; return ViaC
@@ -809,13 +926,18 @@ codegen_ = do reserved "C"; return ViaC
809 <?> "code generation language"
926 <?> "code generation language"
811{- |Parses a compiler directive
928{- |Parses a compiler directive
812StringList ::=
930StringList ::=
814 | String ',' StringList
932 | String ',' StringList
817Directive ::= '%' Directive';
937Directive ::= '%' Directive';
819Directive' ::= 'lib' CodeGen String_t
941Directive' ::= 'lib' CodeGen String_t
820 | 'link' CodeGen String_t
942 | 'link' CodeGen String_t
821 | 'flag' CodeGen String_t
943 | 'flag' CodeGen String_t
@@ -831,6 +953,7 @@ Directive' ::= 'lib' CodeGen String_t
831 | 'language' 'TypeProviders'
953 | 'language' 'TypeProviders'
832 | 'language' 'ErrorReflection'
954 | 'language' 'ErrorReflection'
835directive :: SyntaxInfo -> IdrisParser [PDecl]
958directive :: SyntaxInfo -> IdrisParser [PDecl]
836directive syn = do try (lchar '%' *> reserved "lib"); cgn <- codegen_; lib <- stringLiteral;
959directive syn = do try (lchar '%' *> reserved "lib"); cgn <- codegen_; lib <- stringLiteral;
@@ -899,15 +1022,22 @@ pLangExt = (reserved "TypeProviders" >> return TypeProviders)
899 <|> (reserved "ErrorReflection" >> return ErrorReflection)
1022 <|> (reserved "ErrorReflection" >> return ErrorReflection)
901{- | Parses a totality
1024{- | Parses a totality
902Totality ::= 'partial' | 'total'
1027Totality ::= 'partial' | 'total'
904totality :: IdrisParser Bool
1031totality :: IdrisParser Bool
906 = do reserved "total"; return True
1033 = do reserved "total"; return True
907 <|> do reserved "partial"; return False
1034 <|> do reserved "partial"; return False
909−{- | Parses a type provider
1036+{- | Parses a type provider
910Provider ::= '%' 'provide' '(' FnName TypeSig ')' 'with' Expr;
1039Provider ::= '%' 'provide' '(' FnName TypeSig ')' 'with' Expr;
912provider :: SyntaxInfo -> IdrisParser [PDecl]
1042provider :: SyntaxInfo -> IdrisParser [PDecl]
913provider syn = do try (lchar '%' *> reserved "provide");
1043provider syn = do try (lchar '%' *> reserved "provide");
@@ -919,7 +1049,10 @@ provider syn = do try (lchar '%' *> reserved "provide");
919 <?> "type provider"
1049 <?> "type provider"
921{- | Parses a transform
1051{- | Parses a transform
922Transform ::= '%' 'transform' Expr '==>' Expr
1054Transform ::= '%' 'transform' Expr '==>' Expr
924transform :: SyntaxInfo -> IdrisParser [PDecl]
1057transform :: SyntaxInfo -> IdrisParser [PDecl]
925transform syn = do try (lchar '%' *> reserved "transform")
1058transform syn = do try (lchar '%' *> reserved "transform")
@@ -945,7 +1078,7 @@ parseTactic :: IState -> String -> Result PTactic
945parseTactic st = runparser (fullTactic defaultSyntax) st "(input)"
1078parseTactic st = runparser (fullTactic defaultSyntax) st "(input)"
947-- | Parse module header and imports
1080-- | Parse module header and imports
948−parseImports :: FilePath -> String -> Idris ([String], [String], Maybe Delta)
1081+parseImports :: FilePath -> String -> Idris ([String], [(String, Maybe String, FC)], Maybe Delta)
949parseImports fname input
1082parseImports fname input
950 = do i <- getIState
1083 = do i <- getIState
951 case parseString (runInnerParser (evalStateT imports i)) (Directed (UTF8.fromString fname) 0 0 0 0) input of
1084 case parseString (runInnerParser (evalStateT imports i)) (Directed (UTF8.fromString fname) 0 0 0 0) input of
@@ -953,7 +1086,7 @@ parseImports fname input
953 Success (x, i) -> do -- Discard state updates (there should be
1086 Success (x, i) -> do -- Discard state updates (there should be
954 -- none anyway)
1087 -- none anyway)
955 return x
1088 return x
956− where imports :: IdrisParser (([String], [String], Maybe Delta), IState)
1089+ where imports :: IdrisParser (([String], [(String, Maybe String, FC)], Maybe Delta), IState)
957 imports = do whiteSpace
1090 imports = do whiteSpace
958 mname <- moduleHeader
1091 mname <- moduleHeader
959 ps <- many import_
1092 ps <- many import_
@@ -1064,13 +1197,24 @@ loadSource h lidr f
1064 let def_total = default_total i
1197 let def_total = default_total i
1065 file_in <- runIO $ readFile f
1198 file_in <- runIO $ readFile f
1066 file <- if lidr then tclift $ unlit f file_in else return file_in
1199 file <- if lidr then tclift $ unlit f file_in else return file_in
1067− (mname, modules, pos) <- parseImports f file
1200+ (mname, imports, pos) <- parseImports f file
1202+ -- process and check module aliases
1203+ let modAliases = M.fromList
1204+ [(prep alias, prep realName) | (realName, Just alias, fc) <- imports]
1205+ prep = map T.pack . reverse . Spl.splitOn "/"
1206+ aliasNames = [(alias, fc) | (_, Just alias, fc) <- imports]
1207+ histogram = groupBy ((==) `on` fst) . sortBy (comparing fst) $ aliasNames
1208+ case map head . filter ((/= 1) . length) $ histogram of
1209+ [] -> logLvl 3 $ "Module aliases: " ++ show (M.toList modAliases)
1210+ (n,fc):_ -> throwError . At fc . Msg $ "import alias not unique: " ++ show n
1068 i <- getIState
1212 i <- getIState
1069− putIState (i { default_access = Hidden })
1213+ putIState (i { default_access = Hidden, module_aliases = modAliases })
1070 clearIBC -- start a new .ibc file
1214 clearIBC -- start a new .ibc file
1071− mapM_ (addIBC . IBCImport) modules
1215+ mapM_ (addIBC . IBCImport) [realName | (realName, alias, fc) <- imports]
1072− ds' <- parseProg (defaultSyntax {syn_namespace = reverse mname })
1216+ let syntax = defaultSyntax{ syn_namespace = reverse mname }
1073− f file pos
1217+ ds' <- parseProg syntax f file pos
1074 unless (null ds') $ do
1218 unless (null ds') $ do
1075 let ds = namespaces mname ds'
1219 let ds = namespaces mname ds'
1076 logLvl 3 (show $ showDecls True ds)
1220 logLvl 3 (show $ showDecls True ds)