Skip to content

Commit 6c71e73

Browse files
committed
simplify implementation
1 parent e7f1e42 commit 6c71e73

File tree

1 file changed

+20
-35
lines changed

1 file changed

+20
-35
lines changed

src/Lean/Elab/BuiltinNotation.lean

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -257,64 +257,49 @@ partial def hasCDot : Syntax → Bool
257257
Return `some` if succeeded expanding `·` notation occurring in
258258
the given syntax. Otherwise, return `none`.
259259
Examples:
260-
- `· + 1` => `fun _a_1 => _a_1 + 1`
261-
- `f · · b` => `fun _a_1 _a_2 => f _a_1 _a_2 b` -/
262-
partial def expandCDot? (stx : Term) : MacroM (Option Term) := do
260+
- `· + 1` => `fun x => x + 1`
261+
- `f · · b` => `fun x1 x2 => f x1 x2 b` -/
262+
partial def expandCDot? (stx : Term) : MacroM (Option Term) := withFreshMacroScope do
263263
if hasCDot stx then
264-
let numArgs ← countArgs stx
265-
let (newStx, binders) ← withFreshMacroScope <| (go numArgs stx).run #[]
264+
let mut (newStx, binders) ← (go stx).run #[]
265+
if binders.size == 1 then
266+
-- It is nicer using `x` over `x1` if there's only a single binder.
267+
let x1 := binders[0]!
268+
let x := mkIdentFrom x1 (← MonadQuotation.addMacroScope `x) (canonical := true)
269+
binders := binders.set! 0 x
270+
newStx ← newStx.replaceM fun s => pure (if s == x1 then x else none)
266271
`(fun $binders* => $(⟨newStx⟩))
267272
else
268273
pure none
269274
where
270275
/--
271-
Count arguments, taking into consideration choice nodes
272-
and validating that each alternative has the same number of arguments.
273-
-/
274-
countArgs : Syntax → MacroM Nat
275-
| `(($_)) => return 0
276-
| `(·) => return 1
277-
| stx =>
278-
match stx with
279-
| .node _ k args => do
280-
if k == choiceKind then
281-
if args.isEmpty then
282-
Macro.throwUnsupported
283-
let counts ← args.mapM countArgs
284-
unless counts.all (fun c => counts[0]! == c) do
285-
Macro.throwErrorAt stx "Ambiguous notation in cdot function has different numbers of '·' arguments in each alternative."
286-
return counts[0]!
287-
else
288-
args.foldlM (init := 0) (fun acc arg => return acc + (← countArgs arg))
289-
| _ => return 0
290-
/--
291276
Auxiliary function for expanding the `·` notation.
292277
The extra state `Array Syntax` contains the new binder names.
293278
If `stx` is a `·`, we create a fresh identifier, store it in the
294279
extra state, and return it. Otherwise, we just return `stx`.
295280
-/
296-
go (numArgs : Nat) : Syntax → StateT (Array Ident) MacroM Syntax
281+
go : Syntax → StateT (Array Ident) MacroM Syntax
297282
| stx@`(($(_))) => pure stx
298283
| stx@`(·) => do
299-
let i := (← get).size
300-
let name ← MonadQuotation.addMacroScope <|
301-
if numArgs == 1 then
302-
`x
303-
else
304-
Name.mkSimple s!"x{i + 1}"
284+
let name ← MonadQuotation.addMacroScope <| Name.mkSimple s!"x{(← get).size + 1}"
305285
let id := mkIdentFrom stx name (canonical := true)
306286
modify (fun s => s.push id)
307287
pure id
308288
| stx => match stx with
309289
| .node _ k args => do
310290
let args ←
311291
if k == choiceKind then
292+
if args.isEmpty then
293+
return stx
312294
let s ← get
313-
let args' ← args.mapM (fun arg => go numArgs arg |>.run s)
314-
set args'[0]!.2
295+
let args' ← args.mapM (fun arg => go arg |>.run s)
296+
let s' := args'[0]!.2
297+
unless args'.all (fun (_, s'') => s''.size == s'.size) do
298+
Macro.throwErrorAt stx "Ambiguous notation in cdot function has different numbers of '·' arguments in each alternative."
299+
set s'
315300
pure <| args'.map Prod.fst
316301
else
317-
args.mapM (go numArgs)
302+
args.mapM go
318303
return .node (.fromRef stx (canonical := true)) k args
319304
| _ => pure stx
320305

0 commit comments

Comments
 (0)