feat: add optional (priority := <prio>) to instance command

This commit is contained in:
Leonardo de Moura 2020-12-21 10:02:12 -08:00
parent c43e77d1a5
commit 4fc06bfcca
8 changed files with 47 additions and 29 deletions

View file

@ -45,10 +45,10 @@ def expandDeclNamespace? (stx : Syntax) : Option (Name × Syntax) :=
| some (ns, declId) => some (ns, stx.setArg 1 (decl.setArg 1 declId))
| none => none
else if k == `Lean.Parser.Command.instance then
let optDeclId := decl[2]
let optDeclId := decl[3]
if optDeclId.isNone then none
else match expandDeclIdNamespace? optDeclId[0] with
| some (ns, declId) => some (ns, stx.setArg 1 (decl.setArg 2 (optDeclId.setArg 0 declId)))
| some (ns, declId) => some (ns, stx.setArg 1 (decl.setArg 3 (optDeclId.setArg 0 declId)))
| none => none
else
none

View file

@ -138,18 +138,20 @@ def mkDefViewOfConstant (modifiers : Modifiers) (stx : Syntax) : CommandElabM De
}
def mkDefViewOfInstance (modifiers : Modifiers) (stx : Syntax) : CommandElabM DefView := do
-- parser! attrKind >> "instance " >> optional declId >> declSig >> declVal
-- parser! Term.attrKind >> "instance " >> optNamedPrio >> optional declId >> declSig >> declVal
let attrKind ← toAttributeKind stx[0]
let (binders, type) := expandDeclSig stx[3]
let modifiers := modifiers.addAttribute { kind := attrKind, name := `instance }
let declId ← match stx[2].getOptional? with
let prio ← liftMacroM <| expandOptNamedPrio stx[2]
let attrStx ← `(attr| instance $(quote prio):numLit)
let (binders, type) := expandDeclSig stx[4]
let modifiers := modifiers.addAttribute { kind := attrKind, name := `instance, stx := attrStx }
let declId ← match stx[3].getOptional? with
| some declId => pure declId
| none =>
let id ← MkInstanceName.main type
pure <| Syntax.node ``Parser.Command.declId #[mkIdentFrom stx id, mkNullNode]
return {
ref := stx, kind := DefKind.def, modifiers := modifiers,
declId := declId, binders := binders, type? := type, value := stx[4]
declId := declId, binders := binders, type? := type, value := stx[5]
}
def mkDefViewOfExample (modifiers : Modifiers) (stx : Syntax) : DefView :=

View file

@ -230,21 +230,6 @@ where
| Name.str _ s _ => s ++ str
| _ => str
def expandOptNamedPrio (stx : Syntax) : MacroM Nat :=
if stx.isNone then
return evalPrio! default
else match stx[0] with
| `(Parser.Command.namedPrio| (priority := $prio)) => evalPrio prio
| _ => Macro.throwUnsupported
def expandOptNamedName (stx : Syntax) : MacroM (Option Name) := do
if stx.isNone then
return none
else match stx[0] with
| `(Parser.Command.namedName| (name := $name)) => return name.getId
| _ => Macro.throwUnsupported
/- We assume a new syntax can be treated as an atom when it starts and ends with a token.
Here are examples of atom-like syntax.
```

View file

@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
import Lean.Util.Trace
import Lean.Parser.Syntax
import Lean.Parser.Extension
import Lean.KeyedDeclsAttribute
import Lean.Elab.Exception
@ -26,6 +27,20 @@ def MacroScopesView.format (view : MacroScopesView) (mainModule : Name) : Format
namespace Elab
def expandOptNamedPrio (stx : Syntax) : MacroM Nat :=
if stx.isNone then
return evalPrio! default
else match stx[0] with
| `(Parser.Command.namedPrio| (priority := $prio)) => evalPrio prio
| _ => Macro.throwUnsupported
def expandOptNamedName (stx : Syntax) : MacroM (Option Name) := do
if stx.isNone then
return none
else match stx[0] with
| `(Parser.Command.namedName| (name := $name)) => return name.getId
| _ => Macro.throwUnsupported
structure MacroStackElem where
before : Syntax
after : Syntax

View file

@ -55,10 +55,7 @@ builtin_initialize
name := `instance
descr := "type class instance"
add := fun declName stx attrKind => do
let prio ← match stx with
| Syntax.missing => pure <| evalPrio! default -- small hack, in the elaborator we use `Syntax.missing` when creating attribute views for `instance
| _ => getAttrParamOptPrio stx[1]
-- TODO use prio
let prio ← getAttrParamOptPrio stx[1]
discard <| addInstance declName attrKind prio |>.run {} {}
}

View file

@ -18,6 +18,10 @@ namespace Parser
@[builtinTermParser] def Term.quot := parser! "`(" >> toggleInsideQuot (termParser <|> many1Unbox commandParser) >> ")"
namespace Command
def namedPrio := parser! (atomic ("(" >> nonReservedSymbol "priority") >> " := " >> priorityParser >> ")")
def optNamedPrio := optional namedPrio
def commentBody : Parser :=
{ fn := rawFn (finishCommentBlock 1) true }
@ -42,7 +46,7 @@ def «abbrev» := parser! "abbrev " >> declId >> optDeclSig >> declVal
def «def» := parser! "def " >> declId >> optDeclSig >> declVal
def «theorem» := parser! "theorem " >> declId >> declSig >> declVal
def «constant» := parser! "constant " >> declId >> declSig >> optional declValSimple
def «instance» := parser! Term.attrKind >> "instance " >> optional declId >> declSig >> declVal
def «instance» := parser! Term.attrKind >> "instance " >> optNamedPrio >> optional declId >> declSig >> declVal
def «axiom» := parser! "axiom " >> declId >> declSig
def «example» := parser! "example " >> declSig >> declVal
def inferMod := parser! atomic (symbol "{" >> "}")

View file

@ -50,9 +50,7 @@ end Term
namespace Command
def namedPrio := parser! (atomic ("(" >> nonReservedSymbol "priority") >> " := " >> priorityParser >> ")")
def namedName := parser! (atomic ("(" >> nonReservedSymbol "name") >> " := " >> ident >> ")")
def optNamedPrio := optional namedPrio
def optNamedName := optional namedName
def «prefix» := parser! "prefix"

View file

@ -0,0 +1,17 @@
class Def (α : Type u) where
val : α
instance : Def Nat where
val := 10
theorem ex1 : Def.val = 10 := rfl
instance (priority := default+1) : Def Nat where
val := 20
theorem ex2 : Def.val = 20 := rfl
instance : Def Nat where
val := 30
theorem ex3 : Def.val = 20 := rfl