rubymacros 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -0
  2. data/COPYING.LGPL +503 -158
  3. data/History.txt +115 -5
  4. data/Makefile +68 -0
  5. data/README.txt +29 -6
  6. data/TODO +1 -0
  7. data/bin/macroruby +69 -0
  8. data/example/__dir__.rb +18 -0
  9. data/example/__dir___wrap.rb +18 -0
  10. data/example/andand.rb +18 -0
  11. data/example/andand_wrap.rb +18 -0
  12. data/example/assert.rb +29 -8
  13. data/example/assert0.rb +11 -0
  14. data/example/assert0_wrap.rb +5 -0
  15. data/example/assert_does_nothing_when_disabled.rb +19 -0
  16. data/example/assert_wrap.rb +21 -0
  17. data/example/expected_output.txt +88 -0
  18. data/example/formless_macro.rb +123 -0
  19. data/example/formless_macro_wrap.rb +20 -0
  20. data/example/inline.rb +97 -0
  21. data/example/linenum.rb +19 -1
  22. data/example/linenum_user.rb +18 -0
  23. data/example/linenum_wrap.rb +18 -0
  24. data/example/loop.rb +18 -0
  25. data/example/loop_wrap.rb +18 -0
  26. data/example/meta.rb +25 -0
  27. data/example/meta_wrap.rb +20 -0
  28. data/example/nilresult.rb +26 -0
  29. data/example/nilresult_wrap.rb +21 -0
  30. data/example/pipeline.rb +37 -0
  31. data/example/rescuing.rb +33 -0
  32. data/example/rescuing_wrap.rb +21 -0
  33. data/example/role.rb +103 -0
  34. data/example/role_with_eval.rb +92 -0
  35. data/example/self_in_class.rb +27 -0
  36. data/example/separated_scope.rb +42 -0
  37. data/example/separated_scope_wrap.rb +20 -0
  38. data/example/simple.rb +18 -0
  39. data/example/simple_wrap.rb +18 -0
  40. data/example/unproc.rb +31 -0
  41. data/example/unproc_wrap.rb +21 -0
  42. data/example/unroll.rb +34 -0
  43. data/example/unroll_macros.rb +119 -0
  44. data/example/unroll_wrap.rb +22 -0
  45. data/example/with.rb +50 -7
  46. data/example/with_wrap.rb +19 -0
  47. data/lib/macro.rb +307 -72
  48. data/lib/macro/ReduceWithsFor_RedParse_RedParse__MacroMixin_RedParse__WithMacros_1_8.rb +18880 -0
  49. data/lib/macro/ReduceWithsFor_RedParse_RedParse__MacroMixin_RedParse__WithMacros_1_9.rb +19101 -0
  50. data/lib/macro/form.rb +136 -27
  51. data/lib/macro/node.rb +64 -0
  52. data/lib/macro/version.rb +2 -5
  53. data/lib/rubymacros.rb +19 -0
  54. data/lib/rubymacros/version.rb +23 -0
  55. data/lib/weakkeyhash.rb +18 -0
  56. data/rubymacros.gemspec +60 -0
  57. data/test/test_all.rb +27 -2
  58. data/test/test_examples.rb +91 -0
  59. data/test/test_expand.rb +56 -1
  60. data/test/test_form.rb +108 -10
  61. data/test/test_unroll.rb +120 -0
  62. metadata +93 -65
  63. data/Rakefile +0 -37
@@ -0,0 +1,27 @@
1
+ =begin
2
+ rubymacros - a macro preprocessor for ruby
3
+ Copyright (C) 2008, 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
+
19
+ macro foo_definer
20
+ :( def self.foo; :foo end )
21
+ end
22
+
23
+ class K
24
+ foo_definer
25
+ end
26
+
27
+ p K.foo #should print ':foo'
@@ -0,0 +1,42 @@
1
+ =begin
2
+ rubymacros - a macro preprocessor for ruby
3
+ Copyright (C) 2008, 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
+
19
+ macro separated_scope
20
+ code=yield
21
+ localnames=[]
22
+ code.depthwalk{|parent,i,j,node|
23
+ if RedParse::VarNode===node
24
+ node.name<<'_'
25
+ localnames<<node.name
26
+ end
27
+ }
28
+ :(
29
+ ^localnames.uniq.inject(:(nil)){|sum,lvar|
30
+ RedParse::AssignNode[ RedParse::VarNode[lvar],'=',sum ]
31
+ }
32
+ eval local_variables.map{|lvar| "#{lvar}_ = #{lvar}" }.join(';')
33
+ ^code
34
+ )
35
+ end
36
+
37
+ a = 10
38
+ separated_scope do
39
+ a = a + 1
40
+ p a #=>11
41
+ end
42
+ p a #=>10
@@ -0,0 +1,20 @@
1
+ =begin
2
+ rubymacros - a macro preprocessor for ruby
3
+ Copyright (C) 2008, 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
+
19
+ require 'macro'
20
+ Macro.require 'example/separated_scope'
@@ -1,3 +1,21 @@
1
+ =begin
2
+ rubymacros - a macro preprocessor for ruby
3
+ Copyright (C) 2008, 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
+
1
19
  macro simple(a,b) :(^a+^b) end
