myco 0.1.7 → 0.1.8

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/lib/myco/bootstrap/add_method.rb +38 -0
  3. data/lib/myco/bootstrap/component.rb +43 -21
  4. data/lib/myco/bootstrap/find_constant.rb +73 -25
  5. data/lib/myco/bootstrap/instance.rb +96 -25
  6. data/lib/myco/bootstrap/meme.rb +18 -12
  7. data/lib/myco/bootstrap/tuple.rb +13 -0
  8. data/lib/myco/bootstrap/undefined.rb +9 -0
  9. data/lib/myco/bootstrap/void.rb +5 -4
  10. data/lib/myco/bootstrap.my +24 -13
  11. data/lib/myco/bootstrap.my.rb +41 -4
  12. data/lib/myco/bootstrap.rb +4 -0
  13. data/lib/myco/code_loader.rb +11 -9
  14. data/lib/myco/code_tools/AST/Block.my.rb +2 -2
  15. data/lib/myco/code_tools/AST/ConstantAccess.my.rb +4 -4
  16. data/lib/myco/code_tools/AST/ConstantAssignment.my.rb +4 -4
  17. data/lib/myco/code_tools/AST/Invoke.my +1 -1
  18. data/lib/myco/code_tools/AST/Invoke.my.rb +1 -1
  19. data/lib/myco/code_tools/AST/Node.my +2 -4
  20. data/lib/myco/code_tools/AST/Node.my.rb +3 -3
  21. data/lib/myco/code_tools/AST/PipeOperator.my.rb +1 -1
  22. data/lib/myco/code_tools/AST/ToRuby.my.rb +8 -8
  23. data/lib/myco/code_tools/AST/misc.my.rb +1 -1
  24. data/lib/myco/code_tools/Parser.my +8 -15
  25. data/lib/myco/code_tools/Parser.my.rb +8 -14
  26. data/lib/myco/code_tools/parser/MycoBuilder.my +3 -4
  27. data/lib/myco/code_tools/parser/MycoBuilder.my.rb +5 -6
  28. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my +8 -4
  29. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my.rb +5 -5
  30. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my +2 -2
  31. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my.rb +12 -12
  32. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeParser.my +54 -44
  33. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeParser.my.rb +69 -83
  34. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my +18 -8
  35. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my.rb +24 -10
  36. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Machine.my.rb +1 -1
  37. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my +1 -1
  38. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my.rb +1 -2
  39. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my +1 -1
  40. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my.rb +1 -1
  41. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my +3 -3
  42. data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my.rb +5 -6
  43. data/lib/myco/code_tools/parser/pegleromyces/spec/BasicSpec.my +35 -0
  44. data/lib/myco/code_tools/parser/pegleromyces/spec/BasicSpec.my.rb +35 -0
  45. data/lib/myco/code_tools/parser/pegleromyces/spec/Builder.test.my +10 -0
  46. data/lib/myco/code_tools/parser/pegleromyces/spec/Builder.test.my.rb +9 -0
  47. data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeInstructions.test.my +10 -0
  48. data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeInstructions.test.my.rb +9 -0
  49. data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeParser.test.my +81 -0
  50. data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeParser.test.my.rb +209 -0
  51. data/lib/myco/code_tools/parser/pegleromyces/spec/Constructions.test.my +229 -0
  52. data/lib/myco/code_tools/parser/pegleromyces/spec/Constructions.test.my.rb +663 -0
  53. data/lib/myco/code_tools/parser/pegleromyces/spec/Grammar.test.my +10 -0
  54. data/lib/myco/code_tools/parser/pegleromyces/spec/Grammar.test.my.rb +9 -0
  55. data/lib/myco/code_tools/parser/pegleromyces/spec/Instructions.test.my +10 -0
  56. data/lib/myco/code_tools/parser/pegleromyces/spec/Instructions.test.my.rb +9 -0
  57. data/lib/myco/code_tools/parser/pegleromyces/spec/Machine.test.my +13 -0
  58. data/lib/myco/code_tools/parser/pegleromyces/spec/Machine.test.my.rb +20 -0
  59. data/lib/myco/code_tools/parser/pegleromyces/spec/Parser.test.my +54 -0
  60. data/lib/myco/code_tools/parser/pegleromyces/spec/Parser.test.my.rb +215 -0
  61. data/lib/myco/code_tools/parser/pegleromyces/spec/Patterns.test.my +156 -0
  62. data/lib/myco/code_tools/parser/pegleromyces/spec/Patterns.test.my.rb +334 -0
  63. data/lib/myco/code_tools/parser/pegleromyces/spec/Processor.test.my +10 -0
  64. data/lib/myco/code_tools/parser/pegleromyces/spec/Processor.test.my.rb +9 -0
  65. data/lib/myco/code_tools/parser/pegleromyces/spec/run.my +20 -0
  66. data/lib/myco/code_tools/parser/pegleromyces/spec/run.my.rb +16 -0
  67. data/lib/myco/core/BasicDecorators.my +19 -11
  68. data/lib/myco/core/BasicDecorators.my.rb +24 -20
  69. data/lib/myco/core/BasicObject.my +12 -7
  70. data/lib/myco/core/BasicObject.my.rb +50 -44
  71. data/lib/myco/core/Category.my +12 -2
  72. data/lib/myco/core/Category.my.rb +15 -7
  73. data/lib/myco/core/Decorator.my +1 -1
  74. data/lib/myco/core/Decorator.my.rb +8 -10
  75. data/lib/myco/core/FileToplevel.my +3 -3
  76. data/lib/myco/core/FileToplevel.my.rb +4 -6
  77. data/lib/myco/core/Object.my +7 -10
  78. data/lib/myco/core/Object.my.rb +11 -17
  79. data/lib/myco/core/Ruby.my +6 -0
  80. data/lib/myco/core/Ruby.my.rb +16 -0
  81. data/lib/myco/core/Switch.my +1 -1
  82. data/lib/myco/core/Switch.my.rb +1 -1
  83. data/lib/myco/core.my +4 -0
  84. data/lib/myco/core.my.rb +7 -0
  85. data/lib/myco/dev/call_sites.rb +39 -0
  86. data/lib/myco/dev/counter.rb +26 -0
  87. data/lib/myco/dev.rb +3 -0
  88. data/lib/myco/eval.rb +1 -1
  89. data/lib/myco/tools/BasicCommand.my.rb +1 -1
  90. data/lib/myco/version.rb +1 -1
  91. data/lib/myco.rb +2 -3
  92. metadata +53 -20
  93. data/lib/myco/bootstrap/evaluator.rb +0 -58
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c9a3ec14044d47105eb0c1448e65c08cebedfd9
4
- data.tar.gz: b24c8a056f1df9e441dccc851b1eca9bd4293ad1
3
+ metadata.gz: e8031fe74a54c47a6c344eef7a2c5e13855bf2bc
4
+ data.tar.gz: c2f129e293c295731e643372d5add7704fdf9252
5
5
  SHA512:
