maroon 0.6.5 → 0.7.0
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/README.md +5 -3
- data/Rakefile +2 -1
- data/Test/Context_test.rb +129 -0
- data/Test/ImmutableQueue_test.rb +5 -5
- data/Test/MethodInfo_test.rb +58 -37
- data/Test/alltests.rb +1 -1
- data/Test/assertions.rb +12 -4
- data/Test/production_test.rb +42 -0
- data/Test/stack_test.rb +5 -6
- data/Test/test_helper.rb +2 -2
- data/base/AstRewritter.rb +63 -0
- data/base/ImmutableStack.rb +7 -5
- data/base/Production.rb +145 -0
- data/base/immutable_queue.rb +6 -5
- data/base/maroon_base.rb +196 -154
- data/base/method_info.rb +48 -67
- data/generated/Tokens.rb +24 -0
- data/generated/build.rb +6 -5
- data/lib/AstRewritter.rb +55 -0
- data/lib/Context.rb +190 -172
- data/lib/ImmutableQueue.rb +33 -39
- data/lib/ImmutableStack.rb +25 -29
- data/lib/MethodInfo.rb +57 -69
- data/lib/Production.rb +135 -0
- data/lib/Tokens.rb +24 -0
- data/lib/build.rb +10 -10
- data/lib/interpretation_context.rb +0 -1
- data/lib/maroon/kernel.rb +1 -1
- data/lib/maroon/version.rb +1 -1
- metadata +10 -15
- data/Test/Generate/method_info_test.rb +0 -12
- data/Test/bind_test.rb +0 -13
- data/Test/expression_test.rb +0 -105
- data/Test/method_call_test.rb +0 -83
- data/Test/self_test.rb +0 -46
- data/base/MethodDefinition.rb +0 -124
- data/base/bind_rewriter.rb +0 -58
- data/base/method_call.rb +0 -78
- data/base/self.rb +0 -60
- data/lib/Bind.rb +0 -65
- data/lib/MethodCall.rb +0 -91
- data/lib/MethodDefinition.rb +0 -114
- data/lib/Self.rb +0 -71
data/base/ImmutableStack.rb
CHANGED
@@ -3,18 +3,20 @@ context :ImmutableStack do
|
|
3
3
|
end
|
4
4
|
role :tail do
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
|
+
def pop
|
7
8
|
[@head, @tail]
|
8
9
|
end
|
9
|
-
|
10
|
+
|
11
|
+
def push(element)
|
10
12
|
ImmutableStack.new element, self
|
11
13
|
end
|
12
14
|
|
13
|
-
|
15
|
+
def self.empty
|
14
16
|
@@empty ||= self.new(nil, nil)
|
15
17
|
end
|
16
18
|
|
17
|
-
each
|
19
|
+
def each
|
18
20
|
yield head
|
19
21
|
t = tail
|
20
22
|
while t != ImmutableStack::empty do
|
@@ -23,7 +25,7 @@ context :ImmutableStack do
|
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
|
-
initialize
|
28
|
+
def initialize(h, t)
|
27
29
|
@head = h
|
28
30
|
@tail = t
|
29
31
|
self.freeze
|
data/base/Production.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
context :Production do
|
2
|
+
role :interpretation_context do
|
3
|
+
end
|
4
|
+
role :queue do
|
5
|
+
end
|
6
|
+
|
7
|
+
role :production do
|
8
|
+
def is_role?
|
9
|
+
|
10
|
+
case
|
11
|
+
when production.is_call? && (interpretation_context.roles.has_key?(production[2]))
|
12
|
+
@date = [production[2]]
|
13
|
+
return true
|
14
|
+
when (production == :self ||
|
15
|
+
(production.is_indexer? && (production[1] == nil || production[1] == :self)) ||
|
16
|
+
(production && ((production.instance_of?(Sexp) || production.instance_of?(Array)) && production[0] == :self))) && @interpretation_context.defining_role
|
17
|
+
@data = @interpretation_context.defining_role
|
18
|
+
return true
|
19
|
+
else
|
20
|
+
false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def is_indexer?
|
25
|
+
production.is_call? && (production[2] == :[] || production[2] == :[]=)
|
26
|
+
end
|
27
|
+
|
28
|
+
def is_call?
|
29
|
+
production && ((production.instance_of?(Sexp) || production.instance_of?(Array)) && production[0] == :call)
|
30
|
+
end
|
31
|
+
|
32
|
+
def is_block?
|
33
|
+
production && ((production.instance_of?(Sexp) || production.instance_of?(Array)) && production[0] == :iter)
|
34
|
+
end
|
35
|
+
|
36
|
+
def is_block_with_bind?
|
37
|
+
if production.is_block?
|
38
|
+
body = @production.last()
|
39
|
+
if body && (exp = body[0])
|
40
|
+
bind = Production.new exp, @interpretation_context
|
41
|
+
if bind.type == Tokens::call && bind.data == :bind
|
42
|
+
true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def is_rolemethod_call?
|
49
|
+
can_be = production.is_call?
|
50
|
+
if can_be
|
51
|
+
instance = Production.new(production[1], @interpretation_context)
|
52
|
+
can_be = instance.type == Tokens::role
|
53
|
+
if can_be
|
54
|
+
instance_data = instance.data
|
55
|
+
role = @interpretation_context.roles[instance_data]
|
56
|
+
data = production[2]
|
57
|
+
can_be = role.has_key?(data)
|
58
|
+
@data = [data, instance_data]
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
can_be
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def initialize(ast, interpretation_context)
|
67
|
+
rebind ImmutableQueue::empty.push(ast), interpretation_context
|
68
|
+
end
|
69
|
+
|
70
|
+
def type
|
71
|
+
case
|
72
|
+
when nil == production
|
73
|
+
nil
|
74
|
+
when production.is_block_with_bind?
|
75
|
+
Tokens::block_with_bind
|
76
|
+
when production.is_block?
|
77
|
+
Tokens::block
|
78
|
+
when production.instance_of?(Fixnum) || production.instance_of?(Symbol)
|
79
|
+
Tokens::terminal
|
80
|
+
when production.is_rolemethod_call?
|
81
|
+
Tokens::rolemethod_call
|
82
|
+
when production.is_role?
|
83
|
+
Tokens::role
|
84
|
+
when production.is_indexer?
|
85
|
+
Tokens::indexer
|
86
|
+
when production.is_call?
|
87
|
+
Tokens::call
|
88
|
+
else
|
89
|
+
Tokens::other
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def [](i)
|
94
|
+
@production[i]
|
95
|
+
end
|
96
|
+
|
97
|
+
def []=(i, v)
|
98
|
+
@production[i]=v
|
99
|
+
end
|
100
|
+
|
101
|
+
def length
|
102
|
+
@production.length
|
103
|
+
end
|
104
|
+
|
105
|
+
def last
|
106
|
+
@production.last
|
107
|
+
end
|
108
|
+
|
109
|
+
def first
|
110
|
+
@production.first
|
111
|
+
end
|
112
|
+
|
113
|
+
def data
|
114
|
+
return @data if @data
|
115
|
+
@data = case
|
116
|
+
when production.is_call?
|
117
|
+
@production[2]
|
118
|
+
else
|
119
|
+
@production
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def each
|
124
|
+
yield self
|
125
|
+
if production.instance_of? Sexp || production.instance_of?(Array)
|
126
|
+
@queue = @queue.push_array production
|
127
|
+
end
|
128
|
+
while @queue != ImmutableQueue::empty
|
129
|
+
rebind @queue, @interpretation_context
|
130
|
+
yield self
|
131
|
+
if production.instance_of? Sexp || production.instance_of?(Array)
|
132
|
+
@queue = @queue.push_array production
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def rebind(queue, ctx)
|
140
|
+
@data = nil
|
141
|
+
@production, @queue = queue.pop
|
142
|
+
@interpretation_context = ctx
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
data/base/immutable_queue.rb
CHANGED
@@ -3,12 +3,13 @@ context :ImmutableQueue do
|
|
3
3
|
end
|
4
4
|
role :back do
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
|
+
def push(element)
|
7
8
|
b = back || ImmutableStack::empty
|
8
9
|
ImmutableQueue.new(front, b.push(element))
|
9
10
|
end
|
10
11
|
|
11
|
-
pop
|
12
|
+
def pop
|
12
13
|
f, b = front, back
|
13
14
|
if f == ImmutableStack::empty
|
14
15
|
#reverse the back stack to be able to pop from the front in correct order
|
@@ -25,11 +26,11 @@ context :ImmutableQueue do
|
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
|
-
empty
|
29
|
+
def self.empty
|
29
30
|
@@empty ||= ImmutableQueue.new(ImmutableStack::empty, ImmutableStack::empty)
|
30
31
|
end
|
31
32
|
|
32
|
-
push_array
|
33
|
+
def push_array(arr)
|
33
34
|
q = self
|
34
35
|
if arr
|
35
36
|
arr.each do |i|
|
@@ -41,7 +42,7 @@ context :ImmutableQueue do
|
|
41
42
|
|
42
43
|
private
|
43
44
|
|
44
|
-
initialize
|
45
|
+
def initialize(front, back)
|
45
46
|
@front = front || ImmutableStack::empty
|
46
47
|
@back = back || ImmutableStack::empty
|
47
48
|
self.freeze
|
data/base/maroon_base.rb
CHANGED
@@ -19,7 +19,7 @@
|
|
19
19
|
# end
|
20
20
|
# end
|
21
21
|
# greeting do
|
22
|
-
# p
|
22
|
+
# p 'Hello #{who.say}!'
|
23
23
|
# end
|
24
24
|
# end
|
25
25
|
#
|
@@ -29,239 +29,281 @@
|
|
29
29
|
# end
|
30
30
|
# end
|
31
31
|
#
|
32
|
-
# Greeter.new('world').greeting #Will print
|
32
|
+
# Greeter.new('world').greeting #Will print 'Hello world!'
|
33
33
|
#maroon is base on Marvin which was the first injectionless language for DCI
|
34
34
|
#being injectionless there's no runtime extend or anything else impacting the performance. There' only regular method invocation even when using role methods
|
35
35
|
#Author:: Rune Funch Søltoft (funchsoltoft@gmail.com)
|
36
36
|
#License:: Same as for Ruby
|
37
37
|
##
|
38
|
-
Context
|
39
|
-
context :Context do
|
40
|
-
role :roles do
|
41
|
-
end
|
42
|
-
role :interactions do
|
43
|
-
end
|
44
|
-
role :defining_role do
|
45
|
-
end
|
46
|
-
role :role_alias do
|
47
|
-
end
|
48
|
-
role :alias_list do
|
49
|
-
end
|
50
|
-
role :cached_roles_and_alias_list do
|
51
|
-
end
|
38
|
+
c = context :Context do
|
52
39
|
|
53
|
-
|
54
|
-
#if maroon/kernel is required calling context of Context::define are equivalent
|
55
|
-
#params
|
56
|
-
#name:: the name of the context. Since this is used as the name of a class, class naming convetions should be used
|
57
|
-
#block:: the body of the context. Can include definitions of roles (through the role method) or definitions of interactions
|
58
|
-
#by simply calling a method with the name of the interaction and passing a block as the body of the interaction
|
59
|
-
define :block => :block, :self => self do |*args|
|
40
|
+
def self.define(*args, &block)
|
60
41
|
@@with_contracts ||= nil
|
61
42
|
@@generate_file_path ||= nil
|
62
|
-
alias method_missing role_or_interaction_method
|
43
|
+
(alias :method_missing :role_or_interaction_method)
|
44
|
+
|
63
45
|
base_class, ctx, default_interaction, name = self.send(:create_context_factory, args, block)
|
64
|
-
|
65
|
-
|
66
|
-
|
46
|
+
if (args.last.instance_of?(FalseClass) or args.last.instance_of?(TrueClass)) then
|
47
|
+
ctx.generate_files_in(args.last)
|
48
|
+
end
|
49
|
+
return ctx.send(:finalize, name, base_class, default_interaction, @@generate_file_path, @@with_contracts)
|
67
50
|
|
68
|
-
|
69
|
-
return role_or_interaction_method(:generate_files_in, *args, &b) if block_given?
|
51
|
+
end
|
70
52
|
|
53
|
+
def self.generate_files_in(*args, &b)
|
54
|
+
if block_given? then
|
55
|
+
return role_or_interaction_method(:generate_files_in, *args, &b)
|
56
|
+
end
|
71
57
|
@@generate_file_path = args[0]
|
58
|
+
|
72
59
|
end
|
73
60
|
|
74
61
|
private
|
75
|
-
|
76
|
-
|
62
|
+
|
63
|
+
def get_definitions(b)
|
64
|
+
sexp = b.to_sexp
|
65
|
+
unless is_definition? sexp[3]
|
66
|
+
sexp = sexp[3]
|
67
|
+
if sexp
|
68
|
+
sexp = sexp.select do |exp|
|
69
|
+
is_definition? exp
|
70
|
+
end
|
71
|
+
end
|
72
|
+
sexp ||= []
|
73
|
+
end
|
74
|
+
|
75
|
+
sexp.select do |exp|
|
76
|
+
is_definition? exp
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.create_context_factory(args, block)
|
81
|
+
name, base_class, default_interaction = *args
|
82
|
+
if default_interaction and (not base_class.instance_of?(Class)) then
|
83
|
+
base_class = eval(base_class.to_s)
|
84
|
+
end
|
85
|
+
if base_class and ((not default_interaction) and (not base_class.instance_of?(Class))) then
|
86
|
+
base_class, default_interaction = default_interaction, base_class
|
87
|
+
end
|
88
|
+
ctx = Context.new
|
89
|
+
ctx.instance_eval {
|
90
|
+
sexp = block.to_sexp
|
91
|
+
temp_block = sexp[3]
|
92
|
+
i = 0
|
93
|
+
|
94
|
+
while i < temp_block.length
|
95
|
+
exp = temp_block[i]
|
96
|
+
unless temp_block[i-2] && temp_block[i-2][0] == :call && temp_block[i-1] && temp_block[i-1][0] == :args
|
97
|
+
if exp[0] == :defn || exp[0] == :defs
|
98
|
+
add_method(exp)
|
99
|
+
temp_block.delete_at i
|
100
|
+
i -= 1
|
101
|
+
elsif exp[0] == :call && exp[1] == nil && exp[2] == :private
|
102
|
+
@private = true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
i += 1
|
106
|
+
end
|
107
|
+
ctx.instance_eval &block
|
108
|
+
}
|
109
|
+
|
110
|
+
return [base_class, ctx, default_interaction, name]
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.with_contracts(*args)
|
115
|
+
return @@with_contracts if (args.length == 0)
|
77
116
|
value = args[0]
|
78
|
-
|
117
|
+
if @@with_contracts and (not value) then
|
118
|
+
raise('make up your mind! disabling contracts during execution will result in undefined behavior')
|
119
|
+
end
|
79
120
|
@@with_contracts = value
|
121
|
+
|
80
122
|
end
|
81
123
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
# = Example
|
86
|
-
# role :who do
|
87
|
-
# say do
|
88
|
-
# p @who
|
89
|
-
# end
|
90
|
-
# end
|
91
|
-
#The above code defines a role called 'who' with a role method called say
|
92
|
-
##
|
93
|
-
role :block => :b do |*args|
|
94
|
-
role_name = args[0]
|
95
|
-
return role_or_interaction_method(:role, *args, &b) if args.length != 1 or not (role_name.instance_of? Symbol)
|
124
|
+
def createInfo(definition)
|
125
|
+
MethodInfo.new(definition, @defining_role, @private)
|
126
|
+
end
|
96
127
|
|
128
|
+
def is_definition?(exp)
|
129
|
+
exp && (exp[0] == :defn || exp[0] == :defs)
|
130
|
+
end
|
131
|
+
|
132
|
+
def role(*args, &b)
|
133
|
+
role_name = args[0]
|
134
|
+
if (args.length.!=(1) or (not role_name.instance_of?(Symbol))) then
|
135
|
+
return role_or_interaction_method(:role, *args, &b)
|
136
|
+
end
|
97
137
|
@defining_role = role_name
|
138
|
+
@roles = {} unless @roles
|
98
139
|
@roles[role_name] = Hash.new
|
99
|
-
yield if block_given?
|
100
|
-
@defining_role = nil
|
101
|
-
end
|
102
140
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
@roles = Hash.new
|
108
|
-
@interactions = Hash.new
|
109
|
-
@role_alias = Hash.new
|
110
|
-
@contracts = Hash.new
|
141
|
+
definitions = get_definitions(b)
|
142
|
+
|
143
|
+
definitions.each do |exp|
|
144
|
+
add_method(exp)
|
111
145
|
end
|
112
|
-
end
|
113
146
|
|
114
|
-
role_or_interaction_method(:private) do
|
115
|
-
@private = true
|
116
147
|
end
|
117
148
|
|
118
|
-
current_interpretation_context
|
119
|
-
|
120
|
-
|
149
|
+
def current_interpretation_context(*args, &b)
|
150
|
+
if block_given? then
|
151
|
+
return role_or_interaction_method(:current_interpretation_context, *args, &b)
|
152
|
+
end
|
153
|
+
InterpretationContext.new(@roles, @contracts, @role_alias, nil)
|
154
|
+
|
121
155
|
end
|
122
156
|
|
123
|
-
get_methods
|
157
|
+
def get_methods(*args, &b)
|
124
158
|
return role_or_interaction_method(:get_methods, *args, &b) if block_given?
|
125
159
|
name = args[0]
|
126
160
|
sources = (@defining_role ? (@roles[@defining_role]) : (@interactions))[name]
|
127
|
-
if @defining_role
|
161
|
+
if @defining_role and (not sources) then
|
128
162
|
@roles[@defining_role][name] = []
|
129
163
|
else
|
130
|
-
|
164
|
+
@interactions[name] = []
|
131
165
|
end
|
132
|
-
end
|
133
166
|
|
134
|
-
role :contracts do
|
135
167
|
end
|
136
168
|
|
137
|
-
add_method
|
169
|
+
def add_method(*args, &b)
|
138
170
|
return role_or_interaction_method(:add_method, *args, &b) if block_given?
|
139
|
-
|
140
|
-
|
141
|
-
sources
|
171
|
+
exp = args[0]
|
172
|
+
info = createInfo exp
|
173
|
+
sources = get_methods(info.name)
|
174
|
+
(sources << info)
|
142
175
|
end
|
143
176
|
|
144
|
-
finalize
|
177
|
+
def finalize(*args, &b)
|
145
178
|
return role_or_interaction_method(:finalize, *args, &b) if block_given?
|
146
|
-
name, base_class, default = *args
|
147
|
-
|
179
|
+
name, base_class, default, file_path, with_contracts = *args
|
148
180
|
code = generate_context_code(default, name)
|
149
|
-
|
150
|
-
if @@generate_file_path
|
181
|
+
if file_path then
|
151
182
|
name = name.to_s
|
152
|
-
complete = 'class ' + name + (base_class ? '<< ' + base_class.name : '') + '
|
153
|
-
' + code.to_s + '
|
154
|
-
|
155
|
-
File.open('./' +
|
183
|
+
complete = ((((('class ' + name) + (base_class ? (('<< ' + base_class.name)) : (''))) + '
|
184
|
+
') + code.to_s) + '
|
185
|
+
end')
|
186
|
+
File.open((((('./' + file_path.to_s) + '/') + name) + '.rb'), 'w') do |f|
|
187
|
+
f.write(complete)
|
188
|
+
end
|
156
189
|
complete
|
157
190
|
else
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
191
|
+
c = base_class ? (Class.new(base_class)) : (Class.new)
|
192
|
+
if with_contracts then
|
193
|
+
c.class_eval(
|
194
|
+
'def self.assert_that(obj)
|
195
|
+
ContextAsserter.new(self.contracts,obj)
|
196
|
+
end
|
197
|
+
def self.refute_that(obj)
|
198
|
+
ContextAsserter.new(self.contracts,obj,false)
|
199
|
+
end
|
200
|
+
def self.contracts
|
201
|
+
@@contracts
|
202
|
+
end
|
203
|
+
def self.contracts=(value)
|
204
|
+
@@contracts = value
|
205
|
+
end')
|
206
|
+
c.contracts = contracts
|
207
|
+
end
|
208
|
+
Kernel.const_set(name, c)
|
209
|
+
begin
|
210
|
+
temp = c.class_eval(code)
|
211
|
+
rescue SyntaxError
|
212
|
+
p 'error: ' + code
|
175
213
|
end
|
176
|
-
Kernel.const_set name, c
|
177
|
-
temp = c.class_eval(code)
|
178
|
-
(temp || c)
|
179
|
-
end
|
180
|
-
end
|
181
214
|
|
182
|
-
|
183
|
-
name, base_class, default_interaction = *args
|
184
|
-
#if there's two arguments and the second is not a class it must be an interaction
|
185
|
-
if default_interaction && (!base_class.instance_of? Class) then
|
186
|
-
base_class = eval(base_class.to_s)
|
215
|
+
(temp or c)
|
187
216
|
end
|
188
|
-
|
189
|
-
ctx = Context.new
|
190
|
-
ctx.instance_eval &block
|
191
|
-
return base_class, ctx, default_interaction, name
|
217
|
+
|
192
218
|
end
|
193
219
|
|
194
|
-
generate_context_code
|
195
|
-
|
220
|
+
def generate_context_code(*args, &b)
|
221
|
+
if block_given? then
|
222
|
+
return role_or_interaction_method(:generate_context_code, *args, &b)
|
223
|
+
end
|
196
224
|
default, name = args
|
197
|
-
|
198
225
|
getters = ''
|
199
226
|
impl = ''
|
200
227
|
interactions = ''
|
201
228
|
@interactions.each do |method_name, methods|
|
202
229
|
methods.each do |method|
|
203
230
|
@defining_role = nil
|
204
|
-
code = ' ' +
|
205
|
-
|
206
|
-
getters << code
|
207
|
-
else
|
208
|
-
interactions << code
|
209
|
-
end
|
231
|
+
code = (' ' + method.build_as_context_method(current_interpretation_context))
|
232
|
+
method.is_private ? ((getters << code)) : ((interactions << code))
|
210
233
|
end
|
211
234
|
end
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
arity = ' + name.to_s + '.method(:new).arity
|
235
|
+
if default then
|
236
|
+
(interactions << (((((((('
|
237
|
+
def self.call(*args)
|
238
|
+
arity = ' + name.to_s) + '.method(:new).arity
|
217
239
|
newArgs = args[0..arity-1]
|
218
|
-
obj = ' + name.to_s + '.new *newArgs
|
240
|
+
obj = ') + name.to_s) + '.new *newArgs
|
219
241
|
if arity < args.length
|
220
242
|
methodArgs = args[arity..-1]
|
221
|
-
obj.' + default.to_s + ' *methodArgs
|
243
|
+
obj.') + default.to_s) + ' *methodArgs
|
222
244
|
else
|
223
|
-
obj.' + default.to_s + '
|
224
|
-
|
245
|
+
obj.') + default.to_s) + '
|
246
|
+
end
|
225
247
|
end
|
226
|
-
'
|
227
|
-
interactions << '
|
228
|
-
|
229
|
-
'
|
248
|
+
'))
|
249
|
+
(interactions << (('
|
250
|
+
def call(*args);' + default.to_s) + ' *args; end
|
251
|
+
'))
|
230
252
|
end
|
231
|
-
|
232
253
|
@roles.each do |role, methods|
|
233
|
-
getters << 'attr_reader :' + role.to_s + '
|
234
|
-
'
|
235
|
-
|
254
|
+
(getters << (('attr_reader :' + role.to_s) + '
|
255
|
+
'))
|
236
256
|
methods.each do |method_name, method_sources|
|
237
|
-
|
238
|
-
|
239
|
-
|
257
|
+
unless (method_sources.length < 2) then
|
258
|
+
raise(('Duplicate definition of ' + method_name.to_s))
|
259
|
+
end
|
260
|
+
unless (method_sources.length > 0) then
|
261
|
+
raise(('No source for ' + method_name.to_s))
|
262
|
+
end
|
240
263
|
method_source = method_sources[0]
|
241
264
|
@defining_role = role
|
242
|
-
|
243
|
-
definition = method_source.build_as_context_method
|
244
|
-
(impl << ' ' + definition.to_s) if definition
|
265
|
+
|
266
|
+
definition = method_source.build_as_context_method(current_interpretation_context)
|
267
|
+
(impl << (' ' + definition.to_s)) if definition
|
245
268
|
end
|
246
269
|
end
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
' + getters + '
|
270
|
+
private_string = (getters + impl).strip! != '' ? '
|
271
|
+
private
|
272
|
+
' : ''
|
273
|
+
impl = impl.strip! != '' ? '
|
252
274
|
' + impl + '
|
275
|
+
' : '
|
253
276
|
'
|
277
|
+
interactions + private_string + getters + impl
|
278
|
+
|
254
279
|
end
|
255
280
|
|
256
|
-
role_or_interaction_method(
|
281
|
+
def role_or_interaction_method(*arguments, &b)
|
257
282
|
method_name, on_self = *arguments
|
258
|
-
unless method_name.instance_of?
|
283
|
+
unless method_name.instance_of?(Symbol) then
|
259
284
|
on_self = method_name
|
260
285
|
method_name = :role_or_interaction_method
|
261
286
|
end
|
287
|
+
raise(('Method with out block ' + method_name.to_s)) unless block_given?
|
288
|
+
|
289
|
+
end
|
290
|
+
|
291
|
+
def private
|
292
|
+
@private = true
|
293
|
+
end
|
294
|
+
|
295
|
+
def initialize
|
296
|
+
@roles = {}
|
297
|
+
@interactions = {}
|
298
|
+
@role_alias = {}
|
299
|
+
end
|
262
300
|
|
263
|
-
|
301
|
+
end
|
264
302
|
|
265
|
-
|
303
|
+
if c.instance_of? String
|
304
|
+
file_name = './generated/Context.rb'
|
305
|
+
p "writing to: " + file_name
|
306
|
+
File.open(file_name, 'w') do |f|
|
307
|
+
f.write(c)
|
266
308
|
end
|
267
|
-
end
|
309
|
+
end
|