lean4-htt/Lake/DSL/Config.lean

65 lines
2.2 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 Lean.Elab.ElabRules
import Lake.DSL.Extensions
namespace Lake.DSL
open Lean Elab Term
/--
A dummy default constant for `__dir__` to make it type check
outside Lakefile elaboration (e.g., when editing).
-/
opaque dummyDir : System.FilePath
/--
A dummy default constant for `get_config` to make it type check
outside Lakefile elaboration (e.g., when editing).
-/
opaque dummyGetConfig? : Name → Option String
/--
A macro that expands to the path of package's directory
during the Lakefile's elaboration.
-/
scoped syntax (name := dirConst) "__dir__" : term
@[termElab dirConst]
def elabDirConst : TermElab := fun stx expectedType? => do
let exp :=
if let some dir := dirExt.getState (← getEnv) then
let str := Syntax.mkStrLit dir.toString (SourceInfo.fromRef stx)
Syntax.mkApp (mkCIdentFrom stx ``System.FilePath.mk) #[str]
else
-- `id` app forces Lean to show macro's doc rather than the constant's
Syntax.mkApp (mkCIdentFrom stx ``id) #[mkCIdentFrom stx ``dummyDir]
withMacroExpansion stx exp <| elabTerm exp expectedType?
/--
A macro that expands to the specified configuration option (or `none`,
if not the option has not been set) during the Lakefile's elaboration.
Configuration arguments are set either via the Lake CLI (by the `-K` option)
or via the `with` clause in a `require` statement.
-/
scoped syntax (name := getConfig) "get_config? " ident :term
@[termElab getConfig]
def elabGetConfig : TermElab := fun stx expectedType? => do
tryPostponeIfNoneOrMVar expectedType?
match stx with
| `(getConfig| get_config? $key) => do
let exp : Term ← show TermElabM Term from do
if let some opts := optsExt.getState (← getEnv) then
if let some val := opts.find? key.getId then
`(some $(Syntax.mkStrLit val <| SourceInfo.fromRef (← getRef)))
else
-- Make sure `none` is properly typed
`((none : Option String))
else
return Syntax.mkApp (mkCIdentFrom stx ``dummyGetConfig?) #[quote key.getId]
withMacroExpansion stx exp <| elabTerm exp expectedType?
| _ => throwUnsupportedSyntax