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.
- checksums.yaml +4 -4
- data/Test/Context_test.rb +42 -11
- data/Test/{production_test.rb → abstract_syntax_tree_test.rb} +8 -3
- data/base/{Production.rb → AbstractSyntaxTree.rb} +15 -5
- data/base/AstRewritter.rb +48 -37
- data/base/maroon_base.rb +52 -165
- data/base/transfomer.rb +197 -0
- data/generated/build.rb +2 -2
- data/generated/interpretation_context.rb +7 -1
- data/lib/AstRewritter.rb +41 -31
- data/lib/Context.rb +44 -116
- data/lib/ImmutableQueue.rb +0 -1
- data/lib/ImmutableStack.rb +2 -1
- data/lib/Production.rb +20 -6
- data/lib/Transformer.rb +174 -0
- data/lib/build.rb +3 -3
- data/lib/interpretation_context.rb +7 -1
- data/lib/maroon/version.rb +1 -1
- metadata +6 -7
- data/Test/MethodInfo_test.rb +0 -86
- data/base/method_info.rb +0 -67
- data/lib/MethodInfo.rb +0 -66
data/lib/ImmutableQueue.rb
CHANGED
data/lib/ImmutableStack.rb
CHANGED
data/lib/Production.rb
CHANGED
@@ -77,10 +77,6 @@ class Production
|
|
77
77
|
@interpretation_context = ctx
|
78
78
|
end
|
79
79
|
|
80
|
-
attr_reader :interpretation_context
|
81
|
-
attr_reader :queue
|
82
|
-
attr_reader :production
|
83
|
-
|
84
80
|
def self_production_is_role?()
|
85
81
|
case
|
86
82
|
when (self_production_is_call? and interpretation_context.roles.has_key?(production[2])) then
|
@@ -109,9 +105,23 @@ class Production
|
|
109
105
|
def self_production_is_block_with_bind?()
|
110
106
|
if self_production_is_block? then
|
111
107
|
body = @production.last
|
112
|
-
if body and exp = body[
|
108
|
+
if body and exp = body[1] then
|
113
109
|
bind = Production.new(exp, @interpretation_context)
|
114
|
-
|
110
|
+
if (bind.type == Tokens.call) and (bind.data == :bind) then
|
111
|
+
aliases = {}
|
112
|
+
list = exp.last[(1..-1)]
|
113
|
+
(list.length / 2).times do |i|
|
114
|
+
local = list[(i * 2)].last
|
115
|
+
role_name = list[((i * 2) + 1)].last
|
116
|
+
raise("Local in bind should be a symbol") unless local.instance_of?(Symbol)
|
117
|
+
unless role_name.instance_of?(Symbol) then
|
118
|
+
raise("Role name in bind should be a symbol")
|
119
|
+
end
|
120
|
+
aliases[local] = role_name
|
121
|
+
end
|
122
|
+
@data = aliases
|
123
|
+
true
|
124
|
+
end
|
115
125
|
end
|
116
126
|
end
|
117
127
|
end
|
@@ -132,4 +142,8 @@ class Production
|
|
132
142
|
can_be
|
133
143
|
end
|
134
144
|
|
145
|
+
attr_reader :interpretation_context
|
146
|
+
attr_reader :queue
|
147
|
+
attr_reader :production
|
148
|
+
|
135
149
|
end
|
data/lib/Transformer.rb
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
class Transformer
|
2
|
+
def initialize(context_name, roles, interactions, private_interactions, base_class, default_interaction)
|
3
|
+
@context_name = context_name
|
4
|
+
@roles = roles
|
5
|
+
@interactions = interactions
|
6
|
+
@base_class = base_class
|
7
|
+
@default_interaction = default_interaction
|
8
|
+
@private_interactions = private_interactions
|
9
|
+
@definitions = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def transform(file_path, with_contracts)
|
13
|
+
code = (self_interactions_generated_source + self_roles_generated_source)
|
14
|
+
if file_path then
|
15
|
+
name = context_name.to_s
|
16
|
+
complete = ((((("class " + name) + (@base_class ? (("<< " + @base_class.name)) : (""))) + "\n ") + code.to_s) + "\n end")
|
17
|
+
File.open((((("./" + file_path.to_s) + "/") + name) + ".rb"), "w") do |f|
|
18
|
+
f.write(complete)
|
19
|
+
end
|
20
|
+
complete
|
21
|
+
else
|
22
|
+
c = @base_class ? (Class.new(base_class)) : (Class.new)
|
23
|
+
if with_contracts then
|
24
|
+
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")
|
25
|
+
c.contracts = contracts
|
26
|
+
end
|
27
|
+
Kernel.const_set(context_name, c)
|
28
|
+
begin
|
29
|
+
temp = c.class_eval(code)
|
30
|
+
rescue SyntaxError
|
31
|
+
p(("error: " + code))
|
32
|
+
end
|
33
|
+
(temp or c)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def contracts()
|
39
|
+
@contracts ||= {}
|
40
|
+
end
|
41
|
+
|
42
|
+
def role_aliases()
|
43
|
+
@role_aliases ||= {}
|
44
|
+
end
|
45
|
+
|
46
|
+
def interpretation_context()
|
47
|
+
InterpretationContext.new(roles, contracts, role_aliases, defining_role, @private_interactions)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self_roles_generated_source()
|
51
|
+
impl = ""
|
52
|
+
getters = ""
|
53
|
+
roles.each do |role, methods|
|
54
|
+
(getters << (("attr_reader :" + role.to_s) + "\n "))
|
55
|
+
methods.each do |name, method_sources|
|
56
|
+
temp____defining_role = @defining_role
|
57
|
+
@defining_role = role
|
58
|
+
temp____method_name = @method_name
|
59
|
+
@method_name = name
|
60
|
+
temp____method = @method
|
61
|
+
@method = method_sources
|
62
|
+
definition = self_method_generated_source
|
63
|
+
(impl << (" " + definition)) if definition
|
64
|
+
@method = temp____method
|
65
|
+
@method_name = temp____method_name
|
66
|
+
@defining_role = temp____defining_role
|
67
|
+
end
|
68
|
+
end
|
69
|
+
((((impl.strip! or "") + "\n") + (getters.strip! or "")) + "\n")
|
70
|
+
end
|
71
|
+
|
72
|
+
def self_interactions_generated_source()
|
73
|
+
internal_methods = ""
|
74
|
+
external_methods = self_interactions_default
|
75
|
+
interactions.each do |name, interact|
|
76
|
+
interact.each do |m|
|
77
|
+
temp____method_name = @method_name
|
78
|
+
@method_name = name
|
79
|
+
temp____method = @method
|
80
|
+
@method = m
|
81
|
+
@defining_role = nil
|
82
|
+
code = self_method_generated_source
|
83
|
+
(((self_method_is_private? ? (internal_methods) : (external_methods)) << " ") << code)
|
84
|
+
@method = temp____method
|
85
|
+
@method_name = temp____method_name
|
86
|
+
end
|
87
|
+
end
|
88
|
+
((((external_methods.strip! or "") + "\n private\n") + (internal_methods.strip! or "")) + "\n")
|
89
|
+
end
|
90
|
+
|
91
|
+
def self_interactions_default()
|
92
|
+
if @default then
|
93
|
+
(((((((((("\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 def call(*args);") + default.to_s) + " *args; end\n")
|
94
|
+
else
|
95
|
+
""
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def self_method_is_private?()
|
100
|
+
(defining_role.!=(nil) or private_interactions.has_key?(self_method_name))
|
101
|
+
end
|
102
|
+
|
103
|
+
def self_method_definition()
|
104
|
+
key = ((@defining_role ? (@defining_role.to_s) : ("")) + method_name.to_s)
|
105
|
+
return @definitions[key] if @definitions.has_key?(key)
|
106
|
+
unless method.instance_of?(Sexp) then
|
107
|
+
unless method.instance_of?(Array) and (method.length < 2) then
|
108
|
+
raise((((("Duplicate definition of " + method_name.to_s) + "(") + method.to_s) + ")"))
|
109
|
+
end
|
110
|
+
unless method.instance_of?(Array) and (method.length > 0) then
|
111
|
+
raise(("No source for " + method_name.to_s))
|
112
|
+
end
|
113
|
+
end
|
114
|
+
d = method.instance_of?(Array) ? (method[0]) : (method)
|
115
|
+
raise("Sexp require") unless d.instance_of?(Sexp)
|
116
|
+
@definitions[key] = d
|
117
|
+
end
|
118
|
+
|
119
|
+
def self_method_body()
|
120
|
+
args = self_method_definition.detect { |d| (d[0] == :args) }
|
121
|
+
index = (self_method_definition.index(args) + 1)
|
122
|
+
if (self_method_definition.length > (index + 1)) then
|
123
|
+
body = self_method_definition[(index..-1)]
|
124
|
+
body.insert(0, :block)
|
125
|
+
body
|
126
|
+
else
|
127
|
+
self_method_definition[index]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def self_method_arguments()
|
132
|
+
args = self_method_definition.detect { |d| (d[0] == :args) }
|
133
|
+
args and (args.length > 1) ? (args[(1..-1)]) : ([])
|
134
|
+
end
|
135
|
+
|
136
|
+
def self_method_name()
|
137
|
+
name = if self_method_definition[1].instance_of?(Symbol) then
|
138
|
+
self_method_definition[1].to_s
|
139
|
+
else
|
140
|
+
((self_method_definition[1].select { |e| e.instance_of?(Symbol) }.map do |e|
|
141
|
+
e.to_s
|
142
|
+
end.join(".") + ".") + self_method_definition[2].to_s)
|
143
|
+
end
|
144
|
+
(
|
145
|
+
if defining_role then
|
146
|
+
((("self_" + @defining_role.to_s) + "_") + name.to_s)
|
147
|
+
else
|
148
|
+
name
|
149
|
+
end).to_sym
|
150
|
+
end
|
151
|
+
|
152
|
+
def self_method_generated_source()
|
153
|
+
AstRewritter.new(self_method_body, interpretation_context).rewrite!
|
154
|
+
body = Ruby2Ruby.new.process(self_method_body)
|
155
|
+
raise("Body is undefined") unless body
|
156
|
+
args = self_method_arguments
|
157
|
+
if args and args.length then
|
158
|
+
args = (("(" + args.join(",")) + ")")
|
159
|
+
else
|
160
|
+
args = ""
|
161
|
+
end
|
162
|
+
header = (("def " + self_method_name.to_s) + args)
|
163
|
+
(((header + " ") + body) + " end\n")
|
164
|
+
end
|
165
|
+
|
166
|
+
attr_reader :private_interactions
|
167
|
+
attr_reader :context_name
|
168
|
+
attr_reader :roles
|
169
|
+
attr_reader :interactions
|
170
|
+
attr_reader :method_name
|
171
|
+
attr_reader :defining_role
|
172
|
+
attr_reader :method
|
173
|
+
|
174
|
+
end
|
data/lib/build.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'sorcerer'
|
2
2
|
require 'sourcify'
|
3
3
|
|
4
|
-
|
4
|
+
require_relative './Context'
|
5
5
|
require_relative './Tokens'
|
6
6
|
require_relative './ImmutableStack'
|
7
7
|
require_relative './ImmutableQueue'
|
8
8
|
require_relative './interpretation_context'
|
9
9
|
require_relative './Production'
|
10
10
|
require_relative './AstRewritter'
|
11
|
-
require_relative './
|
11
|
+
require_relative './Transformer'
|
12
|
+
|
12
13
|
|
13
|
-
require_relative './Context'
|
14
14
|
|
@@ -15,7 +15,11 @@ class InterpretationContext
|
|
15
15
|
@defining_role
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
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
|
data/lib/maroon/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: maroon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rune Funch Søltoft
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sourcify
|
@@ -72,18 +72,17 @@ files:
|
|
72
72
|
- Test/Context_test.rb
|
73
73
|
- Test/Greeter_test_disabled.rb
|
74
74
|
- Test/ImmutableQueue_test.rb
|
75
|
-
- Test/
|
75
|
+
- Test/abstract_syntax_tree_test.rb
|
76
76
|
- Test/alltests.rb
|
77
77
|
- Test/assertions.rb
|
78
|
-
- Test/production_test.rb
|
79
78
|
- Test/stack_test.rb
|
80
79
|
- Test/test_helper.rb
|
80
|
+
- base/AbstractSyntaxTree.rb
|
81
81
|
- base/AstRewritter.rb
|
82
82
|
- base/ImmutableStack.rb
|
83
|
-
- base/Production.rb
|
84
83
|
- base/immutable_queue.rb
|
85
84
|
- base/maroon_base.rb
|
86
|
-
- base/
|
85
|
+
- base/transfomer.rb
|
87
86
|
- generated/Tokens.rb
|
88
87
|
- generated/build.rb
|
89
88
|
- generated/interpretation_context.rb
|
@@ -91,9 +90,9 @@ files:
|
|
91
90
|
- lib/Context.rb
|
92
91
|
- lib/ImmutableQueue.rb
|
93
92
|
- lib/ImmutableStack.rb
|
94
|
-
- lib/MethodInfo.rb
|
95
93
|
- lib/Production.rb
|
96
94
|
- lib/Tokens.rb
|
95
|
+
- lib/Transformer.rb
|
97
96
|
- lib/build.rb
|
98
97
|
- lib/interpretation_context.rb
|
99
98
|
- lib/maroon/contracts.rb
|
data/Test/MethodInfo_test.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require_relative '../generated/MethodInfo'
|
3
|
-
require 'ripper'
|
4
|
-
require_relative 'test_helper'
|
5
|
-
|
6
|
-
class MethodInfoTest < Test::Unit::TestCase
|
7
|
-
include SourceAssertions
|
8
|
-
def get_def(&b)
|
9
|
-
(get_sexp &b).detect do |exp|
|
10
|
-
exp[0] == :defn || exp[0] == :defs
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_simple
|
15
|
-
block = get_def do
|
16
|
-
def name (a, b)
|
17
|
-
p 'this is a test'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
source = MethodInfo.new( block,nil,false).build_as_context_method( InterpretationContext.new({}, {}, {}, nil))
|
22
|
-
expected ='def name(a,b) p("this is a test") end'
|
23
|
-
assert_source_equal(expected, source)
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_rolemethod
|
27
|
-
block = get_def do
|
28
|
-
def name (a, b)
|
29
|
-
foo.bar
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
source = MethodInfo.new( block,nil,false).build_as_context_method( InterpretationContext.new({:foo=>{:bar=>[]}}, {}, {}, nil))
|
34
|
-
expected ='def name(a,b) self_foo_bar end'
|
35
|
-
assert_source_equal(expected, source)
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_class_method
|
39
|
-
block = get_def do
|
40
|
-
def self.name(a, b)
|
41
|
-
p 'this is a test'
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
source = MethodInfo.new( block,nil,false).build_as_context_method( InterpretationContext.new({}, {}, {}, nil))
|
46
|
-
expected = 'def self.name(a,b) p("this is a test") end'
|
47
|
-
|
48
|
-
assert_source_equal(expected, source)
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_splat_argument
|
52
|
-
block = get_def do
|
53
|
-
def name (a, *b)
|
54
|
-
p 'this is a test'
|
55
|
-
end
|
56
|
-
end
|
57
|
-
source = MethodInfo.new( block,nil,false).build_as_context_method( InterpretationContext.new({}, {}, {}, nil))
|
58
|
-
expected = 'def name(a,*b) p("this is a test") end'
|
59
|
-
assert_source_equal(expected, source)
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_block_argument
|
63
|
-
block = get_def do
|
64
|
-
def name(a, b,&block)
|
65
|
-
p 'this is a test'
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
source = MethodInfo.new( block,nil,false)
|
70
|
-
source = source.build_as_context_method(InterpretationContext.new({}, {}, {}, nil))
|
71
|
-
expected = 'def name(a,b,&block) p("this is a test") end'
|
72
|
-
|
73
|
-
assert_source_equal(expected, source)
|
74
|
-
end
|
75
|
-
|
76
|
-
def test_block_argument_class_method
|
77
|
-
block = get_def do
|
78
|
-
def self.name(a, *b,&block)
|
79
|
-
p 'is a test'
|
80
|
-
end
|
81
|
-
end
|
82
|
-
source = MethodInfo.new( block,nil,false).build_as_context_method( InterpretationContext.new({}, {}, {}, nil))
|
83
|
-
expected = 'def self.name(a,*b,&block) p("is a test") end'
|
84
|
-
assert_source_equal(expected, source)
|
85
|
-
end
|
86
|
-
end
|
data/base/method_info.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
context :MethodInfo do
|
2
|
-
def initialize(ast, defining_role, is_private)
|
3
|
-
raise('Must be S-Expressions') unless ast.instance_of?(Sexp)
|
4
|
-
|
5
|
-
@defining_role = defining_role
|
6
|
-
@private = is_private
|
7
|
-
@definition = ast
|
8
|
-
self.freeze
|
9
|
-
|
10
|
-
end
|
11
|
-
|
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]
|
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
|
29
|
-
|
30
|
-
def name
|
31
|
-
if definition[1].instance_of? Symbol
|
32
|
-
definition[1]
|
33
|
-
else
|
34
|
-
(definition[1].select { |e| e.instance_of? Symbol }.map { |e| e.to_s }.join('.') + '.' + definition[2].to_s).to_sym
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def is_private
|
40
|
-
@private
|
41
|
-
end
|
42
|
-
|
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
|
65
|
-
'
|
66
|
-
end
|
67
|
-
end
|