maroon 0.7.0 → 0.7.1

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.
@@ -0,0 +1,197 @@
1
+ context :Transformer do
2
+
3
+ def initialize(context_name, roles, interactions,private_interactions, base_class,default_interaction)
4
+ @context_name = context_name
5
+
6
+ @roles = roles
7
+ @interactions = interactions
8
+ @base_class = base_class
9
+ @default_interaction = default_interaction
10
+ @private_interactions = private_interactions
11
+ @definitions = {}
12
+ end
13
+
14
+ role :private_interactions do end
15
+ role :context_name do end
16
+ role :roles do
17
+ def generated_source
18
+ impl = ''
19
+ getters = ''
20
+ roles.each do |role, methods|
21
+ getters << 'attr_reader :' + role.to_s + '
22
+ '
23
+ methods.each do |name, method_sources|
24
+ bind :method_sources => :method , :name=> :method_name , :role => :defining_role
25
+ definition = method.generated_source
26
+ (impl << (' ' + definition )) if definition
27
+ end
28
+ end
29
+ (impl.strip! || '')+ '
30
+ ' + (getters.strip! || '') + '
31
+ '
32
+ end
33
+ end
34
+ role :interactions do
35
+ def generated_source
36
+ internal_methods = ''
37
+ external_methods = interactions.default
38
+ interactions.each do |name, interact|
39
+ interact.each do |m|
40
+ bind :m => :method, :name => :method_name
41
+ @defining_role = nil
42
+ code = method.generated_source
43
+
44
+ (method.is_private? ? internal_methods : external_methods) << ' ' << code
45
+ end
46
+ end
47
+ (external_methods.strip! || '') + '
48
+ private
49
+ ' + (internal_methods.strip! || '') + '
50
+ '
51
+ end
52
+ def default
53
+ if @default
54
+ '
55
+ def self.call(*args)
56
+ arity = ' + name.to_s + '.method(:new).arity
57
+ newArgs = args[0..arity-1]
58
+ obj = ' + name.to_s + '.new *newArgs
59
+ if arity < args.length
60
+ methodArgs = args[arity..-1]
61
+ obj.' + default.to_s + ' *methodArgs
62
+ else
63
+ obj.' + default.to_s + '
64
+ end
65
+ end
66
+ def call(*args);' + default.to_s + ' *args; end
67
+ '
68
+ else
69
+ ''
70
+ end
71
+ end
72
+ end
73
+ role :method_name do end
74
+ role :defining_role do end
75
+ role :method do
76
+ def is_private?
77
+ defining_role != nil || (private_interactions.has_key? method.name)
78
+ end
79
+ def definition
80
+ key = (@defining_role ? @defining_role.to_s : '') + method_name.to_s
81
+ return @definitions[key] if @definitions.has_key? key
82
+ unless method.instance_of? Sexp
83
+ unless (method.instance_of? Array) && method.length < 2 then
84
+ raise(('Duplicate definition of ' + method_name.to_s + '(' + method.to_s + ')'))
85
+ end
86
+ unless (method.instance_of? Array) && method.length > 0 then
87
+ raise(('No source for ' + method_name.to_s))
88
+ end
89
+ end
90
+
91
+ d = (method.instance_of? Array) ? method[0] : method
92
+ raise 'Sexp require' unless d.instance_of? Sexp
93
+ @definitions[key] = d
94
+ end
95
+ def body
96
+ args = method.definition.detect { |d| d[0] == :args }
97
+ index = method.definition.index(args) + 1
98
+ if method.definition.length > index+1
99
+ body = method.definition[index..-1]
100
+ body.insert(0, :block)
101
+ body
102
+ else
103
+ method.definition[index]
104
+ end
105
+ end
106
+
107
+ def arguments
108
+ args = method.definition.detect { |d| d[0] == :args }
109
+ args && args.length > 1 ? args[1..-1] : []
110
+ end
111
+
112
+ def name
113
+ name = if method.definition[1].instance_of? Symbol
114
+ method.definition[1].to_s
115
+ else
116
+ (method.definition[1].select { |e| e.instance_of? Symbol }.map { |e| e.to_s }.join('.') + '.' + method.definition[2].to_s)
117
+ end
118
+ (
119
+ unless defining_role
120
+ name
121
+ else
122
+ 'self_' + @defining_role.to_s + '_' + name.to_s
123
+ end).to_sym
124
+ end
125
+ def generated_source
126
+ AstRewritter.new(method.body, interpretation_context).rewrite!
127
+ body = Ruby2Ruby.new.process(method.body)
128
+ raise 'Body is undefined' unless body
129
+ args = method.arguments
130
+ if args && args.length
131
+ args = '('+ args.join(',') + ')'
132
+ else
133
+ args= ''
134
+ end
135
+
136
+ header = 'def ' + method.name.to_s + args
137
+ header + ' ' + body + ' end
138
+ '
139
+ end
140
+ end
141
+
142
+
143
+ def transform(file_path, with_contracts)
144
+
145
+ code = interactions.generated_source + roles.generated_source
146
+
147
+ if file_path then
148
+ name = context_name.to_s
149
+ complete = ((((('class ' + name) + (@base_class ? (('<< ' + @base_class.name)) : (''))) + '
150
+ ') + code.to_s) + '
151
+ end')
152
+ File.open((((('./' + file_path.to_s) + '/') + name) + '.rb'), 'w') do |f|
153
+ f.write(complete)
154
+ end
155
+ complete
156
+ else
157
+ c = @base_class ? (Class.new(base_class)) : (Class.new)
158
+ if with_contracts then
159
+ c.class_eval(
160
+ 'def self.assert_that(obj)
161
+ ContextAsserter.new(self.contracts,obj)
162
+ end
163
+ def self.refute_that(obj)
164
+ ContextAsserter.new(self.contracts,obj,false)
165
+ end
166
+ def self.contracts
167
+ @@contracts
168
+ end
169
+ def self.contracts=(value)
170
+ @@contracts = value
171
+ end')
172
+ c.contracts = contracts
173
+ end
174
+ Kernel.const_set(context_name, c)
175
+ begin
176
+ temp = c.class_eval(code)
177
+ rescue SyntaxError
178
+ p 'error: ' + code
179
+ end
180
+
181
+ (temp or c)
182
+ end
183
+
184
+ end
185
+
186
+ private
187
+
188
+ def contracts
189
+ (@contracts ||= {})
190
+ end
191
+ def role_aliases
192
+ (@role_aliases ||={})
193
+ end
194
+ def interpretation_context
195
+ InterpretationContext.new(roles, contracts, role_aliases, defining_role, @private_interactions)
196
+ end
197
+ end
@@ -6,9 +6,9 @@ require_relative './Tokens'
6
6
  require_relative './ImmutableStack'
7
7
  require_relative './ImmutableQueue'
8
8
  require_relative './interpretation_context'
9
- require_relative './Production'
9
+ require_relative './AbstractSyntaxTree'
10
10
  require_relative './AstRewritter'
11
- require_relative './MethodInfo'
11
+ require_relative './Transformer'
12
12
 
13
13
 
14
14
 
@@ -15,7 +15,11 @@ class InterpretationContext
15
15
  @defining_role
16
16
  end
17
17
 
18
- def initialize(roles, contracts, role_aliases, defining_role)
18
+ def private_interactions
19
+ (@private_interactions ||= {})
20
+ end
21
+
22
+ def initialize(roles, contracts, role_aliases, defining_role, private_interactions)
19
23
  raise "Aliases must be a hash" unless role_aliases.instance_of? Hash or role_aliases == nil
20
24
  raise "Roles must be a hash" unless roles.instance_of? Hash or roles == nil
21
25
  raise "Contracts must be a hash" unless contracts.instance_of? Hash or contracts == nil
@@ -25,5 +29,7 @@ class InterpretationContext
25
29
  @contracts = contracts
26
30
  @role_aliases = role_aliases
27
31
  @defining_role = defining_role
32
+ @private_interactions = private_interactions
33
+
28
34
  end
29
35
  end
@@ -1,6 +1,7 @@
1
1
  class AstRewritter
2
2
  def initialize(ast, interpretation_context)
3
3
  @ast = Production.new(ast, interpretation_context)
4
+ @roles = interpretation_context.roles
4
5
  end
5
6
 
6
7
  def rewrite!()
@@ -12,36 +13,44 @@ class AstRewritter
12
13
  production[1] = nil
13
14
  when Tokens.block_with_bind then
14
15
  block = production.last
15
- must_b_sym = "aliased_role must be a Symbol".to_sym
16
- local_must_b_sym = "local must be a Symbol".to_sym
17
- raise(must_b_sym) unless aliased_role.instance_of?(Symbol)
18
- raise(local_must_b_sym) unless local.instance_of?(Symbol)
19
- aliased_field = ("@" + aliased_role.to_s).to_sym
20
- temp_symbol = ("temp____" + aliased_role.to_s).to_sym
21
- assignment = Sexp.new
22
- assignment[0] = :iasgn
23
- assignment[1] = aliased_field
24
- load_arg = Sexp.new
25
- load_arg[0] = :lvar
26
- load_arg[1] = local
27
- assignment[2] = load_arg
28
- block.insert(1, assignment)
29
- assignment = Sexp.new
30
- assignment[0] = :lasgn
31
- assignment[1] = temp_symbol
32
- load_field = Sexp.new
33
- load_field[0] = :ivar
34
- load_field[1] = aliased_field
35
- assignment[2] = load_field
36
- block.insert(1, assignment)
37
- assignment = Sexp.new
38
- assignment[0] = :iasgn
39
- assignment[1] = aliased_field
40
- load_temp = Sexp.new
41
- load_temp[0] = :lvar
42
- load_temp[1] = temp_symbol
43
- assignment[2] = load_temp
44
- block[block.length] = assignment
16
+ block.delete_at(1)
17
+ production.data.each do |local, aliased_role|
18
+ must_b_sym = "aliased_role must be a Symbol".to_sym
19
+ local_must_b_sym = "local must be a Symbol".to_sym
20
+ raise(must_b_sym) unless aliased_role.instance_of?(Symbol)
21
+ raise(local_must_b_sym) unless local.instance_of?(Symbol)
22
+ unless @roles.has_key?(aliased_role) then
23
+ role_names = []
24
+ @interpretation_context.each { |k, v| (role_names << k.to_s) }
25
+ raise(((aliased_role.to_s + " is not a role. Available roles are ") + role_names.join(",")))
26
+ end
27
+ aliased_field = ("@" + aliased_role.to_s).to_sym
28
+ temp_symbol = ("temp____" + aliased_role.to_s).to_sym
29
+ assignment = Sexp.new
30
+ assignment[0] = :iasgn
31
+ assignment[1] = aliased_field
32
+ load_arg = Sexp.new
33
+ load_arg[0] = :lvar
34
+ load_arg[1] = local
35
+ assignment[2] = load_arg
36
+ block.insert(1, assignment)
37
+ assignment = Sexp.new
38
+ assignment[0] = :lasgn
39
+ assignment[1] = temp_symbol
40
+ load_field = Sexp.new
41
+ load_field[0] = :ivar
42
+ load_field[1] = aliased_field
43
+ assignment[2] = load_field
44
+ block.insert(1, assignment)
45
+ assignment = Sexp.new
46
+ assignment[0] = :iasgn
47
+ assignment[1] = aliased_field
48
+ load_temp = Sexp.new
49
+ load_temp[0] = :lvar
50
+ load_temp[1] = temp_symbol
51
+ assignment[2] = load_temp
52
+ block[block.length] = assignment
53
+ end
45
54
  else
46
55
  # do nothing
47
56
  end
@@ -49,7 +58,8 @@ class AstRewritter
49
58
  end
50
59
 
51
60
  private
52
- attr_reader :ast
53
61
 
54
62
 
63
+ attr_reader :ast
64
+
55
65
  end
@@ -1,22 +1,35 @@
1
1
  class Context
2
2
  def self.define(*args, &block)
3
+ name, base_class, default_interaction = *args
4
+ if default_interaction and (not base_class.instance_of?(Class)) then
5
+ base_class = eval(base_class.to_s)
6
+ end
7
+ if base_class and ((not default_interaction) and (not base_class.instance_of?(Class))) then
8
+ base_class, default_interaction = default_interaction, base_class
9
+ end
3
10
  @@with_contracts ||= nil
4
11
  @@generate_file_path ||= nil
5
- (alias :method_missing :role_or_interaction_method)
6
- base_class, ctx, default_interaction, name = self.send(:create_context_factory, args, block)
7
- if (args.last.instance_of?(FalseClass) or args.last.instance_of?(TrueClass)) then
8
- ctx.generate_files_in(args.last)
9
- end
10
- return ctx.send(:finalize, name, base_class, default_interaction, @@generate_file_path, @@with_contracts)
12
+ ctx = self.send(:create_context_factory, name, base_class, default_interaction, block)
13
+ transformer = Transformer.new(name, ctx.roles, ctx.interactions, ctx.private_interactions, base_class, default_interaction)
14
+ return transformer.transform(@@generate_file_path, @@with_contracts)
11
15
  end
12
16
 
13
17
  def self.generate_files_in(*args, &b)
14
- if block_given? then
15
- return role_or_interaction_method(:generate_files_in, *args, &b)
16
- end
17
18
  @@generate_file_path = args[0]
18
19
  end
19
20
 
21
+ def roles()
22
+ @roles
23
+ end
24
+
25
+ def interactions()
26
+ @interactions
27
+ end
28
+
29
+ def private_interactions()
30
+ @private_interactions
31
+ end
32
+
20
33
  private
21
34
  def get_definitions(b)
22
35
  sexp = b.to_sexp
@@ -28,15 +41,8 @@ class Context
28
41
  sexp.select { |exp| is_definition?(exp) }
29
42
  end
30
43
 
31
- def self.create_context_factory(args, block)
32
- name, base_class, default_interaction = *args
33
- if default_interaction and (not base_class.instance_of?(Class)) then
34
- base_class = eval(base_class.to_s)
35
- end
36
- if base_class and ((not default_interaction) and (not base_class.instance_of?(Class))) then
37
- base_class, default_interaction = default_interaction, base_class
38
- end
39
- ctx = Context.new
44
+ def self.create_context_factory(name, base_class, default_interaction, block)
45
+ ctx = Context.new(name, base_class, default_interaction)
40
46
  ctx.instance_eval do
41
47
  sexp = block.to_sexp
42
48
  temp_block = sexp[3]
@@ -58,7 +64,7 @@ class Context
58
64
  end
59
65
  ctx.instance_eval(&block)
60
66
  end
61
- return [base_class, ctx, default_interaction, name]
67
+ ctx
62
68
  end
63
69
 
64
70
  def self.with_contracts(*args)
@@ -70,136 +76,58 @@ class Context
70
76
  @@with_contracts = value
71
77
  end
72
78
 
73
- def createInfo(definition)
74
- MethodInfo.new(definition, @defining_role, @private)
75
- end
76
-
77
79
  def is_definition?(exp)
78
80
  exp and ((exp[0] == :defn) or (exp[0] == :defs))
79
81
  end
80
82
 
81
83
  def role(*args, &b)
82
84
  role_name = args[0]
83
- if (args.length.!=(1) or (not role_name.instance_of?(Symbol))) then
84
- return role_or_interaction_method(:role, *args, &b)
85
- end
86
85
  @defining_role = role_name
87
86
  @roles = {} unless @roles
88
87
  @roles[role_name] = Hash.new
89
- definitions = get_definitions(b)
90
- definitions.each { |exp| add_method(exp) }
91
- end
92
-
93
- def current_interpretation_context(*args, &b)
94
88
  if block_given? then
95
- return role_or_interaction_method(:current_interpretation_context, *args, &b)
89
+ definitions = get_definitions(b)
90
+ definitions.each { |exp| add_method(exp) }
96
91
  end
97
- InterpretationContext.new(@roles, @contracts, @role_alias, nil)
98
92
  end
99
93
 
100
94
  def get_methods(*args, &b)
101
- return role_or_interaction_method(:get_methods, *args, &b) if block_given?
102
95
  name = args[0]
103
96
  sources = (@defining_role ? (@roles[@defining_role]) : (@interactions))[name]
104
97
  if @defining_role and (not sources) then
105
98
  @roles[@defining_role][name] = []
106
99
  else
100
+ @private_interactions[name] = true if @private
107
101
  @interactions[name] = []
108
102
  end
109
103
  end
110
104
 
111
- def add_method(*args, &b)
112
- return role_or_interaction_method(:add_method, *args, &b) if block_given?
113
- exp = args[0]
114
- info = createInfo(exp)
115
- sources = get_methods(info.name)
116
- (sources << info)
117
- end
118
-
119
- def finalize(*args, &b)
120
- return role_or_interaction_method(:finalize, *args, &b) if block_given?
121
- name, base_class, default, file_path, with_contracts = *args
122
- code = generate_context_code(default, name)
123
- if file_path then
124
- name = name.to_s
125
- complete = ((((("class " + name) + (base_class ? (("<< " + base_class.name)) : (""))) + "\n ") + code.to_s) + "\n end")
126
- File.open((((("./" + file_path.to_s) + "/") + name) + ".rb"), "w") do |f|
127
- f.write(complete)
128
- end
129
- complete
130
- else
131
- c = base_class ? (Class.new(base_class)) : (Class.new)
132
- if with_contracts then
133
- c.class_eval("def self.assert_that(obj)\n ContextAsserter.new(self.contracts,obj)\nend\ndef self.refute_that(obj)\n ContextAsserter.new(self.contracts,obj,false)\nend\ndef self.contracts\n @@contracts\nend\ndef self.contracts=(value)\n @@contracts = value\nend")
134
- c.contracts = contracts
135
- end
136
- Kernel.const_set(name, c)
137
- begin
138
- temp = c.class_eval(code)
139
- rescue SyntaxError
140
- p(("error: " + code))
141
- end
142
- (temp or c)
143
- end
144
- end
145
-
146
- def generate_context_code(*args, &b)
147
- if block_given? then
148
- return role_or_interaction_method(:generate_context_code, *args, &b)
149
- end
150
- default, name = args
151
- getters = ""
152
- impl = ""
153
- interactions = ""
154
- @interactions.each do |method_name, methods|
155
- methods.each do |method|
156
- @defining_role = nil
157
- code = (" " + method.build_as_context_method(current_interpretation_context))
158
- method.is_private ? ((getters << code)) : ((interactions << code))
159
- end
160
- end
161
- if default then
162
- (interactions << (((((((("\n def self.call(*args)\n arity = " + name.to_s) + ".method(:new).arity\n newArgs = args[0..arity-1]\n obj = ") + name.to_s) + ".new *newArgs\n if arity < args.length\n methodArgs = args[arity..-1]\n obj.") + default.to_s) + " *methodArgs\n else\n obj.") + default.to_s) + "\n end\n end\n "))
163
- (interactions << (("\n def call(*args);" + default.to_s) + " *args; end\n"))
164
- end
165
- @roles.each do |role, methods|
166
- (getters << (("attr_reader :" + role.to_s) + "\n "))
167
- methods.each do |method_name, method_sources|
168
- unless (method_sources.length < 2) then
169
- raise(("Duplicate definition of " + method_name.to_s))
170
- end
171
- unless (method_sources.length > 0) then
172
- raise(("No source for " + method_name.to_s))
173
- end
174
- method_source = method_sources[0]
175
- @defining_role = role
176
- definition = method_source.build_as_context_method(current_interpretation_context)
177
- (impl << (" " + definition.to_s)) if definition
178
- end
179
- end
180
- private_string = (getters + impl).strip!.!=("") ? ("\n private\n") : ("")
181
- impl = impl.strip!.!=("") ? ((("\n " + impl) + "\n ")) : ("\n ")
182
- (((interactions + private_string) + getters) + impl)
183
- end
184
-
185
- def role_or_interaction_method(*arguments, &b)
186
- method_name, on_self = *arguments
187
- unless method_name.instance_of?(Symbol) then
188
- on_self = method_name
189
- method_name = :role_or_interaction_method
190
- end
191
- raise(("Method with out block " + method_name.to_s)) unless block_given?
105
+ def add_method(definition)
106
+ name = if definition[1].instance_of?(Symbol) then
107
+ definition[1]
108
+ else
109
+ ((definition[1].select { |e| e.instance_of?(Symbol) }.map { |e| e.to_s }.join(".") + ".") + definition[2].to_s).to_sym
110
+ end
111
+ sources = get_methods(name)
112
+ (sources << definition)
192
113
  end
193
114
 
194
115
  def private()
195
116
  @private = true
196
117
  end
197
118
 
198
- def initialize()
119
+ def initialize(name, base_class, default_interaction)
199
120
  @roles = {}
200
121
  @interactions = {}
122
+ @private_interactions = {}
201
123
  @role_alias = {}
124
+ @name = name
125
+ @base_class = base_class
126
+ @default_interaction = default_interaction
202
127
  end
203
128
 
129
+ attr_reader :name
130
+ attr_reader :base_class
131
+ attr_reader :default_interaction
204
132
 
205
133
  end