6
- metadata.gz: 59af162beb7b9ce35677eceba813cd1fbf35f73ce4630bac4e0afd87636f09a0e5973c1a3e7f600d99bcf07cffea296c915aa87d73f37360f0ac0f98d1c770b3
7
- data.tar.gz: 37ad5495fa33dd8fa6afb55eff7fa27a221a138f61dcc30d053984c67ad340d3121af3b9b535f152c78f31bea4f6f7d8f7e445fb0887aeee86d7f64259d6ef9d
6
+ metadata.gz: 4fb206f4849977fcfe676b435b76de6d0145cc96507456fde0071f63b291f5743deeac07729f3d30717a58ac94acf55465266d32599395e76fc4e17249f18a7f
7
+ data.tar.gz: 2735f64a252ba18ab5b43ddb62e0f3b96772902146dcc645a9dfb1754d99eb0609a8449d06469e45600b82908702b3c9219f3032f54cebaf7df8acfbba0d03ac
@@ -0,0 +1,38 @@
1
+
2
+ module Myco
3
+ # In Myco, try to always use Myco.add_method instead of Rubinius.add_method
4
+ # to bypass all of the Ruby-specific logic therein.
5
+
6
+ def self.add_method mod, name, executable
7
+ mod.method_table.store(name, executable, :public)
8
+ Rubinius::VM.reset_method_cache(mod, name)
9
+ end
10
+
11
+ # TODO: override Module#define_method in Component to use this?
12
+ # TODO: override Module#thunk_method in Component to use this?
13
+ # TODO: override Module#dynamic_method in Component to use this?
14
+
15
+ # Use instead of Module#thunk_method
16
+ def self.add_thunk_method mod, name, value
17
+ add_method(mod, name, Rubinius::Thunk.new(value))
18
+ end
19
+
20
+ # Use instead of Module#dynamic_method
21
+ def self.add_dynamic_method mod, name, file="(dynamic)", line=1
22
+ g = Rubinius::ToolSets::Runtime::Generator.new
23
+ g.name = name.to_sym
24
+ g.file = file.to_sym
25
+ g.set_line Integer(line)
26
+
27
+ yield g
28
+
29
+ g.close
30
+ g.use_detected
31
+ g.encode
32
+
33
+ code = g.package Rubinius::CompiledCode
34
+ code.scope = Rubinius::ConstantScope.new(mod, Rubinius::ConstantScope.new(Myco))
35
+
36
+ add_method(mod, name, code)
37
+ end
38
+ end
@@ -8,7 +8,7 @@ module Myco
8
8
 
