58 lines
2.6 KiB
Text
58 lines
2.6 KiB
Text
/-
|
||
Copyright (c) 2021 Mac Malone. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Mac Malone
|
||
-/
|
||
import Lake.Config.Package
|
||
import Lake.DSL.Attributes
|
||
import Lake.DSL.DeclUtil
|
||
|
||
namespace Lake.DSL
|
||
open Lean Parser Command
|
||
|
||
syntax packageDeclWithBinders :=
|
||
(ppSpace "(" Term.simpleBinder ")")? -- dir
|
||
(ppSpace "(" Term.simpleBinder ")")? -- args
|
||
(declValSimple <|> declValStruct <|> declValDo)
|
||
|
||
syntax packageDeclSpec :=
|
||
ident (Command.whereStructInst <|> declValTyped <|> packageDeclWithBinders)?
|
||
|
||
scoped syntax (name := packageDecl)
|
||
(docComment)? "package " packageDeclSpec : command
|
||
|
||
def expandPackageBinders
|
||
: (dir? : Option Syntax) → (args? : Option Syntax) → MacroM (Bool × Syntax × Syntax)
|
||
| none, none => do let hole ← `(_); return (false, hole, hole)
|
||
| some dir, none => return (true, dir, ← `(_))
|
||
| none, some args => return (true, ← `(_), args)
|
||
| some dir, some args => return (true, dir, args)
|
||
|
||
def mkPackageDef (defn : Syntax) (doc? : Option Syntax)
|
||
(dir? : Option Syntax) (args? : Option Syntax) (wds? : Option Syntax) : MacroM Syntax := do
|
||
let (hasBinders, dir, args) ← expandPackageBinders dir? args?
|
||
if hasBinders then
|
||
`($[$doc?:docComment]? @[«package»] def «package» : Packager :=
|
||
(fun $dir $args => $defn) $[$wds?]?)
|
||
else
|
||
`($[$doc?:docComment]? @[«package»] def «package» : PackageConfig := $defn $[$wds?]?)
|
||
|
||
@[macro packageDecl]
|
||
def expandPackageDecl : Macro
|
||
| `($[$doc?:docComment]? package $id:ident) =>
|
||
`($[$doc?:docComment]? @[«package»] def «package» : PackageConfig :=
|
||
{name := $(quote id.getId)})
|
||
| `($[$doc?:docComment]? package $id:ident where $[$ds]*) =>
|
||
`($[$doc?:docComment]? @[«package»] def «package» : PackageConfig where
|
||
name := $(quote id.getId) $[$ds]*)
|
||
| `($[$doc?:docComment]? package $id:ident : $ty := $defn $[$wds?]?) =>
|
||
`($[$doc?:docComment]? @[«package»] def «package» : $ty := $defn $[$wds?]?)
|
||
| `($[$doc?:docComment]? package $id:ident $[($dir?)]? $[($args?)]? := $defn $[$wds?]?) =>
|
||
mkPackageDef defn doc? dir? args? wds?
|
||
| `($[$doc?:docComment]? package $id:ident $[($dir?)]? $[($args?)]? { $[$fs $[,]?]* } $[$wds?]?) => do
|
||
mkPackageDef (← `({ name := $(quote id.getId), $[$fs]* })) doc? dir? args? wds?
|
||
| `($[$doc?:docComment]? package $id:ident $[($dir?)]? $[($args?)]? do $seq $[$wds?]?) => do
|
||
let (_, dir, args) ← expandPackageBinders dir? args?
|
||
`($[$doc?:docComment]? @[«package»] def «package» : IOPackager :=
|
||
(fun $dir $args => do $seq) $[$wds?]?)
|
||
| stx => Macro.throwErrorAt stx "ill-formed package declaration"
|