emfrp 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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