fastruby 0.0.19 → 0.0.20

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.
Files changed (121) hide show
  1. data/CHANGELOG +8 -0
  2. data/{README → README.rdoc} +6 -1
  3. data/Rakefile +7 -7
  4. data/benchmarks/benchmark.rb~ +14 -2
  5. data/ext/fastruby_base/fastruby_base.inl +8 -4
  6. data/lib/fastruby/builder/inference_updater.rb +76 -0
  7. data/lib/fastruby/builder/inference_updater.rb~ +76 -0
  8. data/lib/fastruby/builder/inferencer.rb +38 -0
  9. data/lib/fastruby/{inliner → builder}/inliner.rb +16 -27
  10. data/lib/fastruby/builder/inliner.rb~ +60 -0
  11. data/lib/fastruby/builder/locals_inference.rb +53 -0
  12. data/lib/fastruby/builder/lvar_type.rb +43 -0
  13. data/lib/fastruby/builder/lvar_type.rb~ +44 -0
  14. data/lib/fastruby/builder/pipeline.rb +43 -0
  15. data/lib/fastruby/builder/pipeline.rb~ +43 -0
  16. data/lib/fastruby/{reductor → builder}/reductor.rb +6 -3
  17. data/lib/fastruby/builder/reductor.rb~ +42 -0
  18. data/lib/fastruby/builder.rb +73 -25
  19. data/lib/fastruby/builder.rb~ +311 -0
  20. data/lib/fastruby/corelib/fixnum.rb +75 -0
  21. data/lib/fastruby/corelib/fixnum.rb~ +146 -0
  22. data/lib/fastruby/corelib/integer.rb +96 -0
  23. data/lib/fastruby/corelib/integer.rb~ +96 -0
  24. data/lib/fastruby/corelib.rb +23 -0
  25. data/lib/fastruby/corelib.rb~ +23 -0
  26. data/lib/fastruby/getlocals.rb +3 -1
  27. data/lib/fastruby/logging.rb +2 -2
  28. data/lib/fastruby/modules/inferencer/infer.rb +31 -0
  29. data/lib/fastruby/modules/inferencer/literal.rb +42 -0
  30. data/lib/fastruby/modules/inliner/call.rb +327 -0
  31. data/lib/fastruby/{inliner/modules/call.rb → modules/inliner/call.rb~} +14 -24
  32. data/lib/fastruby/modules/inliner/defn.rb +41 -0
  33. data/lib/fastruby/modules/inliner/defn.rb~ +29 -0
  34. data/lib/fastruby/modules/inliner/recursive.rb +40 -0
  35. data/lib/fastruby/{inliner/modules/recursive.rb → modules/inliner/recursive.rb~} +1 -1
  36. data/lib/fastruby/modules/lvar_type/call.rb +36 -0
  37. data/lib/fastruby/modules/lvar_type/call.rb~ +36 -0
  38. data/lib/fastruby/modules/lvar_type/defn.rb +42 -0
  39. data/lib/fastruby/modules/lvar_type/defn.rb~ +42 -0
  40. data/lib/fastruby/modules/lvar_type/lasgn.rb +41 -0
  41. data/lib/fastruby/modules/lvar_type/lasgn.rb~ +42 -0
  42. data/lib/fastruby/modules/lvar_type/recursive.rb +33 -0
  43. data/lib/fastruby/modules/lvar_type/recursive.rb~ +33 -0
  44. data/lib/fastruby/{reductor/modules → modules/reductor}/case.rb +0 -0
  45. data/lib/fastruby/modules/reductor/fastruby_flag.rb +33 -0
  46. data/lib/fastruby/{reductor/modules → modules/reductor}/for.rb +0 -0
  47. data/lib/fastruby/{reductor/modules → modules/reductor}/nontree.rb +0 -0
  48. data/lib/fastruby/modules/reductor/nontree.rb~ +32 -0
  49. data/lib/fastruby/{reductor/modules → modules/reductor}/recursive.rb +1 -1
  50. data/lib/fastruby/modules/reductor/recursive.rb~ +31 -0
  51. data/lib/fastruby/{translator/modules → modules/translator}/block.rb +0 -0
  52. data/lib/fastruby/modules/translator/call.rb +344 -0
  53. data/lib/fastruby/{translator/modules/call.rb → modules/translator/call.rb~} +24 -3
  54. data/lib/fastruby/{translator/modules → modules/translator}/defn.rb +10 -9
  55. data/lib/fastruby/modules/translator/defn.rb~ +267 -0
  56. data/lib/fastruby/{translator/modules → modules/translator}/directive.rb +3 -1
  57. data/lib/fastruby/modules/translator/directive.rb~ +44 -0
  58. data/lib/fastruby/{translator/modules → modules/translator}/exceptions.rb +3 -1
  59. data/lib/fastruby/modules/translator/exceptions.rb~ +120 -0
  60. data/lib/fastruby/{translator/modules → modules/translator}/flow.rb +0 -0
  61. data/lib/fastruby/modules/translator/iter.rb +745 -0
  62. data/lib/fastruby/{translator/modules/iter.rb → modules/translator/iter.rb~} +103 -48
  63. data/lib/fastruby/modules/translator/literal.rb +150 -0
  64. data/lib/fastruby/{translator/modules/literal.rb → modules/translator/literal.rb~} +3 -3
  65. data/lib/fastruby/{translator/modules → modules/translator}/logical.rb +0 -0
  66. data/lib/fastruby/{translator/modules → modules/translator}/method_group.rb +0 -0
  67. data/lib/fastruby/{translator/modules → modules/translator}/nonlocal.rb +18 -6
  68. data/lib/fastruby/modules/translator/nonlocal.rb~ +298 -0
  69. data/lib/fastruby/modules/translator/static.rb +290 -0
  70. data/lib/fastruby/{translator/modules/static.rb → modules/translator/static.rb~} +66 -17
  71. data/lib/fastruby/modules/translator/variable.rb +280 -0
  72. data/lib/fastruby/{translator/modules/variable.rb → modules/translator/variable.rb~} +14 -44
  73. data/lib/fastruby/modules.rb +30 -0
  74. data/lib/fastruby/object.rb +42 -6
  75. data/lib/fastruby/object.rb~ +159 -0
  76. data/lib/fastruby/set_tree.rb +7 -11
  77. data/lib/fastruby/set_tree.rb~ +71 -0
  78. data/lib/fastruby/sexp_extension.rb +29 -7
  79. data/lib/fastruby/sexp_extension.rb~ +262 -0
  80. data/lib/fastruby/translator/scope_mode_helper.rb~ +138 -0
  81. data/lib/fastruby/translator/translator.rb +87 -92
  82. data/lib/fastruby/translator/translator.rb~ +1600 -0
  83. data/lib/fastruby/translator/translator_modules.rb +3 -1
  84. data/lib/fastruby/translator/translator_modules.rb~ +53 -0
  85. data/lib/fastruby.rb +3 -1
  86. data/lib/fastruby.rb~ +3 -1
  87. data/lib/fastruby_only/base.rb +1 -0
  88. data/spec/corelib/numeric/fixnum_spec.rb +110 -0
  89. data/spec/corelib/numeric/fixnum_spec.rb~ +104 -0
  90. data/spec/corelib/numeric/integer_spec.rb +173 -0
  91. data/spec/corelib/numeric/integer_spec.rb~ +173 -0
  92. data/spec/fastruby_only/base_spec.rb +74 -0
  93. data/spec/graph/base_spec.rb +2 -1
  94. data/spec/graph/base_spec.rb~ +35 -0
  95. data/spec/graph/path_spec.rb +2 -2
  96. data/spec/graph/path_spec.rb~ +48 -0
  97. data/spec/graph/vertex_spec.rb +2 -1
  98. data/spec/graph/vertex_spec.rb~ +58 -0
  99. data/spec/reductor/base_spec.rb +1 -1
  100. data/spec/ruby/block/lambda_spec.rb~ +163 -0
  101. data/spec/ruby/block/proc_as_block_spec.rb~ +69 -1
  102. data/spec/ruby/block_spec.rb~ +2 -494
  103. data/spec/ruby/call/base_call_spec.rb +1 -1
  104. data/spec/ruby/call/base_call_spec.rb~ +2 -60
  105. data/spec/ruby/defn/replacement_spec.rb +26 -14
  106. data/spec/ruby/defn/replacement_spec.rb~ +13 -3
  107. data/spec/ruby/exception/internal_ex_spec.rb~ +86 -0
  108. data/spec/ruby/integrity_spec.rb~ +35 -1
  109. data/spec/ruby/variable_spec.rb~ +31 -0
  110. data/spec/scope_mode/flow_spec.rb +1 -1
  111. data/spec/scope_mode/flow_spec.rb~ +109 -0
  112. data/spec/sugar/base_spec.rb +29 -0
  113. data/spec/sugar/base_spec.rb~ +16 -0
  114. metadata +100 -43
  115. data/spec/fastruby/inliner/modules/call_spec.rb +0 -0
  116. data/spec/fastruby/translator/modules/nonlocal_spec.rb +0 -0
  117. data/spec/fastruby/translator/translator_spec.rb +0 -0
  118. data/spec/ruby/block/arguments_spec.rb~ +0 -214
  119. data/spec/ruby/block/break_spec.rb~ +0 -236
  120. data/spec/ruby/block/next_spec.rb~ +0 -85
  121. data/spec/ruby/block/retry_spec.rb~ +0 -43