9
9
  attr_reader :parent
10
10
  attr_reader :parent_meme
11
- attr_reader :categories
11
+ attr_reader :main
12
12
 
13
13
  attr_reader :constant_scope
14
14
 
@@ -53,12 +53,15 @@ module Myco
53
53
  this.instance_eval {
54
54
  @super_components = super_components
55
55
  @parent = parent
56
+ @main = self
56
57
  @filename = filename
57
58
  @line = line
58
59
  @basename = File.basename @filename
59
60
  @dirname = File.dirname @filename
60
- @categories = { main: this }
61
61
  @parent_meme = parent_meme
62
+ @categories = Rubinius::LookupTable.new
63
+
64
+ Myco.add_thunk_method(self, :__component__, self)
62
65
  }
63
66
 
64
67
  all_categories = Hash.new { |h,k| h[k] = Array.new }
@@ -67,33 +70,44 @@ module Myco
67
70
  this.include other
68
71
 
69
72
  if other.is_a? Component
70
- other.categories.each do |name, cat|
71
- all_categories[name] << cat
73
+ other.each_category do |name, cat|
74
+ all_categories[name] << cat unless name == :main
72
75
  end
73
76
  end
74
77
  end
75
78
 
76
79
  all_categories.each do |name, supers|
77
- if name == :main
78
- this.categories[name] = this
79
- else
80
- this.categories[name] = this.__new_category__ name, supers, filename, line
81
- end
80
+ this.__new_category__(name, supers, filename, line)
82
81
  end
83
82
 
84
83
  this
85
84
  end
86
85
 
87
- # Get a reference to the main Component from main or from any inner Category
88
- def main
89
- self < Category ? parent : self
86
+ def __get_category__ name
87
+ if name == :main
88
+ self
89
+ elsif @categories.key?(name)
90
+ @categories[name]
91
+ else
92
+ # If the category doesn't exist, look for one in the super components.
93
+ # This allows for categories to be implicitly inherited after the fact.
94
+ super_cats = []
95
+ @super_components.each { |sup|
96
+ sup.respond_to?(:__get_category__) && (
97
+ cat = sup.__get_category__(name)
98
+ cat && super_cats.push(cat)
99
+ )
100
+ }
101
+ super_cats.any? && __new_category__(name, super_cats, @filename, @line)
102
+ end
90
103
  end
91
104
 
92
- def __category__ name
93
- @categories[name] ||= __new_category__(name)
105
+ def __set_category__ name, cat
106
+ @categories[name] = cat
107
+ cat
94
108
  end
95
109
 
96
- def __new_category__ name, super_cats=[Category], filename=nil, line=nil
110
+ def __new_category__ name, super_cats=[::Myco::Category], filename=nil, line=nil
97
111
  # Get the filename and line from the VM if not specified
