feat: import private

This commit is contained in:
Sebastian Ullrich 2025-04-22 17:54:13 +02:00 committed by Joachim Breitner
parent c3a1669398
commit 965dca1625
4 changed files with 19 additions and 11 deletions

View file

@ -11,9 +11,12 @@ import Lean.CoreM
namespace Lean.Elab
def headerToImports : TSyntax ``Parser.Module.header → Array Import
| `(Parser.Module.header| $[module%$moduleTk]? $[prelude%$preludeTk]? $[import $ns]*) =>
| `(Parser.Module.header| $[module%$moduleTk]? $[prelude%$preludeTk]? $importsStx*) =>
let imports := if preludeTk.isNone then #[{ module := `Init : Import }] else #[]
imports ++ ns.map ({ module := ·.getId })
imports ++ importsStx.map fun
| `(Parser.Module.import| import $[private%$privateTk]? $n) =>
{ module := n.getId, importPrivate := privateTk.isSome }
| _ => unreachable!
| _ => unreachable!
def processHeader (header : TSyntax ``Parser.Module.header) (opts : Options) (messages : MessageLog)

View file

@ -133,8 +133,8 @@ partial def whitespace : Parser := fun input s =>
else
false
def State.pushModule (module : Name) (s : State) : State :=
{ s with imports := s.imports.push { module } }
def State.pushImport (i : Import) (s : State) : State :=
{ s with imports := s.imports.push i }
@[inline] def isIdRestCold (c : Char) : Bool :=
c = '_' || c = '\'' || c == '!' || c == '?' || isLetterLike c || isSubScriptAlnum c
@ -142,7 +142,7 @@ def State.pushModule (module : Name) (s : State) : State :=
@[inline] def isIdRestFast (c : Char) : Bool :=
c.isAlphanum || (c != '.' && c != '\n' && c != ' ' && isIdRestCold c)
partial def moduleIdent : Parser := fun input s =>
partial def moduleIdent (importPrivate : Bool) : Parser := fun input s =>
let rec parse (module : Name) (s : State) :=
let i := s.pos
if h : input.atEnd i then
@ -162,7 +162,7 @@ partial def moduleIdent : Parser := fun input s =>
let s := s.next input s.pos
parse module s
else
whitespace input (s.pushModule module)
whitespace input (s.pushImport { module, importPrivate })
else if isIdFirst curr then
let startPart := i
let s := takeWhile isIdRestFast input (s.next' input i h)
@ -172,7 +172,7 @@ partial def moduleIdent : Parser := fun input s =>
let s := s.next input s.pos
parse module s
else
whitespace input (s.pushModule module)
whitespace input (s.pushImport { module, importPrivate })
else
s.mkError "expected identifier"
parse .anonymous s
@ -187,8 +187,8 @@ partial def moduleIdent : Parser := fun input s =>
def main : Parser :=
keywordCore "module" (fun _ s => { s with isModule := true }) (fun _ s => s) >>
keywordCore "prelude" (fun _ s => s.pushModule `Init) (fun _ s => s) >>
many (keyword "import" >> moduleIdent)
keywordCore "prelude" (fun _ s => s.pushImport `Init) (fun _ s => s) >>
many (keyword "import" >> keywordCore "private" (moduleIdent true) (moduleIdent false))
end ParseImports

View file

@ -94,7 +94,11 @@ instance : GetElem? (Array α) ModuleIdx α (fun a i => i.toNat < a.size) where
abbrev ConstMap := SMap Name ConstantInfo
structure Import where
module : Name
module : Name
/-- `import private`; whether to import and expose all data saved by the module. -/
importPrivate : Bool := false
/-- Whether to activate this import when the current module itself is imported. -/
isExported : Bool := false
deriving Repr, Inhabited
instance : Coe Name Import := ⟨({module := ·})⟩

View file

@ -13,7 +13,8 @@ namespace Parser
namespace Module
def moduleTk := leading_parser "module"
def «prelude» := leading_parser "prelude"
def «import» := leading_parser "import " >> identWithPartialTrailingDot
def «private» := leading_parser (withAnonymousAntiquot := false) "private"
def «import» := leading_parser "import " >> optional «private» >> identWithPartialTrailingDot
def header := leading_parser optional (moduleTk >> ppLine >> ppLine) >>
optional («prelude» >> ppLine) >>
many («import» >> ppLine) >>