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.
- 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/base/bind_rewriter.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
context :Bind, :execute do
|
2
|
-
role :block do
|
3
|
-
end
|
4
|
-
role :local do
|
5
|
-
end
|
6
|
-
role :aliased_role do
|
7
|
-
end
|
8
|
-
initialize do |local, aliased_role, block|
|
9
|
-
@local = local
|
10
|
-
@aliased_role = aliased_role
|
11
|
-
@block = block
|
12
|
-
end
|
13
|
-
##
|
14
|
-
#removes call to bind in a block
|
15
|
-
#and replaces it with assignment to the proper role player local variables
|
16
|
-
#in the end of the block the local variables have their original values reassigned
|
17
|
-
execute do
|
18
|
-
must_b_sym = 'aliased_role must be a Symbol'.to_sym
|
19
|
-
local_must_b_sym = 'local must be a Symbol'.to_sym
|
20
|
-
raise must_b_sym unless aliased_role.instance_of? Symbol
|
21
|
-
raise local_must_b_sym unless local.instance_of? Symbol
|
22
|
-
# assigning role player to role field
|
23
|
-
#notice that this will be executed after the next block
|
24
|
-
aliased_field = ('@' + aliased_role.to_s).to_sym
|
25
|
-
temp_symbol = ('temp____' + aliased_role.to_s).to_sym
|
26
|
-
|
27
|
-
assignment = Sexp.new
|
28
|
-
assignment[0] = :iasgn
|
29
|
-
assignment[1] = aliased_field
|
30
|
-
load_arg = Sexp.new
|
31
|
-
load_arg[0] = :lvar
|
32
|
-
load_arg[1] = local
|
33
|
-
assignment[2] = load_arg
|
34
|
-
block.insert 1, assignment
|
35
|
-
|
36
|
-
# assign role player to temp
|
37
|
-
# notice this is prepended Ie. inserted in front of the role player to role field
|
38
|
-
|
39
|
-
assignment = Sexp.new
|
40
|
-
assignment[0] = :lasgn
|
41
|
-
assignment[1] = temp_symbol
|
42
|
-
load_field = Sexp.new
|
43
|
-
load_field[0] = :ivar
|
44
|
-
load_field[1] = aliased_field
|
45
|
-
assignment[2] = load_field
|
46
|
-
block.insert 1, assignment
|
47
|
-
|
48
|
-
# reassign original player
|
49
|
-
assignment = Sexp.new
|
50
|
-
assignment[0] = :iasgn
|
51
|
-
assignment[1] = aliased_field
|
52
|
-
load_temp = Sexp.new
|
53
|
-
load_temp[0] = :lvar
|
54
|
-
load_temp[1] = temp_symbol
|
55
|
-
assignment[2] = load_temp
|
56
|
-
block[block.length] = assignment
|
57
|
-
end
|
58
|
-
end
|
data/base/method_call.rb
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
require_relative '../lib/maroon/kernel'
|
2
|
-
context :MethodCall, :rewrite_call? do
|
3
|
-
role :interpretation_context do
|
4
|
-
contracts {
|
5
|
-
@interpretation_context.contracts || {}
|
6
|
-
}
|
7
|
-
roles {
|
8
|
-
@interpretation_context.roles || {}
|
9
|
-
}
|
10
|
-
role_aliases {
|
11
|
-
@interpretation_context.role_aliases || {}
|
12
|
-
}
|
13
|
-
end
|
14
|
-
|
15
|
-
role :method do
|
16
|
-
call_in_block? {
|
17
|
-
@in_block unless @in_block == nil
|
18
|
-
(@in_block = (method && method[0] == :lvar))
|
19
|
-
}
|
20
|
-
|
21
|
-
get_role_definition {
|
22
|
-
is_call_expression = method && method[0] == :call
|
23
|
-
self_is_instance_expression = (is_call_expression && !method[1])
|
24
|
-
role_name = nil
|
25
|
-
role_name = method[2] if self_is_instance_expression
|
26
|
-
if (not self_is_instance_expression) and method[1]
|
27
|
-
role_name = method[1][2] if method[1][1] == nil and method[1][0] == :call #call role field is instance
|
28
|
-
role_name = interpretation_context.role_aliases[method[1][1]] if method[1][0] == :lvar #local var potentially bound
|
29
|
-
end
|
30
|
-
role = role_name ? interpretation_context.roles[role_name] : nil
|
31
|
-
[role, (role ? role_name : nil)]
|
32
|
-
}
|
33
|
-
|
34
|
-
role_method_call? { |method_name|
|
35
|
-
|
36
|
-
return nil, nil unless method
|
37
|
-
|
38
|
-
role, role_name = method.get_role_definition #is it a call to a role getter
|
39
|
-
|
40
|
-
#in_block = method.call_in_block?
|
41
|
-
#role_name = interpretation_context.role_aliases[role_name] if in_block
|
42
|
-
is_role_method = role && role.has_key?(method_name)
|
43
|
-
|
44
|
-
return role_name, is_role_method
|
45
|
-
}
|
46
|
-
end
|
47
|
-
|
48
|
-
rewrite_call? do
|
49
|
-
method_name = method[2]
|
50
|
-
if method[0] == :call
|
51
|
-
if method[1] == nil && method.length < 5 && method[3] && method[3].length == 1 && method[3][0] == :arglist
|
52
|
-
#accessing a role field?
|
53
|
-
is_role = interpretation_context.roles.has_key? method[3]
|
54
|
-
method[3] = ':@' + method[3].to_sym if is_role
|
55
|
-
else
|
56
|
-
role_name, is_role_method = method.role_method_call? method_name
|
57
|
-
if is_role_method #role_name only returned if it's a role method call
|
58
|
-
method[1] = nil #remove call to attribute
|
59
|
-
method[2] = ('self_' + role_name.to_s + '_' + method_name.to_s).to_sym
|
60
|
-
else # it's an instance method invocation
|
61
|
-
if interpretation_context.roles.has_key? role_name
|
62
|
-
unless method.length == 3 && method[1] == nil && method[2] == role_name
|
63
|
-
contract_methods = (interpretation_context.contracts[role_name] ||= {})
|
64
|
-
contract_methods[method_name] ||= 0
|
65
|
-
contract_methods[method_name] += 1
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
initialize do |method, interpretation_context|
|
73
|
-
raise 'No method supplied' unless method
|
74
|
-
|
75
|
-
@method = method
|
76
|
-
@interpretation_context = interpretation_context
|
77
|
-
end
|
78
|
-
end
|
data/base/self.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
context :Self, :execute do
|
2
|
-
initialize do |abstract_syntax_tree, interpretationcontext|
|
3
|
-
raise 'Interpretation context missing' unless interpretationcontext
|
4
|
-
raise 'Must have a defining role' unless interpretationcontext.defining_role
|
5
|
-
|
6
|
-
@abstract_syntax_tree = abstract_syntax_tree
|
7
|
-
@interpretation_context = interpretationcontext
|
8
|
-
end
|
9
|
-
|
10
|
-
role :abstract_syntax_tree do
|
11
|
-
is_indexer_call_on_self do
|
12
|
-
abstract_syntax_tree.length == 4 &&
|
13
|
-
abstract_syntax_tree[0] == :call &&
|
14
|
-
abstract_syntax_tree[1] == nil &&
|
15
|
-
abstract_syntax_tree[2] == :[] &&
|
16
|
-
abstract_syntax_tree[3][0] == :argslist
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
role :interpretation_context do
|
21
|
-
defining_role do
|
22
|
-
interpretation_context.defining_role
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
# rewrites a call to self in a role method to a call to the role player accessor
|
27
|
-
# which is subsequently rewritten to a call to the instance variable itself
|
28
|
-
# in the case where no role method is called on the role player
|
29
|
-
# It's rewritten to an instance call on the context object if a role method is called
|
30
|
-
execute do
|
31
|
-
if abstract_syntax_tree
|
32
|
-
if abstract_syntax_tree[0] == :self #if self is used in a role method, then rewrite to role getter
|
33
|
-
abstract_syntax_tree[0] = :call
|
34
|
-
abstract_syntax_tree[1] = nil
|
35
|
-
abstract_syntax_tree[2] = interpretation_context.defining_role
|
36
|
-
elsif abstract_syntax_tree[0] == :call and abstract_syntax_tree[1] == nil
|
37
|
-
method_name = abstract_syntax_tree[2]
|
38
|
-
#self is removed from S-expressions
|
39
|
-
if method_name == :[] or method_name == :[]=
|
40
|
-
get_role = Sexp.new
|
41
|
-
get_role[0] = :call
|
42
|
-
get_role[1] = nil
|
43
|
-
get_role[2] = interpretation_context.defining_role
|
44
|
-
abstract_syntax_tree[1] = get_role
|
45
|
-
end
|
46
|
-
elsif abstract_syntax_tree.instance_of? Sexp
|
47
|
-
if abstract_syntax_tree.is_indexer_call_on_self
|
48
|
-
getter = new Sexp.new
|
49
|
-
getter[0] = :call
|
50
|
-
getter[1] = nil
|
51
|
-
getter[2] = interpretation_context.defining_role
|
52
|
-
arglist = Sexp.new
|
53
|
-
getter[3] = arglist
|
54
|
-
arglist[0] = :arglist
|
55
|
-
abstract_syntax_tree[1] = getter
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
data/lib/Bind.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
class Bind
|
2
|
-
|
3
|
-
def initialize(local,aliased_role,block)
|
4
|
-
@local = local
|
5
|
-
@aliased_role = aliased_role
|
6
|
-
@block = block
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
def execute()
|
11
|
-
must_b_sym = "aliased_role must be a Symbol".to_sym
|
12
|
-
local_must_b_sym = "local must be a Symbol".to_sym
|
13
|
-
raise(must_b_sym) unless aliased_role.instance_of?(Symbol)
|
14
|
-
raise(local_must_b_sym) unless local.instance_of?(Symbol)
|
15
|
-
aliased_field = ("@" + aliased_role.to_s).to_sym
|
16
|
-
temp_symbol = ("temp____" + aliased_role.to_s).to_sym
|
17
|
-
assignment = Sexp.new
|
18
|
-
assignment[0] = :iasgn
|
19
|
-
assignment[1] = aliased_field
|
20
|
-
load_arg = Sexp.new
|
21
|
-
load_arg[0] = :lvar
|
22
|
-
load_arg[1] = local
|
23
|
-
assignment[2] = load_arg
|
24
|
-
block.insert(1, assignment)
|
25
|
-
assignment = Sexp.new
|
26
|
-
assignment[0] = :lasgn
|
27
|
-
assignment[1] = temp_symbol
|
28
|
-
load_field = Sexp.new
|
29
|
-
load_field[0] = :ivar
|
30
|
-
load_field[1] = aliased_field
|
31
|
-
assignment[2] = load_field
|
32
|
-
block.insert(1, assignment)
|
33
|
-
assignment = Sexp.new
|
34
|
-
assignment[0] = :iasgn
|
35
|
-
assignment[1] = aliased_field
|
36
|
-
load_temp = Sexp.new
|
37
|
-
load_temp[0] = :lvar
|
38
|
-
load_temp[1] = temp_symbol
|
39
|
-
assignment[2] = load_temp
|
40
|
-
block[block.length] = assignment
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.call(*args)
|
45
|
-
arity = Bind.method(:new).arity
|
46
|
-
newArgs = args[0..arity-1]
|
47
|
-
obj = Bind.new *newArgs
|
48
|
-
if arity < args.length
|
49
|
-
methodArgs = args[arity..-1]
|
50
|
-
obj.execute *methodArgs
|
51
|
-
else
|
52
|
-
obj.execute
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def call(*args);execute *args; end
|
57
|
-
|
58
|
-
private
|
59
|
-
attr_reader :block
|
60
|
-
attr_reader :local
|
61
|
-
attr_reader :aliased_role
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
data/lib/MethodCall.rb
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
class MethodCall
|
2
|
-
|
3
|
-
def rewrite_call?()
|
4
|
-
method_name = method[2]
|
5
|
-
if (method[0] == :call) then
|
6
|
-
if (method[1] == nil) and ((method.length < 5) and (method[3] and ((method[3].length == 1) and (method[3][0] == :arglist)))) then
|
7
|
-
is_role = interpretation_context.roles.has_key?(method[3])
|
8
|
-
method[3] = (":@" + method[3].to_sym) if is_role
|
9
|
-
else
|
10
|
-
role_name, is_role_method = self_method_role_method_call?(method_name)
|
11
|
-
if is_role_method then
|
12
|
-
method[1] = nil
|
13
|
-
method[2] = ((("self_" + role_name.to_s) + "_") + method_name.to_s).to_sym
|
14
|
-
else
|
15
|
-
if interpretation_context.roles.has_key?(role_name) then
|
16
|
-
unless (method.length == 3) and ((method[1] == nil) and (method[2] == role_name)) then
|
17
|
-
contract_methods = interpretation_context.contracts[role_name] ||= {}
|
18
|
-
contract_methods[method_name] ||= 0
|
19
|
-
contract_methods[method_name] += 1
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def initialize(method,interpretation_context)
|
29
|
-
raise("No method supplied") unless method
|
30
|
-
@method = method
|
31
|
-
@interpretation_context = interpretation_context
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.call(*args)
|
36
|
-
arity = MethodCall.method(:new).arity
|
37
|
-
newArgs = args[0..arity-1]
|
38
|
-
obj = MethodCall.new *newArgs
|
39
|
-
if arity < args.length
|
40
|
-
methodArgs = args[arity..-1]
|
41
|
-
obj.rewrite_call? *methodArgs
|
42
|
-
else
|
43
|
-
obj.rewrite_call?
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def call(*args);rewrite_call? *args; end
|
48
|
-
|
49
|
-
private
|
50
|
-
attr_reader :interpretation_context
|
51
|
-
attr_reader :method
|
52
|
-
|
53
|
-
|
54
|
-
def self_interpretation_context_role_aliases()
|
55
|
-
(@interpretation_context.role_aliases or {})
|
56
|
-
end
|
57
|
-
|
58
|
-
def self_method_call_in_block?()
|
59
|
-
@in_block unless (@in_block == nil)
|
60
|
-
@in_block = (method and (method[0] == :lvar))
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
def self_method_get_role_definition()
|
65
|
-
is_call_expression = (method and (method[0] == :call))
|
66
|
-
self_is_instance_expression = (is_call_expression and (not method[1]))
|
67
|
-
role_name = nil
|
68
|
-
role_name = method[2] if self_is_instance_expression
|
69
|
-
if (not self_is_instance_expression) and method[1] then
|
70
|
-
if (method[1][1] == nil) and (method[1][0] == :call) then
|
71
|
-
role_name = method[1][2]
|
72
|
-
end
|
73
|
-
if (method[1][0] == :lvar) then
|
74
|
-
role_name = self_interpretation_context_role_aliases[method[1][1]]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
role = role_name ? (interpretation_context.roles[role_name]) : (nil)
|
78
|
-
[role, role ? (role_name) : (nil)]
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
def self_method_role_method_call?(method_name)
|
83
|
-
return [nil, nil] unless method
|
84
|
-
role, role_name = self_method_get_role_definition
|
85
|
-
is_role_method = (role and role.has_key?(method_name))
|
86
|
-
return [role_name, is_role_method]
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
end
|
data/lib/MethodDefinition.rb
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
class MethodDefinition
|
2
|
-
|
3
|
-
def rebind()
|
4
|
-
@exp, @expressions = expressions.pop
|
5
|
-
@block, @potential_bind = nil
|
6
|
-
if @exp and (@exp.instance_of?(Sexp) and (@exp[0] == :iter)) then
|
7
|
-
@exp[(1..-1)].each do |expr|
|
8
|
-
if expr and (expr.length and (expr[0] == :block)) then
|
9
|
-
@block, @potential_bind = expr, expr[1]
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
@expressions = @exp.instance_of?(Sexp) ? (@expressions.push_array(exp)) : (@expressions)
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
def transform()
|
18
|
-
until self_expressions_empty? do
|
19
|
-
(self_block_transform
|
20
|
-
if exp and exp.instance_of?(Sexp) then
|
21
|
-
is_indexer = ((exp[0] == :call) and ((exp[1] == nil) and ((exp[2] == :[]) or (exp[2] == :[]=))))
|
22
|
-
if (is_indexer or (exp[0] == :self)) and @interpretation_context.defining_role then
|
23
|
-
Self.new(exp, interpretation_context).execute
|
24
|
-
end
|
25
|
-
if (exp[0] == :call) then
|
26
|
-
MethodCall.new(exp, interpretation_context).rewrite_call?
|
27
|
-
end
|
28
|
-
end
|
29
|
-
rebind)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def initialize(exp,interpretationcontext)
|
34
|
-
no_exp = "No expression supplied".to_sym
|
35
|
-
no_ctx = "No interpretation context".to_sym
|
36
|
-
raise(no_exp) unless exp
|
37
|
-
raise(no_ctx) unless interpretationcontext
|
38
|
-
@interpretation_context = interpretationcontext
|
39
|
-
@expressions = ImmutableQueue.empty.push(exp)
|
40
|
-
rebind
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.call(*args)
|
45
|
-
arity = MethodDefinition.method(:new).arity
|
46
|
-
newArgs = args[0..arity-1]
|
47
|
-
obj = MethodDefinition.new *newArgs
|
48
|
-
if arity < args.length
|
49
|
-
methodArgs = args[arity..-1]
|
50
|
-
obj.transform *methodArgs
|
51
|
-
else
|
52
|
-
obj.transform
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def call(*args);transform *args; end
|
57
|
-
|
58
|
-
private
|
59
|
-
attr_reader :interpretation_context
|
60
|
-
attr_reader :exp
|
61
|
-
attr_reader :expressions
|
62
|
-
attr_reader :potential_bind
|
63
|
-
attr_reader :block
|
64
|
-
|
65
|
-
|
66
|
-
def self_interpretation_context_addalias(key,value)
|
67
|
-
@interpretation_context.role_aliases[key] = value
|
68
|
-
end
|
69
|
-
|
70
|
-
def self_expressions_empty?()
|
71
|
-
(expressions == ImmutableQueue.empty)
|
72
|
-
end
|
73
|
-
|
74
|
-
def self_potential_bind_is_bind?()
|
75
|
-
potential_bind and (potential_bind.length and ((potential_bind[0] == :call) and ((potential_bind[1] == nil) and (potential_bind[2] == :bind))))
|
76
|
-
end
|
77
|
-
|
78
|
-
def self_block_transform()
|
79
|
-
if block then
|
80
|
-
@expressions.push_array(block[(1..-1)]) if self_block_transform_bind?
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def self_block_transform_bind?()
|
85
|
-
self_potential_bind_is_bind? and self_block_rewrite
|
86
|
-
end
|
87
|
-
|
88
|
-
def self_block_rewrite()
|
89
|
-
changed = false
|
90
|
-
arguments = potential_bind[3]
|
91
|
-
if arguments and (arguments[0] == :hash) then
|
92
|
-
block.delete_at(1)
|
93
|
-
count = ((arguments.length - 1) / 2)
|
94
|
-
(1..count).each do |j|
|
95
|
-
temp = (j * 2)
|
96
|
-
local = arguments[(temp - 1)][1]
|
97
|
-
local = local[1] if local.instance_of?(Sexp)
|
98
|
-
raise("invalid value for role alias") unless local.instance_of?(Symbol)
|
99
|
-
aliased_role = arguments[temp][1]
|
100
|
-
aliased_role = aliased_role[1] if aliased_role.instance_of?(Sexp)
|
101
|
-
unless aliased_role.instance_of?(Symbol) and interpretation_context.roles.has_key?(aliased_role) then
|
102
|
-
raise(((aliased_role.to_s + "used in binding is an unknown role ") + roles.to_s))
|
103
|
-
end
|
104
|
-
self_interpretation_context_addalias(local, aliased_role)
|
105
|
-
Bind.new(local, aliased_role, block).execute
|
106
|
-
changed = true
|
107
|
-
end
|
108
|
-
end
|
109
|
-
changed
|
110
|
-
|
111
|
-
end
|
112
|
-
|
113
|
-
|
114
|
-
end
|