98
112
  if !filename || !line
99
113
  location = Rubinius::VM.backtrace(2,false).first
@@ -102,12 +116,23 @@ module Myco
102
116
  end
103
117
 
104
118
  category = Component.new super_cats, self, filename, line
119
+ category.instance_variable_set(:@main, self)
105
120
  category.__name__ = name
106
121
  category_instance = category.instance
107
122
  meme = declare_meme(name) { category_instance }
108
123
  meme.cache = true
109
124
 
110
- category
125
+ __set_category__(name, category)
126
+ end
127
+
128
+ def __category__ name
129
+ __get_category__(name) || __new_category__(name)
130
+ end
131
+
132
+ alias_method :category, :__category__
133
+
134
+ def each_category &block
135
+ @categories.each &block
111
136
  end
112
137
 
113
138
  def instance
@@ -115,9 +140,8 @@ module Myco
115
140
  yield @instance if block_given?
116
141
  else
117
142
  @instance = allocate
118
- @instance.instance_variable_set(:@component, self)
119
143
  yield @instance if block_given?
120
- @instance.__signal__ :creation if @instance.respond_to? :__signal__
144
+ @instance.__signal__ :creation if Rubinius::Type.object_respond_to?(@instance, :__signal__)
121
145
  end
122
146
 
123
147
  @instance
@@ -149,7 +173,6 @@ module Myco
149
173
  # TODO: re-evaluate usefulness and possibly remove in favor of using extend.
150
174
  def inject_into object
151
175
  object.extend InstanceMethods unless object.is_a? InstanceMethods
152
- object.instance_variable_set(:@component, self)
153
176
  extend_object object
154
177
  object
155
178
  end
@@ -158,8 +181,7 @@ module Myco
158
181
  # call setters on the instance with the values given by kwargs.
159
182
  def new **kwargs
160
183
  instance = allocate
161
- instance.instance_variable_set(:@component, self)
162
- kwargs.each { |key,val| instance.send :"#{key}=", val }
184
+ kwargs.each { |key,val| instance.__send__ :"#{key}=", val }
163
185
  instance
164
186
  end
165
187
  end
@@ -6,6 +6,16 @@ module Rubinius
6
6
  attr_reader :myco_component
7
7
  attr_reader :myco_category
8
8
  attr_reader :myco_meme
9
+ attr_reader :is_myco_level
10
+
11
+ def inspect_list
12
+ this_item = "0x#{object_id.to_s(16)} #{self.module}"
13
+ parent ? "#{this_item}, #{parent.inspect_list}" : this_item
14
+ end
15
+
16
+ def inspect
17
+ "#<#{self.class}:#{inspect_list}>"
18
+ end
9
19
 
10
20
  # TODO: Can this be more graceful and more eager?
11
21
  def myco_file
@@ -16,6 +26,13 @@ module Rubinius
16
26
  @myco_levels ||= (parent ? parent.myco_levels.dup : [])
17
27
  end
18
28
 
29
+ def myco_parent
30
+ parent = parent()
31
+ parent ? (
32
+ parent.is_myco_level ? parent : parent.myco_parent
33
+ ) : nil
34
+ end
35
+
19
36
  def set_myco_file
20
37
  raise "myco_file already set for thie ConstantScope" \
21
38
  if @myco_file
@@ -25,6 +42,7 @@ module Rubinius
25
42
  @myco_file.instance_variable_set(:@constant_scope, self)
26
43
 
27
44
  myco_levels << @myco_file
45
+ @is_myco_level = true
28
46
  end
29
47
 
30
48
  def set_myco_component
@@ -34,6 +52,7 @@ module Rubinius
34
52
  @myco_file = parent.myco_file
35
53
 
36
54
  myco_levels << @myco_component
55
+ @is_myco_level = true
37
56
  end
38
57
 
39
58
  def set_myco_category
@@ -44,6 +63,7 @@ module Rubinius
44
63
  @myco_file = parent.myco_file
45
64
 
46
65
  myco_levels << @myco_category
66
+ @is_myco_level = true
47
67
  end
48
68
 
49
69
  def set_myco_meme value
