38 lines
1.8 KiB
Text
38 lines
1.8 KiB
Text
/-
|
||
Copyright (c) 2021 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Leonardo de Moura
|
||
-/
|
||
import Lean.Elab.Syntax
|
||
|
||
namespace Lean.Elab.Command
|
||
open Lean.Syntax
|
||
open Lean.Parser.Term hiding macroArg
|
||
open Lean.Parser.Command
|
||
|
||
/- Convert `macro` arg into a `syntax` command item and a pattern element -/
|
||
def expandMacroArg (stx : Syntax) : MacroM (Syntax × Syntax) := do
|
||
let (id?, id, stx) ← match (← expandMacros stx) with
|
||
| `(macroArg| $id:ident:$stx) => pure (some id, id, stx)
|
||
| `(macroArg| $stx:stx) => pure (none, (← `(x)), stx)
|
||
| _ => Macro.throwUnsupported
|
||
let pat ← match stx with
|
||
| `(stx| $s:str) => pure <| mkNode `token_antiquot #[← strLitToPattern s, mkAtom "%", mkAtom "$", id]
|
||
| `(stx| &$s:str) => pure <| mkNode `token_antiquot #[← strLitToPattern s, mkAtom "%", mkAtom "$", id]
|
||
| `(stx| optional($stx)) => pure <| mkSplicePat `optional id "?"
|
||
| `(stx| many($stx)) => pure <| mkSplicePat `many id "*"
|
||
| `(stx| many1($stx)) => pure <| mkSplicePat `many id "*"
|
||
| `(stx| sepBy($stx, $sep:str $[, $stxsep]? $[, allowTrailingSep]?)) =>
|
||
pure <| mkSplicePat `sepBy id ((isStrLit? sep).get! ++ "*")
|
||
| `(stx| sepBy1($stx, $sep:str $[, $stxsep]? $[, allowTrailingSep]?)) =>
|
||
pure <| mkSplicePat `sepBy id ((isStrLit? sep).get! ++ "*")
|
||
| _ => match id? with
|
||
-- if there is a binding, we assume the user knows what they are doing
|
||
| some id => pure <| mkAntiquotNode id
|
||
-- otherwise `group` the syntax to enforce arity 1, e.g. for `noWs`
|
||
| none => return (← `(stx| group($stx)), mkAntiquotNode id)
|
||
pure (stx, pat)
|
||
where mkSplicePat kind id suffix :=
|
||
mkNullNode #[mkAntiquotSuffixSpliceNode kind (mkAntiquotNode id) suffix]
|
||
|
||
end Lean.Elab.Command
|