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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41c4d573b28bd312c8a720f51ae4b283cd9311bd
|
4
|
+
data.tar.gz: a2a0f21a0278e3af009c884204e18bfa5c633d55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2a48a828cc60e7e8e33bb4df82bdfacc6ff6c128f142a08f0fdca0858dfa5c25ffa2647855d20a745a2c1338a9ea08b0b71dc1beed452ac38955e1512317085
|
7
|
+
data.tar.gz: 00111ba32f2d574dc7ccfd1ba1435b241fd17e97736bc5ca573afab56c6463f26a50f67b40839381a2c3b0383aff3073fc535eac7efb05e253e78c215ef69e3c
|
data/README.md
CHANGED
@@ -41,9 +41,11 @@ Run `rake test` or just `rake` to make the tests run.
|
|
41
41
|
|
42
42
|
1. Fork it
|
43
43
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
44
|
-
3.
|
45
|
-
4.
|
46
|
-
5.
|
44
|
+
3. Make your changes to the files in base.
|
45
|
+
4. Make sure you can run the default rake task with no errors _twice_
|
46
|
+
5. Commit your changes (`git commit -am 'Add some feature'`)
|
47
|
+
6. Push to the branch (`git push origin my-new-feature`)
|
48
|
+
7. Create new Pull Request
|
47
49
|
|
48
50
|
|
49
51
|
Known bugs
|
data/Rakefile
CHANGED
@@ -8,6 +8,7 @@ Rake::TestTask.new do |t|
|
|
8
8
|
end
|
9
9
|
|
10
10
|
task :generate do |t|
|
11
|
+
|
11
12
|
require_relative './lib/Context'
|
12
13
|
require_relative './lib/maroon/kernel'
|
13
14
|
require_relative './lib/build' #use the one in lib. That should be the stable one
|
@@ -32,7 +33,7 @@ end
|
|
32
33
|
|
33
34
|
task :build_generate do |t|
|
34
35
|
require_relative './generated/build' #use the one previously generated
|
35
|
-
Context::generate_files_in('
|
36
|
+
Context::generate_files_in('lib') #generate files
|
36
37
|
`git ls-files ./base/`.split($/).grep(%r{(.)*.rb}).select {|f| require_relative("#{f}")}
|
37
38
|
end
|
38
39
|
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require_relative 'test_helper'
|
3
|
+
class MaroonInternal
|
4
|
+
|
5
|
+
end
|
6
|
+
class ContextTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_role_method_call
|
9
|
+
name = :MyContextRoleMethodCall
|
10
|
+
role_name = :rol
|
11
|
+
Context::define name do
|
12
|
+
role role_name do
|
13
|
+
def rolem(x, y)
|
14
|
+
x+y
|
15
|
+
end
|
16
|
+
end
|
17
|
+
def add(x,y)
|
18
|
+
rol.rolem x,y
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
assert_equal(7, MyContextRoleMethodCall.new.send(:self_rol_rolem, 3, 4))
|
23
|
+
assert_equal(7, MyContextRoleMethodCall.new.add(3, 4))
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_simple
|
27
|
+
name = :MyContextSimple
|
28
|
+
role_name = :r
|
29
|
+
Context::define name do
|
30
|
+
role role_name do
|
31
|
+
end
|
32
|
+
end
|
33
|
+
assert(Kernel::const_defined? name)
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_role_method
|
38
|
+
name = :MyContext
|
39
|
+
role_name = :rol
|
40
|
+
c = Context::define name do
|
41
|
+
role role_name do
|
42
|
+
def rolem
|
43
|
+
0+1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
assert_equal(1, MyContext.new.send(:self_rol_rolem))
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_role_method_args
|
51
|
+
name = :MyContextArgs
|
52
|
+
role_name = :rol
|
53
|
+
Context::define name do
|
54
|
+
role role_name do
|
55
|
+
def rolem(x, y)
|
56
|
+
x+y
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
assert_equal(7, MyContextArgs.new.send(:self_rol_rolem, 3, 4))
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_role_method_splat
|
64
|
+
name = :MyContextSplat
|
65
|
+
role_name = :rol
|
66
|
+
Context::define name do
|
67
|
+
role role_name do
|
68
|
+
def rolem(x, *args)
|
69
|
+
x+(args[0])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
assert_equal(7, MyContextSplat.new.send(:self_rol_rolem, 3, 4))
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_role_method_block
|
77
|
+
name = :MyContextBlock
|
78
|
+
role_name = :rol
|
79
|
+
Context::define name do
|
80
|
+
role role_name do
|
81
|
+
def rolem(*args, &b)
|
82
|
+
res = 0
|
83
|
+
args.each { |x|
|
84
|
+
res = b.call res, x
|
85
|
+
}
|
86
|
+
res
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
assert_equal(7, MyContextBlock.new.send(:self_rol_rolem, 3, 4) { |x, res| res + x })
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_class_method_block
|
94
|
+
name = :MyContextClass
|
95
|
+
role_name = :rol
|
96
|
+
Context::define name do
|
97
|
+
role :dummy do end
|
98
|
+
role role_name do
|
99
|
+
def rolem(*args, &b)
|
100
|
+
res = 0
|
101
|
+
args.each { |x|
|
102
|
+
res = b.call res, x
|
103
|
+
}
|
104
|
+
res
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.mul(x, y)
|
109
|
+
x*y
|
110
|
+
end
|
111
|
+
|
112
|
+
def power(x, y)
|
113
|
+
x**y
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.pow(x,y)
|
117
|
+
x**y
|
118
|
+
end
|
119
|
+
end
|
120
|
+
ctx = MyContextClass.new
|
121
|
+
|
122
|
+
|
123
|
+
assert_equal(8, ctx.power(2, 3))
|
124
|
+
assert_equal(16, MyContextClass::pow(2, 4))
|
125
|
+
assert_equal(12, MyContextClass::mul(3, 4))
|
126
|
+
assert_equal(7, ctx.send(:self_rol_rolem, 3, 4) { |x, res| res + x })
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
data/Test/ImmutableQueue_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require_relative '../generated/ImmutableQueue'
|
3
|
-
|
3
|
+
require_relative '../Test/test_helper'
|
4
4
|
|
5
5
|
|
6
6
|
class ImmutableQueueTest < Test::Unit::TestCase
|
@@ -8,11 +8,11 @@ class ImmutableQueueTest < Test::Unit::TestCase
|
|
8
8
|
def test_sunny
|
9
9
|
queue = ImmutableQueue::empty.push 1
|
10
10
|
queue = queue.push(2)
|
11
|
-
f,queue = queue.pop()
|
11
|
+
f, queue = queue.pop()
|
12
12
|
refute_nil(queue)
|
13
|
-
s,queue = queue.pop()
|
14
|
-
assert_equal(1,f)
|
15
|
-
assert_equal(2,s)
|
13
|
+
s, queue = queue.pop()
|
14
|
+
assert_equal(1, f)
|
15
|
+
assert_equal(2, s)
|
16
16
|
assert_equal(ImmutableQueue::empty, queue)
|
17
17
|
end
|
18
18
|
end
|
data/Test/MethodInfo_test.rb
CHANGED
@@ -5,61 +5,82 @@ require_relative 'test_helper'
|
|
5
5
|
|
6
6
|
class MethodInfoTest < Test::Unit::TestCase
|
7
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
|
+
|
8
14
|
def test_simple
|
9
|
-
block =
|
10
|
-
|
15
|
+
block = get_def do
|
16
|
+
def name (a, b)
|
17
|
+
p 'this is a test'
|
18
|
+
end
|
11
19
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
15
31
|
end
|
16
|
-
|
17
|
-
|
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)
|
18
36
|
end
|
37
|
+
|
19
38
|
def test_class_method
|
20
|
-
block =
|
21
|
-
|
39
|
+
block = get_def do
|
40
|
+
def self.name(a, b)
|
41
|
+
p 'this is a test'
|
42
|
+
end
|
22
43
|
end
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
assert_source_equal(expected,source)
|
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)
|
29
49
|
end
|
30
50
|
|
31
51
|
def test_splat_argument
|
32
|
-
block =
|
52
|
+
block = get_def do
|
53
|
+
def name (a, *b)
|
33
54
|
p 'this is a test'
|
55
|
+
end
|
34
56
|
end
|
35
|
-
source = MethodInfo.new(nil,
|
36
|
-
expected =
|
37
|
-
|
38
|
-
end
|
39
|
-
}
|
40
|
-
assert_source_equal(expected,source)
|
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)
|
41
60
|
end
|
42
61
|
|
43
62
|
def test_block_argument
|
44
|
-
block =
|
63
|
+
block = get_def do
|
64
|
+
def name(a, b,&block)
|
45
65
|
p 'this is a test'
|
66
|
+
end
|
46
67
|
end
|
47
|
-
|
48
|
-
source =
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
assert_source_equal(expected,source)
|
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)
|
54
74
|
end
|
75
|
+
|
55
76
|
def test_block_argument_class_method
|
56
|
-
block =
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
p("this is a test")
|
77
|
+
block = get_def do
|
78
|
+
def self.name(a, *b,&block)
|
79
|
+
p 'is a test'
|
80
|
+
end
|
61
81
|
end
|
62
|
-
}
|
63
|
-
|
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)
|
64
85
|
end
|
65
86
|
end
|
data/Test/alltests.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
`git ls-files`.split($/).grep(%r{(test|spec|features).rb}).select {|f| p f; require_relative("../#{f}")}
|
1
|
+
`git ls-files`.split($/).grep(%r{(test|spec|features).rb}).select { |f| p f; require_relative("../#{f}") }
|
data/Test/assertions.rb
CHANGED
@@ -4,14 +4,22 @@ require 'ruby2ruby'
|
|
4
4
|
module SourceAssertions
|
5
5
|
def assert_source_equal(expected, actual)
|
6
6
|
|
7
|
-
expected_sexp = if expected.instance_of? String then
|
8
|
-
|
7
|
+
expected_sexp = if expected.instance_of? String then
|
8
|
+
Ripper::sexp expected
|
9
|
+
else
|
10
|
+
expected
|
11
|
+
end
|
12
|
+
actual_sexp = if actual.instance_of? String then
|
13
|
+
Ripper::sexp actual
|
14
|
+
else
|
15
|
+
actual
|
16
|
+
end
|
9
17
|
|
10
18
|
message = "
|
11
19
|
Expected: #{expected}
|
12
20
|
but got: #{actual}"
|
13
21
|
assert_sexp_with_ident(expected_sexp, actual_sexp, message)
|
14
|
-
assert_equal(1,1) #just getting the correct assertion count
|
22
|
+
assert_equal(1, 1) #just getting the correct assertion count
|
15
23
|
end
|
16
24
|
|
17
25
|
def is_terminal(sexp)
|
@@ -40,7 +48,7 @@ module SourceAssertions
|
|
40
48
|
end
|
41
49
|
else
|
42
50
|
if expected[i] != actual[i]
|
43
|
-
assert_equal(expected[i],actual[i], message || "the arrays differ at index #{i}")
|
51
|
+
assert_equal(expected[i], actual[i], message || "the arrays differ at index #{i}")
|
44
52
|
end
|
45
53
|
end
|
46
54
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require_relative '../generated/Tokens'
|
3
|
+
require_relative '../generated/Production'
|
4
|
+
require_relative 'test_helper'
|
5
|
+
class ProductionTest < Test::Unit::TestCase
|
6
|
+
def get_method_call &b
|
7
|
+
exp = get_sexp &b
|
8
|
+
exp[3]
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_rolemethod
|
12
|
+
method_call = get_method_call { foo.bar }
|
13
|
+
|
14
|
+
production = get_production(method_call)
|
15
|
+
type = production.type
|
16
|
+
assert_equal(Tokens::rolemethod_call, type)
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_production(method_call)
|
20
|
+
contracts ={}
|
21
|
+
roles = {:foo => {:bar => []}}
|
22
|
+
Production.new(method_call, InterpretationContext.new(roles, contracts, nil, nil))
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_call
|
26
|
+
method_call = get_method_call { foo.baz }
|
27
|
+
|
28
|
+
production = get_production(method_call)
|
29
|
+
type = production.type
|
30
|
+
|
31
|
+
assert_equal(Tokens::call, type)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_indexer
|
35
|
+
method_call = get_method_call { foo[0] }
|
36
|
+
|
37
|
+
production = get_production(method_call)
|
38
|
+
type = production.type
|
39
|
+
|
40
|
+
assert_equal(Tokens::indexer, type)
|
41
|
+
end
|
42
|
+
end
|
data/Test/stack_test.rb
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require_relative '../generated/ImmutableStack'
|
3
3
|
|
4
|
-
ImmutableStack.new nil,nil
|
5
4
|
|
6
5
|
class Stack_Test < Test::Unit::TestCase
|
7
6
|
|
8
7
|
def test_push_pop
|
9
8
|
stack = ImmutableStack.empty.push(1)
|
10
9
|
stack = stack.push 2
|
11
|
-
f,stack = stack.pop
|
12
|
-
s,stack = stack.pop
|
13
|
-
assert_equal(2,f)
|
14
|
-
assert_equal(1,s)
|
15
|
-
assert_equal(stack,ImmutableStack::empty)
|
10
|
+
f, stack = stack.pop
|
11
|
+
s, stack = stack.pop
|
12
|
+
assert_equal(2, f)
|
13
|
+
assert_equal(1, s)
|
14
|
+
assert_equal(stack, ImmutableStack::empty)
|
16
15
|
end
|
17
16
|
end
|
data/Test/test_helper.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
2
|
require 'sourcify'
|
3
3
|
require_relative 'assertions'
|
4
|
-
require_relative '../generated/
|
4
|
+
require_relative '../generated/build'
|
5
5
|
#require 'debugger'
|
6
6
|
|
7
7
|
def get_sexp &b
|
8
8
|
begin
|
9
|
-
|
9
|
+
b.to_sexp
|
10
10
|
rescue
|
11
11
|
puts "failed to get expression"
|
12
12
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
context :AstRewritter do
|
2
|
+
role :ast do
|
3
|
+
end
|
4
|
+
|
5
|
+
def initialize (ast, interpretation_context)
|
6
|
+
@ast = Production.new ast, interpretation_context
|
7
|
+
end
|
8
|
+
|
9
|
+
def rewrite!
|
10
|
+
ast.each { |production|
|
11
|
+
|
12
|
+
case production.type
|
13
|
+
when Tokens::rolemethod_call
|
14
|
+
data = production.data
|
15
|
+
production[2] = ('self_' + data[1].to_s + '_' + data[0].to_s).to_sym
|
16
|
+
production[1] = nil
|
17
|
+
when Tokens::block_with_bind
|
18
|
+
block = production.last
|
19
|
+
must_b_sym = 'aliased_role must be a Symbol'.to_sym
|
20
|
+
local_must_b_sym = 'local must be a Symbol'.to_sym
|
21
|
+
raise must_b_sym unless aliased_role.instance_of? Symbol
|
22
|
+
raise local_must_b_sym unless local.instance_of? Symbol
|
23
|
+
# assigning role player to role field
|
24
|
+
#notice that this will be executed after the next block
|
25
|
+
aliased_field = ('@' + aliased_role.to_s).to_sym
|
26
|
+
temp_symbol = ('temp____' + aliased_role.to_s).to_sym
|
27
|
+
|
28
|
+
assignment = Sexp.new
|
29
|
+
assignment[0] = :iasgn
|
30
|
+
assignment[1] = aliased_field
|
31
|
+
load_arg = Sexp.new
|
32
|
+
load_arg[0] = :lvar
|
33
|
+
load_arg[1] = local
|
34
|
+
assignment[2] = load_arg
|
35
|
+
block.insert 1, assignment
|
36
|
+
|
37
|
+
# assign role player to temp
|
38
|
+
# notice this is prepended Ie. inserted in front of the role player to role field
|
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
|
+
else
|
58
|
+
#do nothing
|
59
|
+
end
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|