fastruby 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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