fastruby 0.0.2 → 0.0.3

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.
data/README CHANGED
@@ -55,8 +55,6 @@ I will stabilize the API and document it for next releases. I promise
55
55
 
56
56
  == Known Limitations & Issues
57
57
 
58
- * fastruby only can be called from inside a class scope, and only can be used to define instance methods (no class methods)
59
- * fastruby invokations can't take more than one method
60
58
  * monkey patching does not work with fastruby methods
61
59
  * calls with blocks to ruby or cruby methods are almost as slow as normal ruby (if the called method is defined by fastruby, the call it's pretty fast)
62
60
  * does not support singleton methods (both define & call)
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ require "rspec/core/rake_task"
7
7
 
8
8
  spec = Gem::Specification.new do |s|
9
9
  s.name = 'fastruby'
10
- s.version = '0.0.2'
10
+ s.version = '0.0.3'
11
11
  s.author = 'Dario Seminara'
12
12
  s.email = 'robertodarioseminara@gmail.com'
13
13
  s.platform = Gem::Platform::RUBY
@@ -15,7 +15,6 @@ spec = Gem::Specification.new do |s|
15
15
  s.homepage = "http://github.com/tario/fastruby"
16
16
  s.add_dependency "RubyInline", "= 3.9.0"
17
17
  s.add_dependency "ruby_parser", "= 2.0.6"
18
- s.add_dependency "sexp_processor", "= 3.0.5"
19
18
  s.has_rdoc = true
20
19
  s.extra_rdoc_files = [ 'README' ]
21
20
  # s.rdoc_options << '--main' << 'README'
data/TODO CHANGED
@@ -20,7 +20,6 @@ To improve:
20
20
 
21
21
  Refactor:
22
22
 
23
- * hashes of methods on builder refactored into an only hash
24
23
  * refactor anonoymous methods (tip: use ruby format string for names)
25
24
  * Clean of duplicated code
26
25
  * Remove ruby inline explicit dependency
@@ -20,25 +20,33 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
20
20
  =end
21
21
  require "fastruby/translator"
22
22
  require "fastruby/inline_extension"
23
+ require "fastruby/method_extension"
23
24
  require "fastruby/logging"
24
25
 
25
26
  module FastRuby
26
- module BuilderModule
27
- def build(signature, method_name)
28
- tree = self.method_tree[method_name]
29
- locals = self.method_locals[method_name]
30
- options = self.method_options[method_name]
31
- mname = "_" + method_name.to_s + signature.map(&:internal_value).map(&:to_s).join
27
+
28
+ class Method
29
+ attr_accessor :tree
30
+ attr_accessor :locals
31
+ attr_accessor :options
32
+
33
+ def initialize(method_name, owner)
34
+ @method_name = method_name
35
+ @owner = owner
36
+ end
37
+
38
+ def build(signature)
39
+ mname = "_" + @method_name.to_s + signature.map(&:internal_value).map(&:to_s).join
32
40
 
33
41
  FastRuby.logger.info mname.to_s
34
42
 
35
43
  begin
36
- if (self.instance_method(mname))
37
- FastRuby.logger.info "NOT Building #{self}::#{method_name} for signature #{signature.inspect}, it's already done"
44
+ if (@owner.instance_method(mname))
45
+ FastRuby.logger.info "NOT Building #{self}::#{@method_name} for signature #{signature.inspect}, it's already done"
38
46
  return
39
47
  end
40
48
  rescue NameError
41
- FastRuby.logger.info "Building #{self}::#{method_name} for signature #{signature.inspect}"
49
+ FastRuby.logger.info "Building #{self}::#{@method_name} for signature #{signature.inspect}"
42
50
  end
43
51
 
44
52
  context = FastRuby::Context.new
@@ -57,41 +65,40 @@ module FastRuby
57
65
 
58
66
  context.infer_self = signature[0]
59
67
 
60
- c_code = context.to_c(tree)
68
+ c_code = context.to_c_method(tree)
61
69
 
62
- inline :C do |builder|
63
- builder.inc << context.extra_code
64
- builder.include "<node.h>"
65
- builder.c c_code
70
+ @owner.class_eval do
71
+ inline :C do |builder|
72
+ builder.inc << context.extra_code
73
+ builder.include "<node.h>"
74
+ builder.c c_code
75
+ end
66
76
  end
67
77
 
68
-
69
- ret = instance_method(mname)
78
+ ret = @owner.instance_method(mname)
70
79
 
71
80
  ret.extend MethodExtent
72
81
  ret.yield_signature = context.yield_signature
73
82
 
74
83
  ret
84
+
75
85
  end
76
86
 
77
87
  module MethodExtent
78
88
  attr_accessor :yield_signature
79
89
  end
90
+ end
80
91
 
81
- def method_tree
82
- @method_tree = Hash.new unless @method_tree
83
- @method_tree
84
- end
85
-
86
- def method_locals
87
- @method_locals = Hash.new unless @method_locals
88
- @method_locals
92
+ module BuilderModule
93
+ def build(signature, method_name)
94
+ fastruby_method(method_name.to_sym).build(signature)
89
95
  end
90
96
 
91
- def method_options
92
- @method_options = Hash.new unless @method_options
93
- @method_options
97
+ def fastruby_method(mname_)
98
+ mname = mname_.to_sym
99
+ @fastruby_method = Hash.new unless @fastruby_method
100
+ @fastruby_method[mname] = FastRuby::Method.new(mname,self) unless @fastruby_method[mname]
101
+ @fastruby_method[mname]
94
102
  end
95
-
96
103
  end
97
104
  end
@@ -19,23 +19,25 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
19
 
20
20
  =end
21
21
  require "rubygems"
22
- require "sexp_processor"
23
22
  require "set"
24
23
 
25
24
  module FastRuby
26
- class GetLocalsProcessor < SexpProcessor
25
+ class GetLocalsProcessor
27
26
 
28
27
  attr_reader :locals
29
28
 
30
29
  def initialize
31
- super()
32
- self.require_empty = false
33
30
  @locals = Set.new
34
31
  end
35
32
 
36
- def process_lasgn(tree)
33
+ def process(tree)
34
+ if tree.node_type == :lasgn
37
35
  @locals << tree[1]
38
- tree.dup
36
+ end
37
+
38
+ tree.select{|subtree| subtree.instance_of? Sexp}.each do |subtree|
39
+ process(subtree)
40
+ end
39
41
  end
40
42
 
41
43
  def self.get_locals(tree)
@@ -0,0 +1,36 @@
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
+
22
+ module FastRuby
23
+ module MethodExtension
24
+ def fastruby
25
+ owner.fastruby_method(name.to_sym)
26
+ end
27
+ end
28
+ end
29
+
30
+ class Method
31
+ include FastRuby::MethodExtension
32
+ end
33
+
34
+ class UnboundMethod
35
+ include FastRuby::MethodExtension
36
+ end
@@ -21,22 +21,120 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
21
21
  require "fastruby/translator"
22
22
  require "fastruby/builder"
23
23
  require "fastruby/getlocals"
24
+ require "fastruby/method_extension"
24
25
  require "ruby_parser"
25
26
  require "inline"
26
27
 
27
28
  # clean rubyinline cache
28
29
  system("rm -fr #{ENV["HOME"]}/.ruby_inline/*")
29
30
 
31
+ $top_level_binding = binding
32
+
33
+ module FastRuby
34
+ def self.encapsulate_tree(tree, method_name)
35
+ generated_tree = tree
36
+
37
+ if generated_tree[0] == :scope
38
+ generated_tree = s(:defn, method_name.to_sym, s(:args),
39
+ s(:scope, s(:block, generated_tree[1])))
40
+ elsif generated_tree[0] == :block
41
+ generated_tree = s(:defn, method_name.to_sym, s(:args),
42
+ s(:scope, generated_tree))
43
+ else
44
+ generated_tree = s(:defn, method_name.to_sym, s(:args),
45
+ s(:scope, s(:block, generated_tree)))
46
+ end
47
+
48
+ generated_tree
49
+ end
50
+ end
51
+
30
52
  class Object
31
- def self.fastruby(rubycode, *options_hashes)
32
- tree = RubyParser.new.parse rubycode
53
+
54
+ def fastruby(argument, *options_hashes)
55
+ tree = nil
56
+
57
+ if argument.instance_of? Sexp
58
+ tree = argument
59
+ elsif argument.instance_of? String
60
+ tree = RubyParser.new.parse(argument)
61
+ else
62
+ raise ArgumentError
63
+ end
64
+
65
+ if tree[0] == :class
66
+ classname = Object.to_class_name tree[1]
67
+
68
+ eval("
69
+ class #{classname}
70
+ end
71
+ ", $top_level_binding)
72
+
73
+ klass = eval(classname)
74
+
75
+ method_name = "_anonymous_" + rand(100000000000).to_s
76
+ $generated_tree = FastRuby.encapsulate_tree(tree[3],method_name)
77
+ $options_hashes = options_hashes
78
+
79
+ klass.class_eval do
80
+ class << self
81
+ fastruby $generated_tree, *$options_hashes
82
+ end
83
+ end
84
+
85
+ klass.send(method_name)
86
+ else
87
+ method_name = "_anonymous_" + rand(100000000000).to_s
88
+ Object.fastruby(FastRuby.encapsulate_tree(tree,method_name), *options_hashes)
89
+ send(method_name)
90
+ end
91
+ end
92
+
93
+ def self.fastruby(argument,*options_hashes)
94
+
95
+ tree = nil
96
+
97
+ if argument.instance_of? Sexp
98
+ tree = argument
99
+ elsif argument.instance_of? String
100
+ tree = RubyParser.new.parse(argument)
101
+ else
102
+ raise ArgumentError
103
+ end
104
+
105
+ if tree.node_type == :defn
106
+ fastruby_defn(tree,*options_hashes)
107
+ else
108
+ method_name = "_anonymous_" + rand(100000000000).to_s
109
+ $generated_tree = FastRuby.encapsulate_tree(tree,method_name)
110
+ $options_hashes = options_hashes
111
+
112
+ klass = self
113
+ klass.class_eval do
114
+ class << self
115
+ fastruby_defn($generated_tree,*$options_hashes)
116
+ end
117
+ end
118
+
119
+ send(method_name)
120
+ end
121
+
122
+ end
123
+
124
+ def self.fastruby_defn(tree, *options_hashes)
33
125
 
34
126
  options_hash = {:validate_lvar_types => true}
35
127
  options_hashes.each do |opt|
36
128
  options_hash.merge!(opt)
37
129
  end
38
130
 
39
- if tree[0] != :defn
131
+ if tree[0] == :block
132
+ (1..tree.size-1).each do |i|
133
+ fastruby(tree[i], *options_hashes)
134
+ end
135
+
136
+ return
137
+ elsif tree[0] != :defn
40
138
  raise ArgumentError, "Only definition of methods are accepted"
41
139
  end
42
140
 
@@ -50,7 +148,7 @@ class Object
50
148
  locals = Set.new
51
149
  locals << :self
52
150
 
53
- FastRuby::GetLocalsProcessor.get_locals(RubyParser.new.parse(rubycode)).each do |local|
151
+ FastRuby::GetLocalsProcessor.get_locals(tree).each do |local|
54
152
  locals << local
55
153
  end
56
154
 
@@ -64,9 +162,10 @@ class Object
64
162
  end
65
163
  end
66
164
 
67
- self_.method_tree[method_name] = tree
68
- self_.method_locals[method_name] = locals
69
- self_.method_options[method_name] = options_hash
165
+ fastrubym = self_.fastruby_method(method_name)
166
+ fastrubym.tree = tree
167
+ fastrubym.locals = locals
168
+ fastrubym.options = options_hash
70
169
 
71
170
  def hash.build(key)
72
171
  @klass.build(key, @method_name)
@@ -159,10 +258,33 @@ class Object
159
258
  end
160
259
  end
161
260
 
261
+ def internal_value
262
+ $refered_from_code_array = Array.new unless $refered_from_code_array
263
+ $refered_from_code_array << self
264
+
265
+ internal_value_
266
+ end
267
+
162
268
  inline :C do |builder|
163
- builder.c "VALUE internal_value() {
269
+ builder.c "VALUE internal_value_() {
164
270
  return INT2FIX(self);
165
271
  }"
166
272
  end
273
+
274
+ private
275
+ def self.to_class_name(argument)
276
+ if argument.instance_of? Symbol
277
+ argument.to_s
278
+ elsif argument.instance_of? Sexp
279
+ if argument[0] == :colon3
280
+ "::" + to_class_name(argument[1])
281
+ elsif argument[0] == :colon2
282
+ to_class_name(argument[1]) + "::" + to_class_name(argument[2])
283
+ elsif argument[0] == :const
284
+ to_class_name(argument[1])
285
+ end
286
+ end
287
+ end
288
+
167
289
  end
168
290
 
@@ -21,6 +21,7 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
21
21
  require "rubygems"
22
22
  require "inline"
23
23
  require "set"
24
+ require "fastruby/method_extension"
24
25
 
25
26
  module FastRuby
26
27
  class Context
@@ -133,9 +134,15 @@ module FastRuby
133
134
 
134
135
  convention = nil
135
136
 
136
- if recvtype.respond_to? :method_tree and inference_complete
137
+ if recvtype.respond_to? :fastruby_method and inference_complete
137
138
 
138
- if recvtype.method_tree[call_tree[2]]
139
+ method_tree = nil
140
+ begin
141
+ method_tree = recvtype.instance_method(call_tree[2]).fastruby.tree
142
+ rescue NoMethodError
143
+ end
144
+
145
+ if method_tree
139
146
  mobject = recvtype.build(signature, call_tree[2])
140
147
  yield_signature = mobject.yield_signature
141
148
 
@@ -394,25 +401,18 @@ module FastRuby
394
401
  to_c(subtree)
395
402
  }.join(";")
