myco 0.1.7 → 0.1.8

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