rubymacros 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +16 -0
- data/Manifest.txt +4 -0
- data/Rakefile +13 -2
- data/example/linenum.rb +18 -0
- data/example/linenum_user.rb +7 -0
- data/example/linenum_wrap.rb +4 -0
- data/lib/macro/form.rb +80 -15
- data/lib/macro/version.rb +1 -1
- data/lib/macro.rb +101 -9
- data/test/test_expand.rb +4 -0
- data/test/test_form.rb +3 -3
- metadata +9 -4
data/History.txt
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
=== 0.1.2 / 2009-04-26
|
2
|
+
|
3
|
+
* 7 minor enhancements
|
4
|
+
* lots of nice comments added, thanks to Paul Brannan and Tatsuji Kawai
|
5
|
+
* Paul fixed the weird rdoc failure too!
|
6
|
+
* incorrect warning removed
|
7
|
+
* Value changed to Expr in parse rules
|
8
|
+
* hack to get 'rake test' to stay in 1 process (to keep netbeans happy)
|
9
|
+
* in test_form.rb, don't test deep_copy on nil forms
|
10
|
+
* all files should be world-readable now
|
11
|
+
|
12
|
+
=== 0.1.0 / 2008-10-24
|
13
|
+
|
14
|
+
* 1 major enhancement
|
15
|
+
* Birthday!
|
16
|
+
|
data/Manifest.txt
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
COPYING.LGPL
|
2
2
|
Manifest.txt
|
3
3
|
README.txt
|
4
|
+
History.txt
|
4
5
|
rubymacros.vpj
|
5
6
|
Rakefile
|
6
7
|
test/test_form.rb
|
@@ -19,3 +20,6 @@ example/simple.rb
|
|
19
20
|
example/simple_wrap.rb
|
20
21
|
example/with.rb
|
21
22
|
example/with_wrap.rb
|
23
|
+
example/linenum.rb
|
24
|
+
example/linenum_user.rb
|
25
|
+
example/linenum_wrap.rb
|
data/Rakefile
CHANGED
@@ -4,7 +4,18 @@ require 'rubygems'
|
|
4
4
|
require 'hoe'
|
5
5
|
require 'lib/macro/version.rb'
|
6
6
|
|
7
|
-
|
7
|
+
|
8
|
+
if $*==["test"]
|
9
|
+
#hack to get 'rake test' to stay in one process
|
10
|
+
#which keeps netbeans happy
|
11
|
+
$:<<"lib"
|
12
|
+
$:<<"../redparse/lib" #hack hack hack
|
13
|
+
require 'redparse'
|
14
|
+
require "test/test_all.rb"
|
15
|
+
Test::Unit::AutoRunner.run
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
|
8
19
|
readme=open("README.txt")
|
9
20
|
readme.readline("\n== DESCRIPTION:")
|
10
21
|
readme.readline("\n\n")
|
@@ -19,7 +30,7 @@ require 'lib/macro/version.rb'
|
|
19
30
|
_.description=desc
|
20
31
|
_.summary=desc[/\A[^.]+\./]
|
21
32
|
# _.spec_extras={:bindir=>''}
|
22
|
-
_.rdoc_pattern=/\A(README\.txt|lib\/.*\.rb)\Z/
|
33
|
+
# _.rdoc_pattern=/\A(README\.txt|lib\/.*\.rb)\Z/
|
23
34
|
_.remote_rdoc_dir="/"
|
24
35
|
end
|
25
36
|
|
data/example/linenum.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
macro __DIR__
|
2
|
+
:(File.dirname(__FILE__))
|
3
|
+
end
|
4
|
+
|
5
|
+
macro foo
|
6
|
+
:(
|
7
|
+
"just an example, to take up several lines,"+
|
8
|
+
"so that line numbers might be messed up"
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
def user_of_foo
|
13
|
+
foo
|
14
|
+
end
|
15
|
+
|
16
|
+
def linenumuser
|
17
|
+
p __LINE__ #should print 17
|
18
|
+
end
|
data/lib/macro/form.rb
CHANGED
@@ -22,15 +22,25 @@
|
|
22
22
|
require "redparse"
|
23
23
|
require "macro"
|
24
24
|
class Macro
|
25
|
+
# The syntax node for forms
|
25
26
|
class FormNode < RedParse::ValueNode
|
26
27
|
param_names :text
|
28
|
+
|
29
|
+
# Create a new form node. The user should normally not call this
|
30
|
+
# function. Form nodes are created by the parser.
|
31
|
+
#
|
32
|
+
# +colon+:: A colon token
|
33
|
+
# +text+:: A ParenedNode or VarLikeNode
|
34
|
+
#
|
27
35
|
def initialize(colon,text)
|
36
|
+
# Certain node types need to be quoted
|
28
37
|
if RedParse::VarLikeNode===text
|
29
38
|
@transform=HashLiteralNode[]
|
30
39
|
super text
|
31
40
|
return
|
32
41
|
end
|
33
42
|
|
43
|
+
# Sanity check - make sure this is a valid ParenedNode
|
34
44
|
fail unless ParenedNode===text && text.size==1
|
35
45
|
text=text.body
|
36
46
|
|
@@ -38,7 +48,10 @@ class Macro
|
|
38
48
|
rebuild_transform
|
39
49
|
end
|
40
50
|
|
51
|
+
# Initialize the transform and create all the form escapes that are
|
52
|
+
# used in this form
|
41
53
|
def rebuild_transform
|
54
|
+
# TODO: this method needs to be better documented/refactored
|
42
55
|
@transform=HashLiteralNode[]
|
43
56
|
@parameters=[]
|
44
57
|
|
@@ -76,18 +89,37 @@ class Macro
|
|
76
89
|
return self
|
77
90
|
end
|
78
91
|
|
92
|
+
# Iterate over all the parameters in this form
|
93
|
+
#
|
94
|
+
# +block+:: the block to call for each parameter
|
95
|
+
#
|
79
96
|
def each_parameter(&block)
|
80
97
|
@parameters.each(&block) if @parameters
|
81
98
|
end
|
82
99
|
|
100
|
+
# Make a deep copy of this form
|
101
|
+
#
|
102
|
+
# +transform+:: TODO
|
103
|
+
#
|
83
104
|
def deep_copy transform={}
|
84
105
|
super(transform).rebuild_transform
|
85
106
|
end
|
86
107
|
|
108
|
+
# Performs the reverse of a parse operation (turns the node into a
|
109
|
+
# string)
|
110
|
+
#
|
111
|
+
# +o+:: a list of options for unparse
|
112
|
+
#
|
87
113
|
def unparse o
|
88
114
|
":("+text.unparse(o)+")"
|
89
115
|
end
|
90
116
|
|
117
|
+
# Called when the form is evaluated to ensure that the abstract form
|
118
|
+
# in the parse tree is a concrete form that can be modified (makes a
|
119
|
+
# copy of the form).
|
120
|
+
#
|
121
|
+
# +transform+:: the transform to use in the deep copy
|
122
|
+
#
|
91
123
|
def reify transform
|
92
124
|
transform.each_pair{|k,v|
|
93
125
|
transform[k]=Macro.quote(v) unless Node===v or VarNameToken===v
|
@@ -95,6 +127,7 @@ class Macro
|
|
95
127
|
deep_copy(transform)
|
96
128
|
end
|
97
129
|
|
130
|
+
# Transform this node into a ParseTree parse tree
|
98
131
|
def parsetree
|
99
132
|
parses_like.parsetree
|
100
133
|
end
|
@@ -103,6 +136,11 @@ class Macro
|
|
103
136
|
|
104
137
|
module ::Macro::Names
|
105
138
|
COUNT=[0]
|
139
|
+
|
140
|
+
# Sets up the mapping from a form name to a form literal
|
141
|
+
#
|
142
|
+
# +form+:: the name of the form
|
143
|
+
#
|
106
144
|
def self.request form
|
107
145
|
result="Number_#{COUNT[0]+=1}"
|
108
146
|
const_set result, form
|
@@ -112,35 +150,62 @@ class Macro
|
|
112
150
|
|
113
151
|
#CallSiteNode=RedParse::CallSiteNode
|
114
152
|
#ConstantNode=RedParse::ConstantNode
|
153
|
+
|
154
|
+
# Turn the form into something that is legal ruby (since :(..) is
|
155
|
+
# not legal ruby syntax). Thus the form is changed from the syntax:
|
156
|
+
#
|
157
|
+
# :(code)
|
158
|
+
#
|
159
|
+
# to:
|
160
|
+
#
|
161
|
+
# RedParse::SomeNodeType[ some transform of code ]
|
162
|
+
#
|
115
163
|
def parses_like
|
164
|
+
# TODO: either split this into mulitple lines or multiple methods
|
165
|
+
# possibly formname() should return the ConstantNode portion of
|
166
|
+
# the below expression (so that we have one "name" for the form
|
167
|
+
# instead of two representations of the same name)
|
116
168
|
CallSiteNode[CallSiteNode[ConstantNode[nil,"Macro","Names",formname], "reify", [@transform],nil,nil], "text", nil,nil,nil]
|
117
169
|
#:(::Macro::Names::^(formname).reify.text)
|
118
170
|
end
|
119
171
|
|
172
|
+
# Lazily evaluate the name of the form and return it
|
120
173
|
def formname
|
121
174
|
@formname ||= ::Macro::Names.request(self)
|
122
175
|
end
|
123
176
|
end
|
124
177
|
|
125
178
|
|
126
|
-
|
127
|
-
|
179
|
+
# The syntax node for a form escape
|
180
|
+
class FormParameterNode < RedParse::ValueNode
|
181
|
+
param_names :val
|
128
182
|
|
129
|
-
|
130
|
-
|
131
|
-
|
183
|
+
# Called by the parser to create a new form parameter node.
|
184
|
+
#
|
185
|
+
# +args+:: TODO
|
186
|
+
#
|
187
|
+
def initialize(*args)
|
188
|
+
super(args.last)
|
189
|
+
end
|
132
190
|
|
133
|
-
|
134
|
-
|
135
|
-
|
191
|
+
# Performs the reverse of a parse operation (turns the node into a
|
192
|
+
# string)
|
193
|
+
#
|
194
|
+
# +o+:: a list of options for unparse
|
195
|
+
#
|
196
|
+
def unparse o
|
197
|
+
"^"+val.unparse(o)
|
198
|
+
end
|
136
199
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
200
|
+
# The number of carats (^) that occur in the escape. Note that
|
201
|
+
# this method is recursive.
|
202
|
+
def wraplevel
|
203
|
+
return val.wraplevel+1 if FormParameterNode===val
|
204
|
+
return 1
|
205
|
+
end
|
141
206
|
|
142
|
-
|
143
|
-
|
144
|
-
|
207
|
+
def inspect
|
208
|
+
val.unparse({})
|
209
|
+
end
|
145
210
|
end
|
146
211
|
end
|
data/lib/macro/version.rb
CHANGED
data/lib/macro.rb
CHANGED
@@ -19,7 +19,6 @@
|
|
19
19
|
#$:.unshift "../redparse/lib"
|
20
20
|
#warn "$: hacked up to find latest redparse"
|
21
21
|
|
22
|
-
warn "rubygems require disabled"
|
23
22
|
require 'rubygems'
|
24
23
|
require 'redparse'
|
25
24
|
require "macro/form"
|
@@ -27,6 +26,13 @@ require "macro/version"
|
|
27
26
|
|
28
27
|
warn "need to insert extra parens around form params and macro texts"
|
29
28
|
|
29
|
+
class Object # :nodoc:
|
30
|
+
#as close as I can get to an empty binding (used below in Macro.eval)
|
31
|
+
def Object.new_binding() # :nodoc:
|
32
|
+
binding
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
30
36
|
class Macro
|
31
37
|
#import Node classes from RedParse
|
32
38
|
RedParse::constants.each{|k|
|
@@ -46,6 +52,9 @@ class Macro
|
|
46
52
|
|
47
53
|
#like Kernel#require, but allows macros (and forms) as well.
|
48
54
|
#c extensions (.dll,.so,etc) cannot be loaded via this method.
|
55
|
+
#
|
56
|
+
# +filename+:: the name of the feature to require
|
57
|
+
#
|
49
58
|
def Macro.require(filename)
|
50
59
|
filename+='.rb' unless filename[/\.rb\Z/]
|
51
60
|
return if $".include? filename
|
@@ -53,12 +62,11 @@ class Macro
|
|
53
62
|
load filename
|
54
63
|
end
|
55
64
|
|
56
|
-
#as close as I can get to an empty binding
|
57
|
-
def Object.new_binding() # :nodoc:
|
58
|
-
binding
|
59
|
-
end
|
60
|
-
|
61
65
|
#like Kernel#load, but allows macros (and forms) as well.
|
66
|
+
#
|
67
|
+
# +filename+:: the name of the file to load
|
68
|
+
# +wrap+:: whether to wrap the loaded file in an anonymous module
|
69
|
+
#
|
62
70
|
def Macro.load(filename,wrap=false)
|
63
71
|
[''].concat($:).each{|pre|
|
64
72
|
pre+="/" unless %r{(\A|/)\Z}===pre
|
@@ -78,6 +86,12 @@ class Macro
|
|
78
86
|
#beware: default for second argument is currently broken.
|
79
87
|
#best practice is to pass an explicit binding (see
|
80
88
|
#Kernel#binding) for now.
|
89
|
+
#
|
90
|
+
# +code+:: a string of code to evaluate
|
91
|
+
# +binding+:: the binding in which to evaluate the code
|
92
|
+
# +file+:: the name of the file this code came from
|
93
|
+
# +line+:: the line number this code came from
|
94
|
+
#
|
81
95
|
def Macro.eval(code,binding=nil,file="(eval)",line=1)
|
82
96
|
#binding should default to Binding.of_caller, but byellgch
|
83
97
|
|
@@ -86,6 +100,16 @@ class Macro
|
|
86
100
|
tree.eval binding||::Object.new_binding,file,line
|
87
101
|
end
|
88
102
|
|
103
|
+
# A helper for Macro.eval which returns a RedParse tree for the given
|
104
|
+
# code string.
|
105
|
+
#
|
106
|
+
# +code+:: a string of code to evaluate
|
107
|
+
# +binding+:: the binding in which to evaluate the code
|
108
|
+
# +file+:: the name of the file this code came from
|
109
|
+
# +line+:: the line number this code came from
|
110
|
+
# +lvars+:: a list of local variables (empty unless called
|
111
|
+
# recursively)
|
112
|
+
#
|
89
113
|
def Macro.parse(code,file="(eval)",line=1,lvars=[])
|
90
114
|
if Binding===file or Array===file
|
91
115
|
lvars=file
|
@@ -100,6 +124,10 @@ class Macro
|
|
100
124
|
UNCOPYABLE= #Symbol|Numeric|true|false|nil|
|
101
125
|
Module|Proc|IO|Method|UnboundMethod|Thread|Continuation
|
102
126
|
|
127
|
+
# Return a quoted node for the given scalar
|
128
|
+
#
|
129
|
+
# +obj+:: any object or node
|
130
|
+
#
|
103
131
|
def Macro.quote obj
|
104
132
|
#result=
|
105
133
|
case obj
|
@@ -108,6 +136,8 @@ class Macro
|
|
108
136
|
when String:
|
109
137
|
obj=obj.gsub(/['\\]/){|ch| '\\'+ch }
|
110
138
|
StringNode[obj,{:@open=>"'", :@close=>"'"}]
|
139
|
+
|
140
|
+
# TODO: The following is dead code and should be removed
|
111
141
|
else
|
112
142
|
#result=:(::Macro::QuotedStore[^QuotedStore.size])
|
113
143
|
result=CallNode[ConstantNode[nil,"Macro","QuotedStore"],"[]",
|
@@ -123,6 +153,7 @@ class Macro
|
|
123
153
|
end
|
124
154
|
end
|
125
155
|
|
156
|
+
# TODO: dead code (only used by the dead else block above).
|
126
157
|
def Macro.copy obj,seen={}
|
127
158
|
result=seen[obj.__id__]
|
128
159
|
return result if result
|
@@ -152,6 +183,26 @@ class Macro
|
|
152
183
|
return result
|
153
184
|
end
|
154
185
|
|
186
|
+
# Create a node to postpone the macro (or method) definition until it
|
187
|
+
# is actually executed. For example, in the following code:
|
188
|
+
#
|
189
|
+
# if foo
|
190
|
+
# macro bar
|
191
|
+
# ...
|
192
|
+
# end
|
193
|
+
# else
|
194
|
+
# macro bar
|
195
|
+
# ...
|
196
|
+
# end
|
197
|
+
# end
|
198
|
+
#
|
199
|
+
# without postponing macro definition, the latter macro would always
|
200
|
+
# override the former.
|
201
|
+
#
|
202
|
+
# +node+:: the RedParse node for the entire method or macro defintion
|
203
|
+
# that is being postponed
|
204
|
+
# +session+:: the context in which this macro is being processed
|
205
|
+
#
|
155
206
|
def Macro.postpone node,session
|
156
207
|
filename=session[:filename]
|
157
208
|
unless session[:@modpath_unsure]
|
@@ -186,6 +237,13 @@ class Macro
|
|
186
237
|
#beware: default for binding is currently broken.
|
187
238
|
#best practice is to pass an explicit binding (see
|
188
239
|
#Kernel#binding) for now.
|
240
|
+
#
|
241
|
+
# +binding+:: the binding in which to evaluate the node
|
242
|
+
# +file+:: for purpose of evaluation, the name of the file this node
|
243
|
+
# came from
|
244
|
+
# +line+:: for purpose of evaluation, the line number this node came
|
245
|
+
# from
|
246
|
+
#
|
189
247
|
def eval(binding=nil,file=nil,line=nil)
|
190
248
|
#binding should default to Binding.of_caller, but.... that's expensive
|
191
249
|
|
@@ -204,6 +262,12 @@ class Macro
|
|
204
262
|
::Kernel.eval unparsed, binding||::Object.new_binding,file||'(eval)',line||1
|
205
263
|
end
|
206
264
|
|
265
|
+
# A helper for Macro.load and Macro.eval. The source code for the
|
266
|
+
# node is saved to a file so that it can be viewed in the debugger.
|
267
|
+
#
|
268
|
+
# +name+:: the name of the file being loaded
|
269
|
+
# +wrap+:: whether to wrap the loaded file in an anonymous module
|
270
|
+
#
|
207
271
|
def load(name='',wrap=false)
|
208
272
|
expanded_tree=self #Macro.expand(deep_copy,::Macro::GLOBALS)
|
209
273
|
|
@@ -233,7 +297,13 @@ class Macro
|
|
233
297
|
return true
|
234
298
|
end
|
235
299
|
|
300
|
+
# Convert this node to an S-expression
|
301
|
+
#
|
302
|
+
# +session+:: the context in which this macro is being processed
|
303
|
+
#
|
236
304
|
def to_sexp session
|
305
|
+
# TODO: this (and all other functions similarly named) is possibly
|
306
|
+
# dead code
|
237
307
|
self.class.name+"["+
|
238
308
|
map{|param| call_to_sexp param,session }.join(", ")+
|
239
309
|
", {"+instance_variables.map{|iv|
|
@@ -464,7 +534,7 @@ class Macro
|
|
464
534
|
if old_modpath
|
465
535
|
session[:@modpath]=old_modpath
|
466
536
|
else
|
467
|
-
session[:@modpath].pop
|
537
|
+
unwind.times{ session[:@modpath].pop }
|
468
538
|
end
|
469
539
|
session[:@namespace_type]=old_namespace_type
|
470
540
|
session[:@modpath_unsure]=old_unsure
|
@@ -507,6 +577,10 @@ class Macro
|
|
507
577
|
return parses_like,false #halt further recursion: already done where necessary
|
508
578
|
end
|
509
579
|
|
580
|
+
# Convert this node to an S-expression
|
581
|
+
#
|
582
|
+
# +session+:: the context in which this macro is being processed
|
583
|
+
#
|
510
584
|
def to_sexp session
|
511
585
|
nest=session[:form_nest_level]
|
512
586
|
session[:form_nest_level]=nest ? nest+1 : 2
|
@@ -523,6 +597,10 @@ class Macro
|
|
523
597
|
end
|
524
598
|
|
525
599
|
class FormParameterNode<ValueNode
|
600
|
+
# Convert this node to an S-expression
|
601
|
+
#
|
602
|
+
# +session+:: the context in which this macro is being processed
|
603
|
+
#
|
526
604
|
def to_sexp session
|
527
605
|
nest=session[:form_nest_level]||1
|
528
606
|
carets=0
|
@@ -563,6 +641,11 @@ class Macro
|
|
563
641
|
alias ensure_ ensures
|
564
642
|
alias ensure ensures
|
565
643
|
|
644
|
+
# Performs the reverse of a parse operation (turns the node into a
|
645
|
+
# string)
|
646
|
+
#
|
647
|
+
# +o+:: a list of options for unparse
|
648
|
+
#
|
566
649
|
def unparse o
|
567
650
|
result="macro "
|
568
651
|
result+=receiver.unparse(o)+'.' if receiver
|
@@ -591,10 +674,10 @@ class Macro
|
|
591
674
|
[
|
592
675
|
-[KW('macro'), KW(beginsendsmatcher).~.*, KW('end'), KW(/^(do|\{)$/).~.la]>>MisparsedNode
|
593
676
|
]+super+[
|
594
|
-
-[Op('^@'),
|
677
|
+
-[Op('^@'), Expr, LowerOp]>>FormParameterNode,
|
595
678
|
-[Op(':@'), (ParenedNode&-{:size=>1})|(VarLikeNode&-{:ident=>"nil"})]>>FormNode,
|
596
679
|
-['macro', CallSiteNode, KW(';'),
|
597
|
-
|
680
|
+
Expr.-, RescueNode.*, ElseNode.-, EnsureNode.-,
|
598
681
|
'end'
|
599
682
|
]>>MacroNode,
|
600
683
|
]
|
@@ -602,6 +685,12 @@ class Macro
|
|
602
685
|
def wants_semi_context
|
603
686
|
super|KW('macro')
|
604
687
|
end
|
688
|
+
|
689
|
+
# A regex for all the keywords that can be terminated with the 'end'
|
690
|
+
# keyword
|
691
|
+
#
|
692
|
+
# We use the base class's list, and add the 'macro' keyword to it.
|
693
|
+
#
|
605
694
|
def beginsendsmatcher
|
606
695
|
return @bem||=/#{super}|^macro$/
|
607
696
|
end
|
@@ -609,6 +698,9 @@ class Macro
|
|
609
698
|
def initialize(*args)
|
610
699
|
super
|
611
700
|
@lexer.enable_macros! if @lexer.respond_to? :enable_macros!
|
701
|
+
|
702
|
+
# Add ^ to the list of operators that could be either unary or
|
703
|
+
# binary
|
612
704
|
@unary_or_binary_op=/^([\^:]|#@unary_or_binary_op)$/o
|
613
705
|
end
|
614
706
|
end
|
data/test/test_expand.rb
CHANGED
@@ -16,6 +16,10 @@
|
|
16
16
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
17
|
=end
|
18
18
|
|
19
|
+
# TODO: add a test for a method definition inside of a method definition
|
20
|
+
# to ensure that the inner method definition is properly postponed
|
21
|
+
|
22
|
+
|
19
23
|
|
20
24
|
require 'test/unit'
|
21
25
|
require "macro"
|
data/test/test_form.rb
CHANGED
@@ -21,7 +21,7 @@ require "macro"
|
|
21
21
|
require 'test/unit'
|
22
22
|
require 'rubygems'
|
23
23
|
require 'rubylexer'
|
24
|
-
require "test/
|
24
|
+
require "rubylexer/test/testcases" #from rubylexer
|
25
25
|
require 'pp'
|
26
26
|
|
27
27
|
|
@@ -30,7 +30,7 @@ class FormTest< Test::Unit::TestCase
|
|
30
30
|
|
31
31
|
EXAMPLES.each_with_index{|x,i|
|
32
32
|
next if /__END__/===x
|
33
|
-
if / \^[^\s]/===x and x.size>1000
|
33
|
+
if / \^[^\s]/===x #and x.size>1000
|
34
34
|
while x['^']
|
35
35
|
warn "disabling tests of '#{x[/^.*\^.*$/]}'"
|
36
36
|
x[/^.*\^.*$/]=''
|
@@ -65,7 +65,7 @@ class FormTest< Test::Unit::TestCase
|
|
65
65
|
|
66
66
|
assert_equal as_tree, as_form
|
67
67
|
|
68
|
-
assert_equal as_form, as_form.deep_copy
|
68
|
+
assert_equal as_form, as_form.deep_copy if as_form
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubymacros
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Caleb Clausen
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-04-30 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.12.2
|
34
34
|
version:
|
35
35
|
description: Macros are programmed in ruby itself. And since parse trees are represented in RedParse format, they're easier to use (programatically) and more object-oriented than other available ruby parsetree formats. (RedParse Node format is actually designed to be straightforward to use and to represent the structure of ruby source code very closely.)
|
36
36
|
email: rubymacros-owner @at@ inforadical .dot. net
|
@@ -41,10 +41,12 @@ extensions: []
|
|
41
41
|
extra_rdoc_files:
|
42
42
|
- Manifest.txt
|
43
43
|
- README.txt
|
44
|
+
- History.txt
|
44
45
|
files:
|
45
46
|
- COPYING.LGPL
|
46
47
|
- Manifest.txt
|
47
48
|
- README.txt
|
49
|
+
- History.txt
|
48
50
|
- rubymacros.vpj
|
49
51
|
- Rakefile
|
50
52
|
- test/test_form.rb
|
@@ -63,6 +65,9 @@ files:
|
|
63
65
|
- example/simple_wrap.rb
|
64
66
|
- example/with.rb
|
65
67
|
- example/with_wrap.rb
|
68
|
+
- example/linenum.rb
|
69
|
+
- example/linenum_user.rb
|
70
|
+
- example/linenum_wrap.rb
|
66
71
|
has_rdoc: true
|
67
72
|
homepage: http://rubymacros.rubyforge.org/
|
68
73
|
post_install_message:
|
@@ -86,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
91
|
requirements: []
|
87
92
|
|
88
93
|
rubyforge_project: rubymacros
|
89
|
-
rubygems_version: 1.3.
|
94
|
+
rubygems_version: 1.3.1
|
90
95
|
signing_key:
|
91
96
|
specification_version: 2
|
92
97
|
summary: Macros are programmed in ruby itself.
|