396
403
 
397
- if tree[-1][0] != :return
398
- str = str + ";last_expression = #{to_c(tree[-1])};"
399
- else
400
- str = str + ";#{to_c(tree[-1])};"
401
- end
404
+ if tree[-1]
402
405
 
403
- caller_code = proc { |name| "
404
- static VALUE #{name}(VALUE param) {
405
- #{@locals_struct} *plocals = (void*)param;
406
- VALUE last_expression;
407
-
408
- #{str}
406
+ if tree[-1][0] != :return
407
+ str = str + ";last_expression = #{to_c(tree[-1])};"
408
+ else
409
+ str = str + ";#{to_c(tree[-1])};"
410
+ end
411
+ end
409
412
 
410
- return last_expression;
411
- }
412
- "
413
- }
413
+ str << "return last_expression;"
414
414
 
415
- anonymous_function(caller_code) + "((VALUE)#{locals_pointer})"
415
+ inline_block str
416
416
  end
417
417
 
418
418
  def to_c_return(tree)
@@ -461,7 +461,52 @@ module FastRuby
461
461
  end
462
462
  end
463
463
 
464
+ def to_c_scope(tree)
465
+ if tree[1]
466
+ to_c(tree[1])
467
+ else
468
+ "Qnil"
469
+ end
470
+ end
471
+
472
+ def to_c_cdecl(tree)
473
+ if tree[1].instance_of? Symbol
474
+ inline_block "
475
+ // set constant #{tree[1].to_s}
476
+ VALUE val = #{to_c tree[2]};
477
+ rb_const_set(rb_cObject, #{tree[1].to_i}, val);
478
+ return val;
479
+ "
480
+ elsif tree[1].instance_of? Sexp
481
+
482
+ if tree[1].node_type == :colon2
483
+ inline_block "
484
+ // set constant #{tree[1].to_s}
485
+ VALUE val = #{to_c tree[2]};
486
+ VALUE klass = #{to_c tree[1][1]};
487
+ rb_const_set(klass, #{tree[1][2].to_i}, val);
488
+ return val;
489
+ "
490
+ elsif tree[1].node_type == :colon3
491
+ inline_block "
492
+ // set constant #{tree[1].to_s}
493
+ VALUE val = #{to_c tree[2]};
494
+ rb_const_set(rb_cObject, #{tree[1][1].to_i}, val);
495
+ return val;
496
+ "
497
+ end
498
+ end
499
+ end
500
+
501
+ def to_c_const(tree)
502
+ "rb_const_get(CLASS_OF(plocals->self), #{tree[1].to_i})"
503
+ end
504
+
464
505
  def to_c_defn(tree)
506
+ "rb_funcall(plocals->self,#{:fastruby.to_i},1,(VALUE)#{tree.internal_value})"
507
+ end
508
+
509
+ def to_c_method(tree)
465
510
  method_name = tree[1]
466
511
  args_tree = tree[2]
467
512
 
@@ -501,7 +546,7 @@ module FastRuby
501
546
  #{@locals_struct} locals;
502
547
  #{@locals_struct} *plocals = (void*)&locals;
503
548
  #{@block_struct} *pblock;
504
- VALUE last_expression;
549
+ VALUE last_expression = Qnil;
505
550
 
506
551
  #{args_tree[1..-1].map { |arg|
507
552
  "locals.#{arg} = #{arg};\n"
@@ -546,6 +591,33 @@ module FastRuby
546
591
  "_rb_ivar_set(#{locals_accessor}self,#{tree[1].to_i},#{to_c tree[2]})"
547
592
  end
548
593
 
594
+ def to_c_colon3(tree)
595
+ "rb_const_get_from(rb_cObject, #{tree[1].to_i})"
596
+ end
597
+ def to_c_colon2(tree)
598
+ inline_block "
599
+ VALUE klass = #{to_c tree[1]};
600
+
601
+ if (rb_is_const_id(#{tree[2].to_i})) {
602
+ switch (TYPE(klass)) {
603
+ case T_CLASS:
604
+ case T_MODULE:
605
+ return rb_const_get_from(klass, #{tree[2].to_i});
606
+ break;
607
+ default:
608
+ rb_raise(rb_eTypeError, \"%s is not a class/module\",
609
+ RSTRING(rb_obj_as_string(klass))->ptr);
610
+ break;
611
+ }
612
+ }
613
+ else {
614
+ return rb_funcall(klass, #{tree[2].to_i}, 0, 0);
615
+ }
616
+
617
+ return Qnil;
618
+ "
619
+ end
620
+
549
621
  def to_c_lasgn(tree)
550
622
  if options[:validate_lvar_types]
551
623
  klass = @infer_lvar_map[tree[1]]
@@ -601,31 +673,19 @@ module FastRuby
601
673
  condition_tree = tree[1]
602
674
  impl_tree = tree[2]
603
675
  else_tree = tree[3]
604
- code = "if (RTEST(#{to_c condition_tree})) {
605
- last_expression = #{to_c impl_tree};
606
- }
607
- "
608
-
609
- if (else_tree)
610
- code = code + " else {
611
- last_expression = #{to_c else_tree};
612
- }
613
- "
614
- end
615
676
 
616
- caller_code = proc { |name| "
617
- static VALUE #{name}(VALUE param) {
618
- #{@locals_struct} *plocals = (void*)param;
619
- VALUE last_expression = Qnil;
620
-
621
- #{code};
622
-
623
- return last_expression;
677
+ inline_block "
678
+ if (RTEST(#{to_c condition_tree})) {
679
+ last_expression = #{to_c impl_tree};
680
+ }#{else_tree ?
681
+ " else {
682
+ last_expression = #{to_c else_tree};
683
+ }
684
+ " : ""
624
685
  }
625
- "
626
- }
627
686
 
628
- anonymous_function(caller_code) + "((VALUE)#{locals_pointer})"
687
+ return last_expression;
688
+ "
629
689
  end
630
690
 
631
691
  def to_c_call(tree)
@@ -665,9 +725,15 @@ module FastRuby
665
725
 
666
726
  convention = nil
667
727
 
668
- if recvtype.respond_to? :method_tree and inference_complete
728
+ if recvtype.respond_to? :fastruby_method and inference_complete
669
729
 
670
- if recvtype.method_tree[tree[2]]
730
+ method_tree = nil
731
+ begin
732
+ method_tree = recvtype.instance_method(tree[2]).fastruby.tree
733
+ rescue NoMethodError
734
+ end
735
+
736
+ if method_tree
671
737
  mobject = recvtype.build(signature, tree[2])
672
738
  convention = :fastruby
673
739
  else
@@ -773,22 +839,21 @@ module FastRuby
773
839
  end
774
840
  end
775
841
 
776
- def to_c_while(tree)
777
- caller_code = proc { |name| "
778
- static VALUE #{name}(VALUE param) {
779
- #{@locals_struct} *plocals = (void*)param;
780
- VALUE last_expression;
842
+ def to_c_class(tree)
843
+ inline_block("
844
+ rb_funcall(plocals->self,#{:fastruby.to_i},1,(VALUE)#{tree.internal_value});
845
+ return Qnil;
846
+ ")
781
847
 
848
+ end
849
+
850
+ def to_c_while(tree)
851
+ inline_block("
782
852
  while (#{to_c tree[1]}) {
783
853
  #{to_c tree[2]};
784
854
  }
785
-
786
855
  return Qnil;
787
- }
788
- "
789
- }
790
-
791
- anonymous_function(caller_code) + "((VALUE)#{locals_pointer})"
856
+ ")
792
857
  end
793
858
 
794
859
  def infer_type(recv)
@@ -850,6 +915,20 @@ module FastRuby
850
915
  end
851
916
  end
852
917
 
918
+ def inline_block(code)
919
+ caller_code = proc { |name| "
920
+ static VALUE #{name}(VALUE param) {
921
+ #{@locals_struct} *plocals = (void*)param;
922
+ VALUE last_expression = Qnil;
923
+
924
+ #{code}
925
+ }
926
+ "
927
+ }
928
+
929
+ anonymous_function(caller_code) + "((VALUE)#{locals_pointer})"
930
+ end
931
+
853
932
  inline :C do |builder|
854
933
  builder.include "<node.h>"
855
934
  builder.c "VALUE getaddress(VALUE method) {
@@ -0,0 +1,138 @@
1
+ require "fastruby"
2
+
3
+ describe FastRuby, "fastruby" do
4
+ it "should compile fastruby code with two methods" do
5
+ class ::E1
6
+ fastruby "
7
+ def foo
8
+ 12
9
+ end
10
+
11
+ def bar
12
+ 15
13
+ end
14
+ "
15
+ end
16
+
17
+ e1 = ::E1.new
18
+ e1.foo.should be == 12
19
+ e1.bar.should be == 15
20
+ end
21
+
22
+ it "should compile fastruby code with class definition and one method" do
23
+ fastruby "
24
+ class ::E2
25
+ def foo
26
+ 12
27
+ end
28
+ end
29
+ "
30
+
31
+ e2 = ::E2.new
32
+ e2.foo.should be == 12
33
+ end
34
+
35
+ it "should compile fastruby code with class definition and two methods" do
36
+ fastruby "
37
+ class ::E3
38
+ def foo
39
+ 12
40
+ end
41
+ def bar
42
+ 15
43
+ end
44
+ end
45
+ "
46
+
47
+ e3 = ::E3.new
48
+ e3.foo.should be == 12
49
+ e3.bar.should be == 15
50
+ end
51
+
52
+ class ::E4
53
+ def foo
54
+ end
55
+ end
56
+
57
+ it "should compile standalone code and execute it inmediatly" do
58
+ $e4 = ::E4
59
+ fastruby "
60
+ require 'fastruby'
61
+ $e4.new.foo
62
+ "
63
+ end
64
+
65
+ it "should compile standalone code togheter with classes and execute it inmediatly" do
66
+ $e4 = ::E4
67
+ fastruby "
68
+ require 'fastruby'
69
+ $e4.new.foo
70
+
71
+ class ::E5
72
+ def foo
73
+ 12
74
+ end
75
+ def bar
76
+ 15
77
+ end
78
+ end
79
+
80
+ "
81
+
82
+ e5 = ::E5.new
83
+ e5.foo.should be == 12
84
+ e5.bar.should be == 15
85
+ end
86
+
87
+ class ::E6
88
+ attr_reader :called
89
+ def foo
90
+ @called = true
91
+ end
92
+ end
93
+ it "should execute standalone code" do
94
+ $e6 = ::E6.new
95
+ fastruby "
96
+ $e6.foo
97
+ "
98
+ $e6.called.should be == true
99
+ end
100
+
101
+ it "should execute standalone code inside a class definition" do
102
+ $e6_1 = ::E6.new
103
+ fastruby "
104
+ class X
105
+ $e6_1.foo
106
+ end
107
+ "
108
+ $e6_1.called.should be == true
109
+ end
110
+
111
+ it "should allow define multiple classes in only one call to fastruby" do
112
+ fastruby "
113
+ class E7X
114
+ end
115
+ class E7Y
116
+ end
117
+ "
118
+ end
119
+
120
+ it "should allow define multiple classes with methods in only one call to fastruby" do
121
+ fastruby "
122
+ class E8X
123
+ def foo
124
+ 123
125
+ end
126
+ end
127
+ class E8Y
128
+ def bar
129
+ 456
130
+ end
131
+ end
132
+ "
133
+
134
+ E8X.new.foo.should be == 123
135
+ E8Y.new.bar.should be == 456
136
+ end
137
+
138
+ end
@@ -60,4 +60,113 @@ describe FastRuby, "fastruby" do
60
60
  u4.foo.should be == 88
61
61
  end
62
62
 
63
+ class ::U5
64
+ fastruby "
65
+ def foo
66
+ U5C = 11
67
+ end
68
+ "
69
+ end
70
+
71
+ it "should write constants" do
72
+ ::U5.new.foo
73
+
74
+ U5C.should be == 11
75
+ end
76
+
77
+ class ::U6
78
+ fastruby "
79
+ def foo
80
+ U6C
81
+ end
82
+ "
83
+ end
84
+
85
+ it "should read constants" do
86
+ ::U6C = 11
87
+ ::U6.new.foo.should be == 11
88
+ end
89
+
90
+
91
+ class ::U7
92
+ class U71
93
+ fastruby "
94
+ def foo
95
+ U7C = 11
96
+ end
97
+ "
98
+ end
99
+ end
100
+
101
+ it "should write nested constants" do
102
+ ::U7::U71.new.foo
103
+ ::U7::U71::U7C.should be == 11
104
+
105
+ lambda {
106
+ ::U7::U7C.should be == 11
107
+ }.should_not raise_error
108
+ end
109
+
110
+ class ::U8
111
+ class U81
112
+ fastruby "
113
+ def foo
114
+ U8C
115
+ end
116
+ "
117
+ end
118
+ end
119
+ it "should read nested constants" do
120
+ ::U8::U81::U8C = 11
121
+ ::U8::U81.new.foo.should be == 11
122
+ end
123
+
124
+ class ::U9
125
+ fastruby "
126
+ def foo
127
+ ::U9C
128
+ end
129
+ "
130
+ end
131
+ it "should read constant with colon3" do
132
+ ::U9C = 21
133
+ ::U9.new.foo.should be == 21
134
+ end
135
+
136
+ it "should write constant with colon3" do
137
+ class ::U10
138
+ fastruby "
139
+ ::U10C = 51
140
+ def foo
141
+ end
142
+ "
143
+ end
144
+ ::U10.new.foo
145
+ ::U10C.should be == 51
146
+ end
147
+
148
+ class ::U11
149
+ fastruby "
150
+ def foo
151
+ ::U11::U11C
152
+ end
153
+ "
154
+ end
155
+ it "should read constant with colon3 and colon2" do
156
+ ::U11::U11C = 21
157
+ ::U11.new.foo.should be == 21
158
+ end
159
+
160
+ it "should write constant with colon3 and colon2" do
161
+ class ::U12
162
+ fastruby "
163
+ ::U12::U12C = 51
164
+ def foo
165
+ end
166
+ "
167
+ end
168
+ ::U12.new.foo
169
+ ::U12::U12C.should be == 51
170
+ end
171
+
63
172
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastruby
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dario Seminara
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-31 00:00:00 -03:00
18
+ date: 2011-08-03 00:00:00 -03:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -50,22 +50,6 @@ dependencies:
50
50
  version: 2.0.6
51
51
  type: :runtime
52
52
  version_requirements: *id002
53
- - !ruby/object:Gem::Dependency
54
- name: sexp_processor
55
- prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - "="
60
- - !ruby/object:Gem::Version
61
- hash: 13
62
- segments:
63
- - 3
64
- - 0
65
- - 5
66
- version: 3.0.5
67
- type: :runtime
68
- version_requirements: *id003
69
53
  description:
70
54
  email: robertodarioseminara@gmail.com
71
55
  executables: []
@@ -92,12 +76,14 @@ files:
92
76
  - lib/fastruby/getlocals.rb
93
77
  - lib/fastruby/translator.rb
94
78
  - lib/fastruby/object.rb
79
+ - lib/fastruby/method_extension.rb
95
80
  - lib/fastruby.rb
96
81
  - spec/variable_spec.rb
97
82
  - spec/control_spec.rb
98
83
  - spec/expression_spec.rb
99
84
  - spec/base_spec.rb
100
85
  - spec/block_spec.rb
86
+ - spec/sugar_spec.rb
101
87
  - spec/literal_spec.rb
102
88
  - spec/integrity_spec.rb
103
89
  - LICENSE