feat: $[...]* antiquotations for sepByIndent
This commit is contained in:
parent
09c4af26fc
commit
733f220ee3
3 changed files with 14 additions and 7 deletions
|
|
@ -434,11 +434,11 @@ def mkSep (a : Array Syntax) (sep : Syntax) : Syntax :=
|
|||
mkNullNode <| mkSepArray a sep
|
||||
|
||||
def SepArray.ofElems {sep} (elems : Array Syntax) : SepArray sep :=
|
||||
⟨mkSepArray elems (mkAtom sep)⟩
|
||||
⟨mkSepArray elems (if sep.isEmpty then mkNullNode else mkAtom sep)⟩
|
||||
|
||||
def SepArray.ofElemsUsingRef [Monad m] [MonadRef m] {sep} (elems : Array Syntax) : m (SepArray sep) := do
|
||||
let ref ← getRef;
|
||||
return ⟨mkSepArray elems (mkAtomFrom ref sep)⟩
|
||||
return ⟨mkSepArray elems (if sep.isEmpty then mkNullNode else mkAtomFrom ref sep)⟩
|
||||
|
||||
instance (sep) : Coe (Array Syntax) (SepArray sep) where
|
||||
coe := SepArray.ofElems
|
||||
|
|
|
|||
|
|
@ -30,12 +30,17 @@ private partial def floatOutAntiquotTerms : Syntax → StateT (Syntax → TermEl
|
|||
return Syntax.node i k (← args.mapM floatOutAntiquotTerms)
|
||||
| stx => pure stx
|
||||
|
||||
private def getSepFromSplice (splice : Syntax) : Syntax :=
|
||||
private def getSepFromSplice (splice : Syntax) : String :=
|
||||
if let Syntax.atom _ sep := getAntiquotSpliceSuffix splice then
|
||||
Syntax.mkStrLit (sep.dropRight 1)
|
||||
sep.dropRight 1 -- drop trailing *
|
||||
else
|
||||
unreachable!
|
||||
|
||||
private def getSepStxFromSplice (splice : Syntax) : Syntax := Unhygienic.run do
|
||||
match getSepFromSplice splice with
|
||||
| "" => `(mkNullNode) -- sepByIdent uses the null node for separator-less enumerations
|
||||
| sep => `(mkAtom $(.mkStrLit sep))
|
||||
|
||||
partial def mkTuple : Array Syntax → TermElabM Syntax
|
||||
| #[] => `(Unit.unit)
|
||||
| #[e] => return e
|
||||
|
|
@ -119,7 +124,7 @@ private partial def quoteSyntax : Syntax → TermElabM Syntax
|
|||
| some x => Array.empty.push x
|
||||
| none => Array.empty)
|
||||
| `many => return getAntiquotTerm antiquot
|
||||
| `sepBy => `(@SepArray.elemsAndSeps $(getSepFromSplice arg) $(getAntiquotTerm antiquot))
|
||||
| `sepBy => `(@SepArray.elemsAndSeps $(quote <| getSepFromSplice arg) $(getAntiquotTerm antiquot))
|
||||
| k => throwErrorAt arg "invalid antiquotation suffix splice kind '{k}'"
|
||||
else if k == nullKind && isAntiquotSplice arg then
|
||||
let k := antiquotSpliceKind? arg
|
||||
|
|
@ -136,7 +141,7 @@ private partial def quoteSyntax : Syntax → TermElabM Syntax
|
|||
let arr ← ids[:ids.size-1].foldrM (fun id arr => `(Array.zip $id $arr)) ids.back
|
||||
`(Array.map (fun $(← mkTuple ids) => $(inner[0])) $arr)
|
||||
let arr ← if k == `sepBy then
|
||||
`(mkSepArray $arr (mkAtom $(getSepFromSplice arg)))
|
||||
`(mkSepArray $arr $(getSepStxFromSplice arg))
|
||||
else
|
||||
pure arr
|
||||
let arr ← bindLets arr
|
||||
|
|
@ -306,7 +311,7 @@ private partial def getHeadInfo (alt : Alt) : TermElabM HeadInfo :=
|
|||
unconditionally fun rhs => match antiquotSuffixSplice? quoted[0] with
|
||||
| `optional => `(let $anti := Syntax.getOptional? discr; $rhs)
|
||||
| `many => `(let $anti := Syntax.getArgs discr; $rhs)
|
||||
| `sepBy => `(let $anti := @SepArray.mk $(getSepFromSplice quoted[0]) (Syntax.getArgs discr); $rhs)
|
||||
| `sepBy => `(let $anti := @SepArray.mk $(quote <| getSepFromSplice quoted[0]) (Syntax.getArgs discr); $rhs)
|
||||
| k => throwErrorAt quoted "invalid antiquotation suffix splice kind '{k}'"
|
||||
else if quoted.getArgs.size == 1 && isAntiquotSplice quoted[0] then pure {
|
||||
check := other pat,
|
||||
|
|
|
|||
|
|
@ -58,9 +58,11 @@ attribute [runBuiltinParserAttributeHooks]
|
|||
withPosition $ many (checkColGe "irrelevant" >> p)
|
||||
|
||||
@[runBuiltinParserAttributeHooks, inline] def sepByIndent (p : Parser) (sep : String) (psep : Parser := symbol sep) (allowTrailingSep : Bool := false) : Parser :=
|
||||
let p := withAntiquotSpliceAndSuffix `sepBy p (symbol "*")
|
||||
withPosition $ sepBy (checkColGe "irrelevant" >> p) sep (psep <|> checkLinebreakBefore >> pushNone) allowTrailingSep
|
||||
|
||||
@[runBuiltinParserAttributeHooks, inline] def sepBy1Indent (p : Parser) (sep : String) (psep : Parser := symbol sep) (allowTrailingSep : Bool := false) : Parser :=
|
||||
let p := withAntiquotSpliceAndSuffix `sepBy p (symbol "*")
|
||||
withPosition $ sepBy1 (checkColGe "irrelevant" >> p) sep (psep <|> checkLinebreakBefore >> pushNone) allowTrailingSep
|
||||
|
||||
@[runBuiltinParserAttributeHooks] abbrev notSymbol (s : String) : Parser :=
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue