On 26/09/17 04:26, Brandon Allbery wrote:
> On Mon, Sep 25, 2017 at 10:23 PM, ToddAndMargo <toddandma...@zoho.com
> <mailto:toddandma...@zoho.com>> wrote:
>
>     On 09/25/2017 07:25 AM, Brandon Allbery wrote:
>
>         So as to make this not entirely content-free: I would suggest
>         that the string language note the line on which it sees a bare
>         newline, and if it subsequently hits a syntax error while
>         still parsing that string it could output something like perl
>         5's "Possible runaway multi-line string starting on line ..."
>         as a suggestion.
>
>
>     Really like this sugestion!
>
>
> I'm actually looking at the code in question now... and unsure how to
> proceed, as hacking on perl 6 parsers is a bit new to me and this
> looks like it needs to be implemented in a way that is usable by
> multiple roles representing different kinds of 'quoted string'
> (single, double, regex, ...).
>
> -- 
> brandon s allbery kf8nh                               sine nomine
> associates
> allber...@gmail.com <mailto:allber...@gmail.com>                      
>            ballb...@sinenomine.net <mailto:ballb...@sinenomine.net>
> unix, openafs, kerberos, infrastructure, xmonad      
>  http://sinenomine.net

Here's a tiny start at this. it finds undeclared variables inside double
quoted strings and points out the double quoted string existing. It does
not understand the difference between "{ $foo }" and "$foo", but there's
a $*ESCAPEBLOCK dynamic variable that gets set in the closure
interpolation piece of the nibbler (called c1), that could be interesting.

One dead-end was $*LASTQUOTE, which is only set when a quote has been
completely parsed. You can, however, probably steal a bit of code from
World.nqp where it detects run-away quotes, it's inside method
typed_exception. Could be enough to ignore $qe there and pretend $qs is
what is set in is-nibbling.

Also, the quotestart and quotetype attributes of the
X::Undeclared::InQuotes are not set by the code at present, and not
included in the message either. That requires a bit of code from the
run-away quote detection to work.

Good luck!

diff --git a/src/Perl6/Grammar.nqp b/src/Perl6/Grammar.nqp
index 9859181..3c855e0 100644
--- a/src/Perl6/Grammar.nqp
+++ b/src/Perl6/Grammar.nqp
@@ -410,7 +410,12 @@ role STD {

                             CATCH {}
                         }
-                        $*W.throw($var, ['X', 'Undeclared'], symbol =>
$name, suggestions => @suggestions, precursor => '1');
+                        if $*is-nibbling {
+                            $*W.throw($var, ['X', 'Undeclared',
'InQuotes'], symbol => $name, suggestions => @suggestions, precursor =>
'1');
+                        }
+                        else {
+                            $*W.throw($var, ['X', 'Undeclared'], symbol
=> $name, suggestions => @suggestions, precursor => '1');
+                        }
                     }
                 }
                 else {
@@ -5110,6 +5115,7 @@ grammar Perl6::QGrammar is HLL::Grammar does STD {
     token do_nibbling {
         :my $from := self.pos;
         :my $to   := $from;
+        :my $*is-nibbling := $/.from;
         [
             <!stopper>
             [
diff --git a/src/core/Exception.pm b/src/core/Exception.pm
index 2d30a50..5f58be3 100644
--- a/src/core/Exception.pm
+++ b/src/core/Exception.pm
@@ -971,6 +971,24 @@ my class X::Undeclared does X::Comp {
     }
 }

+my class X::Undeclared::InQuotes does X::Comp {
+    has $.what = 'Variable';
+    has $.symbol;
+    has @.suggestions;
+    has $.quotetype;
+    has $.quotestart;
+
+    method message() {
+        my $message := "$.what '$.symbol' is not declared, but used in
a double-quoted string";
+        if +@.suggestions == 1 {
+            $message := "$message. Did you mean '@.suggestions[0]'?";
+        } elsif +@.suggestions > 1 {
+            $message := "$message. Did you mean any of these?\n    {
@.suggestions.join("\n    ") }\n";
+        }
+        $message;
+    }
+}
+
 my class X::Attribute::Undeclared is X::Undeclared {
     has $.package-kind;
     has $.package-name;

Reply via email to