lean4-htt/src/Lean/Elab/Arg.lean
2024-10-31 09:18:18 +00:00

63 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.

/-
Copyright (c) 2021 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import Lean.Elab.Term
namespace Lean.Elab.Term
/--
Auxiliary inductive datatype for combining unelaborated syntax
and already elaborated expressions. It is used to elaborate applications.
-/
inductive Arg where
| stx (val : Syntax)
| expr (val : Expr)
deriving Inhabited
/-- Named arguments created using the notation `(x := val)`. -/
structure NamedArg where
ref : Syntax := Syntax.missing
name : Name
val : Arg
/-- If `true`, then make all parameters that depend on this one become implicit.
This is used for projection notation, since structure parameters might be explicit for classes. -/
suppressDeps : Bool := false
deriving Inhabited
/--
Add a new named argument to `namedArgs`, and throw an error if it already contains a named argument
with the same name. -/
def addNamedArg (namedArgs : Array NamedArg) (namedArg : NamedArg) : MetaM (Array NamedArg) := do
if namedArgs.any (namedArg.name == ·.name) then
throwError "argument '{namedArg.name}' was already set"
return namedArgs.push namedArg
partial def expandArgs (args : Array Syntax) : MetaM (Array NamedArg × Array Arg × Bool) := do
let (args, ellipsis) :=
if args.isEmpty then
(args, false)
else if args.back!.isOfKind ``Lean.Parser.Term.ellipsis then
(args.pop, true)
else
(args, false)
let (namedArgs, args) ← args.foldlM (init := (#[], #[])) fun (namedArgs, args) stx => do
if stx.getKind == ``Lean.Parser.Term.namedArgument then
-- trailing_tparser try ("(" >> ident >> " := ") >> termParser >> ")"
let name := stx[1].getId.eraseMacroScopes
let val := stx[3]
let namedArgs ← addNamedArg namedArgs { ref := stx, name := name, val := Arg.stx val }
return (namedArgs, args)
else if stx.getKind == ``Lean.Parser.Term.ellipsis then
throwErrorAt stx "unexpected '..'"
else
return (namedArgs, args.push $ Arg.stx stx)
return (namedArgs, args, ellipsis)
def expandApp (stx : Syntax) : MetaM (Syntax × Array NamedArg × Array Arg × Bool) := do
let (namedArgs, args, ellipsis) ← expandArgs stx[1].getArgs
return (stx[0], namedArgs, args, ellipsis)
end Lean.Elab.Term