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/ImmutableQueue.rb
CHANGED
@@ -1,50 +1,44 @@
|
|
1
1
|
class ImmutableQueue
|
2
|
-
|
3
|
-
def push(element)
|
2
|
+
def push(element)
|
4
3
|
b = (back or ImmutableStack.empty)
|
5
|
-
ImmutableQueue.new(front, b.push(element))
|
4
|
+
ImmutableQueue.new(front, b.push(element))
|
5
|
+
end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
def pop()
|
7
|
+
def pop()
|
10
8
|
f, b = front, back
|
11
|
-
if (f == ImmutableStack.empty) then
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
if (f == ImmutableStack.empty) then
|
10
|
+
until (b == ImmutableStack.empty) do
|
11
|
+
(e, b = b.pop
|
12
|
+
f = f.push(e))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
head, f = f.pop
|
16
|
+
if (f == b) then
|
17
|
+
[head, ImmutableQueue.empty]
|
18
|
+
else
|
19
|
+
[head, ImmutableQueue.new(f, b)]
|
20
|
+
end
|
15
21
|
end
|
16
|
-
end
|
17
|
-
head, f = f.pop
|
18
|
-
if (f == b) then
|
19
|
-
[head, ImmutableQueue.empty]
|
20
|
-
else
|
21
|
-
[head, ImmutableQueue.new(f, b)]
|
22
|
-
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
def self.empty()
|
23
|
+
def self.empty()
|
27
24
|
@@empty ||= ImmutableQueue.new(ImmutableStack.empty, ImmutableStack.empty)
|
28
|
-
|
29
|
-
|
30
|
-
def push_array(arr)
|
31
|
-
q = self
|
32
|
-
arr.each { |i| q = q.push(i) } if arr
|
33
|
-
q
|
25
|
+
end
|
34
26
|
|
35
|
-
|
27
|
+
def push_array(arr)
|
28
|
+
q = self
|
29
|
+
arr.each { |i| q = q.push(i) } if arr
|
30
|
+
q
|
31
|
+
end
|
36
32
|
|
37
|
-
|
38
|
-
|
39
|
-
def initialize(front,back)
|
33
|
+
private
|
34
|
+
def initialize(front, back)
|
40
35
|
@front = (front or ImmutableStack.empty)
|
41
|
-
@back = (back or ImmutableStack.empty)
|
42
|
-
self.freeze
|
36
|
+
@back = (back or ImmutableStack.empty)
|
37
|
+
self.freeze
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_reader :front
|
41
|
+
attr_reader :back
|
42
|
+
|
43
43
|
|
44
|
-
|
45
|
-
attr_reader :front
|
46
|
-
attr_reader :back
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
44
|
+
end
|
data/lib/ImmutableStack.rb
CHANGED
@@ -1,38 +1,34 @@
|
|
1
1
|
class ImmutableStack
|
2
|
-
|
3
|
-
def pop()
|
2
|
+
def pop()
|
4
3
|
[@head, @tail]
|
5
|
-
|
6
|
-
|
7
|
-
def push(element)
|
4
|
+
end
|
5
|
+
|
6
|
+
def push(element)
|
8
7
|
ImmutableStack.new(element, self)
|
9
|
-
|
10
|
-
|
11
|
-
def self.empty()
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.empty()
|
12
11
|
@@empty ||= self.new(nil, nil)
|
13
|
-
|
14
|
-
|
15
|
-
def each()
|
12
|
+
end
|
13
|
+
|
14
|
+
def each()
|
16
15
|
yield(head)
|
17
|
-
t = tail
|
18
|
-
while t.!=(ImmutableStack.empty) do
|
19
|
-
|
20
|
-
|
21
|
-
end
|
16
|
+
t = tail
|
17
|
+
while t.!=(ImmutableStack.empty) do
|
18
|
+
h, t = t.pop
|
19
|
+
yield(h)
|
20
|
+
end
|
21
|
+
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
def initialize(h,t)
|
23
|
+
def initialize(h, t)
|
26
24
|
@head = h
|
27
|
-
@tail = t
|
28
|
-
self.freeze
|
25
|
+
@tail = t
|
26
|
+
self.freeze
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
attr_reader :head
|
31
|
+
attr_reader :tail
|
29
32
|
|
30
|
-
end
|
31
33
|
|
32
|
-
|
33
|
-
attr_reader :head
|
34
|
-
attr_reader :tail
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
34
|
+
end
|
data/lib/MethodInfo.rb
CHANGED
@@ -1,78 +1,66 @@
|
|
1
1
|
class MethodInfo
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@on_self = on_self
|
10
|
-
end
|
11
|
-
@block_source = block_source
|
12
|
-
@private = is_private
|
13
|
-
self.freeze
|
2
|
+
def initialize(ast, defining_role, is_private)
|
3
|
+
raise("Must be S-Expressions") unless ast.instance_of?(Sexp)
|
4
|
+
@defining_role = defining_role
|
5
|
+
@private = is_private
|
6
|
+
@definition = ast
|
7
|
+
self.freeze
|
8
|
+
end
|
14
9
|
|
15
|
-
|
16
|
-
|
17
|
-
def is_private()
|
10
|
+
def is_private()
|
18
11
|
@private
|
19
|
-
|
20
|
-
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
args = if self_block_source_arguments then
|
25
|
-
(("(" + self_block_source_arguments) + ")")
|
26
|
-
else
|
27
|
-
""
|
28
|
-
end
|
29
|
-
on = on_self ? ("self.") : ("")
|
30
|
-
(((((("\ndef " + on.to_s) + context_method_name.to_s) + args) + "\n ") + body) + "\n end\n")
|
12
|
+
end
|
13
|
+
|
14
|
+
def name()
|
15
|
+
self_definition_name
|
16
|
+
end
|
31
17
|
|
32
|
-
|
18
|
+
def build_as_context_method(interpretation_context)
|
19
|
+
AstRewritter.new(self_definition_body, interpretation_context).rewrite!
|
20
|
+
body = Ruby2Ruby.new.process(self_definition_body)
|
21
|
+
raise("Body is undefined") unless body
|
22
|
+
args = self_definition_arguments
|
23
|
+
if args and args.length then
|
24
|
+
args = (("(" + args.join(",")) + ")")
|
25
|
+
else
|
26
|
+
args = ""
|
27
|
+
end
|
28
|
+
real_name = (
|
29
|
+
if (@defining_role == nil) then
|
30
|
+
name.to_s
|
31
|
+
else
|
32
|
+
((("self_" + @defining_role.to_s) + "_") + name.to_s)
|
33
|
+
end).to_s
|
34
|
+
header = (("def " + real_name) + args)
|
35
|
+
(((header + " ") + body) + " end\n")
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
attr_reader :definition
|
33
40
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
return [] if (sexp[1] == nil)
|
45
|
-
sexp = sexp[(1..-1)]
|
46
|
-
args = []
|
47
|
-
sexp.each do |e|
|
48
|
-
(args << (if e.instance_of?(Symbol) then
|
49
|
-
e
|
50
|
-
else
|
51
|
-
(e[0] == :splat) ? (("*" + e[1][1].to_s)) : (e[1])
|
52
|
-
end))
|
53
|
-
end
|
54
|
-
if block then
|
55
|
-
b = ("&" + block.to_s)
|
56
|
-
if args then
|
57
|
-
args = [args] unless args.instance_of?(Array)
|
58
|
-
(args << b)
|
59
|
-
else
|
60
|
-
args = [b]
|
41
|
+
def self_definition_body()
|
42
|
+
args = definition.detect { |d| (d[0] == :args) }
|
43
|
+
index = (definition.index(args) + 1)
|
44
|
+
if (definition.length > (index + 1)) then
|
45
|
+
body = definition[(index..-1)]
|
46
|
+
body.insert(0, :block)
|
47
|
+
body
|
48
|
+
else
|
49
|
+
definition[index]
|
50
|
+
end
|
61
51
|
end
|
62
|
-
end
|
63
|
-
args
|
64
52
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
args and args.length ? (args.join(",")) : (nil)
|
53
|
+
def self_definition_arguments()
|
54
|
+
args = definition.detect { |d| (d[0] == :args) }
|
55
|
+
args and (args.length > 1) ? (args[(1..-1)]) : ([])
|
56
|
+
end
|
70
57
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
58
|
+
def self_definition_name()
|
59
|
+
if definition[1].instance_of?(Symbol) then
|
60
|
+
definition[1]
|
61
|
+
else
|
62
|
+
((definition[1].select { |e| e.instance_of?(Symbol) }.map { |e| e.to_s }.join(".") + ".") + definition[2].to_s).to_sym
|
63
|
+
end
|
64
|
+
end
|
76
65
|
|
77
|
-
|
78
|
-
end
|
66
|
+
end
|
data/lib/Production.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
class Production
|
2
|
+
def initialize(ast, interpretation_context)
|
3
|
+
rebind(ImmutableQueue.empty.push(ast), interpretation_context)
|
4
|
+
end
|
5
|
+
|
6
|
+
def type()
|
7
|
+
case
|
8
|
+
when (nil == production) then
|
9
|
+
nil
|
10
|
+
when self_production_is_block_with_bind? then
|
11
|
+
Tokens.block_with_bind
|
12
|
+
when self_production_is_block? then
|
13
|
+
Tokens.block
|
14
|
+
when (production.instance_of?(Fixnum) or production.instance_of?(Symbol)) then
|
15
|
+
Tokens.terminal
|
16
|
+
when self_production_is_rolemethod_call? then
|
17
|
+
Tokens.rolemethod_call
|
18
|
+
when self_production_is_role? then
|
19
|
+
Tokens.role
|
20
|
+
when self_production_is_indexer? then
|
21
|
+
Tokens.indexer
|
22
|
+
when self_production_is_call? then
|
23
|
+
Tokens.call
|
24
|
+
else
|
25
|
+
Tokens.other
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def [](i)
|
30
|
+
@production[i]
|
31
|
+
end
|
32
|
+
|
33
|
+
def []=(i, v)
|
34
|
+
@production[i] = v
|
35
|
+
end
|
36
|
+
|
37
|
+
def length()
|
38
|
+
@production.length
|
39
|
+
end
|
40
|
+
|
41
|
+
def last()
|
42
|
+
@production.last
|
43
|
+
end
|
44
|
+
|
45
|
+
def first()
|
46
|
+
@production.first
|
47
|
+
end
|
48
|
+
|
49
|
+
def data()
|
50
|
+
return @data if @data
|
51
|
+
@data = case
|
52
|
+
when self_production_is_call? then
|
53
|
+
@production[2]
|
54
|
+
else
|
55
|
+
@production
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def each()
|
60
|
+
yield(self)
|
61
|
+
if production.instance_of?((Sexp or production.instance_of?(Array))) then
|
62
|
+
@queue = @queue.push_array(production)
|
63
|
+
end
|
64
|
+
while @queue.!=(ImmutableQueue.empty) do
|
65
|
+
rebind(@queue, @interpretation_context)
|
66
|
+
yield(self)
|
67
|
+
if production.instance_of?((Sexp or production.instance_of?(Array))) then
|
68
|
+
@queue = @queue.push_array(production)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
def rebind(queue, ctx)
|
75
|
+
@data = nil
|
76
|
+
@production, @queue = queue.pop
|
77
|
+
@interpretation_context = ctx
|
78
|
+
end
|
79
|
+
|
80
|
+
attr_reader :interpretation_context
|
81
|
+
attr_reader :queue
|
82
|
+
attr_reader :production
|
83
|
+
|
84
|
+
def self_production_is_role?()
|
85
|
+
case
|
86
|
+
when (self_production_is_call? and interpretation_context.roles.has_key?(production[2])) then
|
87
|
+
@date = [production[2]]
|
88
|
+
return true
|
89
|
+
when (((production == :self) or ((self_production_is_indexer? and ((production[1] == nil) or (production[1] == :self))) or (production and ((production.instance_of?(Sexp) or production.instance_of?(Array)) and (production[0] == :self))))) and @interpretation_context.defining_role) then
|
90
|
+
@data = @interpretation_context.defining_role
|
91
|
+
return true
|
92
|
+
else
|
93
|
+
false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def self_production_is_indexer?()
|
98
|
+
self_production_is_call? and ((production[2] == :[]) or (production[2] == :[]=))
|
99
|
+
end
|
100
|
+
|
101
|
+
def self_production_is_call?()
|
102
|
+
production and ((production.instance_of?(Sexp) or production.instance_of?(Array)) and (production[0] == :call))
|
103
|
+
end
|
104
|
+
|
105
|
+
def self_production_is_block?()
|
106
|
+
production and ((production.instance_of?(Sexp) or production.instance_of?(Array)) and (production[0] == :iter))
|
107
|
+
end
|
108
|
+
|
109
|
+
def self_production_is_block_with_bind?()
|
110
|
+
if self_production_is_block? then
|
111
|
+
body = @production.last
|
112
|
+
if body and exp = body[0] then
|
113
|
+
bind = Production.new(exp, @interpretation_context)
|
114
|
+
true if (bind.type == Tokens.call) and (bind.data == :bind)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def self_production_is_rolemethod_call?()
|
120
|
+
can_be = self_production_is_call?
|
121
|
+
if can_be then
|
122
|
+
instance = Production.new(production[1], @interpretation_context)
|
123
|
+
can_be = (instance.type == Tokens.role)
|
124
|
+
if can_be then
|
125
|
+
instance_data = instance.data
|
126
|
+
role = @interpretation_context.roles[instance_data]
|
127
|
+
data = production[2]
|
128
|
+
can_be = role.has_key?(data)
|
129
|
+
@data = [data, instance_data]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
can_be
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
data/lib/Tokens.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
class Tokens
|
2
|
+
def self.define_token(name)
|
3
|
+
class_eval("@@#{name} = Tokens.new :#{name};def Tokens.#{name};@@#{name};end")
|
4
|
+
end
|
5
|
+
|
6
|
+
def to_s
|
7
|
+
@type.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def initialize(type)
|
12
|
+
@type = type
|
13
|
+
self.freeze
|
14
|
+
end
|
15
|
+
|
16
|
+
define_token :terminal
|
17
|
+
define_token :role
|
18
|
+
define_token :rolemethod_call
|
19
|
+
define_token :other
|
20
|
+
define_token :call
|
21
|
+
define_token :indexer
|
22
|
+
define_token :block
|
23
|
+
define_token :block_with_bind
|
24
|
+
end
|
data/lib/build.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'sorcerer'
|
2
2
|
require 'sourcify'
|
3
3
|
|
4
|
-
|
5
|
-
require_relative '
|
6
|
-
require_relative '
|
7
|
-
require_relative '
|
8
|
-
require_relative 'interpretation_context'
|
9
|
-
require_relative '
|
10
|
-
require_relative '
|
11
|
-
require_relative '
|
12
|
-
|
13
|
-
require_relative 'Context'
|
4
|
+
|
5
|
+
require_relative './Tokens'
|
6
|
+
require_relative './ImmutableStack'
|
7
|
+
require_relative './ImmutableQueue'
|
8
|
+
require_relative './interpretation_context'
|
9
|
+
require_relative './Production'
|
10
|
+
require_relative './AstRewritter'
|
11
|
+
require_relative './MethodInfo'
|
12
|
+
|
13
|
+
require_relative './Context'
|
14
14
|
|