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