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