maroon 0.7.1 → 0.8.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -6
  3. data/Rakefile +3 -3
  4. data/Test/Context_test.rb +16 -16
  5. data/{Examples/Dijkstra → Test/Examples}/CalculateShortestDistance.rb +11 -13
  6. data/Test/Examples/MoneyTransfer_test.rb +76 -0
  7. data/{Examples/Dijkstra → Test/Examples}/calculate_shortest_path.rb +77 -89
  8. data/{Examples/Dijkstra → Test/Examples}/data.rb +0 -0
  9. data/{Examples/Dijkstra/dijkstra.rb → Test/Examples/dijkstra_test.rb} +34 -24
  10. data/Test/Examples/greeter_test.rb +48 -0
  11. data/{Examples/meter.rb → Test/Examples/meter_test.rb} +44 -30
  12. data/Test/abstract_syntax_tree_test.rb +17 -26
  13. data/Test/alltests.rb +1 -1
  14. data/Test/test_helper.rb +2 -0
  15. data/base/AbstractSyntaxTree.rb +24 -3
  16. data/base/ImmutableStack.rb +1 -1
  17. data/base/dependency_graph.rb +94 -0
  18. data/base/immutable_queue.rb +1 -1
  19. data/base/maroon_base.rb +50 -11
  20. data/base/transfomer.rb +196 -197
  21. data/generated/Tokens.rb +64 -2
  22. data/generated/build.rb +1 -3
  23. data/generated/maroon/kernel.rb +7 -0
  24. data/lib/AbstractSyntaxTree.rb +120 -0
  25. data/lib/AstRewritter.rb +53 -58
  26. data/lib/Context.rb +104 -126
  27. data/lib/DependencyGraph.rb +76 -0
  28. data/lib/ImmutableQueue.rb +28 -39
  29. data/lib/ImmutableStack.rb +20 -34
  30. data/lib/Tokens.rb +64 -2
  31. data/lib/Transformer.rb +125 -165
  32. data/lib/build.rb +2 -4
  33. data/lib/maroon/kernel.rb +1 -1
  34. data/lib/maroon/version.rb +1 -1
  35. metadata +13 -11
  36. data/Examples/MoneyTransfer.rb +0 -62
  37. data/Examples/greeter.rb +0 -46
  38. data/Test/Greeter_test_disabled.rb +0 -203
  39. data/lib/Production.rb +0 -149
@@ -6,9 +6,7 @@ require_relative './Tokens'
6
6
  require_relative './ImmutableStack'
7
7
  require_relative './ImmutableQueue'
8
8
  require_relative './interpretation_context'
9
- require_relative './Production'
9
+ require_relative './AbstractSyntaxTree'
10
10
  require_relative './AstRewritter'
11
11
  require_relative './Transformer'
12
-
13
-
14
-
12
+ require_relative './DependencyGraph'
@@ -2,6 +2,6 @@ require_relative '../Context'
2
2
 
3
3
  unless Kernel::methods.detect { |m| m== :context }
4
4
  def context(*args, &b)
5
- Context::define *args, &b
5
+ Context.define *args, &b
6
6
  end
7
7
  end
@@ -1,3 +1,3 @@
1
1
  module Maroon
2
- VERSION = '0.7.1'
2
+ VERSION = '0.8.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maroon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rune Funch Søltoft
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-22 00:00:00.000000000 Z
11
+ date: 2013-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sourcify
@@ -58,19 +58,18 @@ extensions: []
58
58
  extra_rdoc_files: []
59
59
  files:
60
60
  - .gitignore
61
- - Examples/Dijkstra/CalculateShortestDistance.rb
62
- - Examples/Dijkstra/calculate_shortest_path.rb
63
- - Examples/Dijkstra/data.rb
64
- - Examples/Dijkstra/dijkstra.rb
65
- - Examples/MoneyTransfer.rb
66
- - Examples/greeter.rb
67
- - Examples/meter.rb
68
61
  - Gemfile
69
62
  - LICENSE.txt
70
63
  - README.md
71
64
  - Rakefile
72
65
  - Test/Context_test.rb
73
- - Test/Greeter_test_disabled.rb
66
+ - Test/Examples/CalculateShortestDistance.rb
67
+ - Test/Examples/MoneyTransfer_test.rb
68
+ - Test/Examples/calculate_shortest_path.rb
69
+ - Test/Examples/data.rb
70
+ - Test/Examples/dijkstra_test.rb
71
+ - Test/Examples/greeter_test.rb
72
+ - Test/Examples/meter_test.rb
74
73
  - Test/ImmutableQueue_test.rb
75
74
  - Test/abstract_syntax_tree_test.rb
