Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save judofyr/198967 to your computer and use it in GitHub Desktop.
Save judofyr/198967 to your computer and use it in GitHub Desktop.
From 80ca680d8c16a6dccd80c2d7ab09bf9eea816b35 Mon Sep 17 00:00:00 2001
From: Magnus Holm <judofyr@gmail.com>
Date: Wed, 30 Sep 2009 21:19:29 +0200
Subject: [PATCH 1/4] * test/ripper/test_parser_events.rb: Add test case for 1939
---
test/ripper/test_parser_events.rb | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb
index fa640a3..9b0985a 100644
--- a/test/ripper/test_parser_events.rb
+++ b/test/ripper/test_parser_events.rb
@@ -492,6 +492,15 @@ class TestRipper_ParserEvents < Test::Unit::TestCase
end
=end
+ def test_local_variables
+ cmd = 'command(w,[regexp_literal(xstring_add(xstring_new(),25 # ),/)])'
+ div = 'binary(ref(w),/,25)'
+
+ assert_equal "[#{cmd}]", parse('w /25 # /')
+ assert_equal "[assign(var_field(w),1),#{div}]", parse("w = 1; w /25 # /")
+ assert_equal "[fcall(p,[],&block([w],[#{div}]))]", parse("p{|w|w /25 # /\n}")
+ assert_equal "[def(p,[w],body_stmt([binary(ref(w),/,25)],,,))]", parse("def p(w)\nw /25 # /\nend")
+ end
end
rescue LoadError
--
1.6.2.4
From 35fd22253697d48f2ada75619679ab1df853113a Mon Sep 17 00:00:00 2001
From: Magnus Holm <judofyr@gmail.com>
Date: Wed, 30 Sep 2009 23:19:29 +0200
Subject: [PATCH 2/4] * parse.y: Ripper now uses a struct for YYSTYPE
---
parse.y | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/parse.y b/parse.y
index e325c5c..be846bf 100644
--- a/parse.y
+++ b/parse.y
@@ -26,6 +26,16 @@
#include <errno.h>
#include <ctype.h>
+#ifdef RIPPER
+typedef struct RIPPER_YYSTYPE {
+ VALUE val;
+ NODE *node;
+ ID id;
+ int num;
+} RIPPER_YYSTYPE;
+#define YYSTYPE RIPPER_YYSTYPE
+#endif
+
#define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
#define YYMALLOC(size) rb_parser_malloc(parser, size)
@@ -4735,10 +4745,10 @@ static int parser_here_document(struct parser_params*,NODE*);
#else
# define set_yylval_str(x) (void)(x)
# define set_yylval_num(x) (void)(x)
-# define set_yylval_id(x) (void)(x)
+# define set_yylval_id(x) yylval.id = x
# define set_yylval_literal(x) (void)(x)
# define set_yylval_node(x) (void)(x)
-# define yylval_id() SYM2ID(yylval.val)
+# define yylval_id() yylval.id
#endif
#ifdef RIPPER
--
1.6.2.4
From 2204a8de2c692e4d9d357a81342b46b4b51518af Mon Sep 17 00:00:00 2001
From: Magnus Holm <judofyr@gmail.com>
Date: Thu, 1 Oct 2009 12:56:54 +0200
Subject: [PATCH 3/4] * parse.y: Expose lvtbl to Ripper
---
parse.y | 49 +++++++++++++++++++++++++++++++++++++------------
1 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/parse.y b/parse.y
index be846bf..cdeb339 100644
--- a/parse.y
+++ b/parse.y
@@ -115,7 +115,6 @@ struct local_vars {
#define DVARS_SPECIAL_P(tbl) (!POINTER_P(tbl))
#define POINTER_P(val) ((VALUE)(val) & ~(VALUE)3)
-#ifndef RIPPER
static int
vtable_size(const struct vtable *tbl)
{
@@ -191,7 +190,6 @@ typedef struct token_info {
int nonspc;
struct token_info *next;
} token_info;
-#endif
/*
Structure of Lexer Buffer:
@@ -384,8 +382,11 @@ static NODE *call_uni_op_gen(struct parser_params*,NODE*,ID);
static NODE *new_args_gen(struct parser_params*,NODE*,NODE*,ID,NODE*,ID);
#define new_args(f,o,r,p,b) new_args_gen(parser, f,o,r,p,b)
+
+#endif /* !RIPPER */
static void shadowing_lvar_gen(struct parser_params*,ID);
#define shadowing_lvar(name) shadowing_lvar_gen(parser, name)
+#ifndef RIPPER
static NODE *negate_lit(NODE*);
static NODE *ret_args_gen(struct parser_params*,NODE*);
@@ -398,8 +399,16 @@ static NODE *gettable_gen(struct parser_params*,ID);
#define gettable(id) gettable_gen(parser,id)
static NODE *assignable_gen(struct parser_params*,ID,NODE*);
#define assignable(id,node) assignable_gen(parser, id, node)
+
+#else /* if RIPPER */
+static void assignment_var_gen(struct parser_params*,ID);
+#define assignment_var(id) assignment_var_gen(parser, id)
+#endif /* !RIPPER */
+
static void new_bv_gen(struct parser_params*,ID);
#define new_bv(id) new_bv_gen(parser, id)
+
+#ifndef RIPPER
static NODE *aryset_gen(struct parser_params*,NODE*,NODE*);
#define aryset(node1,node2) aryset_gen(parser, node1, node2)
static NODE *attrset_gen(struct parser_params*,NODE*,ID);
@@ -413,6 +422,7 @@ static NODE *node_assign_gen(struct parser_params*,NODE*,NODE*);
static NODE *match_op_gen(struct parser_params*,NODE*,NODE*);
#define match_op(node1,node2) match_op_gen(parser, node1, node2)
+#endif /* !RIPPER */
static void local_push_gen(struct parser_params*,int);
#define local_push(top) local_push_gen(parser,top)
static void local_pop_gen(struct parser_params*);
@@ -439,11 +449,14 @@ static int dvar_defined_gen(struct parser_params*,ID);
#define dvar_defined(id) dvar_defined_gen(parser, id)
static int dvar_curr_gen(struct parser_params*,ID);
#define dvar_curr(id) dvar_curr_gen(parser, id)
+#ifndef RIPPER
static void fixup_nodes(NODE **);
+#endif /* !RIPPER */
extern int rb_dvar_defined(ID);
extern int rb_local_defined(ID);
+#ifndef RIPPER
extern int rb_parse_in_eval(void);
extern int rb_parse_in_main(void);
@@ -4729,12 +4742,6 @@ static int parser_here_document(struct parser_params*,NODE*);
# define heredoc_restore(n) parser_heredoc_restore(parser,n)
# define whole_match_p(e,l,i) parser_whole_match_p(parser,e,l,i)
-#ifdef RIPPER
-/* FIXME */
-# define local_id(x) 1
-# define dyna_in_block() 1
-#endif /* RIPPER */
-
#ifndef RIPPER
# define set_yylval_str(x) yylval.node = NEW_STR(x)
# define set_yylval_num(x) yylval.num = x
@@ -6061,11 +6068,7 @@ arg_ambiguous_gen(struct parser_params *parser)
static int
lvar_defined_gen(struct parser_params *parser, ID id)
{
-#ifndef RIPPER
return (dyna_in_block() && dvar_defined(id)) || local_id(id);
-#else
- return 0;
-#endif
}
/* emacsen -*- hack */
@@ -8072,6 +8075,23 @@ assignable_gen(struct parser_params *parser, ID id, NODE *val)
}
return 0;
}
+#endif /* !RIPPER */
+
+static void
+assignment_var_gen(struct parser_params *parser, ID name)
+{
+ if (!name || !is_local_id(name)) return;
+
+ if (dyna_in_block()) {
+ if (!dvar_defined(name) && !local_id(name)) {
+ dyna_var(name);
+ }
+ } else {
+ if (!local_id(name)) {
+ local_var(name);
+ }
+ }
+}
static void
shadowing_lvar_gen(struct parser_params *parser, ID name)
@@ -8108,6 +8128,7 @@ new_bv_gen(struct parser_params *parser, ID name)
shadowing_lvar(name);
dyna_var(name);
}
+#ifndef RIPPER
static NODE *
aryset_gen(struct parser_params *parser, NODE *recv, NODE *idx)
@@ -8760,6 +8781,7 @@ new_args_gen(struct parser_params *parser, NODE *m, NODE *o, ID r, NODE *p, ID b
return node;
}
+#endif /* !RIPPER */
static void
local_push_gen(struct parser_params *parser, int inherit_dvars)
{
@@ -8905,6 +8927,7 @@ dvar_curr_gen(struct parser_params *parser, ID id)
return (vtable_included(lvtbl->args, id) ||
vtable_included(lvtbl->vars, id));
}
+#ifndef RIPPER
VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline);
VALUE rb_reg_check_preprocess(VALUE);
@@ -9239,6 +9262,7 @@ rb_gc_mark_symbols(void)
global_symbols.op_sym + tLAST_TOKEN);
}
+#endif /* !RIPPER */
static ID
internal_id_gen(struct parser_params *parser)
{
@@ -9246,6 +9270,7 @@ internal_id_gen(struct parser_params *parser)
id += ((tLAST_TOKEN - ID_INTERNAL) >> ID_SCOPE_SHIFT) + 1;
return ID_INTERNAL | (id << ID_SCOPE_SHIFT);
}
+#ifndef RIPPER
static int
is_special_global_name(const char *m, const char *e, rb_encoding *enc)
--
1.6.2.4
From f28199f3e1bffdf025c8f86ef71a956e15601909 Mon Sep 17 00:00:00 2001
From: Magnus Holm <judofyr@gmail.com>
Date: Thu, 1 Oct 2009 13:11:34 +0200
Subject: [PATCH 4/4] * parse.y: Ripper now uses the lvtbl
---
parse.y | 86 +++++++++++++++++++++++++++++++-------------------------------
1 files changed, 43 insertions(+), 43 deletions(-)
diff --git a/parse.y b/parse.y
index cdeb339..5ca6b5f 100644
--- a/parse.y
+++ b/parse.y
@@ -786,6 +786,7 @@ program : {
$<num>$ = compile_for_eval || rb_parse_in_main();
local_push($<num>$);
/*%
+ local_push(1);
%*/
}
compstmt
@@ -803,11 +804,11 @@ program : {
}
}
ruby_eval_tree = NEW_SCOPE(0, block_append(ruby_eval_tree, $2));
- local_pop();
/*%
$$ = $2;
parser->result = dispatch1(program, $$);
%*/
+ local_pop();
}
;
@@ -1258,8 +1259,8 @@ block_command : block_call
cmd_brace_block : tLBRACE_ARG
{
- /*%%%*/
dyna_push();
+ /*%%%*/
$<num>$ = ruby_sourceline;
/*%
%*/
@@ -1271,10 +1272,10 @@ cmd_brace_block : tLBRACE_ARG
/*%%%*/
$$ = NEW_ITER($3,$4);
nd_set_line($$, $<num>2);
- dyna_pop();
/*%
$$ = dispatch2(brace_block, escape_Qundef($3), $4);
%*/
+ dyna_pop();
}
;
@@ -1541,6 +1542,7 @@ mlhs_node : variable
/*%%%*/
$$ = assignable($1, 0);
/*%
+ assignment_var($<id>1);
$$ = $1;
%*/
}
@@ -1615,6 +1617,7 @@ lhs : variable
/*%%%*/
if (!($$ = assignable($1, 0))) $$ = NEW_BEGIN(0);
/*%
+ assignment_var($<id>1);
$$ = dispatch1(var_field, $1);
%*/
}
@@ -2830,8 +2833,8 @@ primary : literal
{
if (in_def || in_single)
yyerror("class definition in method body");
- /*%%%*/
local_push(0);
+ /*%%%*/
$<num>$ = ruby_sourceline;
/*%
%*/
@@ -2842,10 +2845,10 @@ primary : literal
/*%%%*/
$$ = NEW_CLASS($2, $5, $3);
nd_set_line($$, $<num>4);
- local_pop();
/*%
$$ = dispatch3(class, $2, $3, $5);
%*/
+ local_pop();
}
| k_class tLSHFT expr
{
@@ -2856,10 +2859,7 @@ primary : literal
{
$<num>$ = in_single;
in_single = 0;
- /*%%%*/
local_push(0);
- /*%
- %*/
}
bodystmt
k_end
@@ -2867,10 +2867,10 @@ primary : literal
/*%%%*/
$$ = NEW_SCLASS($3, $7);
fixpos($$, $3);
- local_pop();
/*%
$$ = dispatch2(sclass, $3, $7);
%*/
+ local_pop();
in_def = $<num>4;
in_single = $<num>6;
}
@@ -2878,8 +2878,8 @@ primary : literal
{
if (in_def || in_single)
yyerror("module definition in method body");
- /*%%%*/
local_push(0);
+ /*%%%*/
$<num>$ = ruby_sourceline;
/*%
%*/
@@ -2890,20 +2890,17 @@ primary : literal
/*%%%*/
$$ = NEW_MODULE($2, $4);
nd_set_line($$, $<num>3);
- local_pop();
/*%
$$ = dispatch2(module, $2, $4);
%*/
+ local_pop();
}
| k_def fname
{
$<id>$ = cur_mid;
cur_mid = $2;
in_def++;
- /*%%%*/
local_push(0);
- /*%
- %*/
}
f_arglist
bodystmt
@@ -2914,10 +2911,10 @@ primary : literal
reduce_nodes(&body);
$$ = NEW_DEFN($2, $4, body, NOEX_PRIVATE);
fixpos($$, $4);
- local_pop();
/*%
$$ = dispatch3(def, $2, $4, $5);
%*/
+ local_pop();
in_def--;
cur_mid = $<id>3;
}
@@ -2925,10 +2922,7 @@ primary : literal
{
in_single++;
lex_state = EXPR_END; /* force for args */
- /*%%%*/
local_push(0);
- /*%
- %*/
}
f_arglist
bodystmt
@@ -2939,10 +2933,10 @@ primary : literal
reduce_nodes(&body);
$$ = NEW_DEFS($2, $5, $7, body);
fixpos($$, $2);
- local_pop();
/*%
$$ = dispatch5(defs, $2, $3, $5, $7, $8);
%*/
+ local_pop();
in_single--;
}
| keyword_break
@@ -3134,6 +3128,7 @@ f_marg : f_norm_arg
/*%%%*/
$$ = assignable($1, 0);
/*%
+ assignment_var($<id>1);
$$ = dispatch1(mlhs_paren, $1);
%*/
}
@@ -3178,6 +3173,7 @@ f_margs : f_marg_list
/*%%%*/
$$ = NEW_MASGN($1, assignable($4, 0));
/*%
+ assignment_var($<id>4);
$$ = mlhs_add_star($1, $4);
%*/
}
@@ -3186,6 +3182,7 @@ f_margs : f_marg_list
/*%%%*/
$$ = NEW_MASGN($1, NEW_POSTARG(assignable($4, 0), $6));
/*%
+ assignment_var($<id>4);
$$ = mlhs_add_star($1, $4);
%*/
}
@@ -3210,6 +3207,7 @@ f_margs : f_marg_list
/*%%%*/
$$ = NEW_MASGN(0, assignable($2, 0));
/*%
+ assignment_var($<id>2);
$$ = mlhs_add_star(mlhs_new(), $2);
%*/
}
@@ -3221,6 +3219,7 @@ f_margs : f_marg_list
#if 0
TODO: Check me
#endif
+ assignment_var($<id>2);
$$ = mlhs_add_star($2, $4);
%*/
}
@@ -3430,8 +3429,8 @@ bv_decls : bvar
bvar : tIDENTIFIER
{
- /*%%%*/
new_bv($1);
+ /*%%%*/
/*%
$$ = $1;
%*/
@@ -3443,10 +3442,7 @@ bvar : tIDENTIFIER
;
lambda : {
- /*%%%*/
dyna_push();
- /*%
- %*/
$<num>$ = lpar_beg;
lpar_beg = ++paren_nest;
}
@@ -3457,10 +3453,10 @@ lambda : {
/*%%%*/
$$ = $2;
$$->nd_body = NEW_SCOPE($2->nd_head, $3);
- dyna_pop();
/*%
$$ = dispatch2(lambda, $2, $3);
%*/
+ dyna_pop();
}
;
@@ -3494,8 +3490,8 @@ lambda_body : tLAMBEG compstmt '}'
do_block : keyword_do_block
{
- /*%%%*/
dyna_push();
+ /*%%%*/
$<num>$ = ruby_sourceline;
/*% %*/
}
@@ -3506,10 +3502,10 @@ do_block : keyword_do_block
/*%%%*/
$$ = NEW_ITER($3,$4);
nd_set_line($$, $<num>2);
- dyna_pop();
/*%
$$ = dispatch2(do_block, escape_Qundef($3), $4);
%*/
+ dyna_pop();
}
;
@@ -3640,8 +3636,8 @@ method_call : operation paren_args
brace_block : '{'
{
- /*%%%*/
dyna_push();
+ /*%%%*/
$<num>$ = ruby_sourceline;
/*%
%*/
@@ -3652,15 +3648,15 @@ brace_block : '{'
/*%%%*/
$$ = NEW_ITER($3,$4);
nd_set_line($$, $<num>2);
- dyna_pop();
/*%
$$ = dispatch2(brace_block, escape_Qundef($3), $4);
%*/
+ dyna_pop();
}
| keyword_do
{
- /*%%%*/
dyna_push();
+ /*%%%*/
$<num>$ = ruby_sourceline;
/*%
%*/
@@ -3671,10 +3667,10 @@ brace_block : '{'
/*%%%*/
$$ = NEW_ITER($3,$4);
nd_set_line($$, $<num>2);
- dyna_pop();
/*%
$$ = dispatch2(do_block, escape_Qundef($3), $4);
%*/
+ dyna_pop();
}
;
@@ -4153,6 +4149,7 @@ var_lhs : variable
/*%%%*/
$$ = assignable($1, 0);
/*%
+ assignment_var($<id>1);
$$ = dispatch1(var_field, $1);
%*/
}
@@ -4372,26 +4369,26 @@ f_norm_arg : f_bad_arg
/*%%%*/
if (!is_local_id($1))
yyerror("formal argument must be local variable");
- shadowing_lvar($1);
/*%
%*/
+ shadowing_lvar($<id>1);
$$ = $1;
}
;
f_arg_item : f_norm_arg
{
+ arg_var($<id>1);
/*%%%*/
- arg_var($1);
$$ = NEW_ARGS_AUX($1, 1);
/*%
%*/
}
| tLPAREN f_margs rparen
{
- /*%%%*/
ID tid = internal_id();
arg_var(tid);
+ /*%%%*/
if (dyna_in_block()) {
$2->nd_value = NEW_DVAR(tid);
}
@@ -4428,13 +4425,14 @@ f_arg : f_arg_item
f_opt : tIDENTIFIER '=' arg_value
{
+ shadowing_lvar($<id>1);
+ arg_var($<id>1);
/*%%%*/
if (!is_local_id($1))
yyerror("formal argument must be local variable");
- shadowing_lvar($1);
- arg_var($1);
$$ = NEW_OPT_ARG(0, assignable($1, $3));
/*%
+ assignment_var($<id>1);
$$ = rb_assoc_new($1, $3);
%*/
}
@@ -4442,13 +4440,14 @@ f_opt : tIDENTIFIER '=' arg_value
f_block_opt : tIDENTIFIER '=' primary_value
{
+ shadowing_lvar($<id>1);
+ arg_var($<id>1);
/*%%%*/
if (!is_local_id($1))
yyerror("formal argument must be local variable");
- shadowing_lvar($1);
- arg_var($1);
$$ = NEW_OPT_ARG(0, assignable($1, $3));
/*%
+ assignment_var($<id>1);
$$ = rb_assoc_new($1, $3);
%*/
}
@@ -4508,11 +4507,11 @@ restarg_mark : '*'
f_rest_arg : restarg_mark tIDENTIFIER
{
+ shadowing_lvar($<id>2);
+ arg_var($2);
/*%%%*/
if (!is_local_id($2))
yyerror("rest argument must be local variable");
- shadowing_lvar($2);
- arg_var($2);
$$ = $2;
/*%
$$ = dispatch1(rest_param, $2);
@@ -4520,9 +4519,10 @@ f_rest_arg : restarg_mark tIDENTIFIER
}
| restarg_mark
{
+ ID tid = internal_id();
+ arg_var(tid);
/*%%%*/
- $$ = internal_id();
- arg_var($$);
+ $$ = tid;
/*%
$$ = dispatch1(rest_param, Qnil);
%*/
@@ -4540,12 +4540,12 @@ f_block_arg : blkarg_mark tIDENTIFIER
yyerror("block argument must be local variable");
else if (!dyna_in_block() && local_id($2))
yyerror("duplicated block argument name");
- shadowing_lvar($2);
- arg_var($2);
$$ = $2;
/*%
$$ = dispatch1(blockarg, $2);
%*/
+ shadowing_lvar($<id>2);
+ arg_var($<id>2);
}
;
--
1.6.2.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment