maroon 0.6.5 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -3
- data/Rakefile +2 -1
- data/Test/Context_test.rb +129 -0
- data/Test/ImmutableQueue_test.rb +5 -5
- data/Test/MethodInfo_test.rb +58 -37
- data/Test/alltests.rb +1 -1
- data/Test/assertions.rb +12 -4
- data/Test/production_test.rb +42 -0
- data/Test/stack_test.rb +5 -6
- data/Test/test_helper.rb +2 -2
- data/base/AstRewritter.rb +63 -0
- data/base/ImmutableStack.rb +7 -5
- data/base/Production.rb +145 -0
- data/base/immutable_queue.rb +6 -5
- data/base/maroon_base.rb +196 -154
- data/base/method_info.rb +48 -67
- data/generated/Tokens.rb +24 -0
- data/generated/build.rb +6 -5
- data/lib/AstRewritter.rb +55 -0
- data/lib/Context.rb +190 -172
- data/lib/ImmutableQueue.rb +33 -39
- data/lib/ImmutableStack.rb +25 -29
- data/lib/MethodInfo.rb +57 -69
- data/lib/Production.rb +135 -0
- data/lib/Tokens.rb +24 -0
- data/lib/build.rb +10 -10
- data/lib/interpretation_context.rb +0 -1
- data/lib/maroon/kernel.rb +1 -1
- data/lib/maroon/version.rb +1 -1
- metadata +10 -15
- data/Test/Generate/method_info_test.rb +0 -12
- data/Test/bind_test.rb +0 -13
- data/Test/expression_test.rb +0 -105
- data/Test/method_call_test.rb +0 -83
- data/Test/self_test.rb +0 -46
- data/base/MethodDefinition.rb +0 -124
- data/base/bind_rewriter.rb +0 -58
- data/base/method_call.rb +0 -78
- data/base/self.rb +0 -60
- data/lib/Bind.rb +0 -65
- data/lib/MethodCall.rb +0 -91
- data/lib/MethodDefinition.rb +0 -114
- data/lib/Self.rb +0 -71
data/lib/maroon/kernel.rb
CHANGED
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.
|
4
|
+
version: 0.7.0
|
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-04-
|
11
|
+
date: 2013-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sourcify
|
@@ -69,36 +69,31 @@ files:
|
|
69
69
|
- LICENSE.txt
|
70
70
|
- README.md
|
71
71
|
- Rakefile
|
72
|
-
- Test/
|
72
|
+
- Test/Context_test.rb
|
73
73
|
- Test/Greeter_test_disabled.rb
|
74
74
|
- Test/ImmutableQueue_test.rb
|
75
75
|
- Test/MethodInfo_test.rb
|
76
76
|
- Test/alltests.rb
|
77
77
|
- Test/assertions.rb
|
78
|
-
- Test/
|
79
|
-
- Test/expression_test.rb
|
80
|
-
- Test/method_call_test.rb
|
81
|
-
- Test/self_test.rb
|
78
|
+
- Test/production_test.rb
|
82
79
|
- Test/stack_test.rb
|
83
80
|
- Test/test_helper.rb
|
81
|
+
- base/AstRewritter.rb
|
84
82
|
- base/ImmutableStack.rb
|
85
|
-
- base/
|
86
|
-
- base/bind_rewriter.rb
|
83
|
+
- base/Production.rb
|
87
84
|
- base/immutable_queue.rb
|
88
85
|
- base/maroon_base.rb
|
89
|
-
- base/method_call.rb
|
90
86
|
- base/method_info.rb
|
91
|
-
-
|
87
|
+
- generated/Tokens.rb
|
92
88
|
- generated/build.rb
|
93
89
|
- generated/interpretation_context.rb
|
94
|
-
- lib/
|
90
|
+
- lib/AstRewritter.rb
|
95
91
|
- lib/Context.rb
|
96
92
|
- lib/ImmutableQueue.rb
|
97
93
|
- lib/ImmutableStack.rb
|
98
|
-
- lib/MethodCall.rb
|
99
|
-
- lib/MethodDefinition.rb
|
100
94
|
- lib/MethodInfo.rb
|
101
|
-
- lib/
|
95
|
+
- lib/Production.rb
|
96
|
+
- lib/Tokens.rb
|
102
97
|
- lib/build.rb
|
103
98
|
- lib/interpretation_context.rb
|
104
99
|
- lib/maroon/contracts.rb
|
data/Test/bind_test.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require_relative '../generated/bind'
|
2
|
-
require_relative 'test_helper'
|
3
|
-
|
4
|
-
class Bind_test < MiniTest::Unit::TestCase
|
5
|
-
def test_sunny
|
6
|
-
block = Sexp.new
|
7
|
-
Bind.new(:role, :alias, block).execute
|
8
|
-
assert_equal(nil, block[0])
|
9
|
-
assert_equal(:@alias, block[1][2][1])
|
10
|
-
assert_equal(:role, block[2][2][1])
|
11
|
-
assert_equal(:@alias, block.last()[1])
|
12
|
-
end
|
13
|
-
end
|
data/Test/expression_test.rb
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
require_relative '../generated/MethodDefinition'
|
2
|
-
require_relative 'test_helper'
|
3
|
-
require 'ripper'
|
4
|
-
|
5
|
-
class Expression_test < MiniTest::Unit::TestCase
|
6
|
-
include SourceAssertions
|
7
|
-
def get_context
|
8
|
-
contracts = {}
|
9
|
-
roles = {:foo=>{:bar=>nil},:baz=>{:rolemethod=>nil},:role=>{}}
|
10
|
-
aliases = {}
|
11
|
-
InterpretationContext.new(roles,contracts,aliases,:role)
|
12
|
-
end
|
13
|
-
def assert_transform(expected,block)
|
14
|
-
raise "No block" unless block
|
15
|
-
|
16
|
-
ctx = get_context
|
17
|
-
md = MethodDefinition.new(block,ctx)
|
18
|
-
md.transform
|
19
|
-
|
20
|
-
assert_source_equal(expected,block)
|
21
|
-
ctx
|
22
|
-
end
|
23
|
-
def test_method_call
|
24
|
-
block = (get_sexp { baz.rolemethod })[3]
|
25
|
-
|
26
|
-
expected = (get_sexp { self_baz_rolemethod })[3]
|
27
|
-
|
28
|
-
assert_transform(expected,block)
|
29
|
-
end
|
30
|
-
def test_index
|
31
|
-
block = (get_sexp do
|
32
|
-
self[0]
|
33
|
-
end)[3]
|
34
|
-
expected = (get_sexp do
|
35
|
-
role[0]
|
36
|
-
end)[3]
|
37
|
-
ctx = assert_transform(expected,block)
|
38
|
-
assert_equal(1,ctx.contracts[:role][:[]])
|
39
|
-
end
|
40
|
-
def test_bind
|
41
|
-
block = get_sexp do [].each do |r|
|
42
|
-
bind :r=>:foo
|
43
|
-
r.bar
|
44
|
-
foo.baz
|
45
|
-
end
|
46
|
-
end
|
47
|
-
expected = (get_sexp do
|
48
|
-
[].each do |r|
|
49
|
-
temp____foo = @foo
|
50
|
-
@foo = r
|
51
|
-
self_foo_bar
|
52
|
-
foo.baz
|
53
|
-
@foo = temp____foo
|
54
|
-
end
|
55
|
-
end)
|
56
|
-
assert_transform(expected,block)
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_sunny
|
60
|
-
block = get_sexp do
|
61
|
-
[].each do |r|
|
62
|
-
bind :r => :foo
|
63
|
-
r.bar
|
64
|
-
r.baz
|
65
|
-
baz.rolemethod
|
66
|
-
self[boo]
|
67
|
-
end
|
68
|
-
self[0]
|
69
|
-
end
|
70
|
-
expected = (get_sexp do
|
71
|
-
[].each do |r|
|
72
|
-
temp____foo = @foo
|
73
|
-
@foo = r
|
74
|
-
self_foo_bar
|
75
|
-
r.baz
|
76
|
-
self_baz_rolemethod
|
77
|
-
role[boo]
|
78
|
-
@foo = temp____foo
|
79
|
-
end
|
80
|
-
role[0]
|
81
|
-
end)
|
82
|
-
|
83
|
-
interpretation_context = get_context
|
84
|
-
MethodDefinition.new(block,interpretation_context).transform
|
85
|
-
assert_source_equal(expected,block)
|
86
|
-
contracts = interpretation_context.contracts
|
87
|
-
assert_equal(2,contracts.length)
|
88
|
-
assert(contracts[:role].has_key? :[])
|
89
|
-
assert_equal(1,contracts[:role].length)
|
90
|
-
assert(contracts[:foo].has_key? :baz)
|
91
|
-
assert_nil(contracts[:baz])
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_nested_lambda
|
95
|
-
|
96
|
-
block = (get_sexp {lambda {
|
97
|
-
lambda {baz.rolemethod}}.call})
|
98
|
-
|
99
|
-
expected = (get_sexp {lambda {
|
100
|
-
lambda {self_baz_rolemethod}}.call})
|
101
|
-
|
102
|
-
assert_transform(expected,block)
|
103
|
-
end
|
104
|
-
|
105
|
-
end
|
data/Test/method_call_test.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
require_relative '../generated/MethodCall'
|
2
|
-
require_relative 'test_helper'
|
3
|
-
|
4
|
-
class Method_call_test < MiniTest::Unit::TestCase
|
5
|
-
def get_method_call &b
|
6
|
-
exp = get_sexp &b
|
7
|
-
exp[3]
|
8
|
-
end
|
9
|
-
include SourceAssertions
|
10
|
-
def test_adding_to_contracts_no_role
|
11
|
-
method_call = get_method_call {foo.bar}
|
12
|
-
|
13
|
-
contracts ={}
|
14
|
-
MethodCall.new(method_call, InterpretationContext.new({},contracts,nil,nil)).rewrite_call?
|
15
|
-
assert_nil(contracts[nil]) #wasn't a role
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_adding_to_contracts_with_role
|
19
|
-
method_call = get_method_call {foo.bar}
|
20
|
-
|
21
|
-
contracts ={}
|
22
|
-
roles = Hash.new
|
23
|
-
roles[:foo] = Hash.new
|
24
|
-
MethodCall.new(method_call, InterpretationContext.new(roles,contracts,nil,nil)).rewrite_call?
|
25
|
-
assert_equal(1,contracts.length)
|
26
|
-
assert_equal(1, contracts[:foo].length)
|
27
|
-
assert_equal(1, contracts[:foo][:bar])
|
28
|
-
end
|
29
|
-
def test_role_methods_not_added_to_contracts
|
30
|
-
method_call = get_method_call {foo.bar}
|
31
|
-
|
32
|
-
contracts ={}
|
33
|
-
roles = Hash.new
|
34
|
-
roles[:foo] = {:bar => nil}
|
35
|
-
MethodCall.new(method_call, InterpretationContext.new(roles,contracts,nil,nil)).rewrite_call?
|
36
|
-
assert_equal(0,contracts.length)
|
37
|
-
assert_source_equal(get_method_call {self_foo_bar},method_call)
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_contract_and_bind
|
41
|
-
block =get_sexp do [].each do |r|
|
42
|
-
temp____foo = @foo
|
43
|
-
@foo = r
|
44
|
-
r.bar
|
45
|
-
foo.baz
|
46
|
-
@foo = temp____foo
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
contracts ={}
|
51
|
-
roles = {:foo=> {:bar => nil},:role=>{}}
|
52
|
-
methodcall1 = block[3][3][3]
|
53
|
-
methodcall2 = block[3][3][4]
|
54
|
-
expected1 = get_method_call {self_foo_bar}
|
55
|
-
expected2 = get_method_call {foo.baz}
|
56
|
-
|
57
|
-
MethodCall.new(methodcall1, InterpretationContext.new(roles,contracts,{:r=>:foo},:role)).rewrite_call?
|
58
|
-
MethodCall.new(methodcall2, InterpretationContext.new(roles,contracts,{:r=>:foo},:role)).rewrite_call?
|
59
|
-
|
60
|
-
assert_source_equal(expected2,methodcall2)
|
61
|
-
assert_source_equal(expected1,methodcall1)
|
62
|
-
assert_equal(1,contracts.length)
|
63
|
-
assert_equal(1,contracts[:foo].length)
|
64
|
-
assert_equal(1,contracts[:foo][:baz])
|
65
|
-
assert_nil(contracts[:bar])
|
66
|
-
end
|
67
|
-
def test_index_contracts
|
68
|
-
methodcall = (get_sexp do
|
69
|
-
role[boo]
|
70
|
-
end)[3]
|
71
|
-
|
72
|
-
contracts = {}
|
73
|
-
roles = {:foo=>{:bar=>nil},:baz=>{:rolemethod=>nil},:role=>{}}
|
74
|
-
aliases = {}
|
75
|
-
interpretation_context = InterpretationContext.new(roles,contracts,aliases,:role)
|
76
|
-
mc = MethodCall.new(methodcall, interpretation_context)
|
77
|
-
mc.rewrite_call?
|
78
|
-
|
79
|
-
assert_equal(1,contracts.length)
|
80
|
-
assert_equal(1,interpretation_context.contracts[:role].length)
|
81
|
-
assert_equal(1,interpretation_context.contracts[:role][:[]])
|
82
|
-
end
|
83
|
-
end
|
data/Test/self_test.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
require_relative '../generated/self'
|
2
|
-
require_relative 'test_helper'
|
3
|
-
|
4
|
-
require 'ruby2ruby'
|
5
|
-
|
6
|
-
class Self_test < MiniTest::Unit::TestCase
|
7
|
-
include SourceAssertions
|
8
|
-
def assert_self(abstract_syntax_tree, defining_role)
|
9
|
-
assert_equal(:call,abstract_syntax_tree[0])
|
10
|
-
assert_nil(abstract_syntax_tree[1])
|
11
|
-
assert_equal(defining_role, abstract_syntax_tree[2])
|
12
|
-
assert_instance_of(Sexp,abstract_syntax_tree[3])
|
13
|
-
assert_equal(abstract_syntax_tree[3][0], :arglist)
|
14
|
-
end
|
15
|
-
def interpretation_context
|
16
|
-
InterpretationContext.new({:role=>{}},nil,nil,:role)
|
17
|
-
end
|
18
|
-
def test_sunny
|
19
|
-
ast = (get_sexp { self.bar })[3]
|
20
|
-
|
21
|
-
Self.new(ast[1],interpretation_context).execute
|
22
|
-
|
23
|
-
expected = (get_sexp { role.bar })[3]
|
24
|
-
assert_source_equal(expected,ast)
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_indexer
|
28
|
-
ast = (get_sexp {self[0]})[3]
|
29
|
-
|
30
|
-
Self.new(ast,interpretation_context).execute
|
31
|
-
|
32
|
-
expected = (get_sexp { role[0] })[3]
|
33
|
-
assert_source_equal(expected,ast)
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_as_index
|
37
|
-
ast = (get_sexp {bar[self]})[3]
|
38
|
-
|
39
|
-
Self.new(ast[3],interpretation_context).execute
|
40
|
-
|
41
|
-
expected = (get_sexp { bar[role] })[3]
|
42
|
-
refute_nil(ast)
|
43
|
-
refute_equal(0,ast.length)
|
44
|
-
assert_source_equal(expected,ast)
|
45
|
-
end
|
46
|
-
end
|
data/base/MethodDefinition.rb
DELETED
@@ -1,124 +0,0 @@
|
|
1
|
-
context :MethodDefinition, :transform do
|
2
|
-
|
3
|
-
rebind do
|
4
|
-
@exp, @expressions = expressions.pop
|
5
|
-
@block, @potential_bind = nil
|
6
|
-
if @exp && (@exp.instance_of? Sexp) && @exp[0] == :iter
|
7
|
-
@exp[1..-1].each do |expr|
|
8
|
-
#find the block
|
9
|
-
if expr && expr.length && expr[0] == :block
|
10
|
-
@block, @potential_bind = expr, expr[1]
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
@expressions = if @exp.instance_of? Sexp then
|
15
|
-
@expressions.push_array(exp)
|
16
|
-
else
|
17
|
-
@expressions
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
transform do
|
22
|
-
#could have been recursive but the stack depth isn't enough for even simple contexts
|
23
|
-
until expressions.empty?
|
24
|
-
|
25
|
-
block.transform
|
26
|
-
if exp && (exp.instance_of? Sexp)
|
27
|
-
is_indexer = exp[0] == :call && exp[1] == nil && (exp[2] == :[] || exp[2] == :[]=)
|
28
|
-
if (is_indexer || (exp[0] == :self)) && @interpretation_context.defining_role
|
29
|
-
Self.new(exp, interpretation_context).execute
|
30
|
-
end
|
31
|
-
if exp[0] == :call
|
32
|
-
MethodCall.new(exp, interpretation_context).rewrite_call?
|
33
|
-
end
|
34
|
-
end
|
35
|
-
rebind
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
initialize do |exp, interpretationcontext|
|
40
|
-
no_exp = 'No expression supplied'.to_sym
|
41
|
-
no_ctx = 'No interpretation context'.to_sym
|
42
|
-
|
43
|
-
raise no_exp unless exp
|
44
|
-
raise no_ctx unless interpretationcontext
|
45
|
-
|
46
|
-
@interpretation_context = interpretationcontext
|
47
|
-
@expressions = ImmutableQueue::empty.push exp
|
48
|
-
rebind
|
49
|
-
end
|
50
|
-
|
51
|
-
role :interpretation_context do
|
52
|
-
addalias do |key, value|
|
53
|
-
@interpretation_context.role_aliases[key] = value
|
54
|
-
end
|
55
|
-
end
|
56
|
-
role :exp do
|
57
|
-
end
|
58
|
-
role :expressions do
|
59
|
-
empty? do
|
60
|
-
expressions == ImmutableQueue::empty
|
61
|
-
end
|
62
|
-
end
|
63
|
-
role :potential_bind do
|
64
|
-
is_bind? do
|
65
|
-
potential_bind &&
|
66
|
-
potential_bind.length &&
|
67
|
-
(potential_bind[0] == :call &&
|
68
|
-
potential_bind[1] == nil &&
|
69
|
-
potential_bind[2] == :bind)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
role :block do
|
73
|
-
##
|
74
|
-
#Transforms blocks as needed
|
75
|
-
#-Rewrites self in role methods to the role getter
|
76
|
-
#-Rewrites binds when needed
|
77
|
-
#-Rewrites role method calls to instance method calls on the context
|
78
|
-
##
|
79
|
-
transform {
|
80
|
-
if block
|
81
|
-
if block.transform_bind?
|
82
|
-
@expressions.push_array(block[1..-1])
|
83
|
-
end
|
84
|
-
end
|
85
|
-
}
|
86
|
-
##
|
87
|
-
#Calls rewrite_block if needed and will return true if the AST was changed otherwise false
|
88
|
-
##
|
89
|
-
transform_bind? {
|
90
|
-
#check if the first call is a bind call
|
91
|
-
potential_bind.is_bind? && block.rewrite
|
92
|
-
}
|
93
|
-
|
94
|
-
rewrite {
|
95
|
-
changed = false
|
96
|
-
arguments = potential_bind[3]
|
97
|
-
|
98
|
-
if arguments && arguments[0] == :hash
|
99
|
-
block.delete_at 1
|
100
|
-
count = (arguments.length-1) / 2
|
101
|
-
(1..count).each do |j|
|
102
|
-
temp = j * 2
|
103
|
-
local = arguments[temp-1][1]
|
104
|
-
if local.instance_of? Sexp
|
105
|
-
local = local[1]
|
106
|
-
end
|
107
|
-
raise 'invalid value for role alias' unless local.instance_of? Symbol
|
108
|
-
#find the name of the role being bound to
|
109
|
-
aliased_role = arguments[temp][1]
|
110
|
-
if aliased_role.instance_of? Sexp
|
111
|
-
aliased_role = aliased_role[1]
|
112
|
-
end
|
113
|
-
raise aliased_role.to_s + 'used in binding is an unknown role ' + roles.to_s unless aliased_role.instance_of? Symbol and interpretation_context.roles.has_key? aliased_role
|
114
|
-
interpretation_context.addalias local, aliased_role
|
115
|
-
#replace bind call with assignment of iteration variable to role field
|
116
|
-
Bind.new(local, aliased_role, block).execute
|
117
|
-
changed = true
|
118
|
-
end
|
119
|
-
end
|
120
|
-
changed
|
121
|
-
}
|
122
|
-
end
|
123
|
-
|
124
|
-
end
|