summaryrefslogtreecommitdiff
path: root/toke.c
diff options
context:
space:
mode:
authorAaron Crane <arc@cpan.org>2019-10-23 13:11:02 +0100
committerAaron Crane <arc@cpan.org>2019-11-04 10:32:29 +0000
commit539c839f22460a19392aab61176e02194b84c4d4 (patch)
tree49b34a972f7a59e5404033eed8affd417e4666e2 /toke.c
parentcd77589fe037f9469baae92cb5d6af3ed823cc2d (diff)
downloadperl-539c839f22460a19392aab61176e02194b84c4d4.tar.gz
toke.c: bundle some yyl_just_a_word() params into a struct
This makes calls to it much easier to understand.
Diffstat (limited to 'toke.c')
-rw-r--r--toke.c169
1 files changed, 98 insertions, 71 deletions
diff --git a/toke.c b/toke.c
index e05a0a669b..e6fb322006 100644
--- a/toke.c
+++ b/toke.c
@@ -290,6 +290,37 @@ static const char* const lex_state_names[] = {
} STMT_END
+/* A file-local structure for passing around information about subroutines and
+ * related definable words */
+struct code {
+ SV *sv;
+ CV *cv;
+ GV *gv, **gvp;
+ OP *rv2cv_op;
+ PADOFFSET off;
+ bool lex;
+};
+
+static const struct code no_code = { NULL, NULL, NULL, NULL, NULL, 0, FALSE };
+
+PERL_STATIC_INLINE struct code
+make_code(SV *sv, CV *cv, GV *gv, GV **gvp, OP *rv2cv_op, PADOFFSET off, bool lex)
+{
+ struct code c;
+ c.sv = sv;
+ c.sv = sv;
+ c.cv = cv;
+ c.gv = gv;
+ c.gvp = gvp;
+ c.rv2cv_op = rv2cv_op;
+ c.off = off;
+ c.lex = lex;
+ return c;
+}
+
+#define MAKE_CODE(lEx) make_code(sv, cv, gv, gvp, rv2cv_op, off, lEx)
+
+
#ifdef DEBUGGING
/* how to interpret the pl_yylval associated with the token */
@@ -7182,9 +7213,8 @@ yyl_strictwarn_bareword(pTHX_ const char lastchar)
}
static int
-yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, PADOFFSET off,
- I32 orig_keyword, SV *sv, CV *cv, GV *gv, GV **gvp,
- OP *rv2cv_op, const bool lex, const bool saw_infix_sigil)
+yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, I32 orig_keyword,
+ struct code c, const bool saw_infix_sigil)
{
int pkgname = 0;
const char lastchar = (PL_bufptr == PL_oldoldbufptr ? 0 : PL_bufptr[-1]);
@@ -7238,8 +7268,8 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, PADOFFSET off,
UTF8fARG(UTF, len, PL_tokenbuf));
len -= 2;
PL_tokenbuf[len] = '\0';
- gv = NULL;
- gvp = 0;
+ c.gv = NULL;
+ c.gvp = 0;
safebw = TRUE;
}
else {
@@ -7248,35 +7278,35 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, PADOFFSET off,
/* if we saw a global override before, get the right name */
- if (!sv)
- sv = S_newSV_maybe_utf8(aTHX_ PL_tokenbuf, len);
- if (gvp) {
- SV * const tmp_sv = sv;
- sv = newSVpvs("CORE::GLOBAL::");
- sv_catsv(sv, tmp_sv);
- SvREFCNT_dec(tmp_sv);
+ if (!c.sv)
+ c.sv = S_newSV_maybe_utf8(aTHX_ PL_tokenbuf, len);
+ if (c.gvp) {
+ SV *sv = newSVpvs("CORE::GLOBAL::");
+ sv_catsv(sv, c.sv);
+ SvREFCNT_dec(c.sv);
+ c.sv = sv;
}
/* Presume this is going to be a bareword of some sort. */
CLINE;
- pl_yylval.opval = newSVOP(OP_CONST, 0, sv);
+ pl_yylval.opval = newSVOP(OP_CONST, 0, c.sv);
pl_yylval.opval->op_private = OPpCONST_BARE;
/* And if "Foo::", then that's what it certainly is. */
if (safebw)
return yyl_safe_bareword(aTHX_ s, lastchar, saw_infix_sigil);
- if (!off) {
- OP *const_op = newSVOP(OP_CONST, 0, SvREFCNT_inc_NN(sv));
+ if (!c.off) {
+ OP *const_op = newSVOP(OP_CONST, 0, SvREFCNT_inc_NN(c.sv));
const_op->op_private = OPpCONST_BARE;
- rv2cv_op = newCVREF(OPpMAY_RETURN_CONSTANT<<8, const_op);
- cv = lex
- ? isGV(gv)
- ? GvCV(gv)
- : SvROK(gv) && SvTYPE(SvRV(gv)) == SVt_PVCV
- ? (CV *)SvRV(gv)
- : ((CV *)gv)
- : rv2cv_op_cv(rv2cv_op, RV2CVOPCV_RETURN_STUB);
+ c.rv2cv_op = newCVREF(OPpMAY_RETURN_CONSTANT<<8, const_op);
+ c.cv = c.lex
+ ? isGV(c.gv)
+ ? GvCV(c.gv)
+ : SvROK(c.gv) && SvTYPE(SvRV(c.gv)) == SVt_PVCV
+ ? (CV *)SvRV(c.gv)
+ : ((CV *)c.gv)
+ : rv2cv_op_cv(c.rv2cv_op, RV2CVOPCV_RETURN_STUB);
}
/* Use this var to track whether intuit_method has been
@@ -7307,7 +7337,7 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, PADOFFSET off,
/* Two barewords in a row may indicate method call. */
if ( ( isIDFIRST_lazy_if_safe(s, PL_bufend, UTF)
|| *s == '$')
- && (key = intuit_method(s, lex ? NULL : sv, cv)))
+ && (key = intuit_method(s, c.lex ? NULL : c.sv, c.cv)))
{
/* the code at method: doesn't use s */
goto method;
@@ -7320,7 +7350,7 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, PADOFFSET off,
if (
( !immediate_paren && (PL_last_lop_op == OP_SORT
- || (!cv
+ || (!c.cv
&& (PL_last_lop_op != OP_MAPSTART
&& PL_last_lop_op != OP_GREPSTART))))
|| (PL_tokenbuf[0] == '_' && PL_tokenbuf[1] == '\0'
@@ -7330,7 +7360,7 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, PADOFFSET off,
{
PL_expect = (PL_last_lop == PL_oldoldbufptr) ? XTERM : XOPERATOR;
yyl_strictwarn_bareword(aTHX_ lastchar);
- op_free(rv2cv_op);
+ op_free(c.rv2cv_op);
return yyl_safe_bareword(aTHX_ s, lastchar, saw_infix_sigil);
}
}
@@ -7340,18 +7370,18 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, PADOFFSET off,
/* Is this a word before a => operator? */
if (*s == '=' && s[1] == '>' && !pkgname) {
- op_free(rv2cv_op);
+ op_free(c.rv2cv_op);
CLINE;
- if (gvp || (lex && !off)) {
- assert (cSVOPx(pl_yylval.opval)->op_sv == sv);
+ if (c.gvp || (c.lex && !c.off)) {
+ assert (cSVOPx(pl_yylval.opval)->op_sv == c.sv);
/* This is our own scalar, created a few lines
above, so this is safe. */
- SvREADONLY_off(sv);
- sv_setpv(sv, PL_tokenbuf);
+ SvREADONLY_off(c.sv);
+ sv_setpv(c.sv, PL_tokenbuf);
if (UTF && !IN_BYTES
&& is_utf8_string((U8*)PL_tokenbuf, len))
- SvUTF8_on(sv);
- SvREADONLY_on(sv);
+ SvUTF8_on(c.sv);
+ SvREADONLY_on(c.sv);
}
TERM(BAREWORD);
}
@@ -7359,26 +7389,26 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, PADOFFSET off,
/* If followed by a paren, it's certainly a subroutine. */
if (*s == '(') {
CLINE;
- if (cv) {
+ if (c.cv) {
char *d = s + 1;
while (SPACE_OR_TAB(*d))
d++;
- if (*d == ')' && (sv = cv_const_sv_or_av(cv)))
- return yyl_constant_op(aTHX_ d + 1, sv, cv, rv2cv_op, off);
+ if (*d == ')' && (c.sv = cv_const_sv_or_av(c.cv)))
+ return yyl_constant_op(aTHX_ d + 1, c.sv, c.cv, c.rv2cv_op, c.off);
}
NEXTVAL_NEXTTOKE.opval =
- off ? rv2cv_op : pl_yylval.opval;
- if (off)
+ c.off ? c.rv2cv_op : pl_yylval.opval;
+ if (c.off)
op_free(pl_yylval.opval), force_next(PRIVATEREF);
- else op_free(rv2cv_op), force_next(BAREWORD);
+ else op_free(c.rv2cv_op), force_next(BAREWORD);
pl_yylval.ival = 0;
TOKEN('&');
}
/* If followed by var or block, call it a method (unless sub) */
- if ((*s == '$' || *s == '{') && !cv) {
- op_free(rv2cv_op);
+ if ((*s == '$' || *s == '{') && !c.cv) {
+ op_free(c.rv2cv_op);
PL_last_lop = PL_oldbufptr;
PL_last_lop_op = OP_METHOD;
if (!PL_lex_allbrackets && PL_lex_fakeeof > LEX_FAKEEOF_LOWLOGIC)
@@ -7393,19 +7423,19 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, PADOFFSET off,
if ( key == 1
&& !orig_keyword
&& (isIDFIRST_lazy_if_safe(s, PL_bufend, UTF) || *s == '$')
- && (key = intuit_method(s, lex ? NULL : sv, cv)))
+ && (key = intuit_method(s, c.lex ? NULL : c.sv, c.cv)))
{
method:
- if (lex && !off) {
- assert(cSVOPx(pl_yylval.opval)->op_sv == sv);
- SvREADONLY_off(sv);
- sv_setpvn(sv, PL_tokenbuf, len);
+ if (c.lex && !c.off) {
+ assert(cSVOPx(pl_yylval.opval)->op_sv == c.sv);
+ SvREADONLY_off(c.sv);
+ sv_setpvn(c.sv, PL_tokenbuf, len);
if (UTF && !IN_BYTES
&& is_utf8_string((U8*)PL_tokenbuf, len))
- SvUTF8_on (sv);
- else SvUTF8_off(sv);
+ SvUTF8_on(c.sv);
+ else SvUTF8_off(c.sv);
}
- op_free(rv2cv_op);
+ op_free(c.rv2cv_op);
if (key == METHOD && !PL_lex_allbrackets
&& PL_lex_fakeeof > LEX_FAKEEOF_LOWLOGIC)
{
@@ -7416,10 +7446,10 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, PADOFFSET off,
/* Not a method, so call it a subroutine (if defined) */
- if (cv) {
+ if (c.cv) {
/* Check for a constant sub */
- sv = cv_const_sv_or_av(cv);
- return yyl_constant_op(aTHX_ s, sv, cv, rv2cv_op, off);
+ c.sv = cv_const_sv_or_av(c.cv);
+ return yyl_constant_op(aTHX_ s, c.sv, c.cv, c.rv2cv_op, c.off);
}
/* Call it a bare word */
@@ -7429,7 +7459,7 @@ yyl_just_a_word(pTHX_ char *s, STRLEN len, I32 key, PADOFFSET off,
else
yyl_strictwarn_bareword(aTHX_ lastchar);
- op_free(rv2cv_op);
+ op_free(c.rv2cv_op);
return yyl_safe_bareword(aTHX_ s, lastchar, saw_infix_sigil);
}
@@ -7600,8 +7630,7 @@ yyl_try(pTHX_ char initial_state, char *s, STRLEN len,
OPERATOR(',');
case ':':
if (s[1] == ':')
- return yyl_just_a_word(aTHX_ s, 0, 0, 0, 0, 0, NULL, NULL, NULL,
- NULL, NULL, saw_infix_sigil);
+ return yyl_just_a_word(aTHX_ s, 0, 0, 0, no_code, saw_infix_sigil);
return yyl_colon(aTHX_ s + 1);
case '(':
@@ -7922,8 +7951,7 @@ yyl_try(pTHX_ char initial_state, char *s, STRLEN len,
/* x::* is just a word, unless x is "CORE" */
if (!anydelim && *s == ':' && s[1] == ':') {
if (memEQs(PL_tokenbuf, len, "CORE")) goto case_KEY_CORE;
- return yyl_just_a_word(aTHX_ s, len, 0, off, orig_keyword, sv, cv,
- gv, gvp, rv2cv_op, FALSE, saw_infix_sigil);
+ return yyl_just_a_word(aTHX_ s, len, 0, orig_keyword, MAKE_CODE(FALSE), saw_infix_sigil);
}
d = s;
@@ -7996,9 +8024,9 @@ yyl_try(pTHX_ char initial_state, char *s, STRLEN len,
off = 0;
if (!gv) {
sv_free(sv);
- return yyl_just_a_word(aTHX_ s, len, tmp, off,
- orig_keyword, NULL, cv, gv, gvp,
- rv2cv_op, FALSE, saw_infix_sigil);
+ sv = NULL;
+ return yyl_just_a_word(aTHX_ s, len, tmp, orig_keyword,
+ MAKE_CODE(FALSE), saw_infix_sigil);
}
}
else {
@@ -8006,8 +8034,8 @@ yyl_try(pTHX_ char initial_state, char *s, STRLEN len,
rv2cv_op->op_targ = off;
cv = find_lexical_cv(off);
}
- return yyl_just_a_word(aTHX_ s, len, tmp, off, orig_keyword, sv,
- cv, gv, gvp, rv2cv_op, TRUE, saw_infix_sigil);
+ return yyl_just_a_word(aTHX_ s, len, tmp, orig_keyword,
+ MAKE_CODE(TRUE), saw_infix_sigil);
}
off = 0;
}
@@ -8033,8 +8061,8 @@ yyl_try(pTHX_ char initial_state, char *s, STRLEN len,
reserved_word:
switch (tmp) {
default: /* not a keyword */
- return yyl_just_a_word(aTHX_ s, len, tmp, off, orig_keyword, sv, cv,
- gv, gvp, rv2cv_op, FALSE, saw_infix_sigil);
+ return yyl_just_a_word(aTHX_ s, len, tmp, orig_keyword,
+ MAKE_CODE(FALSE), saw_infix_sigil);
case KEY___FILE__:
FUN0OP(
@@ -8075,8 +8103,8 @@ yyl_try(pTHX_ char initial_state, char *s, STRLEN len,
case KEY_END:
if (PL_expect == XSTATE)
return yyl_sub(aTHX_ PL_bufptr, tmp);
- return yyl_just_a_word(aTHX_ s, len, tmp, off, orig_keyword, sv, cv,
- gv, gvp, rv2cv_op, FALSE, saw_infix_sigil);
+ return yyl_just_a_word(aTHX_ s, len, tmp, orig_keyword,
+ MAKE_CODE(FALSE), saw_infix_sigil);
case_KEY_CORE:
{
@@ -8088,9 +8116,8 @@ yyl_try(pTHX_ char initial_state, char *s, STRLEN len,
|| (!(tmp = keyword(PL_tokenbuf, len, 1)) && *s == '\''))
{
Copy(PL_bufptr, PL_tokenbuf, olen, char);
- return yyl_just_a_word(aTHX_ d, olen, tmp, off, orig_keyword,
- sv, cv, gv, gvp, rv2cv_op, FALSE,
- saw_infix_sigil);
+ return yyl_just_a_word(aTHX_ d, olen, tmp, orig_keyword,
+ MAKE_CODE(FALSE), saw_infix_sigil);
}
if (!tmp)
Perl_croak(aTHX_ "CORE::%" UTF8f " is not a keyword",
@@ -8965,8 +8992,8 @@ yyl_try(pTHX_ char initial_state, char *s, STRLEN len,
Mop(OP_REPEAT);
}
check_uni();
- return yyl_just_a_word(aTHX_ s, len, tmp, off, orig_keyword, sv, cv,
- gv, gvp, rv2cv_op, FALSE, saw_infix_sigil);
+ return yyl_just_a_word(aTHX_ s, len, tmp, orig_keyword,
+ MAKE_CODE(FALSE), saw_infix_sigil);
case KEY_xor:
if (!PL_lex_allbrackets && PL_lex_fakeeof >= LEX_FAKEEOF_LOWLOGIC)