emfrp 0.1.2 → 0.1.3

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +45 -12
  3. data/bin/emfrp +4 -1
  4. data/examples/LCDClock/LCDClock.mfrp +93 -93
  5. data/examples/LCDClock/LCDClock_LPC1768.bin +0 -0
  6. data/examples/LCDClock/README.md +24 -24
  7. data/examples/LCDPositioner/LCDPositioner.mfrp +30 -30
  8. data/examples/LCDPositioner/LCDPositionerMain.c +15 -15
  9. data/examples/MostDistantPoint/MostDistantPoint.mfrp +25 -25
  10. data/examples/MostDistantPoint/MostDistantPointMain.c +14 -14
  11. data/lib/emfrp/compile/c/alloc.rb +200 -200
  12. data/lib/emfrp/compile/c/codegen.rb +18 -18
  13. data/lib/emfrp/compile/c/codegen_context.rb +218 -218
  14. data/lib/emfrp/compile/c/monofy.rb +185 -185
  15. data/lib/emfrp/compile/c/syntax_codegen.rb +364 -364
  16. data/lib/emfrp/compile/c/syntax_exp_codegen.rb +119 -119
  17. data/lib/emfrp/compile/graphviz/graphviz.rb +53 -53
  18. data/lib/emfrp/compile_error.rb +95 -95
  19. data/lib/emfrp/interpreter/command_manager.rb +367 -367
  20. data/lib/emfrp/interpreter/evaluater.rb +146 -146
  21. data/lib/emfrp/interpreter/file_loader.rb +52 -52
  22. data/lib/emfrp/interpreter/interpreter.rb +200 -195
  23. data/lib/emfrp/parser/expression.rb +386 -386
  24. data/lib/emfrp/parser/misc.rb +184 -184
  25. data/lib/emfrp/parser/newnode_convert.rb +72 -72
  26. data/lib/emfrp/parser/operator.rb +25 -25
  27. data/lib/emfrp/parser/parser.rb +150 -150
  28. data/lib/emfrp/parser/parsing_error.rb +49 -49
  29. data/lib/emfrp/parser/toplevel.rb +555 -555
  30. data/lib/emfrp/pre_convert/pre_convert.rb +32 -32
  31. data/lib/emfrp/syntax.rb +171 -171
  32. data/lib/emfrp/typing/typing_error.rb +47 -47
  33. data/lib/emfrp/typing/union_type.rb +197 -197
  34. data/lib/emfrp/version.rb +1 -1
  35. data/mfrp_include/Std.mfrp +122 -122
  36. data/tests/Rakefile +8 -8
  37. data/tests/Rakefile.common +27 -27
  38. data/tests/command/Rakefile +2 -2
  39. data/tests/command/ReplaceNode.mfrp +39 -39
  40. data/tests/compiler/ComplexDataType/ComplexDataType.mfrp +14 -14
  41. data/tests/compiler/ComplexDataType/ComplexDataTypeMain.c +15 -15
  42. data/tests/compiler/ComplexDataType/Rakefile +2 -2
  43. data/tests/compiler/ComplexDataType/expected_out.txt +0 -0
  44. data/tests/compiler/ComplexDataType/in.txt +5 -5
  45. data/tests/compiler/LCDClock/LCDClock.mfrp +90 -90
  46. data/tests/compiler/LCDClock/LCDClockMain.c +0 -0
  47. data/tests/compiler/LCDClock/Rakefile +2 -2
  48. data/tests/compiler/LCDClock/expected_out.txt +0 -0
  49. data/tests/compiler/LCDClock/in.txt +0 -0
  50. data/tests/compiler/LCDPositioner/LCDPositioner.mfrp +30 -30
  51. data/tests/compiler/LCDPositioner/LCDPositionerMain.c +15 -15
  52. data/tests/compiler/LCDPositioner/Rakefile +2 -2
  53. data/tests/compiler/LCDPositioner/graph.dot +0 -0
  54. data/tests/compiler/LCDPositioner/graph.png +0 -0
  55. data/tests/compiler/Rakefile +8 -8
  56. data/tests/compiler/Rakefile.common +23 -23
  57. data/tests/compiler/UseData/Rakefile +2 -2
  58. data/tests/compiler/UseData/UseData.mfrp +8 -8
  59. data/tests/compiler/UseSubModule/Rakefile +2 -2
  60. data/tests/compiler/UseSubModule/SubModule.mfrp +8 -8
  61. data/tests/compiler/UseSubModule/SubModule2.mfrp +5 -5
  62. data/tests/compiler/UseSubModule/UseSubModule.mfrp +11 -11
  63. data/tests/core/FromAnnotation.mfrp +18 -18
  64. data/tests/core/Last.mfrp +10 -10
  65. data/tests/core/Rakefile +2 -2
  66. data/tests/core/TypingTest.mfrp +11 -11
  67. data/tests/core/WithoutInputs.mfrp +19 -19
  68. data/tests/load_time_error/Rakefile +32 -32
  69. data/tests/load_time_error/TypeMismatch.mfrp +4 -4
  70. metadata +3 -3