@@ -51,10 +71,61 @@ module Rubinius
51
71
  if @myco_meme
52
72
  @myco_meme = value
53
73
  end
74
+
75
+ def get_myco_constant_ref(name)
76
+ @myco_constant_refs ||= Rubinius::LookupTable.new
77
+ @myco_constant_refs[name] ||= ::Myco::ConstantReference.new(name, self)
78
+ end
54
79
  end
55
80
  end
56
81
 
57
82
  module Myco
83
+ class ConstantReference
84
+ class << self
85
+ attr_accessor :verbose
86
+ end
87
+
88
+ attr_reader :name
89
+ attr_reader :scope
90
+
91
+ def initialize name, scope
92
+ @name = name
93
+ @scope = scope
94
+ end
95
+
96
+ def value
97
+ serial = @serial
98
+ new_serial = Rubinius.global_serial
99
+
100
+ if serial && serial >= new_serial
101
+ @value
102
+ else
103
+ @serial = new_serial
104
+ @value = find_value
105
+ end
106
+ end
107
+
108
+ def find_value
109
+ bucket = find_constant_bucket_in_module(scope.module, name)
110
+ bucket ? bucket.constant : (
111
+ parent = scope.myco_parent
112
+ parent ? parent.get_myco_constant_ref(name).value : (
113
+ Rubinius::Type.const_get(::Myco, name)
114
+ )
115
+ )
116
+ end
117
+
118
+ def find_constant_bucket_in_module mod, name
119
+ current = mod
120
+ while current and Rubinius::Type.object_kind_of? current, Module
121
+ # p current if Myco::ConstantReference.verbose
122
+ return bucket if bucket = current.constant_table.lookup(name)
123
+ current = current.direct_superclass
124
+ end
125
+
126
+ return nil
127
+ end
128
+ end
58
129
 
59
130
  # Get the "current" ConstantScope (from the caller's perspective)
60
131
  def self.cscope
@@ -62,29 +133,6 @@ module Myco
62
133
  end
63
134
 
64
135
  def self.find_constant(name, scope=Rubinius::ConstantScope.of_sender)
65
- # TODO: optimize this constant search
66
- # (it currently searches each ancestor of each nested component scope)
67
- bucket = nil
68
- scope.myco_levels.detect { |level|
69
- bucket = find_constant_bucket_in_module(level, name)
70
- }
71
- bucket ? bucket.constant : Rubinius::Type.const_get(::Myco, name)
72
- end
73
-
74
- def self.find_constant_bucket_in_module(mod, name, inherit=true)
75
- current = mod
76
-
77
- while current and Rubinius::Type.object_kind_of? current, Module
78
- if bucket = current.constant_table.lookup(name)
79
- return bucket
80
- end
81
-
82
- return nil unless inherit
83
-
84
- current = current.direct_superclass
85
- end
86
-
87
- return nil
136
+ scope.get_myco_constant_ref(name).value
88
137
  end
89
-
90
- end
138
+ end
@@ -1,50 +1,121 @@
1
1
 
2
2
  module Myco
3
- module InstanceMethods
4
- include ::Kernel
3
+ module PrimitiveInstanceMethods
4
+ # These methods are taken from Ruby's Kernel.
5
+ # TODO: Audit which of these should remain.
5
6
 
6
- def to_s
7
- "#<#{@component.to_s}>"
7
+ def __set_ivar__ sym, value
8
+ Rubinius.primitive :object_set_ivar
9
+ ::Kernel.raise ::PrimitiveFailure, "Rubinius.primitive :object_set_ivar failed"
8
10
  end
9
11
 
