lean4-htt/Lake/DSL.lean

54 lines
2.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Lean.Parser
import Lake.Package
open Lean Parser
namespace Lake.DSL
syntax packageStruct :=
"{" manyIndent(group(Term.structInstField optional(", "))) "}"
syntax packageDeclValSpecial :=
(packageStruct <|> (ppSpace Term.do)) (Term.whereDecls)?
syntax packageDeclWithBinders :=
(ppSpace "(" Term.simpleBinder ")")? -- dir
(ppSpace "(" Term.simpleBinder ")")? -- args
ppSpace (Command.declValSimple <|> packageDeclValSpecial)
syntax packageDeclTyped :=
Term.typeSpec Command.declValSimple
scoped syntax (name := packageDecl) declModifiers
"package" (Term.whereDecls <|> packageDeclTyped <|> packageDeclWithBinders) : command
def expandPackageBinders
: (dir? : Option Syntax) → (args? : Option Syntax) → MacroM (Bool × Syntax × Syntax)
| none, none => do let hole ← `(_); (false, hole, hole)
| some dir, none => do (true, dir, ← `(_))
| none, some args => do (true, ← `(_), args)
| some dir, some args => do (true, dir, args)
def mkPackageDef (defn : Syntax) (mods : Syntax)
(dir? : Option Syntax) (args? : Option Syntax) (wds? : Option Syntax) : MacroM Syntax := do
let (hasBinders, dir, args) ← expandPackageBinders dir? args?
if hasBinders then
`($mods:declModifiers def $(mkIdent `package) : Packager :=
(fun $dir $args => $defn) $[$wds?]?)
else
`($mods:declModifiers def $(mkIdent `package) : PackageConfig := $defn $[$wds?]?)
@[macro packageDecl]
def expandPackageDecl : Macro
| `($mods:declModifiers package where $[$ds]*) =>
`($mods:declModifiers def $(mkIdent `package) : PackageConfig where $[$ds]*)
| `($mods:declModifiers package : $ty := $defn $[$wds?]?) =>
`($mods:declModifiers def $(mkIdent `package) : $ty := $defn $[$wds?]?)
| `($mods:declModifiers package $[($dir?)]? $[($args?)]? := $defn $[$wds?]?) =>
mkPackageDef defn mods dir? args? wds?
| `($mods:declModifiers package $[($dir?)]? $[($args?)]? { $[$fs $[,]?]* } $[$wds?]?) => do
mkPackageDef (← `({ $[$fs]* })) mods dir? args? wds?
| `($mods:declModifiers package $[($dir?)]? $[($args?)]? do $seq $[$wds?]?) => do
let (_, dir, args) ← expandPackageBinders dir? args?
`($mods:declModifiers def $(mkIdent `package) : IOPackager :=
(fun $dir $args => do $seq) $[$wds?]?)
| stx => Macro.throwErrorAt stx "ill-formed package declaration"