@@ -13,6 +13,7 @@ use crate::parser::error::ParseResult;
1313use crate :: parser:: internal:: ident:: is_reserved_ident;
1414use crate :: parser:: internal:: precedence:: { Associativity , Precedence } ;
1515use crate :: parser:: state:: State ;
16+ use crate :: prelude:: ByteString ;
1617use crate :: prelude:: DefaultMatchArm ;
1718
1819pub mod ast;
@@ -1052,9 +1053,11 @@ impl Parser {
10521053 e
10531054 }
10541055 TokenKind :: StringPart ( _) => self . interpolated_string ( state) ?,
1055- TokenKind :: StartHeredoc ( _ , kind) => {
1056+ TokenKind :: StartHeredoc ( label , kind) => {
10561057 let kind = kind. clone ( ) ;
1057- self . doc_string ( state, kind) ?
1058+ let label = label. clone ( ) ;
1059+
1060+ self . doc_string ( state, label, kind) ?
10581061 } ,
10591062 TokenKind :: True => {
10601063 let e = Expression :: Bool { value : true } ;
@@ -1568,44 +1571,57 @@ impl Parser {
15681571 Ok ( Expression :: InterpolatedString { parts } )
15691572 }
15701573
1571- fn doc_string ( & self , state : & mut State , kind : DocStringKind ) -> ParseResult < Expression > {
1574+ fn doc_string ( & self , state : & mut State , label : ByteString , kind : DocStringKind ) -> ParseResult < Expression > {
15721575 state. next ( ) ;
15731576
1574- let mut parts = Vec :: new ( ) ;
1577+ Ok ( match kind {
1578+ DocStringKind :: Heredoc => {
1579+ let mut parts = Vec :: new ( ) ;
15751580
1576- while !matches ! ( state. current. kind, TokenKind :: EndHeredoc ( _, _, _) ) {
1577- if let Some ( part) = self . interpolated_string_part ( state) ? {
1578- parts. push ( part) ;
1579- }
1580- }
1581+ while !matches ! ( state. current. kind, TokenKind :: EndHeredoc ( _, _, _) ) {
1582+ if let Some ( part) = self . interpolated_string_part ( state) ? {
1583+ parts. push ( part) ;
1584+ }
1585+ }
15811586
1582- let ( indentation_type, indentation_amount) = match state. current . kind {
1583- TokenKind :: EndHeredoc ( _, indentation_type, indentation_amount) => ( indentation_type, indentation_amount) ,
1584- _ => unreachable ! ( ) ,
1585- } ;
1586-
1587- state. next ( ) ;
1587+ let ( indentation_type, indentation_amount) = match state. current . kind {
1588+ TokenKind :: EndHeredoc ( _, indentation_type, indentation_amount) => ( indentation_type, indentation_amount) ,
1589+ _ => unreachable ! ( ) ,
1590+ } ;
1591+
1592+ state. next ( ) ;
15881593
1589- // FIXME: Can we move this logic above into the loop, by peeking ahead in
1590- // the token stream for the EndHeredoc? Might be more performant.
1591- if let Some ( indentation_type) = indentation_type {
1592- let search_char: u8 = indentation_type. into ( ) ;
1593-
1594- for part in parts. iter_mut ( ) {
1595- match part {
1596- StringPart :: Const ( bytes) => {
1597- for _ in 0 ..indentation_amount {
1598- if bytes. starts_with ( & [ search_char] ) {
1599- bytes. remove ( 0 ) ;
1600- }
1594+ // FIXME: Can we move this logic above into the loop, by peeking ahead in
1595+ // the token stream for the EndHeredoc? Might be more performant.
1596+ if let Some ( indentation_type) = indentation_type {
1597+ let search_char: u8 = indentation_type. into ( ) ;
1598+
1599+ for part in parts. iter_mut ( ) {
1600+ match part {
1601+ StringPart :: Const ( bytes) => {
1602+ for _ in 0 ..indentation_amount {
1603+ if bytes. starts_with ( & [ search_char] ) {
1604+ bytes. remove ( 0 ) ;
1605+ }
1606+ }
1607+ } ,
1608+ _ => continue ,
16011609 }
1602- } ,
1603- _ => continue ,
1610+ }
16041611 }
1605- }
1606- }
16071612
1608- Ok ( Expression :: InterpolatedString { parts } )
1613+ Expression :: Heredoc { parts }
1614+ } ,
1615+ DocStringKind :: Nowdoc => {
1616+ // FIXME: This feels hacky. We should probably produce different tokens from the lexer
1617+ // but since I already had the logic in place for parsing heredocs, this was
1618+ // the fastest way to get nowdocs working too.
1619+ let s = expect_token ! ( [ TokenKind :: StringPart ( s) => s] , state, "constant string" ) ;
1620+ expect_token ! ( [ TokenKind :: EndHeredoc ( ..) ] , state, "label" ) ;
1621+
1622+ Expression :: Nowdoc { value : s }
1623+ } ,
1624+ } )
16091625 }
16101626
16111627 fn interpolated_string_part ( & self , state : & mut State ) -> ParseResult < Option < StringPart > > {
0 commit comments