2
20
  def simple_user
3
21
  p simple(1,2)
@@ -1,3 +1,21 @@
1
+ =begin
2
+ rubymacros - a macro preprocessor for ruby
3
+ Copyright (C) 2008, 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
+
1
19
  require 'macro'
2
20
  Macro.require 'example/simple'
3
21
 
@@ -0,0 +1,31 @@
1
+ =begin
2
+ rubymacros - a macro preprocessor for ruby
3
+ Copyright (C) 2008, 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
+
19
+ macro unproc0 pr
20
+ pr.body
21
+ end
22
+
23
+ macro unproc(*args)
24
+ yield(*args)
25
+ end
26
+
27
+
28
+ unproc{
29
+ p :foo
30
+ }
31
+
@@ -0,0 +1,21 @@
1
+ =begin
2
+ rubymacros - a macro preprocessor for ruby
3
+ Copyright (C) 2008, 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
+
19
+ require 'macro'
20
+ Macro.require 'example/unproc'
21
+
@@ -0,0 +1,34 @@
1
+ =begin
2
+ rubymacros - a macro preprocessor for ruby
3
+ Copyright (C) 2008, 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
+
19
+
20
+ unroll1(1,2,3){|x| p x}
21
+
22
+ i=1
23
+ unroll( while i<=3; p i; i+=1 end )
24
+ i=1
25
+ unroll( until i>3; p i; i+=1 end )
26
+ i=1
27
+ unroll( ( p i; i+=1 ) while i<=3 )
28
+ i=1
29
+ unroll( ( p i; i+=1 ) until i>3 )
30
+
31
+ unroll 3.times{|i| p i+1 }
32
+ unroll 8.times{|i| p i+1 }
33
+ unroll 9.times{|i| p i+1 }
34
+
@@ -0,0 +1,119 @@
1
+ =begin
2
+ rubymacros - a macro preprocessor for ruby
3
+ Copyright (C) 2008, 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
+
19
+ macro unroll0(ary,code)
20
+ ary.inject(:()){|sum,x|
21
+ sum + :(^code[x])
22
+ }
23
+ end
24
+
25
+ macro unroll1(*ary)
26
+ ary.inject(:()){|sum,x|
27
+ sum + yield( x )
28
+ }
29
+ end
30
+
31
+ module Unroll
32
+ def self.unroll_loop loop
33
+ result=:( while true; end )
34
+ result.body=RedParse::SequenceNode[]
35
+ body=loop.body.deep_copy
36
+
37
+ #what if body contains redo? (break/next is ok)
38
+ #was: fail if loop.body.rfind{|n| RedParse::KWCallNode===n and /^(?:next|redo)$/===n.ident }
39
+ nexting=redoing=breaking=nil
40
+ uniq= rand(0x1_0000_0000) #hacky!; should be: Macro.gensym
41
+ body.replace_flow_control(
42
+ #:next=>proc{ nexting=1; :(throw :"Unroll__Loop__next__#{^uniq}")},
43
+ :redo=>proc{ redoing=1; :(throw :"Unroll__Loop__redo__#{^uniq}")}
44
+ )
45
+ if redoing
46
+ #wrap in appropriate catches
47
+ body=:(catch(:"Unroll__Loop__redo__#{^uniq}"){^body}) if redoing
48
+ end
49
+
50
+ warn "should optimize some common flow control patterns like"
51
+ warn "break at end of the block in toplevel"
52
+ warn "break in a if or unless stmt in toplevel"
53
+
54
+ cond=loop.condition
55
+ chec=if loop.reversed
56
+ :(break if ^cond) unless RedParse::VarLikeNode===cond && /^(nil|false)$/===cond.ident
57
+ else
58
+ :(break unless ^cond) unless
59
+ RedParse::LiteralNode===cond or RedParse::VarLikeNode===cond && "true"==cond.ident
60
+ end
61
+ $LOOP_MULTIPLIER.times {
62
+ result.body<<chec.deep_copy if chec
63
+ result.body<<loop.body.deep_copy
64
+ }
65
+ return result
66
+ end
67
+
68
+ def self.unroll_times loop
69
+ result=:( while true; end )
70
+ result.body=RedParse::SequenceNode[]
71
+
72
+ fail if loop.block.rfind{|n| RedParse::KWCallNode===n and /^(?:next|redo|retry|break)$/===n.ident }
73
+ iterations=loop.receiver.val
74
+ iter_var=loop.blockparams[0]
75
+ warn "#{iter_var.name} was confined to #times block, but now leaks into caller's scope"
76
+ if iterations<2*$LOOP_MULTIPLIER
77
+ result=RedParse::SequenceNode[]
78
+ iterations.times{|i|
79
+ result<<:( (^iter_var) = ^i ) if iter_var
80
+ result<<loop.block.deep_copy
81
+ }
82
+ else
83
+ iter_var ||= VarNode["ii"]
84
+ result=:( (^iter_var) = 0; while ^iter_var<^(iterations-iterations%$LOOP_MULTIPLIER); end )
85
+ inner=result.last
86
+ inner.body=RedParse::SequenceNode[]
87
+ $LOOP_MULTIPLIER.times{
88
+ inner.body<<loop.block.deep_copy
89
+ inner.body<<:( (^iter_var) += 1 )
90
+ }
91
+ sofar=iterations-iterations%$LOOP_MULTIPLIER
92
+ sofar.upto(iterations-1){|i|
93
+ result<<:( (^iter_var) = ^i )
94
+ result<<loop.block.deep_copy
95
+ }
96
+ end
97
+ return result
98
+ end
99
+ end
100
+
101
+ warn "several unhandled cases in unroll macro"
102
+ macro unroll(loop)
103
+ $LOOP_MULTIPLIER||=4
104
+ case loop
105
+ when RedParse::LoopNode,RedParse::UntilOpNode,RedParse::WhileOpNode
106
+ Unroll.unroll_loop loop
107
+ when RedParse::CallSiteNode
108
+ if RedParse::LiteralNode===loop.receiver and "times"==loop.name and loop.params.nil?
109
+ Unroll.unroll_times loop
110
+ elsif loop.receiver.nil? and "loop"==loop.name and loop.params.nil?
111
+ huh
112
+ elsif "each"==loop.name and loop.params.nil?
113
+ huh
114
+ else fail
115
+ end
116
+ else fail
117
+ end
118
+ end
119
+
@@ -0,0 +1,22 @@
1
+ =begin
2
+ rubymacros - a macro preprocessor for ruby
3
+ Copyright (C) 2008, 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
+
19
+ require 'macro'
20
+ Macro.require 'example/unroll_macros'
21
+ Macro.require 'example/unroll'
22
+
@@ -1,7 +1,51 @@
1
- =begin doesn't work yet
1
+ =begin
2
+ rubymacros - a macro preprocessor for ruby
3
+ Copyright (C) 2008, 2016 Caleb Clausen
2
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
+
19
+ =begin xform_tree! version, doesn't work yet (grrr)
3
20
  #change the default receiver within the block from self to new_default
