Skip to content

Commit 307f146

Browse files
committed
Complain at a higher level in nqp::sprintf.
Previously failed {int,num,str}ification let the low-level message bubble up to the HLL. Now we instead throw a VMException that contains a complaint about the directive vs type mismatch as message and the actual failed argument as payload.
1 parent cdc5419 commit 307f146

File tree

1 file changed

+57
-10
lines changed

1 file changed

+57
-10
lines changed

src/HLL/sprintf.nqp

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ my module sprintf {
7171
make nqp::join('', @statements);
7272
}
7373

74+
sub panic($payload, $directive) {
75+
my $ex := nqp::newexception();
76+
nqp::setmessage($ex, "Directive $directive not applicable for type " ~ $payload.HOW.name($payload));
77+
nqp::setpayload($ex, $payload);
78+
nqp::throw($ex);
79+
}
80+
7481
sub infix_x($s, $n) {
7582
my @strings;
7683
my int $i := 0;
@@ -146,7 +153,11 @@ my module sprintf {
146153
}
147154

148155
method directive:sym<b>($/) {
149-
my $int := intify(next_argument($/));
156+
my $next := next_argument($/);
157+
CATCH {
158+
panic($next, 'b');
159+
}
160+
my $int := intify($next);
150161
$int := nqp::base_I($int, 2);
151162
my $pre := ($<sym> eq 'b' ?? '0b' !! '0B') if $int ne '0' && has_flag($/, 'hash');
152163
if nqp::chars($<precision>) {
@@ -159,11 +170,19 @@ my module sprintf {
159170
make $int;
160171
}
161172
method directive:sym<c>($/) {
162-
make nqp::chr(next_argument($/))
173+
my $next := next_argument($/);
174+
CATCH {
175+
panic($next, 'c');
176+
}
177+
make nqp::chr($next)
163178
}
164179

165180
method directive:sym<d>($/) {
166-
my $int := intify(next_argument($/));
181+
my $next := next_argument($/);
182+
CATCH {
183+
panic($next, 'd');
184+
}
185+
my $int := intify($next);
167186
my $pad := padding_char($/);
168187
my $sign := nqp::islt_I($int, $zero) ?? '-'
169188
!! has_flag($/, 'plus') ?? '+'
@@ -321,28 +340,44 @@ my module sprintf {
321340
}
322341

323342
method directive:sym<e>($/) {
324-
my $float := next_argument($/);
343+
my $next := next_argument($/);
344+
CATCH {
345+
panic($next, 'e');
346+
}
347+
my $float := $next;
325348
my $precision := $<precision> ?? $<precision>.made !! 6;
326349
my $pad := padding_char($/);
327350
my $size := $<size> ?? $<size>.made !! 0;
328351
make scientific($float, $<sym>, $precision, $size, $pad, $/);
329352
}
330353
method directive:sym<f>($/) {
331-
my $int := next_argument($/);
354+
my $next := next_argument($/);
355+
CATCH {
356+
panic($next, 'f');
357+
}
358+
my $int := $next;
332359
my $precision := $<precision> ?? $<precision>.made !! 6;
333360
my $pad := padding_char($/);
334361
my $size := $<size> ?? $<size>.made !! 0;
335362
make fixed-point($int, $precision, $size, $pad, $/);
336363
}
337364
method directive:sym<g>($/) {
338-
my $float := next_argument($/);
365+
my $next := next_argument($/);
366+
CATCH {
367+
panic($next, 'g');
368+
}
369+
my $float := $next;
339370
my $precision := $<precision> ?? $<precision>.made !! 6;
340371
my $pad := padding_char($/);
341372
my $size := $<size> ?? $<size>.made !! 0;
342373
make shortest($float, $<sym> eq 'G' ?? 'E' !! 'e', $precision, $size, $pad, $/);
343374
}
344375
method directive:sym<o>($/) {
345-
my $int := intify(next_argument($/));
376+
my $next := next_argument($/);
377+
CATCH {
378+
panic($next, 'o');
379+
}
380+
my $int := intify($next);
346381
$int := nqp::base_I($int, 8);
347382
my $pre := '0' if $int ne '0' && has_flag($/, 'hash');
348383
if nqp::chars($<precision>) {
@@ -356,7 +391,11 @@ my module sprintf {
356391
}
357392

358393
method directive:sym<s>($/) {
359-
my $string := next_argument($/);
394+
my $next := next_argument($/);
395+
CATCH {
396+
panic($next, 's');
397+
}
398+
my $string := $next;
360399
if nqp::chars($<precision>) && nqp::chars($string) > $<precision>.made {
361400
$string := nqp::substr($string, 0, $<precision>.made);
362401
}
@@ -365,7 +404,11 @@ my module sprintf {
365404
# XXX: Should we emulate an upper limit, like 2**64?
366405
# XXX: Should we emulate p5 behaviour for negative values passed to %u ?
367406
method directive:sym<u>($/) {
368-
my $int := intify(next_argument($/));
407+
my $next := next_argument($/);
408+
CATCH {
409+
panic($next, 'u');
410+
}
411+
my $int := intify($next);
369412
if nqp::islt_I($int, $zero) {
370413
my $err := nqp::getstderr();
371414
nqp::printfh($err, "negative value '"
@@ -378,7 +421,11 @@ my module sprintf {
378421
make nqp::tostr_I($int)
379422
}
380423
method directive:sym<x>($/) {
381-
my $int := intify(next_argument($/));
424+
my $next := next_argument($/);
425+
CATCH {
426+
panic($next, 'x');
427+
}
428+
my $int := intify($next);
382429
$int := nqp::base_I($int, 16);
383430
my $pre := '0X' if $int ne '0' && has_flag($/, 'hash');
384431
if nqp::chars($<precision>) {

0 commit comments

Comments
 (0)