lean4-htt/src/Lean/Parser/StrInterpolation.lean
2021-04-24 21:48:12 +02:00

64 lines
2.1 KiB
Text

/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
import Lean.Parser.Basic
namespace Lean.Parser
def isQuotableCharForStrInterpolant (c : Char) : Bool :=
c == '{' || isQuotableCharDefault c
partial def interpolatedStrFn (p : ParserFn) : ParserFn := fun c s =>
let input := c.input
let stackSize := s.stackSize
let rec parse (startPos : Nat) (c : ParserContext) (s : ParserState) : ParserState :=
let i := s.pos
if input.atEnd i then
let s := s.pushSyntax Syntax.missing
let s := s.mkNode interpolatedStrKind stackSize
s.setError "unterminated string literal"
else
let curr := input.get i
let s := s.setPos (input.next i)
if curr == '\"' then
let s := mkNodeToken interpolatedStrLitKind startPos c s
s.mkNode interpolatedStrKind stackSize
else if curr == '\\' then
andthenFn (quotedCharCoreFn isQuotableCharForStrInterpolant) (parse startPos) c s
else if curr == '{' then
let s := mkNodeToken interpolatedStrLitKind startPos c s
let s := p c s
if s.hasError then s
else
let i := s.pos
let curr := input.get i
if curr == '}' then
let s := s.setPos (input.next i)
parse i c s
else
let s := s.pushSyntax Syntax.missing
let s := s.mkNode interpolatedStrKind stackSize
s.setError "'}'"
else
parse startPos c s
let startPos := s.pos
if input.atEnd startPos then
s.mkEOIError
else
let curr := input.get s.pos;
if curr != '\"' then
s.mkError "interpolated string"
else
let s := s.next input startPos
parse startPos c s
@[inline] def interpolatedStrNoAntiquot (p : Parser) : Parser := {
fn := interpolatedStrFn p.fn,
info := mkAtomicInfo "interpolatedStr"
}
def interpolatedStr (p : Parser) : Parser :=
withAntiquot (mkAntiquot "interpolatedStr" interpolatedStrKind) $ interpolatedStrNoAntiquot p
end Lean.Parser