maroon 0.6.5 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,86 +1,67 @@
1
1
  context :MethodInfo do
2
- initialize do |on_self, block_source, is_private|
3
- raise 'Must be S-Expressions' unless block_source.instance_of? Sexp
2
+ def initialize(ast, defining_role, is_private)
3
+ raise('Must be S-Expressions') unless ast.instance_of?(Sexp)
4
4
 
5
- if on_self.instance_of? Hash
6
- @block = on_self[:block]
7
- @on_self = on_self[:self]
8
- else
9
- @on_self = on_self
10
- end
11
- @block_source = block_source
5
+ @defining_role = defining_role
12
6
  @private = is_private
7
+ @definition = ast
13
8
  self.freeze
14
9
 
15
10
  end
16
11
 
17
- role :on_self do
18
- end
19
-
20
- role :block do
21
- end
22
-
23
- role :block_source do
24
- get_arguments {
25
- sexp = block_source[2]
26
- return nil unless sexp
27
- return sexp[1] if sexp[0] == :lasgn
28
- return [] if sexp[1] == nil
29
- sexp = sexp[1..-1]
30
- args = []
31
- sexp.each do |e|
32
- args << if e.instance_of? Symbol
33
- e
34
- else
35
- if e[0] == :splat
36
- '*' + e[1][1].to_s
37
- else
38
- e[1]
39
- end
40
- end
12
+ role :definition do
13
+ def body
14
+ args = definition.detect { |d| d[0] == :args }
15
+ index = definition.index(args) + 1
16
+ if definition.length > index+1
17
+ body = definition[index..-1]
18
+ body.insert(0, :block)
19
+ body
20
+ else
21
+ definition[index]
41
22
  end
23
+ end
24
+
25
+ def arguments
26
+ args = definition.detect { |d| d[0] == :args }
27
+ args && args.length > 1 ? args[1..-1] : []
28
+ end
42
29
 
43
- if block
44
- b = '&' + block.to_s
45
- if args
46
- unless args.instance_of? Array
47
- args = [args]
48
- end
49
- args << b
30
+ def name
31
+ if definition[1].instance_of? Symbol
32
+ definition[1]
50
33
  else
51
- args = [b]
34
+ (definition[1].select { |e| e.instance_of? Symbol }.map { |e| e.to_s }.join('.') + '.' + definition[2].to_s).to_sym
52
35
  end
53
- end
54
- args
55
- }
56
-
57
- arguments {
58
- args = block_source.get_arguments
59
- args && args.length ? args.join(',') : nil
60
- }
61
-
62
- body {
63
- block_source[3]
64
- }
36
+ end
65
37
  end
66
38
 
67
- is_private do
39
+ def is_private
68
40
  @private
69
41
  end
70
42
 
71
- build_as_context_method do |context_method_name, interpretation_context|
72
- MethodDefinition.new(block_source.body, interpretation_context).transform
73
- body = Ruby2Ruby.new.process(block_source.body)
74
- args = block_source.arguments ? '(' + block_source.arguments + ')' : ""
75
- on = if on_self then
76
- 'self.'
77
- else
78
- ''
79
- end
80
- '
81
- def ' + on.to_s + context_method_name.to_s + args +'
82
- ' + body +'
83
- end
43
+ def name
44
+ definition.name
45
+ end
46
+
47
+ def build_as_context_method(interpretation_context)
48
+ AstRewritter.new(definition.body, interpretation_context).rewrite!
49
+ body = Ruby2Ruby.new.process(definition.body)
50
+ raise 'Body is undefined' unless body
51
+ args = definition.arguments
52
+ if args && args.length
53
+ args = '('+ args.join(',') + ')'
54
+ else
55
+ args= ''
56
+ end
57
+
58
+ real_name = (if @defining_role == nil
59
+ name.to_s
60
+ else
61
+ 'self_' + @defining_role.to_s + '_' + name.to_s
62
+ end).to_s
63
+ header = 'def ' + real_name + args
64
+ header + ' ' + body + ' end
84
65
  '
85
66
  end
86
67
  end