10
- def inspect
11
- vars = (instance_variables - [:@component]).map { |var|
12
- [var.to_s[1..-1], instance_variable_get(var).inspect].join(": ")
13
- }
14
- vars = vars.any? ? (" " + vars.join(", ")) : ""
15
- "#<#{@component.to_s}#{vars}>"
12
+ def __get_ivar__ sym
13
+ Rubinius.primitive :object_get_ivar
14
+ ::Kernel.raise ::PrimitiveFailure, "Rubinius.primitive :object_get_ivar failed"
15
+ end
16
+
17
+ def __ivar_defined__ sym
18
+ Rubinius.primitive :object_ivar_defined
19
+ ::Kernel.raise ::PrimitiveFailure, "Rubinius.primitive :object_ivar_defined failed"
20
+ end
21
+
22
+ def __kind_of__ mod
23
+ Rubinius.primitive :object_kind_of
24
+ ::Kernel.raise ::PrimitiveFailure, "Rubinius.primitive :object_kind_of failed"
25
+ end
26
+
27
+ def __class__
28
+ Rubinius.primitive :object_class
29
+ ::Kernel.raise ::PrimitiveFailure, "Rubinius.primitive :object_class failed"
30
+ end
31
+
32
+ def __dup__ # TODO: remove
33
+ copy = Rubinius::Type.object_class(self).allocate
34
+ Rubinius.invoke_primitive :object_copy_object, copy, self
35
+ copy
36
+ end
37
+
38
+ def __hash__
39
+ Rubinius.primitive :object_hash
40
+ ::Kernel.raise ::PrimitiveFailure, "Rubinius.primitive :object_hash failed"
41
+ end
42
+
43
+ # These methods are taken from Ruby's BasicObject.
44
+ # TODO: Audit which of these should remain.
45
+
46
+ def __send__ message, *args
47
+ Rubinius.primitive :object_send
48
+ ::Kernel.raise ::PrimitiveFailure, "Rubinius.primitive :object_send failed"
49
+ end
50
+
51
+ def __id__
52
+ Rubinius.primitive :object_id
53
+ ::Kernel.raise ::PrimitiveFailure, "Rubinius.primitive :object_id failed"
16
54
  end
17
55
 
18
- # TODO: remove (for now it makes debugging easier with RSpec)
19
- def pretty_print str
20
- p str
56
+ def __ivar_names__
57
+ Rubinius.primitive :object_ivar_names
58
+ ::Kernel.raise ::PrimitiveFailure, "Rubinius.primitive :object_ivar_names failed"
21
59
  end
22
60
 
23
- attr_reader :component
61
+ def __equal__(other)
62
+ Rubinius.primitive :object_equal
63
+ ::Kernel.raise ::PrimitiveFailure, "Rubinius.primitive :object_equal failed"
64
+ end
65
+ end
66
+
67
+ module InstanceMethods
68
+ include PrimitiveInstanceMethods
69
+
70
+ def component
71
+ __component__
72
+ end
24
73
 
25
74
  def parent
26
- @component.parent && @component.parent.instance
75
+ __component__.parent && __component__.parent.instance
27
76
  end
28
77
 
29
78
  def parent_meme
30
- @component.parent_meme
79
+ __component__.parent_meme
31
80
  end
32
81
 
33
82
  def memes
34
- @component.memes
83
+ __component__.memes
35
84
  end
36
85
  end
37
86
 
38
- class Instance < ::BasicObject
87
+ Instance = Class.new nil do
39
88
  include InstanceMethods
40
89
 
41
- # # TODO: clean this up
42
- # prepend (::Module.new {
43
- def method_missing name, *args
44
- msg = "#{to_s} has no method called '#{name}'"
45
- ::Ruby::Kernel.raise ::NoMethodError.new(msg, name, args)
46
- end
47
- # })
90
+ # These are not included in InstanceMethods because they should not shadow
91
+ # existing method definitions when extended into an existing object.
92
+
93
+ def method_missing name, *args
94
+ msg = "#{to_s} has no method called '#{name}'"
95
+ ::Kernel.raise ::NoMethodError.new(msg, name, args)
96
+ end
97
+
98
+ def to_s
99
+ "#<#{__component__.to_s}>"
100
+ end
101
+
102
+ def inspect
103
+ vars = __ivar_names__.map { |var|
104
+ [var.to_s[1..-1], __get_ivar__(var).inspect].join(": ")
105
+ }
106
+ vars = vars.any? ? (" " + vars.join(", ")) : ""
107
+ "#<#{__component__.to_s}#{vars}>"
108
+ end
109
+
110
+ alias_method :hash, :__hash__ # TODO: remove?
111
+ alias_method :equal?, :__equal__ # TODO: remove?
112
+ alias_method :==, :__equal__ # TODO: remove?
48
113
 
