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.
- checksums.yaml +4 -4
- data/lib/myco/bootstrap/add_method.rb +38 -0
- data/lib/myco/bootstrap/component.rb +43 -21
- data/lib/myco/bootstrap/find_constant.rb +73 -25
- data/lib/myco/bootstrap/instance.rb +96 -25
- data/lib/myco/bootstrap/meme.rb +18 -12
- data/lib/myco/bootstrap/tuple.rb +13 -0
- data/lib/myco/bootstrap/undefined.rb +9 -0
- data/lib/myco/bootstrap/void.rb +5 -4
- data/lib/myco/bootstrap.my +24 -13
- data/lib/myco/bootstrap.my.rb +41 -4
- data/lib/myco/bootstrap.rb +4 -0
- data/lib/myco/code_loader.rb +11 -9
- data/lib/myco/code_tools/AST/Block.my.rb +2 -2
- data/lib/myco/code_tools/AST/ConstantAccess.my.rb +4 -4
- data/lib/myco/code_tools/AST/ConstantAssignment.my.rb +4 -4
- data/lib/myco/code_tools/AST/Invoke.my +1 -1
- data/lib/myco/code_tools/AST/Invoke.my.rb +1 -1
- data/lib/myco/code_tools/AST/Node.my +2 -4
- data/lib/myco/code_tools/AST/Node.my.rb +3 -3
- data/lib/myco/code_tools/AST/PipeOperator.my.rb +1 -1
- data/lib/myco/code_tools/AST/ToRuby.my.rb +8 -8
- data/lib/myco/code_tools/AST/misc.my.rb +1 -1
- data/lib/myco/code_tools/Parser.my +8 -15
- data/lib/myco/code_tools/Parser.my.rb +8 -14
- data/lib/myco/code_tools/parser/MycoBuilder.my +3 -4
- data/lib/myco/code_tools/parser/MycoBuilder.my.rb +5 -6
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my +8 -4
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeHelpers.my.rb +5 -5
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my +2 -2
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeInstructions.my.rb +12 -12
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeParser.my +54 -44
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/BytecodeParser.my.rb +69 -83
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my +18 -8
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Grammar.my.rb +24 -10
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Machine.my.rb +1 -1
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my +1 -1
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Parser.my.rb +1 -2
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my +1 -1
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Patterns.my.rb +1 -1
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my +3 -3
- data/lib/myco/code_tools/parser/pegleromyces/lib/pegleromyces/Processor.my.rb +5 -6
- data/lib/myco/code_tools/parser/pegleromyces/spec/BasicSpec.my +35 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/BasicSpec.my.rb +35 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Builder.test.my +10 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Builder.test.my.rb +9 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeInstructions.test.my +10 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeInstructions.test.my.rb +9 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeParser.test.my +81 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/BytecodeParser.test.my.rb +209 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Constructions.test.my +229 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Constructions.test.my.rb +663 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Grammar.test.my +10 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Grammar.test.my.rb +9 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Instructions.test.my +10 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Instructions.test.my.rb +9 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Machine.test.my +13 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Machine.test.my.rb +20 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Parser.test.my +54 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Parser.test.my.rb +215 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Patterns.test.my +156 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Patterns.test.my.rb +334 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Processor.test.my +10 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/Processor.test.my.rb +9 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/run.my +20 -0
- data/lib/myco/code_tools/parser/pegleromyces/spec/run.my.rb +16 -0
- data/lib/myco/core/BasicDecorators.my +19 -11
- data/lib/myco/core/BasicDecorators.my.rb +24 -20
- data/lib/myco/core/BasicObject.my +12 -7
- data/lib/myco/core/BasicObject.my.rb +50 -44
- data/lib/myco/core/Category.my +12 -2
- data/lib/myco/core/Category.my.rb +15 -7
- data/lib/myco/core/Decorator.my +1 -1
- data/lib/myco/core/Decorator.my.rb +8 -10
- data/lib/myco/core/FileToplevel.my +3 -3
- data/lib/myco/core/FileToplevel.my.rb +4 -6
- data/lib/myco/core/Object.my +7 -10
- data/lib/myco/core/Object.my.rb +11 -17
- data/lib/myco/core/Ruby.my +6 -0
- data/lib/myco/core/Ruby.my.rb +16 -0
- data/lib/myco/core/Switch.my +1 -1
- data/lib/myco/core/Switch.my.rb +1 -1
- data/lib/myco/core.my +4 -0
- data/lib/myco/core.my.rb +7 -0
- data/lib/myco/dev/call_sites.rb +39 -0
- data/lib/myco/dev/counter.rb +26 -0
- data/lib/myco/dev.rb +3 -0
- data/lib/myco/eval.rb +1 -1
- data/lib/myco/tools/BasicCommand.my.rb +1 -1
- data/lib/myco/version.rb +1 -1
- data/lib/myco.rb +2 -3
- metadata +53 -20
- data/lib/myco/bootstrap/evaluator.rb +0 -58
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e8031fe74a54c47a6c344eef7a2c5e13855bf2bc
|
|
4
|
+
data.tar.gz: c2f129e293c295731e643372d5add7704fdf9252
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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 :
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
|
93
|
-
@categories[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
|
|
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.
|
|
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
|
-
|
|
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
|
|
4
|
-
|
|
3
|
+
module PrimitiveInstanceMethods
|
|
4
|
+
# These methods are taken from Ruby's Kernel.
|
|
5
|
+
# TODO: Audit which of these should remain.
|
|
5
6
|
|
|
6
|
-
def
|
|
7
|
-
|
|
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
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
|
|
75
|
+
__component__.parent && __component__.parent.instance
|
|
27
76
|
end
|
|
28
77
|
|
|
29
78
|
def parent_meme
|
|
30
|
-
|
|
79
|
+
__component__.parent_meme
|
|
31
80
|
end
|
|
32
81
|
|
|
33
82
|
def memes
|
|
34
|
-
|
|
83
|
+
__component__.memes
|
|
35
84
|
end
|
|
36
85
|
end
|
|
37
86
|
|
|
38
|
-
|
|
87
|
+
Instance = Class.new nil do
|
|
39
88
|
include InstanceMethods
|
|
40
89
|
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
data/lib/myco/bootstrap/meme.rb
CHANGED
|
@@ -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.
|
|
18
|
+
decorators = main.category(:decorators)
|
|
19
19
|
decorators = decorators && decorators.instance
|
|
20
20
|
|
|
21
|
-
unless
|
|
22
|
-
reason = if decorators
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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(:
|
|
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
|
-
|
|
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
|
|
data/lib/myco/bootstrap/void.rb
CHANGED
|
@@ -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
|
|
38
|
-
class
|
|
39
|
-
class
|
|
40
|
-
class
|
|
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
|
data/lib/myco/bootstrap.my
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
|
|
2
|
-
::Myco::RubyEval < EmptyObject {
|
|
3
|
-
from_string: |string| ::Ruby
|
|
2
|
+
::Myco::RubyEval < ::Myco::EmptyObject {
|
|
3
|
+
from_string: |string| ::Ruby.__send__(:eval, string)
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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"
|