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/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
|