114
+ def != other
115
+ self == other ? false : true
116
+ end
117
+
118
+ alias_method :"!", :false?
49
119
  end
120
+
50
121
  end
@@ -2,7 +2,7 @@
2
2
  module Myco
3
3
  module MemeBindable
4
4
  def memes
5
- @memes ||= {}
5
+ @memes ||= Rubinius::LookupTable.new
6
6
  end
7
7
 
8
8
  def declare_meme name, decorations=[], body=nil, cscope=nil, &blk
@@ -15,11 +15,11 @@ module Myco
15
15
  meme.body = body || blk
16
16
 
17
17
  decorations = decorations.map do |decoration, arguments|
18
- decorators = main.categories[:decorators]
18
+ decorators = main.category(:decorators)
19
19
  decorators = decorators && decorators.instance
20
20
 
21
- unless decorators.respond_to?(decoration)
22
- reason = if decorators.nil?
21
+ unless Rubinius::Type.object_respond_to?(decorators, decoration)
22
+ reason = if !decorators
23
23
  "#{self} has no [decorators] category."
24
24
  else
25
25
  "Known decorators in #{decorators}: " \
@@ -29,7 +29,7 @@ module Myco
29
29
  "Unknown decorator for #{self}##{name}: '#{decoration}'. #{reason}"
30
30
  end
31
31
 
32
- [decorators.send(decoration), arguments]
32
+ [decorators.__send__(decoration), arguments]
33
33
  end
34
34
  decorations.each { |deco, args| deco.transforms.apply meme, *args }
35
35
  decorations.each { |deco, args| deco.apply meme, *args }
@@ -76,6 +76,10 @@ module Myco
76
76
 
77
77
  def body= value
78
78
  case value
79
+ when Rubinius::BlockEnvironment::AsMethod
80
+ @body = value
81
+ when Rubinius::Thunk
82
+ @body = value
79
83
  when Rubinius::Executable
80
84
  @body = value
81
85
  @body.scope.set_myco_meme self
@@ -131,6 +135,9 @@ module Myco
131
135
 
132
136
  @target.memes[@name] = self
133
137
 
138
+ # TODO: consider removing
139
+ @target.include(::Myco::PrimitiveInstanceMethods) unless @target < ::Myco::PrimitiveInstanceMethods
140
+
134
141
  if @var
135
142
  bind_var_getter
136
143
  bind_var_setter
@@ -145,7 +152,7 @@ module Myco
145
152
  bind_cache_method
146
153
  @effective_body = @target.instance_method(@name).executable
147
154
  else
148
- Rubinius.add_method @name, @body, @target, :public
155
+ Myco.add_method(@target, @name, @body)
149
156
  end
150
157
  end
151
158
 
@@ -173,8 +180,7 @@ module Myco
173
180
  # on the call stack.
174
181
  # TODO: move this bytecode generation to a helper method
175
182
  meme = self
176
-
177
- target.dynamic_method @name, '(myco_internal)' do |g|
183
+ Myco.add_dynamic_method target, @name, '(myco_internal)' do |g|
178
184
  g.splat_index = 0 # *args
179
185
 
180
186
  invoke = g.new_label
@@ -252,7 +258,7 @@ module Myco
252
258
  # TODO: move this bytecode generation to a helper method
253
259
  meme = self
254
260
 
255
- target.dynamic_method @name, '(myco_internal)' do |g|
261
+ Myco.add_dynamic_method target, @name, '(myco_internal)' do |g|
256
262
  get = g.new_label
257
263
  ret = g.new_label
258
264
 
@@ -264,14 +270,14 @@ module Myco
264
270
  g.pop
265
271
 
266
272
  ##
267
- # if instance_variable_defined?(#{name})
273
+ # if __ivar_defined__(#{name})
268
274
  # @#{name} = meme.body.invoke meme.name, @target, obj, [], nil
269
275
  # end
270
276
  # return @#{name}
271
277
  #
272
278
  g.push_self
273
279
  g.push_literal(:"@#{@name}")