@@ -0,0 +1,24 @@
1
+ class Tokens
2
+ def self.define_token(name)
3
+ class_eval("@@#{name} = Tokens.new :#{name};def Tokens.#{name};@@#{name};end")
4
+ end
5
+
6
+ def to_s
7
+ @type.to_s
8
+ end
9
+
10
+ private
11
+ def initialize(type)
12
+ @type = type
13
+ self.freeze
14
+ end
15
+
16
+ define_token :terminal
17
+ define_token :role
18
+ define_token :rolemethod_call
19
+ define_token :other
20
+ define_token :call
21
+ define_token :indexer
22
+ define_token :block
23
+ define_token :block_with_bind
24
+ end
@@ -1,13 +1,14 @@
1
1
  require 'sorcerer'
2
2
  require 'sourcify'
3
3
 
4
- require_relative './Self'
5
- require_relative './Bind'
4
+ require_relative './Context'
5
+ require_relative './Tokens'
6
6
  require_relative './ImmutableStack'
7
7
  require_relative './ImmutableQueue'
8
8
  require_relative './interpretation_context'
9
+ require_relative './Production'
10
+ require_relative './AstRewritter'
9
11
  require_relative './MethodInfo'
10
- require_relative './MethodCall'
11
- require_relative './MethodDefinition'
12
- require_relative './Context'
12
+
13
+
13
14
 
@@ -0,0 +1,55 @@
1
+ class AstRewritter
2
+ def initialize(ast, interpretation_context)
3
+ @ast = Production.new(ast, interpretation_context)
4
+ end
5
+
6
+ def rewrite!()
7
+ ast.each do |production|
8
+ case production.type
9
+ when Tokens.rolemethod_call then
10
+ data = production.data
11
+ production[2] = ((("self_" + data[1].to_s) + "_") + data[0].to_s).to_sym
12
+ production[1] = nil
13
+ when Tokens.block_with_bind then
14
+ 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
45
+ else
46
+ # do nothing
47
+ end
48
+ end
49
+ end
50
+
51
+ private
52
+ attr_reader :ast
53
+
54
+
55
+ end
@@ -1,187 +1,205 @@
1
1
  class Context
2
-
3
- def self.define(*args,&block)
2
+ def self.define(*args, &block)
4
3
  @@with_contracts ||= nil
5
- @@generate_file_path ||= nil
6
- (alias :method_missing :role_or_interaction_method)
7
- base_class, ctx, default_interaction, name = self.send(:create_context_factory, args, block)
8
- if (args.last.instance_of?(FalseClass) or args.last.instance_of?(TrueClass)) then
9
- ctx.generate_files_in(args.last)
10
- end
11
- return ctx.send(:finalize, name, base_class, default_interaction)
12
-
13
- end
14
-
15
- def self.generate_files_in(*args,&b)
4
+ @@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)
11
+ end
12
+
13
+ def self.generate_files_in(*args, &b)
16
14
  if block_given? then
17
- return role_or_interaction_method(:generate_files_in, *args, &b)
18
- end
19
- @@generate_file_path = args[0]
15
+ return role_or_interaction_method(:generate_files_in, *args, &b)
16
+ end
17
+ @@generate_file_path = args[0]
18
+ end
20
19
 
21
- end
20
+ private
21
+ def get_definitions(b)
22
+ sexp = b.to_sexp
23
+ unless is_definition?(sexp[3]) then
24
+ sexp = sexp[3]
25
+ sexp = sexp.select { |exp| is_definition?(exp) } if sexp
26
+ sexp ||= []
27
+ end
28
+ sexp.select { |exp| is_definition?(exp) }
29
+ end
30
+
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
40
+ ctx.instance_eval do
41
+ sexp = block.to_sexp
42
+ temp_block = sexp[3]
43
+ i = 0
44
+ while (i < temp_block.length) do
45
+ exp = temp_block[i]
46
+ unless temp_block[(i - 2)] and ((temp_block[(i - 2)][0] == :call) and (temp_block[(i - 1)] and (temp_block[(i - 1)][0] == :args))) then
47
+ if ((exp[0] == :defn) or (exp[0] == :defs)) then
48
+ add_method(exp)
49
+ temp_block.delete_at(i)
50
+ i = (i - 1)
51
+ else
52
+ if (exp[0] == :call) and ((exp[1] == nil) and (exp[2] == :private)) then
53
+ @private = true
54
+ end
55
+ end
56
+ end
57
+ i = (i + 1)
58
+ end
59
+ ctx.instance_eval(&block)
60
+ end
61
+ return [base_class, ctx, default_interaction, name]
62
+ end
22
63
 
