summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-04-20 03:24:59 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-04-20 03:24:59 +0000
commite63df5319855c1b4ebba0498a466c3806dedba99 (patch)
tree3541d5b3f730ad63215ec50167b152d50dac9500
parent85cb4ee236ee14ec00aebcd90130555ce909d3a2 (diff)
* parse.y (lex_state_e, IS_END, IS_SPCARG, parser_yylex): separate
the state after vcall. [ruby-core:29578] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27414 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--parse.y21
-rw-r--r--test/ruby/test_parse.rb24
3 files changed, 40 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index c21ea2f723..0df7c03c9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Apr 20 12:24:57 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (lex_state_e, IS_END, IS_SPCARG, parser_yylex): separate
+ the state after vcall. [ruby-core:29578]
+
Tue Apr 20 01:03:00 2010 Yusuke Endoh <mame@tsg.ne.jp>
* bootstraptest/test_fork.rb: add a test for [ruby-core:28924].
diff --git a/parse.y b/parse.y
index 36d9d75eff..76ed6ca4f0 100644
--- a/parse.y
+++ b/parse.y
@@ -67,7 +67,9 @@ enum lex_state_e {
EXPR_FNAME, /* ignore newline, no reserved words. */
EXPR_DOT, /* right after `.' or `::', no reserved words. */
EXPR_CLASS, /* immediate after `class', no here document. */
- EXPR_VALUE /* alike EXPR_BEG but label is disallowed. */
+ EXPR_VALUE, /* alike EXPR_BEG but label is disallowed. */
+ EXPR_VCALL, /* immediate after vcall */
+ EXPR_MAX_STATE
};
typedef VALUE stack_type;
@@ -6413,9 +6415,9 @@ parser_prepare(struct parser_params *parser)
}
#define IS_ARG() (lex_state == EXPR_ARG || lex_state == EXPR_CMDARG)
-#define IS_END() (lex_state == EXPR_END || lex_state == EXPR_ENDARG)
+#define IS_END() (lex_state == EXPR_END || lex_state == EXPR_ENDARG || lex_state == EXPR_VCALL)
#define IS_BEG() (lex_state == EXPR_BEG || lex_state == EXPR_MID || lex_state == EXPR_VALUE || lex_state == EXPR_CLASS)
-#define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
+#define IS_SPCARG(c) ((IS_ARG() || lex_state == EXPR_VCALL) && space_seen && !ISSPACE(c))
static int
parser_yylex(struct parser_params *parser)
@@ -6660,8 +6662,7 @@ parser_yylex(struct parser_params *parser)
if (c == '<' &&
lex_state != EXPR_DOT &&
lex_state != EXPR_CLASS &&
- !IS_END() &&
- (!IS_ARG() || space_seen)) {
+ (!(IS_ARG() || IS_END()) || space_seen)) {
int token = heredoc_identifier();
if (token) return token;
}
@@ -6736,11 +6737,11 @@ parser_yylex(struct parser_params *parser)
return tSTRING_BEG;
case '?':
- if (IS_END()) {
+ c = nextc();
+ if (IS_END() && (!space_seen || ISSPACE(c))) {
lex_state = EXPR_VALUE;
return '?';
}
- c = nextc();
if (c == -1) {
compile_error(PARSER_ARG "incomplete character syntax");
return 0;
@@ -7316,7 +7317,7 @@ parser_yylex(struct parser_params *parser)
CMDARG_PUSH(0);
return tLAMBEG;
}
- if (IS_ARG() || lex_state == EXPR_END)
+ if (IS_ARG() || lex_state == EXPR_END || lex_state == EXPR_VCALL)
c = '{'; /* block (primary) */
else if (lex_state == EXPR_ENDARG)
c = tLBRACE_ARG; /* block (expr) */
@@ -7624,7 +7625,7 @@ parser_yylex(struct parser_params *parser)
}
if ((lex_state == EXPR_BEG && !cmd_state) ||
- IS_ARG()) {
+ IS_ARG() || lex_state == EXPR_VCALL) {
if (peek(':') && !(lex_p + 1 < lex_pend && lex_p[1] == ':')) {
lex_state = EXPR_BEG;
nextc();
@@ -7687,7 +7688,7 @@ parser_yylex(struct parser_params *parser)
set_yylval_name(ident);
if (last_state != EXPR_DOT && is_local_id(ident) && lvar_defined(ident)) {
- lex_state = EXPR_END;
+ lex_state = EXPR_VCALL;
}
}
return result;
diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb
index 49ecfc56ed..aa664ebd44 100644
--- a/test/ruby/test_parse.rb
+++ b/test/ruby/test_parse.rb
@@ -823,4 +823,28 @@ x = __ENCODING__
c.instance_eval { remove_class_variable(:@var) }
end
end
+
+ def result(arg = nil, &pro)
+ pro || arg
+ end
+
+ def test_method_and_lvar
+ result = nil
+ bug3163 = '[ruby-core:29578]'
+ assert_equal(%[bug3163], (result %[bug3163]), bug3163)
+ assert_equal(/bug3163/x, (result /bug3163/x), bug3163)
+ pro = proc {}
+ assert_equal(pro, (result &pro), bug3163)
+ assert_equal(bug3163, (result *bug3163), bug3163)
+ f = g = nil
+ assert_raise(SyntaxError, bug3163) {eval("result ?f : g")}
+ assert_equal("123\n", eval("result <<FOO\n123\nFOO"), bug3163)
+
+ bug3163_2 = '[ruby-core:29594]'
+ one = 1
+ assert_equal(+1, (result +one), bug3163_2)
+ assert_equal(-1, (result -one), bug3163_2)
+
+ assert_equal({:a => 1}, (result a: 1))
+ end
end