4
- macro with(new_default,&block)
21
+ #kinda like instance_eval, except it doesn't affect instance vars
22
+ macro with(new_default)
23
+ yield.xform_tree!(
24
+ RedParse::CallNode&-{:receiver => NilClass>>new_default}
25
+ )
26
+ end
27
+
28
+ #used like this:
29
+ class Foo
30
+ def bar
31
+ @quux=999
32
+ p with( "baz" ){
33
+ [
34
+ @quux, #=>999, not nil
35
+ size #=>3, not 99
36
+ ]
37
+ }
38
+ end
39
+
40
+ def size; 99 end
41
+ end
42
+ Foo.new.bar
43
+ =end
44
+
45
+ #change the default receiver within the block from self to new_default
46
+ #kinda like instance_eval, except it doesn't affect instance vars
47
+ macro with(new_default)
48
+ block=yield
5
49
  block.walk{|parent,i,subi,node|
6
50
  if RedParse::CallNode===node and node.receiver.nil?
7
51
  node.receiver=new_default
@@ -15,21 +59,19 @@ end
15
59
  class Foo
16
60
  def bar
17
61
  @quux=999
18
- p with "baz" do
62
+ p with( "baz" ){
19
63
  [
20
64
  @quux, #=>999, not nil
21
65
  size #=>3, not 99
22
66
  ]
23
- end
67
+ }
24
68
  end
25
69
 
26
70
  def size; 99 end
27
71
  end
28
72
  Foo.new.bar
29
73
 
30
-
31
- =end
32
-
74
+ =begin old way
33
75
  #change the default receiver within the block from self to new_default
34
76
  macro with(new_default,block)
35
77
  block.walk{|parent,i,subi,node|
@@ -54,3 +96,4 @@ class Foo
54
96
  def size; 99 end
55
97
  end
56
98
  Foo.new.bar
99
+ =end