76
75
  - Test/alltests.rb
@@ -80,17 +79,20 @@ files:
80
79
  - base/AbstractSyntaxTree.rb
81
80
  - base/AstRewritter.rb
82
81
  - base/ImmutableStack.rb
82
+ - base/dependency_graph.rb
83
83
  - base/immutable_queue.rb
84
84
  - base/maroon_base.rb
85
85
  - base/transfomer.rb
86
86
  - generated/Tokens.rb
87
87
  - generated/build.rb
88
88
  - generated/interpretation_context.rb
89
+ - generated/maroon/kernel.rb
90
+ - lib/AbstractSyntaxTree.rb
89
91
  - lib/AstRewritter.rb
90
92
  - lib/Context.rb
93
+ - lib/DependencyGraph.rb
91
94
  - lib/ImmutableQueue.rb
92
95
  - lib/ImmutableStack.rb
93
- - lib/Production.rb
94
96
  - lib/Tokens.rb
95
97
  - lib/Transformer.rb
96
98
  - lib/build.rb
@@ -1,62 +0,0 @@
1
- require './lib/maroon.rb'
2
-
3
- Context::define :MoneyTransfer do
4
- role :source do
5
- withdraw do |amount|
6
- source.movement(amount)
7
- source.log "withdrawal #{amount}"
8
- end
9
- log do |message|
10
- p "#{@source} source #{message}"
11
- end
12
- end
13
-
14
- role :destination do
15
- deposit do |amount|
16
- @destination.movement(amount)
17
- @destination.log "deposit #{amount}"
18
- end
19
- logger do |message|
20
- p "#{@source} destination #{message}"
21
- end
22
- end
23
-
24
- role :amount do
25
- end
26
-
27
- transfer do
28
- source.withdraw -amount
29
- destination.deposit amount
30
- end
31
- end
32
-
33
- class MoneyTransfer
34
- def initialize(source, destination, amount)
35
- @source = source
36
- @destination = destination
37
- @amount = amount
38
- end
39
- end
40
- class Account
41
- def initialize (amount, id)
42
- @balance = amount
43
- @account_id = id
44
- end
45
-
46
- def movement(amount)
47
- log "Amount #{amount}"
48
- @balance+=amount
49
- end
50
-
51
- def log(message)
52
- (p s = "instance #{message}")
53
- end
54
-
55
- def to_s
56
- "balance of #{@account_id}: #{@balance}"
57
- end
58
- end
59
-
60
- account = Account.new 1000, "source"
61
- ctx = MoneyTransfer.new account, account, 100
62
- ctx.transfer
@@ -1,46 +0,0 @@
1
- #Thanks to Ted Milken for updating the original example
2
- require_relative '../base/maroon_base.rb'
3
- #require_relative '../base/maroon/kernel.rb'
4
- #require_relative '../base/maroon/contracts.rb'
5
-
6
- class Person
7
- attr_accessor :name
8
- attr_accessor :greeting
9
- end
10
-
11
- ctx, source = Context::define :Greet_Someone, :greet do
12
- role :greeter do
13
- welcome do
14
- self.greeting
15
- end
16
- end
17
-
18
- role :greeted do
19
- end
20
-
21
- greet do
22
- puts %{#{greeter.name}: "#{greeter.welcome}, #{greeted.name}!"}
23
- end
24
- end
25
-
26
- class Greet_Someone
27
- def initialize(greeter, greeted)
28
- @greeter = greeter
29
- @greeted = greeted
30
- end
31
- end
32
-
33
- p source
34
- p1 = Person.new
35
- p1.name = 'Bob'
36
- p1.greeting = 'Hello'
37
-
38
- p2 = Person.new
39
- p2.name = 'World!'
40
- p2.greeting = 'Greetings'
41
-
42
- #Execute is automagically created for the default interaction (specified by the second argument in context :Greet_Someone, :greet do)
43
- #Executes construct a context object and calls the default interaction on this object
44
- #Greet_Someone.assert_that(p1).can_play(:greeter)
45
- #constructs a Greet_Someone context object and executes greet.
46
- Greet_Someone.new(p2, p1).greet
@@ -1,203 +0,0 @@
1
- require_relative './test_helper.rb'
2
-
3
- require_relative '../lib/maroon/kernel.rb'
4
- require_relative '../lib/build'
5
-
6
- require_relative 'assertions.rb'
7
- #require './Examples/meter.rb'
8
-
9
-
10
- class BasicTests < MiniTest::Unit::TestCase
11
- include SourceAssertions
12
-
13
- def test_define_context
14
- name = :MyContext
15
- ctx, source = Context::define name do
16
- end
17
- assert_equal(ctx.name, "Kernel::#{name}")
18
- assert_equal(source, "class #{name}\r\n\n\n private\n\n\n\r\nend")
19
- end
20
-
21
- def test_base_class
22
- name = :MyDerivedContext
23
- ctx, source = context name, Person do
24
- end
25
- obj = MyDerivedContext.new
26
- obj.name = name
27
- assert_equal(ctx.name, "Kernel::#{name}")
28
- refute_nil(obj.name)
29
- assert((obj.class < Person), 'Object is not a Person')
30
- assert_equal(name, obj.name)
31
- end
32
-
33
- def test_define_role
34
- name, role_name = :MyContextWithRole, :my_role
35
- ctx, source = Context::define name do
36
- role role_name do
37
- role_go_do do
38
-
39
- end
40
- end
41
- end
42
- refute_nil(ctx)
43
- assert_equal(ctx.name, "Kernel::#{name}")
44
- assert_source_equal("class #{name}\r\n\n@#{role_name}\n\n private\ndef #{role_name};@#{role_name} end\n\n \ndef self_#{role_name}_role_go_do \n end\n\n\r\nend", source)
45
- end
46
-
47
- def test_args_on_role_method
48
- name, role_name = :MyContextWithRoleAndArgs, :my_role
49
- ctx, source = Context::define name do
50
- role role_name do
51
- role_go_do do |x, y|
52
-
53
- end
54
- role_go do |x|
55
-
56
- end
57
- end
58
- end
59
- refute_nil(ctx)
60
- assert_equal(ctx.name, "Kernel::#{name}")
61
- assert_source_equal("class #{name}\r\n\n@#{role_name}\n\n private\ndef #{role_name};@#{role_name} end\n\n \ndef self_#{role_name}_role_go_do(x,y) \n end\n\ndef self_#{role_name}_role_go(x) \n end\n\n\r\nend", source)
62
- end
63
-
64
- def test_bind
65
- name, other_name = :MyContextUsingBind, :other_role
66
- ctx, source = Context::define name do
67
- role other_name do
68
- plus_one do
69
- (self + 1)
70
- end
71
- end
72
- go_do do
73
- a = Array.new
74
- [1, 2].each do |e|
75
- bind e => :other_role
76
- a << e.plus_one
77
- end
78
- a
79
- end
80
- end
81
- arr = MyContextUsingBind.new.go_do
82
- refute_nil(ctx)
83
- assert_equal(ctx.name, "Kernel::#{name}")
84
- expected = "class MyContextUsingBind\r\n \ndef go_do \na = Array.new\n [1, 2].each do |e|\n temp____other_role = @other_role\n @other_role = e\n (a << self_other_role_plus_one)\n @other_role = temp____other_role\n end\n a\n end\n\n@other_role\n\n private\ndef other_role;@other_role end\n\n \ndef self_other_role_plus_one \n(other_role + 1) end\n\n\r\nend"
85
- assert_source_equal(expected, source)
86
- assert_equal(2, arr[0])
87
- assert_equal(3, arr[1])
88
- end
89
- end
90
-
91
-
92
- context :Greet_Someone, :greet do
93
- role :greeter do
94
- welcome do
95
- self.greeting
96
- end
97
- end
98
-
99
- role :greeted do
100
- end
101
-
102
- greet do
103
- "#{greeter.name}: \"#{greeter.welcome}, #{greeted.name}!\""
104
- end
105
- end
106
-
107
- context :Greet_Someone2, :greet do
108
- role :greeter do
109
- welcome do
110
- self.greeting
111
- end
112
- end
113
-
114
- role :greeted do
115
- end
116
-
117
- greet do |msg|
118
- a = "#{greeter.name}: \"#{greeter.welcome}, #{greeted.name}!\" #{msg}"
119
- p a
120
- a
121
- end
122
- end
123
-
124
- class Person
125
- attr_accessor :name
126
- attr_accessor :greeting
127
- end
128
-
129
-
130
- class Greet_Someone
131
- def initialize(greeter, greeted)
132
- @greeter = greeter
133
- @greeted = greeted
134
- end
135
- end
136
-
137
- class Greet_Someone2
138
- def initialize(greeter, greeted)
139
- @greeter = greeter
140
- @greeted = greeted
141
- end
142
- end
143
-
144
- class TestExamples < MiniTest::Unit::TestCase
145
- def test_greeter
146
- p1 = Person.new
147
- p1.name = 'Bob'
148
- p1.greeting = 'Hello'
149
-
150
- p2 = Person.new
151
- p2.name = 'World!'
152
- p2.greeting = 'Greetings'
153
-
154
- #Execute is automagically created for the default interaction (specified by the second argument in context :Greet_Someone, :greet do)
155
- #Executes constructs a context object and calls the default interaction on this object
156
- res1 = Greet_Someone.call p1, p2
157
- res2 = Greet_Someone.new(p2, p1).greet
158
- res3 = Greet_Someone.new(p2, p1).call
159
- assert_equal(res1, "#{p1.name}: \"#{p1.greeting}, #{p2.name}!\"")
160
- assert_equal(res1, Greet_Someone.new(p1, p2).greet) #verifies default action
161
- #constructs a Greet_Someone context object and executes greet.
162
- assert_equal(res2, "#{p2.name}: \"#{p2.greeting}, #{p1.name}!\"")
163
- assert_equal(res2, res3)
164
- end
165
- end
166
-
167
-
168
- class TestExamples < MiniTest::Unit::TestCase
169
- def test_greeter
170
- p1 = Person.new
171
- p1.name = 'Bob'
172
- p1.greeting = 'Hello'
173
-
174
- p2 = Person.new
175
- p2.name = 'World!'
176
- p2.greeting = 'Greetings'
177
-
178
- puts "with_contracts: #{Context::with_contracts}"
179
- Greet_Someone.assert_that(p1).can_play(:greeter)
180
- Greet_Someone.refute_that(self).can_play(:greeter)
181
- message = ' Nice weather, don\'t you think?'
182
- res1 = Greet_Someone2.call p1, p2, message
183
- res2 = Greet_Someone2.new(p2, p1).greet message
184
- res3 = Greet_Someone2.new(p2, p1).call message
185
- assert_equal(res1, "#{p1.name}: \"#{p1.greeting}, #{p2.name}!\" #{message}")
186
- assert_equal(res1, Greet_Someone2.new(p1, p2).greet(message)) #verifies default action
187
- #constructs a Greet_Someone context object and executes greet.
188
- assert_equal(res2, "#{p2.name}: \"#{p2.greeting}, #{p1.name}!\" #{message}")
189
- assert_equal(res2, res3)
190
- end
191
- end
192
-
193
- class TestExamples < MiniTest::Unit::TestCase
194
- def test_meter_example
195
- meter = Meter.new Time::now, Position.new(1, 2, 0)
196
- result = meter.call Position.new(2, 4, 1)
197
- assert_equal(3, result.to_i)
198
- end
199
- end
200
-
201
-
202
-
203
-
@@ -1,149 +0,0 @@
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
- def self_production_is_role?()
81
- case
82
- when (self_production_is_call? and interpretation_context.roles.has_key?(production[2])) then
83
- @date = [production[2]]
84
- return true
85
- 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
86
- @data = @interpretation_context.defining_role
87
- return true
88
- else
89
- false
90
- end
91
- end
92
-
93
- def self_production_is_indexer?()
94
- self_production_is_call? and ((production[2] == :[]) or (production[2] == :[]=))
95
- end
96
-
97
- def self_production_is_call?()
98
- production and ((production.instance_of?(Sexp) or production.instance_of?(Array)) and (production[0] == :call))
99
- end
100
-
101
- def self_production_is_block?()
102
- production and ((production.instance_of?(Sexp) or production.instance_of?(Array)) and (production[0] == :iter))
103
- end
104
-
105
- def self_production_is_block_with_bind?()
106
- if self_production_is_block? then
107
- body = @production.last
108
- if body and exp = body[1] then
109
- bind = Production.new(exp, @interpretation_context)
110
- if (bind.type == Tokens.call) and (bind.data == :bind) then
111
- aliases = {}
112
- list = exp.last[(1..-1)]
113
- (list.length / 2).times do |i|
114
- local = list[(i * 2)].last
115
- role_name = list[((i * 2) + 1)].last
116
- raise("Local in bind should be a symbol") unless local.instance_of?(Symbol)
117
- unless role_name.instance_of?(Symbol) then
118
- raise("Role name in bind should be a symbol")
119
- end
120
- aliases[local] = role_name
121
- end
122
- @data = aliases
123
- true
124
- end
125
- end
126
- end
127
- end
128
-
129
- def self_production_is_rolemethod_call?()
130
- can_be = self_production_is_call?
131
- if can_be then
132
- instance = Production.new(production[1], @interpretation_context)
133
- can_be = (instance.type == Tokens.role)
134
- if can_be then
135
- instance_data = instance.data
136
- role = @interpretation_context.roles[instance_data]
137
- data = production[2]
138
- can_be = role.has_key?(data)
139
- @data = [data, instance_data]
140
- end
141
- end
142
- can_be
143
- end
144
-
145
- attr_reader :interpretation_context
146
- attr_reader :queue
147
- attr_reader :production
148
-
149
- end