diff options
author | Nicholas Clark <nick@ccl4.org> | 2021-09-28 19:42:40 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2021-09-30 10:28:24 +0000 |
commit | 6d16ed8d4fcdc57defc118806293f6c62de46d42 (patch) | |
tree | 52b00b90ac8a4ee6f52542cae34bf0d6852c74cf /toke.c | |
parent | d3cdb7217b5126d36b00eccc3a6755589554862e (diff) | |
download | perl-6d16ed8d4fcdc57defc118806293f6c62de46d42.tar.gz |
Replace "grandfather ..." in toke.c with a full description
"grandfather return to old style" only really makes sense if you are
familiar with parsing changes between perl 2 and perl 3.
For everyone else, add an explanation of a special case which is still
relevant to the present day.
Diffstat (limited to 'toke.c')
-rw-r--r-- | toke.c | 76 |
1 files changed, 75 insertions, 1 deletions
@@ -275,7 +275,81 @@ static const char* const lex_state_names[] = { #define UNIBRACK(f) UNI3(f,0,0) -/* grandfather return to old style */ +/* return has special case parsing. + * + * List operators have low precedence. Functions have high precedence. + * Every built in, *except return*, if written with () around its arguments, is + * parsed as a function. Hence every other list built in: + * + * $ perl -lwe 'sub foo { join 2,4,6 * 1.5 } print for foo()' # join 2,4,9 + * 429 + * $ perl -lwe 'sub foo { join(2,4,6) * 1.5 } print for foo()' # 426 * 1.5 + * 639 + * $ perl -lwe 'sub foo { join+(2,4,6) * 1.5 } print for foo()' + * Useless use of a constant (2) in void context at -e line 1. + * Useless use of a constant (4) in void context at -e line 1. + * + * $ + * + * empty line output because C<(2, 4, 6) * 1.5> is the comma operator, not a + * list. * forces scalar context, 6 * 1.5 is 9, and join(9) is the empty string. + * + * Whereas return: + * + * $ perl -lwe 'sub foo { return 2,4,6 * 1.5 } print for foo()' + * 2 + * 4 + * 9 + * $ perl -lwe 'sub foo { return(2,4,6) * 1.5 } print for foo()' + * Useless use of a constant (2) in void context at -e line 1. + * Useless use of a constant (4) in void context at -e line 1. + * 9 + * $ perl -lwe 'sub foo { return+(2,4,6) * 1.5 } print for foo()' + * Useless use of a constant (2) in void context at -e line 1. + * Useless use of a constant (4) in void context at -e line 1. + * 9 + * $ + * + * and: + * $ perl -lwe 'sub foo { return(2,4,6) } print for foo()' + * 2 + * 4 + * 6 + * + * This last example is what we expect, but it's clearly inconsistent with how + * C<return(2,4,6) * 1.5> *ought* to behave, if the rules were consistently + * followed. + * + * + * Perl 3 attempted to be consistent: + * + * The rules are more consistent about where parens are needed and + * where they are not. In particular, unary operators and list operators now + * behave like functions if they're called like functions. + * + * However, the behaviour for return was reverted to the "old" parsing with + * patches 9-12: + * + * The construct + * return (1,2,3); + * did not do what was expected, since return was swallowing the + * parens in order to consider itself a function. The solution, + * since return never wants any trailing expression such as + * return (1,2,3) + 2; + * is to simply make return an exception to the paren-makes-a-function + * rule, and treat it the way it always was, so that it doesn't + * strip the parens. + * + * To demonstrate the special-case parsing, replace OLDLOP(OP_RETURN); with + * LOP(OP_RETURN, XTERM); + * + * and constructs such as + * + * return (Internals::V())[2] + * + * turn into syntax errors + */ + #define OLDLOP(f) \ do { \ if (!PL_lex_allbrackets && PL_lex_fakeeof > LEX_FAKEEOF_LOWLOGIC) \ |