23
- private
24
-
25
- def self.with_contracts(*args)
64
+ def self.with_contracts(*args)
26
65
  return @@with_contracts if (args.length == 0)
27
- value = args[0]
28
- if @@with_contracts and (not value) then
29
- raise("make up your mind! disabling contracts during execution will result in undefined behavior")
30
- end
31
- @@with_contracts = value
32
-
33
- end
34
-
35
- def role(*args,&b)
66
+ value = args[0]
67
+ if @@with_contracts and (not value) then
68
+ raise("make up your mind! disabling contracts during execution will result in undefined behavior")
69
+ end
70
+ @@with_contracts = value
71
+ end
72
+
73
+ def createInfo(definition)
74
+ MethodInfo.new(definition, @defining_role, @private)
75
+ end
76
+
77
+ def is_definition?(exp)
78
+ exp and ((exp[0] == :defn) or (exp[0] == :defs))
79
+ end
80
+
81
+ def role(*args, &b)
36
82
  role_name = args[0]
37
- if (args.length.!=(1) or (not role_name.instance_of?(Symbol))) then
38
- return role_or_interaction_method(:role, *args, &b)
39
- end
40
- @defining_role = role_name
41
- @roles[role_name] = Hash.new
42
- yield if block_given?
43
- @defining_role = nil
44
-
45
- end
46
-
47
- def initialize(*args,&b)
48
- if block_given? then
49
- role_or_interaction_method(:initialize, *args, &b)
50
- else
51
- @roles = Hash.new
52
- @interactions = Hash.new
53
- @role_alias = Hash.new
54
- @contracts = Hash.new
55
- end
56
- end
57
-
58
- def private()
59
- @private = true
60
- end
61
-
62
- def current_interpretation_context(*args,&b)
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
+ @defining_role = role_name
87
+ @roles = {} unless @roles
88
+ @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)
63
94
  if block_given? then
64
- return role_or_interaction_method(:current_interpretation_context, *args, &b)
65
- end
66
- InterpretationContext.new(roles, contracts, role_alias, nil)
95
+ return role_or_interaction_method(:current_interpretation_context, *args, &b)
96
+ end
97
+ InterpretationContext.new(@roles, @contracts, @role_alias, nil)
98
+ end
67
99
 
68
- end
69
-
70
- def get_methods(*args,&b)
100
+ def get_methods(*args, &b)
71
101
  return role_or_interaction_method(:get_methods, *args, &b) if block_given?
72
- name = args[0]
73
- sources = (@defining_role ? (@roles[@defining_role]) : (@interactions))[name]
74
- if @defining_role and (not sources) then
75
- @roles[@defining_role][name] = []
76
- else
77
- @interactions[name] = []
78
- end
79
-
80
- end
81
-
82
- def add_method(*args,&b)
102
+ name = args[0]
103
+ sources = (@defining_role ? (@roles[@defining_role]) : (@interactions))[name]
104
+ if @defining_role and (not sources) then
105
+ @roles[@defining_role][name] = []
106
+ else
107
+ @interactions[name] = []
108
+ end
109
+ end
110
+
111
+ def add_method(*args, &b)
83
112
  return role_or_interaction_method(:add_method, *args, &b) if block_given?
84
- name, method = *args
85
- sources = get_methods(name)
86
- (sources << method)
113
+ exp = args[0]
114
+ info = createInfo(exp)
115
+ sources = get_methods(info.name)
116
+ (sources << info)
117
+ end
87
118
 
88
- end
89
-
90
- def finalize(*args,&b)
119
+ def finalize(*args, &b)
91
120
  return role_or_interaction_method(:finalize, *args, &b) if block_given?
