Skip to content

Commit

Permalink
Merge branch 'tbrowder-decl-blk2'
Browse files Browse the repository at this point in the history
  • Loading branch information
tbrowder committed Oct 17, 2019
2 parents 2b52e0f + d420f30 commit 8ea5716
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 10 deletions.
130 changes: 120 additions & 10 deletions src/Perl6/Grammar.nqp
Expand Up @@ -3633,9 +3633,30 @@ grammar Perl6::Grammar is HLL::Grammar does STD {
:my $*VAR;
:my $orig_arg_flat_ok := $*ARG_FLAT_OK;
:dba('term')
# TODO try to use $/ for lookback to check for erroneous
# use of pod6 trailing declarator block, e.g.:
#
# #=!
#
# instead of
#
# #=(
#
[
|| [
| <prefixish>+ [ <.arg_flat_nok> <term> || {} <.panic("Prefix " ~ $<prefixish>[-1].Str ~ " requires an argument, but no valid term found")> ]
| <prefixish>+
[ <.arg_flat_nok> <term>
||
{}
<.panic("Prefix " ~ $<prefixish>[-1].Str
~ " requires an argument, but no valid term found"
~ ".\nDid you mean "
~ $<prefixish>[-1].Str
~ " to be an opening bracket for a declarator block?"
)>
]
| <.arg_flat_nok> <term>
]
|| <!{ $*QSIGIL }> <?before <infixish> {
Expand Down Expand Up @@ -4672,46 +4693,135 @@ if $*COMPILING_CORE_SETTING {
'#' {} \N*
}
token comment:sym<#`(...)> {
'#`' <?opener> {}
[ <.quibble(self.slang_grammar('Quote'))> || <.typed_panic: 'X::Syntax::Comment::Embedded'> ]
#==========================================================
# Embedded comments and declarator blocks
#==========================================================
# These comment-like objects can be like ordinary one-line
# comments if, and only if, their beginning two-character
# starting points are followed by a space. Examples:
#
# embedded:
# #` some comment
# leading declarator block:
# #| some comment
# trailing declarator block:
# #= some comment
#
# If any character other than a space follows the first
# two, it must be a valid opening bracketing character,
# otherwise an exception is thrown.
#
# Note that declarator blocks retain their special handling
# even in the one-line format.
#==========================================================
#==========================================================
# An in-line or multi-line comment (aka 'embedded comment')
#==========================================================
# examples of valid ones:
# in-line:
# my $a = #`( ) 3;
# multi-line:
# my $a = #`(
# some comment
# ) 3;
# #`(
# some comment
# )
# this is an ordinary trailing one-line comment:
# my $a = #` some comment
# 3;
#
#==========================================================
#```````````
#|||||||||||||
# we panic when a non-opening bracket char follows the sym
token comment:sym<#`> {
'#`' <!after \s> <!opener>
<.typed_panic: 'X::Syntax::Comment::Embedded'>
}
token comment:sym<#`(...)> {
'#`' <?opener>
#[ <.quibble(self.slang_grammar('Quote'))> || <.typed_panic: 'X::Syntax::Comment::Embedded'> ]
<.quibble(self.slang_grammar('Quote'))>
}
#==========================
# leading declarator blocks
#==========================
# examples of valid ones:
# #| single line
# #|(
# multi-
# line
# )
#==========================
# a multi-line leading declarator block:
# we panic when a non-opening bracket char follows the sym
token comment:sym<#|(...)> {
'#|' <?opener> <attachment=.quibble(self.slang_grammar('Quote'))>
'#|' [ <?opener> || <.typed_panic('X::Syntax::Pod::DeclaratorLeading')> ]
<attachment=.quibble(self.slang_grammar('Quote'))>
{
unless $*POD_BLOCKS_SEEN{ self.from() } {
$*POD_BLOCKS_SEEN{ self.from() } := 1;
if $*DECLARATOR_DOCS eq '' {
$*DECLARATOR_DOCS := $<attachment><nibble>;
} else {
$*DECLARATOR_DOCS := nqp::concat($*DECLARATOR_DOCS, nqp::concat("\n", $<attachment><nibble>));
}
else {
$*DECLARATOR_DOCS := nqp::concat($*DECLARATOR_DOCS,
nqp::concat("\n", $<attachment><nibble>));
}
}
}
}
# a single-line leading declarator block:
token comment:sym<#|> {
'#|' \h+ $<attachment>=[\N*]
{
unless $*POD_BLOCKS_SEEN{ self.from() } {
$*POD_BLOCKS_SEEN{ self.from() } := 1;
if $*DECLARATOR_DOCS eq '' {
$*DECLARATOR_DOCS := $<attachment>;
} else {
$*DECLARATOR_DOCS := nqp::concat($*DECLARATOR_DOCS, nqp::concat("\n", $<attachment>));
}
else {
$*DECLARATOR_DOCS := nqp::concat($*DECLARATOR_DOCS,
nqp::concat("\n", $<attachment>));
}
}
}
}
#===========================
# trailing declarator blocks
#===========================
# examples of valid ones:
# #= single line
# #=(
# multi-
# line
# )
#===========================
# a multi-line trailing declarator block:
# we would like to panic when a non-opening bracket char follows the sym
# TODO find a way to panic with a suitable exception class.
# I believe it may have to be done inside the:
# quibble(self.slang_grammar('Quote'))
# chunk since no variations of the following seem to work:
# [ <?opener> || <.typed_panic('X::Syntax::Pod::DeclaratorTrailing')> ]
token comment:sym<#=(...)> {
'#=' <?opener> <attachment=.quibble(self.slang_grammar('Quote'))>
{
self.attach_trailing_docs(~$<attachment><nibble>);
}
}
# a single-line trailing declarator block:
token comment:sym<#=> {
'#=' \h+ $<attachment>=[\N*]
{
Expand Down
8 changes: 8 additions & 0 deletions src/core/Exception.pm6
Expand Up @@ -1528,6 +1528,14 @@ my class X::Syntax::Comment::Embedded does X::Syntax {
method message() { "Opening bracket required for #` comment" }
}

my class X::Syntax::Pod::DeclaratorLeading does X::Syntax {
method message() { "Opening bracket required for #| declarator block" }
}

my class X::Syntax::Pod::DeclaratorTrailing does X::Syntax {
method message() { "Opening bracket required for #= declarator block" }
}

my class X::Syntax::Pod::BeginWithoutIdentifier does X::Syntax does X::Pod {
method message() {
'=begin must be followed by an identifier; (did you mean "=begin pod"?)'
Expand Down

0 comments on commit 8ea5716

Please sign in to comment.