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.
@@ -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