92
- name, base_class, default = *args
93
- code = generate_context_code(default, name)
94
- if @@generate_file_path then
95
- name = name.to_s
96
- complete = ((((("class " + name) + (base_class ? (("<< " + base_class.name)) : (""))) + "\n ") + code.to_s) + "\n end")
97
- File.open((((("./" + @@generate_file_path.to_s) + "/") + name) + ".rb"), "w") do |f|
98
- f.write(complete)
99
- end
100
- complete
101
- else
102
- c = base_class ? (Class.new(base_class)) : (Class.new)
103
- if @@with_contracts then
104
- c.class_eval("def self.assert_that(obj)\n ContextAsserter.new(self.contracts,obj)\n end\n def self.refute_that(obj)\n ContextAsserter.new(self.contracts,obj,false)\n end\n def self.contracts\n @@contracts\n end\n def self.contracts=(value)\n raise 'Contracts must be supplied' unless value\n @@contracts = value\n end")
105
- c.contracts = contracts
106
- end
107
- Kernel.const_set(name, c)
108
- temp = c.class_eval(code)
109
- (temp or c)
110
- end
111
-
112
- end
113
-
114
- def self.create_context_factory(args,block)
115
- name, base_class, default_interaction = *args
116
- if default_interaction and (not base_class.instance_of?(Class)) then
117
- base_class = eval(base_class.to_s)
118
- end
119
- if base_class and ((not default_interaction) and (not base_class.instance_of?(Class))) then
120
- base_class, default_interaction = default_interaction, base_class
121
- end
122
- ctx = Context.new
123
- ctx.instance_eval(&block)
124
- return [base_class, ctx, default_interaction, name]
125
-
126
- end
127
-
128
- def generate_context_code(*args,&b)
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)
129
147
  if block_given? then
130
- return role_or_interaction_method(:generate_context_code, *args, &b)
131
- end
132
- default, name = args
133
- getters = ""
134
- impl = ""
135
- interactions = ""
136
- @interactions.each do |method_name, methods|
137
- methods.each do |method|
138
- @defining_role = nil
139
- code = (" " + method.build_as_context_method(method_name, current_interpretation_context))
140
- method.is_private ? ((getters << code)) : ((interactions << code))
141
- end
142
- end
143
- if default then
144
- (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 "))
145
- (interactions << (("\n def call(*args);" + default.to_s) + " *args; end\n"))
146
- end
147
- @roles.each do |role, methods|
148
- (getters << (("attr_reader :" + role.to_s) + "\n "))
149
- methods.each do |method_name, method_sources|
150
- unless (method_sources.length < 2) then
151
- raise(("Duplicate definition of " + method_name.to_s))
152
- end
153
- unless (method_sources.length > 0) then
154
- raise(("No source for " + method_name.to_s))
155
- end
156
- method_source = method_sources[0]
157
- @defining_role = role
158
- rewritten_method_name = ((("self_" + role.to_s) + "_") + method_name.to_s)
159
- definition = method_source.build_as_context_method(rewritten_method_name, current_interpretation_context)
160
- (impl << (" " + definition.to_s)) if definition
161
- end
162
- end
163
- (((((interactions + "\n private\n") + getters) + "\n ") + impl) + "\n ")
164
-
165
- end
166
-
167
- def role_or_interaction_method(*arguments,&b)
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)
168
186
  method_name, on_self = *arguments
169
- unless method_name.instance_of?(Symbol) then
170
- on_self = method_name
171
- method_name = :role_or_interaction_method
172
- end
173
- raise(("Method with out block " + method_name.to_s)) unless block_given?
174
- add_method(method_name, MethodInfo.new(on_self, b.to_sexp, @private))
175
-
176
- end
177
- attr_reader :roles
178
- attr_reader :interactions
179
- attr_reader :defining_role
180
- attr_reader :role_alias
181
- attr_reader :alias_list
182
- attr_reader :cached_roles_and_alias_list
183
- attr_reader :contracts
184
-
185
-
186
-
187
- end
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?
192
+ end
193
+
194
+ def private()
195
+ @private = true
196
+ end
197
+
198
+ def initialize()
199
+ @roles = {}
200
+ @interactions = {}
201
+ @role_alias = {}
202
+ end
203
+
204
+
205
+ end