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