@@ -1,200 +1,200 @@
1
- module Emfrp
2
- class AllocRequirement
3
- def initialize(top)
4
- @top = top
5
- @alloc_table = AllocTable.new(top)
6
- @sorted_nodes = @top[:dict][:sorted_nodes].map{|x| x.get}
7
- end
8
-
9
- def requirement
10
- sorted_datas = @top[:dict][:sorted_datas].map{|x| x.get}
11
- init_nodes = @sorted_nodes.select{|n| n[:init_exp]}
12
- max_amount = Alloc.empty
13
- max_amount = data_requirement(sorted_datas, max_amount)
14
- max_amount = node_init_requirement(init_nodes, max_amount, sorted_datas)
15
- max_amount = node_loop_requirement(max_amount, init_nodes, sorted_datas)
16
- return max_amount
17
- end
18
-
19
- def data_requirement(sorted_datas, max_amount)
20
- retains = []
21
- sorted_datas.each do |d|
22
- max_amount |= type_alloc_sum(retains) & exp_alloc(d[:exp])
23
- end
24
- return max_amount
25
- end
26
-
27
- def node_init_requirement(init_nodes, max_amount, datas)
28
- retains = datas.clone
29
- init_nodes.each do |n|
30
- max_amount |= type_alloc_sum(retains) & exp_alloc(n[:init_exp])
31
- retains << n
32
- end
33
- return max_amount
34
- end
35
-
36
- def node_loop_requirement(max_amount, init_nodes, datas)
37
- lrefs = init_nodes
38
- crefs = []
39
- @sorted_nodes.each_with_index do |n, i|
40
- max_amount |= type_alloc_sum(datas + lrefs + crefs) & exp_alloc(n[:exp])
41
- crefs << n
42
- lrefs.reject! do |x|
43
- i >= ref_pos_last(x)
44
- end
45
- crefs.reject! do |x|
46
- i >= ref_pos_current(x)
47
- end
48
- end
49
- return max_amount
50
- end
51
-
52
- def ref_pos_last(node)
53
- res = -1
54
- @sorted_nodes.each_with_index do |n, i|
55
- if n[:params].any?{|param| param[:last] && param[:name] == node[:name]}
56
- res = i
57
- end
58
- end
59
- return res
60
- end
61
-
62
- def ref_pos_current(node)
63
- res = -1
64
- @sorted_nodes.each_with_index do |n, i|
65
- if n[:params].any?{|param| !param[:last] && param[:name] == node[:name]}
66
- res = i
67
- end
68
- end
69
- return res
70
- end
71
-
72
- def life_point(node)
73
- self_position = @sorted_nodes.index{|x| x == node}
74
- distance_to_end = @sorted_nodes.size - self_position
75
- res = []
76
- @sorted_nodes.each_with_index do |x, i|
77
- x[:params].each do |param|
78
- if param[:name] == node[:name]
79
- if param[:last]
80
- res << distance_to_end + i
81
- else
82
- res << i - self_position
83
- end
84
- end
85
- end
86
- end
87
- if res == []
88
- raise "Assertion error"
89
- else
90
- return res.max
91
- end
92
- end
93
-
94
- def type_alloc_sum(defs)
95
- defs.inject(Alloc.empty) do |acc, d|
96
- type_def = @alloc_table.utype_to_type_def(d[:typing])
97
- acc & @alloc_table.type_alloc(type_def)
98
- end
99
- end
100
-
101
- def exp_alloc(exp)
102
- @alloc_table.exp_alloc(exp)
103
- end
104
- end
105
-
106
- class AllocTable
107
- def initialize(top)
108
- @top = top
109
- @tbl = {}
110
- @type_tbl = {}
111
- end
112
-
113
- def utype_to_type_def(utype)
114
- if t = @top[:dict][:itype_space][utype.to_uniq_str]
115
- t.get
116
- elsif t = @top[:dict][:type_space][utype.typename]
117
- t.get
118
- else
119
- raise "Assertion error"
120
- end
121
- end
122
-
123
- def type_alloc(type_def)
124
- return @type_tbl[type_def] if @type_tbl[type_def]
125
- case type_def
126
- when TypeDef
127
- tvalue_type_max_allocs = type_def[:tvalues].map do |tval|
128
- param_type_max_allocs = tval[:params].map do |param|
129
- type_alloc(utype_to_type_def(param[:typing]))
130
- end
131
- param_type_max_allocs.inject(Alloc.empty, &:&)
132
- end
133
- self_type_alloc = type_def[:static] ? Alloc.empty : Alloc.one(Link.new(type_def))
134
- @type_tbl[type_def] = tvalue_type_max_allocs.inject(&:|) & self_type_alloc
135
- when PrimTypeDef
136
- @type_tbl[type_def] = Alloc.empty
137
- end
138
- end
139
-
140
- def exp_alloc(exp)
141
- return @tbl[exp] if @tbl[exp]
142
- case exp
143
- when MatchExp
144
- @tbl[exp] = exp[:cases].map{|c| exp_alloc(c[:exp])}.inject(&:|) & exp_alloc(exp[:exp])
145
- when FuncCall
146
- args_alloc = exp[:args].map{|x| exp_alloc(x)}.inject(&:&)
147
- key = ([exp] + exp[:args]).map{|x| x[:typing].to_uniq_str} + [exp[:name][:desc]]
148
- if @top[:dict][:ifunc_space][key]
149
- f = @top[:dict][:ifunc_space][key].get
150
- @tbl[exp] = args_alloc & exp_alloc(f[:exp])
151
- elsif f = @top[:dict][:func_space][exp[:name][:desc]]
152
- if f.get.is_a?(PrimFuncDef)
153
- @tbl[exp] = args_alloc
154
- else
155
- raise "Assertion error"
156
- end
157
- else
158
- raise "Assertion error"
159
- end
160
- when ValueConst
161
- args_alloc = exp[:args].map{|x| exp_alloc(x)}.inject(Alloc.empty, &:&)
162
- key = exp[:typing].to_uniq_str
163
- raise "Assertion error" unless @top[:dict][:itype_space][key]
164
- type_def = @top[:dict][:itype_space][key].get
165
- @tbl[exp] = args_alloc & Alloc.one(Link.new(type_def))
166
- when Syntax
167
- @tbl[exp] = Alloc.empty
168
- else
169
- raise "Assertion error"
170
- end
171
- end
172
- end
173
-
174
- class Alloc
175
- attr_reader :h
176
- def initialize(hash)
177
- @h = hash
178
- end
179
-
180
- def self.empty
181
- self.new({})
182
- end
183
-
184
- def self.one(k)
185
- self.new(k => 1)
186
- end
187
-
188
- def |(other)
189
- Alloc.new self.h.merge(other.h){|k, v1, v2| [v1, v2].max}
190
- end
191
-
192
- def &(other)
193
- Alloc.new self.h.merge(other.h){|k, v1, v2| v1 + v2}
194
- end
195
-
196
- def each(&block)
197
- @h.each(&block)
198
- end
199
- end
200
- end
1
+ module Emfrp
2
+ class AllocRequirement
3
+ def initialize(top)
4
+ @top = top
5
+ @alloc_table = AllocTable.new(top)
6
+ @sorted_nodes = @top[:dict][:sorted_nodes].map{|x| x.get}
7
+ end
8
+
9
+ def requirement
10
+ sorted_datas = @top[:dict][:sorted_datas].map{|x| x.get}
11
+ init_nodes = @sorted_nodes.select{|n| n[:init_exp]}
12
+ max_amount = Alloc.empty
13
+ max_amount = data_requirement(sorted_datas, max_amount)
14
+ max_amount = node_init_requirement(init_nodes, max_amount, sorted_datas)
15
+ max_amount = node_loop_requirement(max_amount, init_nodes, sorted_datas)
16
+ return max_amount
17
+ end
18
+
19
+ def data_requirement(sorted_datas, max_amount)
20
+ retains = []
21
+ sorted_datas.each do |d|
22
+ max_amount |= type_alloc_sum(retains) & exp_alloc(d[:exp])
23
+ end
24
+ return max_amount
25
+ end
26
+
27
+ def node_init_requirement(init_nodes, max_amount, datas)
28
+ retains = datas.clone
29
+ init_nodes.each do |n|
30
+ max_amount |= type_alloc_sum(retains) & exp_alloc(n[:init_exp])
31
+ retains << n
32
+ end
33
+ return max_amount
34
+ end
35
+
36
+ def node_loop_requirement(max_amount, init_nodes, datas)
37
+ lrefs = init_nodes
38
+ crefs = []
39
+ @sorted_nodes.each_with_index do |n, i|
40
+ max_amount |= type_alloc_sum(datas + lrefs + crefs) & exp_alloc(n[:exp])
41
+ crefs << n
42
+ lrefs.reject! do |x|
43
+ i >= ref_pos_last(x)
44
+ end
45
+ crefs.reject! do |x|
46
+ i >= ref_pos_current(x)
47
+ end
48
+ end
49
+ return max_amount
50
+ end
51
+
52
+ def ref_pos_last(node)
53
+ res = -1
54
+ @sorted_nodes.each_with_index do |n, i|
55
+ if n[:params].any?{|param| param[:last] && param[:name] == node[:name]}
56
+ res = i
57
+ end
58
+ end
59
+ return res
60
+ end
61
+
62
+ def ref_pos_current(node)
63
+ res = -1
64
+ @sorted_nodes.each_with_index do |n, i|
65
+ if n[:params].any?{|param| !param[:last] && param[:name] == node[:name]}
66
+ res = i
67
+ end
68
+ end
69
+ return res
70
+ end
71
+
72
+ def life_point(node)
73
+ self_position = @sorted_nodes.index{|x| x == node}
74
+ distance_to_end = @sorted_nodes.size - self_position
75
+ res = []
76
+ @sorted_nodes.each_with_index do |x, i|
77
+ x[:params].each do |param|
78
+ if param[:name] == node[:name]
79
+ if param[:last]
80
+ res << distance_to_end + i
81
+ else
82
+ res << i - self_position
83
+ end
84
+ end
85
+ end
86
+ end
87
+ if res == []
88
+ raise "Assertion error"
89
+ else
90
+ return res.max
91
+ end
92
+ end
93
+
94
+ def type_alloc_sum(defs)
95
+ defs.inject(Alloc.empty) do |acc, d|
96
+ type_def = @alloc_table.utype_to_type_def(d[:typing])
97
+ acc & @alloc_table.type_alloc(type_def)
98
+ end
99
+ end
100
+
101
+ def exp_alloc(exp)
102
+ @alloc_table.exp_alloc(exp)
103
+ end
104
+ end
105
+
106
+ class AllocTable
107
+ def initialize(top)
108
+ @top = top
109
+ @tbl = {}
110
+ @type_tbl = {}
111
+ end
112
+
113
+ def utype_to_type_def(utype)
114
+ if t = @top[:dict][:itype_space][utype.to_uniq_str]
115
+ t.get
116
+ elsif t = @top[:dict][:type_space][utype.typename]
117
+ t.get
118
+ else
119
+ raise "Assertion error"
120
+ end
121
+ end
122
+
123
+ def type_alloc(type_def)
124
+ return @type_tbl[type_def] if @type_tbl[type_def]
125
+ case type_def
126
+ when TypeDef
127
+ tvalue_type_max_allocs = type_def[:tvalues].map do |tval|
128
+ param_type_max_allocs = tval[:params].map do |param|
129
+ type_alloc(utype_to_type_def(param[:typing]))
130
+ end
131
+ param_type_max_allocs.inject(Alloc.empty, &:&)
132
+ end
133
+ self_type_alloc = type_def[:static] ? Alloc.empty : Alloc.one(Link.new(type_def))
134
+ @type_tbl[type_def] = tvalue_type_max_allocs.inject(&:|) & self_type_alloc
135
+ when PrimTypeDef
136
+ @type_tbl[type_def] = Alloc.empty
137
+ end
138
+ end
139
+
140
+ def exp_alloc(exp)
141
+ return @tbl[exp] if @tbl[exp]
142
+ case exp
143
+ when MatchExp
144
+ @tbl[exp] = exp[:cases].map{|c| exp_alloc(c[:exp])}.inject(&:|) & exp_alloc(exp[:exp])
145
+ when FuncCall
146
+ args_alloc = exp[:args].map{|x| exp_alloc(x)}.inject(&:&)
147
+ key = ([exp] + exp[:args]).map{|x| x[:typing].to_uniq_str} + [exp[:name][:desc]]
148
+ if @top[:dict][:ifunc_space][key]
149
+ f = @top[:dict][:ifunc_space][key].get
150
+ @tbl[exp] = args_alloc & exp_alloc(f[:exp])
151
+ elsif f = @top[:dict][:func_space][exp[:name][:desc]]
152
+ if f.get.is_a?(PrimFuncDef)
153
+ @tbl[exp] = args_alloc
154
+ else
155
+ raise "Assertion error"
156
+ end
157
+ else
158
+ raise "Assertion error"
159
+ end
160
+ when ValueConst
161
+ args_alloc = exp[:args].map{|x| exp_alloc(x)}.inject(Alloc.empty, &:&)
162
+ key = exp[:typing].to_uniq_str
163
+ raise "Assertion error" unless @top[:dict][:itype_space][key]
164
+ type_def = @top[:dict][:itype_space][key].get
165
+ @tbl[exp] = args_alloc & Alloc.one(Link.new(type_def))
166
+ when Syntax
167
+ @tbl[exp] = Alloc.empty
168
+ else
169
+ raise "Assertion error"
170
+ end
171
+ end
172
+ end
173
+
174
+ class Alloc
175
+ attr_reader :h
176
+ def initialize(hash)
177
+ @h = hash
178
+ end
179
+
180
+ def self.empty
181
+ self.new({})
182
+ end
183
+
184
+ def self.one(k)
185
+ self.new(k => 1)
186
+ end
187
+
188
+ def |(other)
189
+ Alloc.new self.h.merge(other.h){|k, v1, v2| [v1, v2].max}
190
+ end
191
+
192
+ def &(other)
193
+ Alloc.new self.h.merge(other.h){|k, v1, v2| v1 + v2}
194
+ end
195
+
196
+ def each(&block)
197
+ @h.each(&block)
198
+ end
199
+ end
200
+ end
@@ -1,18 +1,18 @@
1
- require 'emfrp/compile/c/monofy'
2
- require 'emfrp/compile/c/alloc'
3
- require 'emfrp/compile/c/codegen_context'
4
- require 'emfrp/compile/c/syntax_codegen'
5
-
6
- module Emfrp
7
- module Codegen
8
- extend self
9
-
10
- def codegen(top, c_output, h_output, main_output, name)
11
- Monofy.monofy(top)
12
- ct = CodegenContext.new(top)
13
- ar = AllocRequirement.new(top)
14
- top.codegen(ct, ar)
15
- ct.code_generate(c_output, h_output, main_output, name)
16
- end
17
- end
18
- end
1
+ require 'emfrp/compile/c/monofy'
2
+ require 'emfrp/compile/c/alloc'
3
+ require 'emfrp/compile/c/codegen_context'
4
+ require 'emfrp/compile/c/syntax_codegen'
5
+
6
+ module Emfrp
7
+ module Codegen
8
+ extend self
9
+
10
+ def codegen(top, c_output, h_output, main_output, name)
11
+ Monofy.monofy(top)
12
+ ct = CodegenContext.new(top)
13
+ ar = AllocRequirement.new(top)
14
+ top.codegen(ct, ar)
15
+ ct.code_generate(c_output, h_output, main_output, name)
16
+ end
17
+ end
18
+ end