redparse 0.8.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -0
- data/COPYING.LGPL +503 -158
- data/History.txt +192 -0
- data/Makefile +9 -0
- data/README.txt +72 -39
- data/bin/redparse +108 -14
- data/lib/miniredparse.rb +1543 -0
- data/lib/redparse.rb +971 -105
- data/lib/redparse/ReduceWithsFor_RedParse_1_8.rb +17412 -0
- data/lib/redparse/ReduceWithsFor_RedParse_1_9.rb +17633 -0
- data/lib/redparse/babynodes.rb +17 -0
- data/lib/redparse/babyparser.rb +17 -0
- data/lib/redparse/cache.rb +290 -6
- data/lib/redparse/compile.rb +6 -97
- data/lib/redparse/decisiontree.rb +1 -1
- data/lib/redparse/float_accurate_to_s.rb +30 -6
- data/lib/redparse/generate.rb +18 -0
- data/lib/redparse/node.rb +415 -124
- data/lib/redparse/parse_tree_server.rb +20 -2
- data/lib/redparse/problemfiles.rb +1 -1
- data/lib/redparse/pthelper.rb +17 -31
- data/lib/redparse/reg_more_sugar.rb +1 -1
- data/lib/redparse/replacing/parse_tree.rb +30 -0
- data/lib/redparse/replacing/ripper.rb +20 -0
- data/lib/redparse/replacing/ruby_parser.rb +28 -0
- data/lib/redparse/ripper.rb +393 -0
- data/lib/redparse/ripper_sexp.rb +153 -0
- data/lib/redparse/stackableclasses.rb +113 -0
- data/lib/redparse/version.rb +18 -1
- data/redparse.gemspec +29 -9
- data/rplt.txt +31 -0
- data/test/data/hd_with_blank_string.rb +3 -0
- data/test/data/pt_known_output.rb +13273 -0
- data/test/data/wp.pp +0 -0
- data/test/generate_parse_tree_server_rc.rb +17 -0
- data/test/rp-locatetest.rb +2 -2
- data/test/test_1.9.rb +338 -35
- data/test/test_all.rb +22 -3
- data/test/test_part.rb +32 -0
- data/test/test_redparse.rb +396 -74
- data/test/test_xform_tree.rb +18 -0
- data/test/unparse_1.9_exceptions.txt +85 -0
- data/test/unparse_1.9_exceptions.txt.old +81 -0
- metadata +71 -46
- data/Rakefile +0 -35
@@ -1,3 +1,20 @@
|
|
1
|
+
=begin
|
2
|
+
redparse - a ruby parser written in ruby
|
3
|
+
Copyright (C) 2012, 2016 Caleb Clausen
|
4
|
+
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
1
18
|
require 'tempfile'
|
2
19
|
#require 'yaml'
|
3
20
|
#require 'marshal'
|
@@ -57,6 +74,7 @@ class ParseTreeServer
|
|
57
74
|
end
|
58
75
|
|
59
76
|
def main
|
77
|
+
Process.setsid
|
60
78
|
si=STDIN
|
61
79
|
so=STDOUT
|
62
80
|
@out=so; @in=si
|
@@ -78,14 +96,14 @@ class ParseTreeServer
|
|
78
96
|
tree=
|
79
97
|
begin
|
80
98
|
instance.parse_tree_for_string(str) #tree
|
81
|
-
rescue Exception=>e
|
99
|
+
rescue Exception=>e
|
82
100
|
tree=e
|
83
101
|
end
|
84
102
|
put tree
|
85
103
|
|
86
104
|
open(STDERR.path){|f|
|
87
105
|
f.pos=pos
|
88
|
-
put warnings=f.read.split #warnings
|
106
|
+
put warnings=f.read.split("\n") #warnings
|
89
107
|
}
|
90
108
|
end
|
91
109
|
rescue Exception=>e; put e; raise
|
data/lib/redparse/pthelper.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
=begin
|
2
|
+
redparse - a ruby parser written in ruby
|
3
|
+
Copyright (C) 2012, 2016 Caleb Clausen
|
4
|
+
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
1
18
|
class RedParse
|
2
19
|
def self.remove_silly_begins(pt)
|
3
20
|
pt.each_with_index{|x,i|
|
@@ -10,34 +27,3 @@ class RedParse
|
|
10
27
|
}
|
11
28
|
end
|
12
29
|
end
|
13
|
-
|
14
|
-
__END__
|
15
|
-
begin require 'rubygems'
|
16
|
-
rescue LoadError; #do nothing
|
17
|
-
end
|
18
|
-
|
19
|
-
have_graphwalk=true
|
20
|
-
begin require 'ron/graphedge'
|
21
|
-
rescue LoadError;
|
22
|
-
warn 'Ron::GraphWalk not found; some tests will be too strict'
|
23
|
-
have_graphwalk=false
|
24
|
-
end
|
25
|
-
|
26
|
-
unless have_graphwalk
|
27
|
-
class RedParse
|
28
|
-
def self.remove_silly_begins(pt) pt end
|
29
|
-
end
|
30
|
-
else
|
31
|
-
class RedParse
|
32
|
-
def self.remove_silly_begins(pt)
|
33
|
-
munger=proc{|cntr,o,i,ty,useit|
|
34
|
-
if Array===o and o.size==2 and o.first==:begin
|
35
|
-
useit[0]=true
|
36
|
-
Ron::GraphWalk.graphcopy(o.last,&munger)
|
37
|
-
end
|
38
|
-
}
|
39
|
-
Ron::GraphWalk.graphcopy(pt,&munger)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
@@ -1,6 +1,6 @@
|
|
1
1
|
=begin
|
2
2
|
redparse - a ruby parser written in ruby
|
3
|
-
Copyright (C) 2008 Caleb Clausen
|
3
|
+
Copyright (C) 2008, 2012, 2016 Caleb Clausen
|
4
4
|
|
5
5
|
This program is free software: you can redistribute it and/or modify
|
6
6
|
it under the terms of the GNU Lesser General Public License as published by
|
@@ -0,0 +1,30 @@
|
|
1
|
+
=begin
|
2
|
+
redparse - a ruby parser written in ruby
|
3
|
+
Copyright (C) 2012, 2016 Caleb Clausen
|
4
|
+
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
require 'redparse'
|
19
|
+
|
20
|
+
class ParseTree
|
21
|
+
def initialize
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_tree_for_string(source,
|
26
|
+
filename = '(string)', line = 1, verbose = true)
|
27
|
+
@parser=RedParse.new(source,filename,line)
|
28
|
+
@parser.parse.to_parsetree
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
=begin
|
2
|
+
redparse - a ruby parser written in ruby
|
3
|
+
Copyright (C) 2012, 2016 Caleb Clausen
|
4
|
+
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
require 'redparse/ripper'
|
19
|
+
class Ripper<RedParse::Ripper; end
|
20
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
=begin
|
2
|
+
redparse - a ruby parser written in ruby
|
3
|
+
Copyright (C) 2012, 2016 Caleb Clausen
|
4
|
+
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
class RubyParser
|
19
|
+
def initialize
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse code,file="(eval)",line=1
|
24
|
+
huh #should translate to unified format here too
|
25
|
+
@parser=RedParse.new(code,file,line)
|
26
|
+
@parser.parse.to_parsetree
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,393 @@
|
|
1
|
+
=begin
|
2
|
+
redparse - a ruby parser written in ruby
|
3
|
+
Copyright (C) 2012, 2016 Caleb Clausen
|
4
|
+
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
8
|
+
(at your option) any later version.
|
9
|
+
|
10
|
+
This program is distributed in the hope that it will be useful,
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
GNU Lesser General Public License for more details.
|
14
|
+
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
16
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
=end
|
18
|
+
require 'redparse'
|
19
|
+
class RedParse
|
20
|
+
class Ripper
|
21
|
+
def initialize(text,file="(eval)",line=1,options={})
|
22
|
+
options[:rubyversion]||=1.9
|
23
|
+
@lineno=@column=0 #hack, for now. fix this later
|
24
|
+
@parser=RedParse.new(text,file,line,options)
|
25
|
+
end
|
26
|
+
attr_accessor :lineno,:column,:parser
|
27
|
+
|
28
|
+
alias [] instance_variable_get
|
29
|
+
alias []= instance_variable_set
|
30
|
+
|
31
|
+
def parse options={}
|
32
|
+
@quirks=options[:quirks]
|
33
|
+
tree=@parser
|
34
|
+
tree=tree.parse if tree.respond_to? :parse
|
35
|
+
on_program tree.rip(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
def quirks?; @quirks end
|
39
|
+
|
40
|
+
def self.instrumentSexpBuilder k
|
41
|
+
events=k.instance_methods.grep(/\Aon_/)
|
42
|
+
events.map!{|e| <<-"endcode" }
|
43
|
+
alias noinst_#{e} #{e}
|
44
|
+
def #{e}(*a)
|
45
|
+
@record<<a.dup.unshift(:#{e})
|
46
|
+
noinst_#{e}(*a)
|
47
|
+
end
|
48
|
+
endcode
|
49
|
+
events<<<<-"endcode"
|
50
|
+
alias noinst_parse parse
|
51
|
+
def parse *a
|
52
|
+
@record=[]
|
53
|
+
result=[@record,(noinst_parse *a)]
|
54
|
+
@record=nil
|
55
|
+
return result
|
56
|
+
end
|
57
|
+
endcode
|
58
|
+
k.module_eval events.join
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class LiteralNode
|
63
|
+
def rip p
|
64
|
+
if Symbol===val
|
65
|
+
#p.pos huh
|
66
|
+
p.on_symbol_literal \
|
67
|
+
p.on_symbol \
|
68
|
+
p.on_ident(val.to_s)
|
69
|
+
elsif Integer===val
|
70
|
+
p.on_int(val.to_s)
|
71
|
+
else fail
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class SequenceNode
|
77
|
+
def rip p
|
78
|
+
stmts_rip self,p
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class CallNode
|
83
|
+
def rip p
|
84
|
+
receiver=receiver()
|
85
|
+
name=p.on_ident(name().dup)
|
86
|
+
return p.on_var_ref(name) if p.quirks? and !receiver and !params and !block and @not_real_parens
|
87
|
+
if receiver
|
88
|
+
result=[@not_real_parens ? :on_command_call : :on_call, receiver.rip(p), :".", name]
|
89
|
+
else
|
90
|
+
result=[@not_real_parens ? :on_command : :on_fcall, name]
|
91
|
+
end
|
92
|
+
|
93
|
+
result=p.send(*result)
|
94
|
+
result=p.on_method_add_arg(
|
95
|
+
result,
|
96
|
+
p.on_arg_paren(
|
97
|
+
p.on_args_add_block(
|
98
|
+
args_rip(params,p),
|
99
|
+
false
|
100
|
+
))) if params
|
101
|
+
|
102
|
+
result=p.on_method_add_block(result,p.on_brace_block(nil,block.rip(p))) if block
|
103
|
+
|
104
|
+
return result
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class OpNode
|
109
|
+
def rip p
|
110
|
+
p.on_binary(left.rip(p), op.to_sym, right.rip(p))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
class AndNode
|
114
|
+
def rip p
|
115
|
+
p.on_binary(left.rip(p), op.to_sym, right.rip(p))
|
116
|
+
end
|
117
|
+
end
|
118
|
+
class OrNode
|
119
|
+
def rip p
|
120
|
+
p.on_binary(left.rip(p), op.to_sym, right.rip(p))
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class UnOpNode
|
125
|
+
def rip p
|
126
|
+
p.on_unary(op.to_sym, val.rip(p))
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class RescueOpNode
|
131
|
+
def rip p
|
132
|
+
p.send( "on_#{op}_mod", rescue_with.rip(p), body.rip(p) )
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class WhileOpNode
|
137
|
+
def rip p
|
138
|
+
if BeginNode===consequent
|
139
|
+
if @quirks
|
140
|
+
#this is WRONG!!!, but it's how ripper works... urk
|
141
|
+
#if expression modified by a while operator is a begin node,
|
142
|
+
#ruby always executes the loop at least once,
|
143
|
+
#and doesn't check the condition til after the first execution.
|
144
|
+
#Ripper reverses the order of condition and consequent to signal
|
145
|
+
#an execute-at-least-once loop. But, that's not good enough.
|
146
|
+
#because 'begin a end while b' now parses the same as 'b while begin a end'
|
147
|
+
p.on_while_mod( condition.rip(p), consequent.rip(p) )
|
148
|
+
else
|
149
|
+
p.on_while_mod( consequent.rip(p), condition.rip(p), :loop_first )
|
150
|
+
end
|
151
|
+
else
|
152
|
+
p.on_while_mod( consequent.rip(p), condition.rip(p) )
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
class UntilOpNode
|
158
|
+
def rip p
|
159
|
+
if BeginNode===consequent
|
160
|
+
if @quirks
|
161
|
+
#this is WRONG!!!, but it's how ripper works... urk
|
162
|
+
#if expression modified by a until operator is a begin node,
|
163
|
+
#ruby always executes the loop at least once,
|
164
|
+
#and doesn't check the condition til after the first execution.
|
165
|
+
#Ripper reverses the order of condition and consequent to signal
|
166
|
+
#an execute-at-least-once loop. But, that's not good enough.
|
167
|
+
#because 'begin a end until b' now parses the same as 'b until begin a end'
|
168
|
+
p.on_until_mod( condition.rip(p), consequent.rip(p) )
|
169
|
+
else
|
170
|
+
p.on_until_mod( consequent.rip(p), condition.rip(p), :loop_first )
|
171
|
+
end
|
172
|
+
else
|
173
|
+
p.on_until_mod( consequent.rip(p), condition.rip(p) )
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
class IfOpNode
|
179
|
+
def rip p
|
180
|
+
p.on_if_mod( condition.rip(p), consequent.rip(p) )
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
class UnlessOpNode
|
185
|
+
def rip p
|
186
|
+
p.on_unless_mod( condition.rip(p), consequent.rip(p) )
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
class VarNode
|
191
|
+
def rip p
|
192
|
+
p.on_var_ref(
|
193
|
+
case name[0]
|
194
|
+
when ?$; p.on_gvar(name)
|
195
|
+
when ?@; name[1]==?@ ? p.on_cvar(name) : p.on_ivar(name)
|
196
|
+
when ?A..?Z; p.on_const(name)
|
197
|
+
else p.on_ident(name)
|
198
|
+
end
|
199
|
+
)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
class ConstantNode
|
204
|
+
def rip p
|
205
|
+
if first
|
206
|
+
start=p.on_var_ref \
|
207
|
+
p.on_const(first)
|
208
|
+
start_i=1
|
209
|
+
else
|
210
|
+
start=p.on_top_const_ref \
|
211
|
+
p.on_const(self[1])
|
212
|
+
start_i=2
|
213
|
+
end
|
214
|
+
(start_i...size).inject(start){|sum,i|
|
215
|
+
p.on_const_path_ref(sum,p.on_const(self[i]))
|
216
|
+
}
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
class StringNode
|
221
|
+
def rip p
|
222
|
+
list=self.dup
|
223
|
+
list.shift if String===list.first and list.first.empty?
|
224
|
+
p.on_string_literal \
|
225
|
+
list.inject(p.on_string_content){|sum,chunk|
|
226
|
+
p.on_string_add sum,
|
227
|
+
if String===chunk
|
228
|
+
p.on_tstring_content chunk
|
229
|
+
else
|
230
|
+
p.on_string_embexpr chunk.rip(p)
|
231
|
+
end
|
232
|
+
}
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
class Node
|
237
|
+
def rip_and_rescues p
|
238
|
+
unless rescues.empty?
|
239
|
+
r=rescues.map{|resc| resc.rip(p)}
|
240
|
+
r.each_with_index{|x,i| x<<r[i+1] unless i+1==r.size }
|
241
|
+
r=r.first
|
242
|
+
end
|
243
|
+
p.on_bodystmt(
|
244
|
+
force_stmt_list_rip(body,p),
|
245
|
+
r,
|
246
|
+
else_&&else_.rip(p),
|
247
|
+
ensure_&&p.on_ensure(force_stmt_list_rip(ensure_,p))
|
248
|
+
)
|
249
|
+
end
|
250
|
+
def rip_explode! init,receiver=self,&block
|
251
|
+
receiver.inject(init,&block)
|
252
|
+
end
|
253
|
+
def stmts_rip list,p
|
254
|
+
list.inject(p.on_stmts_new){|sum,expr| p.on_stmts_add(sum,expr.rip(p)) }
|
255
|
+
end
|
256
|
+
def force_stmt_list_rip expr,p
|
257
|
+
if SequenceNode===expr
|
258
|
+
expr.rip(p)
|
259
|
+
else
|
260
|
+
stmts_rip [expr],p
|
261
|
+
end
|
262
|
+
end
|
263
|
+
def args_rip list,p
|
264
|
+
list.inject(p.on_args_new){|sum,param|
|
265
|
+
p.on_args_add(sum,param.rip(p))
|
266
|
+
}
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
class ClassNode
|
271
|
+
def rip p
|
272
|
+
p.on_class( name.rip(p), parent&&parent.rip(p), rip_and_rescues(p) )
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
class ModuleNode
|
277
|
+
def rip p
|
278
|
+
p.on_module( name.rip(p), rip_and_rescues(p) )
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
class MetaClassNode
|
283
|
+
def rip p
|
284
|
+
p.on_sclass( object.rip(p), rip_and_rescues(p) )
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
class MethodNode
|
289
|
+
def get_while params,should_be
|
290
|
+
param=nil
|
291
|
+
result=[]
|
292
|
+
result<<yield( param )while should_be===params.first and param=params.shift
|
293
|
+
ensure
|
294
|
+
return result unless result.empty?
|
295
|
+
end
|
296
|
+
|
297
|
+
def rip p
|
298
|
+
params=args ? args.dup : []
|
299
|
+
params2=[]
|
300
|
+
#param=nil
|
301
|
+
|
302
|
+
params2.push get_while(params,VarNode){|param| p.on_ident param.name}
|
303
|
+
params2.push get_while(params,AssignNode){|param| [p.on_ident(param.left.name), param.right.rip(p)]}
|
304
|
+
get_while(params,UnaryStarNode){|param| params2.push p.on_rest_param p.on_ident param.val.name; break }
|
305
|
+
params2.push get_while(params,VarNode){|param| p.on_ident param.name}
|
306
|
+
get_while(params,UnaryAmpNode){|param| params2.push p.on_blockarg p.on_ident param.val.name; break }
|
307
|
+
|
308
|
+
params=p.on_params( *params2 )
|
309
|
+
params=p.on_paren( params ) if has_parens?
|
310
|
+
|
311
|
+
result=[p.on_ident(name), params, rip_and_rescues(p)]
|
312
|
+
result.unshift receiver.rip(p), p.on_period(".") if receiver
|
313
|
+
p.on_def( *result )
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
class BeginNode
|
318
|
+
def rip p
|
319
|
+
p.on_begin rip_and_rescues(p)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
class RescueNode
|
324
|
+
def rip p
|
325
|
+
p.on_rescue(
|
326
|
+
exceptions.empty??nil:exceptions.map{|ex| ex.rip(p)},
|
327
|
+
name&&p.on_var_field(p.on_ident(name.name)),
|
328
|
+
force_stmt_list_rip(action,p)
|
329
|
+
)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
class IfNode
|
334
|
+
def rip p
|
335
|
+
elses=p.on_else(force_stmt_list_rip(otherwise,p)) if otherwise
|
336
|
+
elsifs.reverse_each{|ei|
|
337
|
+
elses=p.on_elsif(
|
338
|
+
ei.condition.rip(p),
|
339
|
+
force_stmt_list_rip(ei.consequent,p),
|
340
|
+
elses
|
341
|
+
)
|
342
|
+
}
|
343
|
+
p.on_if(
|
344
|
+
condition.rip(p),
|
345
|
+
force_stmt_list_rip(consequent,p),
|
346
|
+
elses
|
347
|
+
)
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
class LoopNode
|
352
|
+
def rip p
|
353
|
+
event= @reverse ? :on_until : :on_while
|
354
|
+
p.send(event, condition.rip(p), force_stmt_list_rip(body,p))
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
class ParenedNode
|
359
|
+
def rip p
|
360
|
+
list= SequenceNode===val ? val : [val]
|
361
|
+
p.on_paren stmts_rip list,p
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
class TernaryNode
|
366
|
+
def rip p
|
367
|
+
p.on_ifop condition.rip(p), consequent.rip(p), otherwise.rip(p)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
class RangeNode
|
372
|
+
def rip p
|
373
|
+
dots= exclude_end? ? :on_dot3 : :on_dot2
|
374
|
+
p.send dots, left.rip(p), right.rip(p)
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
|
379
|
+
class ArrayLiteralNode
|
380
|
+
def rip p
|
381
|
+
p.on_array(args_rip(self,p))
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
class HashLiteralNode
|
386
|
+
def rip p
|
387
|
+
list=[]
|
388
|
+
(0...size).step(2){|i| list.push p.on_assoc_new(self[i].rip(p),self[i+1].rip(p)) }
|
389
|
+
p.on_hash((p.on_assoclist_from_args(list) unless empty?))
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
end
|