274
- g.send(:instance_variable_defined?, 1)
280
+ g.send(:__ivar_defined__, 1)
275
281
  g.goto_if_true(get)
276
282
 
277
283
  g.push_local 1 # meme
@@ -309,7 +315,7 @@ module Myco
309
315
  meme = self
310
316
 
311
317
  # TODO: move this bytecode generation to a helper method
312
- target.dynamic_method :"#{@name}=", '(myco_internal)' do |g|
318
+ Myco.add_dynamic_method target, :"#{@name}=", '(myco_internal)' do |g|
313
319
  g.total_args = 1
314
320
  g.local_count = 1
315
321
 
@@ -0,0 +1,13 @@
1
+
2
+ class ::Array
3
+ # Create a method named :__tuple__ that uses the access_Array_tuple primitive.
4
+ attr_reader_specific :tuple, :__tuple__
5
+ end
6
+
7
+ module Myco
8
+ class << self
9
+ def tuple(*ary)
10
+ ary.__tuple__
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+
2
+ module Myco
3
+ class << self
4
+ dynamic_method(:undefined) { |g|
5
+ g.push_undef
6
+ g.ret
7
+ }
8
+ end
9
+ end
@@ -34,7 +34,8 @@ module Myco
34
34
  end
35
35
 
36
36
  # Patch the base classes to make them respond_to :false?
37
- class ::NilClass; def false?; true end; def void?; false end end
38
- class ::TrueClass; def false?; false end; def void?; false end end
39
- class ::FalseClass; def false?; true end; def void?; false end end
40
- class ::BasicObject; def false?; false end; def void?; false end end
37
+ class ::NilClass; def false?; true end; def void?; false end end
38
+ class ::TrueClass; def false?; false end; def void?; false end end
39
+ class ::FalseClass; def false?; true end; def void?; false end end
40
+ class ::BasicObject; def false?; false end; def void?; false end end
41
+ module ::Myco::InstanceMethods; def false?; false end; def void?; false end end
@@ -1,16 +1,27 @@
1
1
 
2
- ::Myco::RubyEval < EmptyObject {
3
- from_string: |string| ::Ruby::Kernel.instance_method(:eval).bind(self).call(string)
2
+ ::Myco::RubyEval < ::Myco::EmptyObject {
3
+ from_string: |string| ::Ruby.__send__(:eval, string)
4
4
  }
5
5
 
6
- RubyEval @@@
7
- Myco.eval_file("core/Category.my", [Myco::CoreLoadPath])
8
- Myco.eval_file("core/BasicDecorators.my", [Myco::CoreLoadPath])
9
- Myco.eval_file("core/BasicObject.my", [Myco::CoreLoadPath])
10
- Myco.eval_file("core/Decorator.my", [Myco::CoreLoadPath])
11
- Myco.eval_file("core/Object.my", [Myco::CoreLoadPath])
12
- Myco.eval_file("core/FileToplevel.my", [Myco::CoreLoadPath])
13
-
14
- # Below are not necessary for bootstrapping; TODO: move out of RubyEval
15
- Myco.eval_file("core/Switch.my", [Myco::CoreLoadPath])
16
- @@@
6
+ ::Myco::Category < ::Myco::EmptyObject { }
7
+ ::Myco::BasicDecorators < ::Myco::EmptyObject { }
8
+ ::Myco::BasicObject < ::Myco::EmptyObject, ::Myco::BasicDecorators { }
9
+ ::Myco::Decorator < ::Myco::BasicObject { }
10
+ ::Myco::FileToplevel < ::Myco::BasicObject { }
11
+
12
+ [decorators]
13
+
14
+ load: LoadDecorator # TODO: avoid this hack
15
+ LoadDecorator: ::Myco::Decorator {
16
+ apply: |meme| ::Myco.eval_file(meme.name.to_s, [::Myco::CoreLoadPath])
17
+ [transforms]
18
+ apply: { }
19
+ }
20
+
21
+ [main]
22
+
23
+ load "core/Category.my"
24
+ load "core/Decorator.my"
25
+ load "core/BasicDecorators.my"
26
+ load "core/BasicObject.my"
27
+ load "core/FileToplevel.my"