maroon 0.7.0 → 0.7.1

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