@@ -0,0 +1,42 @@
1
+ =begin
2
+
3
+ This file is part of the fastruby project, http://github.com/tario/fastruby
4
+
5
+ Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ fastruby is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ fastruby is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "define_method_handler"
22
+
23
+ module FastRuby
24
+ class LvarType
25
+ define_method_handler(:process) {|tree|
26
+ if @process_defn_disabled
27
+ tree
28
+ else
29
+ old = @process_defn_disabled
30
+ @process_defn_disabled = true
31
+ begin
32
+ next tree.map &method(:process)
33
+ ensure
34
+ @process_defn_disabled = old
35
+ end
36
+ end
37
+
38
+ tree
39
+ }.condition{|tree| tree.node_type == :defn or tree.node_type == :defs}
40
+
41
+ end
42
+ end
@@ -0,0 +1,41 @@
1
+ =begin
2
+
3
+ This file is part of the fastruby project, http://github.com/tario/fastruby
4
+
5
+ Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ fastruby is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ fastruby is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "define_method_handler"
22
+
23
+ module FastRuby
24
+ class LvarType
25
+
26
+
27
+ define_method_handler(:process) {|tree|
28
+ @current_index = (@current_index || 1) + 1
29
+ varname = "lvar_type_tmp_#{@current_index}".to_sym
30
+ class_condition = fs("_static{CLASS_OF(_a) == ::#{@infer_lvar_map[tree[1]].to_s}._invariant }", :_a => fs(:lvar,varname))
31
+
32
+ fs(:block,
33
+ fs(:lasgn, varname, tree[2]),
34
+ fs(:if, class_condition, fs(:lasgn, tree[1], fs(:lvar, varname.to_sym)), fs('_raise(FastRuby::TypeMismatchAssignmentException, "")') )
35
+ )
36
+ }.condition{|tree| tree &&
37
+ tree.node_type == :lasgn &&
38
+ tree.size == 3 &&
39
+ @infer_lvar_map[tree[1]] }
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ =begin
2
+
3
+ This file is part of the fastruby project, http://github.com/tario/fastruby
4
+
5
+ Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ fastruby is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ fastruby is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "define_method_handler"
22
+
23
+ module FastRuby
24
+ class LvarType
25
+
26
+ if RUBY_VERSION =~ /^1\\.9/
27
+ define_method_handler(:process) {|tree|
28
+ @current_index = (@current_index || 1) + 1
29
+ varname = "lvar_type_tmp_#{@current_index}".to_sym
30
+ class_condition = fs("_static{CLASS_OF(_a) == ::#{@infer_lvar_map[tree[1]].to_s}._invariant }", :_a => fs(:lvar,varname))
31
+
32
+ fs(:block,
33
+ fs(:lasgn, varname, tree[2]),
34
+ fs(:if, class_condition, fs(:lasgn, tree[1], fs(:lvar, varname.to_sym)), fs('_raise(FastRuby::TypeMismatchAssignmentException, "")') )
35
+ )
36
+ }.condition{|tree| tree &&
37
+ tree.node_type == :lasgn &&
38
+ tree.size == 3 &&
39
+ @infer_lvar_map[tree[1]] }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,33 @@
1
+ =begin
2
+
3
+ This file is part of the fastruby project, http://github.com/tario/fastruby
4
+
5
+ Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ fastruby is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ fastruby is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "define_method_handler"
22
+
23
+ module FastRuby
24
+ class LvarType
25
+ define_method_handler(:process, :priority => -100) {|tree|
26
+ tree.map {|subtree| process subtree}
27
+ }.condition{|tree| tree.respond_to?(:node_type)}
28
+
29
+ define_method_handler(:process, :priority => 1000) {|tree|
30
+ tree
31
+ }.condition{|tree| not tree.respond_to?(:node_type)}
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ =begin
2
+
3
+ This file is part of the fastruby project, http://github.com/tario/fastruby
4
+
5
+ Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ fastruby is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ fastruby is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "define_method_handler"
22
+
23
+ module FastRuby
24
+ class LvarType
25
+ define_method_handler(:process, :priority => -100) {|tree|
26
+ tree.map &method(:process)
27
+ }.condition{|tree| tree.respond_to?(:node_type)}
28
+
29
+ define_method_handler(:process, :priority => 1000) {|tree|
30
+ tree
31
+ }.condition{|tree| not tree.respond_to?(:node_type)}
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ =begin
2
+
3
+ This file is part of the fastruby project, http://github.com/tario/fastruby
4
+
5
+ Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ fastruby is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ fastruby is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ module FastRuby
22
+ class Reductor
23
+ define_method_handler(:reduce, :priority => 100) { |*x|
24
+ tree, result_var = x
25
+
26
+ fs(:true)
27
+ }.condition{|*x|
28
+ tree, result_var = x
29
+
30
+ tree.respond_to? :node_type and tree.node_type == :call and tree[2] == :fastruby? and tree[1] == nil
31
+ }
32
+ end
33
+ end
@@ -0,0 +1,32 @@
1
+ =begin
2
+
3
+ This file is part of the fastruby project, http://github.com/tario/fastruby
4
+
5
+ Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ fastruby is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ fastruby is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "set"
22
+ require "sexp"
23
+ require "define_method_handler"
24
+
25
+ module FastRuby
26
+ class Reductor
27
+ define_method_handler(:reduce, :priority => -100) {|tree|
28
+ print caller.join("\n")
29
+ tree
30
+ }.condition{|tree| not tree.respond_to?(:node_type)}
31
+ end
32
+ end
@@ -25,7 +25,7 @@ require "define_method_handler"
25
25
  module FastRuby
26
26
  class Reductor
27
27
  define_method_handler(:reduce, :priority => -100) {|tree|
28
- tree.map &method(:reduce)
28
+ tree.map{|subtree| reduce subtree}
29
29
  }.condition{|tree| tree.respond_to?(:node_type)}
30
30
  end
31
31
  end
@@ -0,0 +1,31 @@
1
+ =begin
2
+
3
+ This file is part of the fastruby project, http://github.com/tario/fastruby
4
+
5
+ Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ fastruby is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ fastruby is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "set"
22
+ require "sexp"
23
+ require "define_method_handler"
24
+
25
+ module FastRuby
26
+ class Reductor
27
+ define_method_handler(:reduce, :priority => -100) {|*x| tree = x.first;
28
+ tree.map{|subtree| reduce subtree}
29
+ }.condition{|*x| tree = x.first; tree.respond_to?(:node_type)}
30
+ end
31
+ end
@@ -0,0 +1,344 @@
1
+ =begin
2
+
3
+ This file is part of the fastruby project, http://github.com/tario/fastruby
4
+
5
+ Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ fastruby is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ fastruby is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ module FastRuby
22
+ class Context
23
+ define_translator_for(:call, :method => :to_c_call)
24
+ def to_c_call(tree, result_var = nil)
25
+ repass_var = @repass_var
26
+
27
+ recv = tree[1]
28
+ mname = tree[2]
29
+ args = tree[3]
30
+ args_tree = tree[3]
31
+
32
+ if mname == :_class
33
+ if result_var
34
+ return "#{result_var} = CLASS_OF(#{to_c(recv)});"
35
+ else
36
+ return "CLASS_OF(#{to_c(recv)})"
37
+ end
38
+ end
39
+
40
+ if mname == :_raise
41
+ if result_var
42
+ return "
43
+ #{_raise(to_c(args_tree[1]), "")};
44
+ #{result_var} = Qnil;
45
+ "
46
+ else
47
+ return inline_block lambda{"
48
+ #{_raise(to_c(args_tree[1]), "")};
49
+ return Qnil;
50
+ "}
51
+ end
52
+ end
53
+
54
+
55
+ # search block_pass on arguments
56
+ block_pass_arg = args.find{|arg| if arg == :arglist
57
+ false
58
+ else
59
+ arg[0] == :block_pass
60
+ end}
61
+
62
+ if block_pass_arg
63
+ args_tree = args_tree.dup.reject{|st|
64
+ if st.respond_to? :node_type
65
+ st.node_type == :block_pass
66
+ else
67
+ false
68
+ end
69
+ }
70
+ args = args_tree
71
+ end
72
+
73
+ mname = :require_fastruby if mname == :require
74
+
75
+ argnum = args.size - 1
76
+
77
+ recv = recv || s(:self)
78
+
79
+ recvtype = infer_type(recv)
80
+
81
+ if args.size > 1
82
+ if (not recvtype) or args.last[0] == :splat or (not RUBY_VERSION =~ /^1\\.9/)
83
+ if block_pass_arg
84
+ call_tree = tree.dup
85
+ call_tree[3] = args.select{|arg| if arg == :arglist
86
+ true
87
+ else
88
+ arg[0] != :block_pass
89
+ end
90
+ }
91
+
92
+ block_arguments_tree = s(:masgn, s(:array, s(:splat, s(:lasgn, :__xblock_arguments))))
93
+ block_tree = s(:call, s(:lvar, :__x_proc), :call, s(:arglist, s(:splat, s(:lvar, :__xblock_arguments))))
94
+
95
+ replace_iter_tree = s(:block,
96
+ s(:lasgn, :__x_proc, s(:call, block_pass_arg[1], :to_proc, s(:arglist))),
97
+ s(:iter, call_tree, block_arguments_tree, block_tree)
98
+ ).to_fastruby_sexp
99
+ if result_var
100
+ return to_c(replace_iter_tree,result_var)
101
+ else
102
+ return to_c(replace_iter_tree)
103
+ end
104
+ end
105
+ end
106
+
107
+ if args.last[0] == :splat
108
+ aux_varname = "_aux_" + rand(1000000).to_s
109
+ code = protected_block(
110
+ "
111
+
112
+ VALUE array = Qnil;
113
+
114
+ #{to_c args.last[1], "array"};
115
+
116
+ if (TYPE(array) != T_ARRAY) {
117
+ array = rb_ary_new4(1,&array);
118
+ }
119
+
120
+ int argc = #{args.size-2};
121
+ VALUE argv[#{args.size} + _RARRAY_LEN(array)];
122
+ VALUE #{aux_varname} = Qnil;
123
+ #{
124
+ i = -1
125
+ args[1..-2].map {|arg|
126
+ i = i + 1
127
+ "#{to_c arg, aux_varname};
128
+ argv[#{i}] = #{aux_varname};
129
+ "
130
+ }.join(";\n")
131
+ };
132
+
133
+ VALUE recv = Qnil;
134
+
135
+ #{to_c recv, "recv"};
136
+
137
+ int array_len = _RARRAY_LEN(array);
138
+
139
+ int i;
140
+ for (i=0; i<array_len;i++) {
141
+ argv[argc] = rb_ary_entry(array,i);
142
+ argc++;
143
+ }
144
+
145
+ last_expression = rb_funcall2(recv, #{intern_num tree[2]}, argc, argv);
146
+ ", true, repass_var)
147
+
148
+ if result_var
149
+ return "#{result_var} = #{code};\n"
150
+ else
151
+ return code
152
+ end
153
+ end
154
+ end
155
+
156
+ if recvtype
157
+
158
+ address = nil
159
+ mobject = nil
160
+
161
+ inference_complete = true
162
+ signature = [recvtype]
163
+
164
+ args[1..-1].each do |arg|
165
+ argtype = infer_type(arg)
166
+ signature << argtype
167
+ unless argtype
168
+ inference_complete = false
169
+ end
170
+ end
171
+
172
+ if repass_var
173
+ extraargs = ","+repass_var
174
+ extraargs_signature = ",VALUE " + repass_var
175
+ else
176
+ extraargs = ""
177
+ extraargs_signature = ""
178
+ end
179
+
180
+ block_proc_tree = s(:call, block_pass_arg[1], :to_proc, s(:arglist)) if block_pass_arg
181
+
182
+ block_wrapping_proc = proc { |name| "
183
+ static VALUE #{name}(int argc, VALUE* argv, VALUE _locals, VALUE _parent_frame) {
184
+ return rb_proc_call(_locals, rb_ary_new4(argc, argv));
185
+ }
186
+ "
187
+ }
188
+
189
+ if argnum == 0
190
+ value_cast = "VALUE,VALUE,VALUE"
191
+
192
+
193
+ if block_pass_arg or result_var
194
+ code = proc{ "
195
+ {
196
+ VALUE recv = Qnil;
197
+ #{to_c recv, "recv"};
198
+
199
+ #{@block_struct} block, *pblock = Qfalse;
200
+
201
+ #{if block_pass_arg
202
+ "
203
+ VALUE proc = Qnil;
204
+ #{to_c(block_proc_tree, "proc") }
205
+
206
+ VALUE block_address_value = rb_ivar_get(proc, #{intern_num "__block_address"});
207
+
208
+ if (block_address_value != Qnil) {
209
+ block.block_function_address = NUM2PTR(block_address_value);
210
+ block.block_function_param = NUM2PTR(rb_ivar_get(proc, #{intern_num "__block_param"}));
211
+ block.proc = proc;
212
+ pblock = &block;
213
+ } else {
214
+ // create a block from a proc
215
+ block.block_function_address = ((void*)#{anonymous_function(&block_wrapping_proc)});
216
+ block.block_function_param = (void*)proc;
217
+ block.proc = proc;
218
+ pblock = &block;
219
+ }
220
+
221
+ "
222
+ end
223
+ }
224
+
225
+ #{if result_var
226
+ "
227
+ #{result_var} = ((VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(recv, (VALUE)pblock, (VALUE)pframe, 0, (VALUE[]){});
228
+ "
229
+ else
230
+ "
231
+ ((VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(recv, (VALUE)pblock, (VALUE)pframe, 0, (VALUE[]){});
232
+ "
233
+ end
234
+ }
235
+ }
236
+ "
237
+ }
238
+
239
+ result_var ? code.call : inline_block(&code)
240
+ else
241
+ "((VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(#{to_c recv}, Qfalse, (VALUE)pframe, 0, (VALUE[]){})"
242
+ end
243
+
244
+ else
245
+ value_cast = ( ["VALUE"]*(args.size) ).join(",") + ",VALUE,VALUE"
246
+ suffix = "_" + rand(1000000).to_s+"_"
247
+
248
+ strargs = (0..args_tree.size-2).map{|i| "#{suffix}arg#{i}"}.join(",")
249
+ if block_pass_arg or result_var
250
+ code = proc{ "
251
+ {
252
+ VALUE recv = Qnil;
253
+
254
+ #{
255
+ (0..args_tree.size-2).map{ |x|
256
+ "VALUE #{suffix}arg#{x};"
257
+ }.join("\n")
258
+ }
259
+
260
+ #{
261
+ (0..args_tree.size-2).map{ |x|
262
+ to_c(args_tree[x+1], "#{suffix}arg#{x}") + ";"
263
+ }.join("\n")
264
+ }
265
+
266
+ #{to_c recv, "recv"};
267
+
268
+ #{@block_struct} block, *pblock = Qfalse;
269
+
270
+ #{if block_pass_arg
271
+ "
272
+ VALUE proc = Qnil;
273
+ #{to_c(block_proc_tree, "proc") }
274
+ VALUE block_address_value = rb_ivar_get(proc, #{intern_num "__block_address"});
275
+ if (block_address_value != Qnil) {
276
+ block.block_function_address = NUM2PTR(block_address_value);
277
+ block.block_function_param = NUM2PTR(rb_ivar_get(proc, #{intern_num "__block_param"}));
278
+ block.proc = proc;
279
+ pblock = &block;
280
+ } else {
281
+ // create a block from a proc
282
+ block.block_function_address = ((void*)#{anonymous_function(&block_wrapping_proc)});
283
+ block.block_function_param = (void*)proc;
284
+ block.proc = proc;
285
+ pblock = &block;
286
+ }
287
+
288
+ "
289
+ end
290
+ }
291
+
292
+ #{if result_var
293
+ "
294
+ #{result_var} = ((VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(recv, (VALUE)pblock, (VALUE)pframe, #{args.size-1}, (VALUE[]){#{strargs}});
295
+ "
296
+ else
297
+ "
298
+ ((VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(recv, (VALUE)pblock, (VALUE)pframe, #{args.size-1}, (VALUE[]){#{strargs}});
299
+ "
300
+ end
301
+ }
302
+
303
+
304
+ }
305
+ "
306
+ }
307
+
308
+ result_var ? code.call : inline_block(&code)
309
+ else
310
+ strargs = args[1..-1].map{|arg| to_c arg}.join(",")
311
+ "((VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*))#{encode_address(recvtype,signature,mname,tree,inference_complete)})(#{to_c recv}, Qfalse, (VALUE)pframe, #{args.size-1}, (VALUE[]){#{strargs}})"
312
+ end
313
+ end
314
+
315
+ else # else recvtype
316
+ if argnum == 0
317
+ code = protected_block("last_expression = rb_funcall(#{to_c recv}, #{intern_num tree[2]}, 0)", true, repass_var)
318
+ if result_var
319
+ "
320
+ #{result_var} = #{code};
321
+ "
322
+ else
323
+ code
324
+ end
325
+ else
326
+ strargs = args[1..-1].map{|arg| to_c arg}.join(",")
327
+ code = protected_block("last_expression = rb_funcall(#{to_c recv}, #{intern_num tree[2]}, #{argnum}, #{strargs} )", true, repass_var)
328
+ if result_var
329
+ "
330
+ #{result_var} = #{code};
331
+ "
332
+ else
333
+ code
334
+ end
335
+ end
336
+ end # if recvtype
337
+ end
338
+
339
+ define_translator_for(:call, :method => :to_c_attrasgn, :arity => 1)
340
+ def to_c_attrasgn(tree)
341
+ to_c_call(tree)
342
+ end
343
+ end
344
+ end