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,364 +1,364 @@
1
- require 'emfrp/syntax'
2
- require 'emfrp/compile/c/syntax_exp_codegen'
3
-
4
- module Emfrp
5
- class Top
6
- def codegen(ct, ar)
7
- self[:dict][:itype_space].each do |k, v|
8
- v.get.struct_gen(ct)
9
- v.get.constructor_gen(ct)
10
- v.get.marker_gen(ct)
11
- end
12
- self[:inputs].each do |i|
13
- if i[:init_exp]
14
- i.init_func_gen(ct)
15
- ct.define_init_stmt "#{i.node_var_name(ct)}[last_side] = #{i.init_func_name(ct)}();"
16
- end
17
- i.node_var_gen(ct)
18
- end
19
- self[:dict][:sorted_nodes].each_with_index do |n, i|
20
- node = n.get
21
- node.func_gen(ct)
22
- node.node_var_gen(ct)
23
- if node[:init_exp]
24
- node.init_func_gen(ct)
25
- ct.define_init_stmt "#{node.node_var_name(ct)}[last_side] = #{node.init_func_name(ct)}();"
26
- t = ct.tdef(node)
27
- if t.is_a?(TypeDef) && !t.enum?(ct)
28
- ct.define_init_stmt "#{t.marker_func_name(ct)}(#{node.node_var_name(ct)}[last_side], #{ar.ref_pos_last(node) + 1});"
29
- end
30
- end
31
- end
32
- self[:dict][:ifunc_space].each do |k, v|
33
- v.get.codegen(ct)
34
- end
35
- self[:dict][:used_pfuncs].each do |v|
36
- v.get.codegen(ct)
37
- end
38
- self[:dict][:sorted_datas].reverse.each do |v|
39
- v.get.codegen(ct)
40
- end
41
- memory_gen(ct, ar)
42
- main_gen(ct, ar)
43
- io_proto_gen(ct)
44
- end
45
-
46
- def memory_gen(ct, ar)
47
- max_memory = ar.requirement()
48
- max_memory.each do |t, i|
49
- t = t.get
50
- next if t[:static] || t.enum?(ct)
51
- ct.define_global_var("struct #{t.struct_name(ct)}", "#{t.memory_name(ct)}[#{i}]")
52
- ct.define_global_var("int", "#{t.memory_size_name(ct)}", "#{i}")
53
- ct.define_global_var("int", "#{t.memory_counter_name(ct)}", "0")
54
- end
55
- ct.define_global_var("int", "Counter", "1")
56
- ct.define_global_var("int", "NodeSize", "#{self[:dict][:sorted_nodes].size}")
57
- ct.define_func("void", "refreshMark", []) do |x|
58
- x << "int i;"
59
- max_memory.each do |t, i|
60
- t = t.get
61
- next if t[:static] || t.enum?(ct)
62
- mn = "#{t.memory_name(ct)}[i].mark"
63
- stmts = []
64
- stmts << "if (#{mn} < Counter) #{mn} = 0;"
65
- stmts << "else #{mn} -= Counter - 1;"
66
- x << ct.make_block("for (i = 0; i < #{t.memory_size_name(ct)}; i++) {", stmts, "}")
67
- end
68
- end
69
- end
70
-
71
- def main_gen(ct, ar)
72
- ct.define_func("void", "Activate" + self[:module_name][:desc], [], :none) do |x|
73
- x << "int current_side = 0, last_side = 1;"
74
- ct.define_init_stmt "Counter = NodeSize + 1;"
75
- ct.define_init_stmt "refreshMark();"
76
- ct.init_stmts.each do |i|
77
- x << i
78
- end
79
- stmts = []
80
- stmts << "Counter = 1;"
81
- inputs = self[:inputs].map{|x| "&#{x.node_var_name(ct)}[current_side]"}.join(", ")
82
- stmts << "Input(#{inputs});"
83
- self[:dict][:sorted_nodes].each do |n|
84
- node = n.get
85
- args = node[:params].map do |x|
86
- pn = self[:dict][:node_space][x[:name][:desc]].get
87
- "#{pn.node_var_name(ct)}[#{x[:last] ? "last_side" : "current_side"}]"
88
- end
89
- output_arg = "&#{node.node_var_name(ct)}[current_side]"
90
- stmts << "#{node.node_func_name(ct)}(#{[*args, output_arg].join(", ")});"
91
- t = ct.tdef(node)
92
- if t.is_a?(TypeDef) && !t.enum?(ct)
93
- mark_val = "Counter + #{ar.life_point(node)}"
94
- stmts << "#{t.marker_func_name(ct)}(#{node.node_var_name(ct)}[current_side], #{mark_val});"
95
- end
96
- stmts << "Counter++;"
97
- end
98
- outputs = self[:outputs].map do |x|
99
- node = self[:dict][:node_space][x[:name][:desc]].get
100
- "&#{node.node_var_name(ct)}[current_side]"
101
- end
102
- stmts << "Output(#{outputs.join(", ")});"
103
- stmts << "refreshMark();"
104
- stmts << "current_side ^= 1;"
105
- stmts << "last_side ^= 1;"
106
- x << ct.make_block("while (1) {", stmts, "}")
107
- end
108
- end
109
-
110
- def io_proto_gen(ct)
111
- ct.define_proto("void", "Input", self[:inputs].map{|x| ct.tref(x) + "*"}, :extern)
112
- ct.define_proto("void", "Output", self[:outputs].map{|x| ct.tref(x) + "*"}, :extern)
113
- end
114
- end
115
-
116
- class TypeDef
117
- def struct_gen(ct)
118
- return if enum?(ct)
119
- ct.define_struct("struct", struct_name(ct), nil) do |s1|
120
- s1 << "int tvalue_id;" if self[:tvalues].length > 1
121
- s1 << "int mark;" unless self[:static]
122
- s1 << ct.define_struct("union", nil, "value") do |s2|
123
- self[:tvalues].each_with_index do |tvalue, i|
124
- next if tvalue[:params].size == 0
125
- s2 << ct.define_struct("struct", nil, tvalue.struct_name(ct)) do |s3|
126
- tvalue[:params].each_with_index do |param, i|
127
- s3 << "#{ct.tref(param)} member#{i};"
128
- end
129
- end
130
- end
131
- end
132
- end
133
- end
134
-
135
- def constructor_gen(ct)
136
- return if enum?(ct)
137
- self[:tvalues].each_with_index do |tvalue, i|
138
- params = tvalue[:params].each_with_index.map do |param, i|
139
- [ct.tref(param), "member#{i}"]
140
- end
141
- ct.define_func(ref_name(ct), tvalue.constructor_name(ct), params) do |s|
142
- while_stmts = []
143
- while_stmts << "#{memory_counter_name(ct)}++;"
144
- while_stmts << "#{memory_counter_name(ct)} %= #{memory_size_name(ct)};"
145
- mn = "#{memory_name(ct)}[#{memory_counter_name(ct)}].mark"
146
- while_stmts << "if (#{mn} < Counter) { x = #{memory_name(ct)} + #{memory_counter_name(ct)}; break; }"
147
- s << "#{ref_name(ct)} x;"
148
- s << ct.make_block("while (1) {", while_stmts, "}")
149
- s << "x->tvalue_id = #{i};" if self[:tvalues].length > 1
150
- tvalue[:params].each_with_index do |param, i|
151
- s << "x->value.#{tvalue.struct_name(ct)}.member#{i} = member#{i};"
152
- end
153
- s << "return x;"
154
- end
155
- end
156
- end
157
-
158
- def marker_gen(ct)
159
- return if enum?(ct)
160
- params = [[ref_name(ct), "x"], ["int", "mark"]]
161
- ct.define_func("void", marker_func_name(ct), params) do |x|
162
- x << "x->mark = mark;" unless self[:static]
163
- accessor = self[:static] ? "." : "->"
164
- cases = []
165
- self[:tvalues].each_with_index do |tvalue, i|
166
- calls = []
167
- tvalue[:params].each_with_index do |param, i|
168
- if ct.tdef(param).is_a?(TypeDef) && !ct.tdef(param).enum?(ct)
169
- fn = ct.tdef(param).marker_func_name(ct)
170
- calls << "#{fn}(x#{accessor}value.#{tvalue.struct_name(ct)}.member#{i}, mark);"
171
- end
172
- end
173
- cases << "case #{i}: #{calls.join(" ")} break;" if calls.size > 0
174
- end
175
- if cases.size > 0
176
- switch_exp = self[:tvalues].size == 1 ? "0" : "x#{accessor}tvalue_id"
177
- x << ct.make_block("switch (#{switch_exp}) {", cases, "}")
178
- end
179
- end
180
- end
181
-
182
- def enum?(ct)
183
- self[:tvalues].all?{|x| x[:params].length == 0}
184
- end
185
-
186
- def struct_name(ct)
187
- unless enum?(ct)
188
- self[:tvalues][0][:typing].to_flatten_uniq_str
189
- else
190
- raise
191
- end
192
- end
193
-
194
- def marker_func_name(ct)
195
- unless enum?(ct)
196
- "mark_#{struct_name(ct)}"
197
- else
198
- raise
199
- end
200
- end
201
-
202
- def ref_name(ct)
203
- if enum?(ct)
204
- "int"
205
- else
206
- "struct " + struct_name(ct) + (self[:static] ? "" : "*")
207
- end
208
- end
209
-
210
- def memory_name(ct)
211
- "memory_#{struct_name(ct)}"
212
- end
213
-
214
- def memory_size_name(ct)
215
- "size_#{struct_name(ct)}"
216
- end
217
-
218
- def memory_counter_name(ct)
219
- "counter_#{struct_name(ct)}"
220
- end
221
- end
222
-
223
- class TValue
224
- def constructor_name(ct)
225
- self[:name][:desc] + "_" + ct.serial(self[:name][:desc], self).to_s
226
- end
227
-
228
- def struct_name(ct)
229
- self[:name][:desc]
230
- end
231
- end
232
-
233
- class PrimTypeDef
234
- def codegen(ct)
235
- # do nothing
236
- end
237
-
238
- def ref_name(ct)
239
- ctype_foreign = self[:foreigns].find{|x| x[:language][:desc] == "c"}
240
- unless ctype_foreign
241
- raise "compile error: foreign for c is undefined in #{self[:name][:desc]}"
242
- end
243
- ctype_foreign[:desc]
244
- end
245
- end
246
-
247
- class NodeDef
248
- def func_gen(ct)
249
- params = self[:params].map{|x| [ct.tref(x), ct.escape_name(x[:as][:desc])]}
250
- output_param = [ct.tref(self) + "*", "output"]
251
- ct.define_func("int", node_func_name(ct), params + [output_param]) do |x|
252
- x << "*output = #{self[:exp].codegen(ct, x)};"
253
- x << "return 1;"
254
- end
255
- end
256
-
257
- def init_func_gen(ct)
258
- ct.define_func(ct.tref(self), init_func_name(ct), []) do |x|
259
- x << "return #{self[:init_exp].codegen(ct, x)};"
260
- end
261
- end
262
-
263
- def node_var_gen(ct)
264
- ct.define_global_var(ct.tref(self), "#{node_var_name(ct)}[2]")
265
- end
266
-
267
- def init_func_name(ct)
268
- "init_#{ct.escape_name(self[:name][:desc])}"
269
- end
270
-
271
- def node_func_name(ct)
272
- "node_#{ct.escape_name(self[:name][:desc])}"
273
- end
274
-
275
- def node_var_name(ct)
276
- "node_memory_#{ct.escape_name(self[:name][:desc])}"
277
- end
278
-
279
- def var_suffix(ct)
280
- "_nvar#{ct.serial(nil, self)}"
281
- end
282
-
283
- def var_name(ct, name)
284
- ct.escape_name(name)
285
- end
286
- end
287
-
288
- class InputDef
289
- def init_func_gen(ct)
290
- ct.define_func(ct.tref(self), init_func_name(ct), []) do |x|
291
- x << "return #{self[:init_exp].codegen(ct, x)};"
292
- end
293
- end
294
-
295
- def node_var_gen(ct)
296
- ct.define_global_var(ct.tref(self), "#{node_var_name(ct)}[2]")
297
- end
298
-
299
- def init_func_name(ct)
300
- "init_#{self[:name][:desc]}"
301
- end
302
-
303
- def node_var_name(ct)
304
- "node_memory_#{self[:name][:desc]}"
305
- end
306
- end
307
-
308
- class DataDef
309
- def codegen(ct)
310
- t = ct.tref(self)
311
- ct.define_global_var(t, var_name(ct, self[:name][:desc]))
312
- ct.define_init_stmt("#{var_name(ct, self[:name][:desc])} = #{init_func_name(ct)}();")
313
- ct.define_func(t, init_func_name(ct), []) do |x|
314
- x << "return #{self[:exp].codegen(ct, x)};"
315
- end
316
- end
317
-
318
- def var_name(ct)
319
- "data_#{self[:name][:desc]}"
320
- end
321
-
322
- def init_func_name(ct)
323
- "init_#{self[:name][:desc]}"
324
- end
325
-
326
- def var_name(ct, name)
327
- ct.escape_name(name)
328
- end
329
- end
330
-
331
- class FuncDef
332
- def codegen(ct)
333
- params = self[:params].map{|x| [ct.tref(x), x[:name][:desc]]}
334
- ct.define_func(ct.tref(self), func_name(ct), params) do |x|
335
- x << "return #{self[:exp].codegen(ct, x)};"
336
- end
337
- end
338
-
339
- def func_name(ct)
340
- ct.escape_name(self[:name][:desc]) + "_" + ct.serial(self[:name][:desc], self).to_s
341
- end
342
-
343
- def var_name(ct, name)
344
- ct.escape_name(name)
345
- end
346
- end
347
-
348
- class PrimFuncDef
349
- def codegen(ct)
350
- params = self[:params].map{|x| x[:name][:desc]}
351
- exp = self[:foreigns].find{|x| x[:language][:desc] == "c"}
352
- raise "assertion error: foreign for c is undefined in #{self[:name][:desc]}" unless exp
353
- ct.define_macro(func_name(ct), params, exp[:desc])
354
- end
355
-
356
- def func_name(ct)
357
- ct.escape_name(self[:name][:desc])
358
- end
359
- end
360
-
361
- class ParamDef
362
-
363
- end
364
- end
1
+ require 'emfrp/syntax'
2
+ require 'emfrp/compile/c/syntax_exp_codegen'
3
+
4
+ module Emfrp
5
+ class Top
6
+ def codegen(ct, ar)
7
+ self[:dict][:itype_space].each do |k, v|
8
+ v.get.struct_gen(ct)
9
+ v.get.constructor_gen(ct)
10
+ v.get.marker_gen(ct)
11
+ end
12
+ self[:inputs].each do |i|
13
+ if i[:init_exp]
14
+ i.init_func_gen(ct)
15
+ ct.define_init_stmt "#{i.node_var_name(ct)}[last_side] = #{i.init_func_name(ct)}();"
16
+ end
17
+ i.node_var_gen(ct)
18
+ end
19
+ self[:dict][:sorted_nodes].each_with_index do |n, i|
20
+ node = n.get
21
+ node.func_gen(ct)
22
+ node.node_var_gen(ct)
23
+ if node[:init_exp]
24
+ node.init_func_gen(ct)
25
+ ct.define_init_stmt "#{node.node_var_name(ct)}[last_side] = #{node.init_func_name(ct)}();"
26
+ t = ct.tdef(node)
27
+ if t.is_a?(TypeDef) && !t.enum?(ct)
28
+ ct.define_init_stmt "#{t.marker_func_name(ct)}(#{node.node_var_name(ct)}[last_side], #{ar.ref_pos_last(node) + 1});"
29
+ end
30
+ end
31
+ end
32
+ self[:dict][:ifunc_space].each do |k, v|
33
+ v.get.codegen(ct)
34
+ end
35
+ self[:dict][:used_pfuncs].each do |v|
36
+ v.get.codegen(ct)
37
+ end
38
+ self[:dict][:sorted_datas].reverse.each do |v|
39
+ v.get.codegen(ct)
40
+ end
41
+ memory_gen(ct, ar)
42
+ main_gen(ct, ar)
43
+ io_proto_gen(ct)
44
+ end
45
+
46
+ def memory_gen(ct, ar)
47
+ max_memory = ar.requirement()
48
+ max_memory.each do |t, i|
49
+ t = t.get
50
+ next if t[:static] || t.enum?(ct)
51
+ ct.define_global_var("struct #{t.struct_name(ct)}", "#{t.memory_name(ct)}[#{i}]")
52
+ ct.define_global_var("int", "#{t.memory_size_name(ct)}", "#{i}")
53
+ ct.define_global_var("int", "#{t.memory_counter_name(ct)}", "0")
54
+ end
55
+ ct.define_global_var("int", "Counter", "1")
56
+ ct.define_global_var("int", "NodeSize", "#{self[:dict][:sorted_nodes].size}")
57
+ ct.define_func("void", "refreshMark", []) do |x|
58
+ x << "int i;"
59
+ max_memory.each do |t, i|
60
+ t = t.get
61
+ next if t[:static] || t.enum?(ct)
62
+ mn = "#{t.memory_name(ct)}[i].mark"
63
+ stmts = []
64
+ stmts << "if (#{mn} < Counter) #{mn} = 0;"
65
+ stmts << "else #{mn} -= Counter - 1;"
66
+ x << ct.make_block("for (i = 0; i < #{t.memory_size_name(ct)}; i++) {", stmts, "}")
67
+ end
68
+ end
69
+ end
70
+
71
+ def main_gen(ct, ar)
72
+ ct.define_func("void", "Activate" + self[:module_name][:desc], [], :none) do |x|
73
+ x << "int current_side = 0, last_side = 1;"
74
+ ct.define_init_stmt "Counter = NodeSize + 1;"
75
+ ct.define_init_stmt "refreshMark();"
76
+ ct.init_stmts.each do |i|
77
+ x << i
78
+ end
79
+ stmts = []
80
+ stmts << "Counter = 1;"
81
+ inputs = self[:inputs].map{|x| "&#{x.node_var_name(ct)}[current_side]"}.join(", ")
82
+ stmts << "Input(#{inputs});"
83
+ self[:dict][:sorted_nodes].each do |n|
84
+ node = n.get
85
+ args = node[:params].map do |x|
86
+ pn = self[:dict][:node_space][x[:name][:desc]].get
87
+ "#{pn.node_var_name(ct)}[#{x[:last] ? "last_side" : "current_side"}]"
88
+ end
89
+ output_arg = "&#{node.node_var_name(ct)}[current_side]"
90
+ stmts << "#{node.node_func_name(ct)}(#{[*args, output_arg].join(", ")});"
91
+ t = ct.tdef(node)
92
+ if t.is_a?(TypeDef) && !t.enum?(ct)
93
+ mark_val = "Counter + #{ar.life_point(node)}"
94
+ stmts << "#{t.marker_func_name(ct)}(#{node.node_var_name(ct)}[current_side], #{mark_val});"
95
+ end
96
+ stmts << "Counter++;"
97
+ end
98
+ outputs = self[:outputs].map do |x|
99
+ node = self[:dict][:node_space][x[:name][:desc]].get
100
+ "&#{node.node_var_name(ct)}[current_side]"
101
+ end
102
+ stmts << "Output(#{outputs.join(", ")});"
103
+ stmts << "refreshMark();"
104
+ stmts << "current_side ^= 1;"
105
+ stmts << "last_side ^= 1;"
106
+ x << ct.make_block("while (1) {", stmts, "}")
107
+ end
108
+ end
109
+
110
+ def io_proto_gen(ct)
111
+ ct.define_proto("void", "Input", self[:inputs].map{|x| ct.tref(x) + "*"}, :extern)
112
+ ct.define_proto("void", "Output", self[:outputs].map{|x| ct.tref(x) + "*"}, :extern)
113
+ end
114
+ end
115
+
116
+ class TypeDef
117
+ def struct_gen(ct)
118
+ return if enum?(ct)
119
+ ct.define_struct("struct", struct_name(ct), nil) do |s1|
120
+ s1 << "int tvalue_id;" if self[:tvalues].length > 1
121
+ s1 << "int mark;" unless self[:static]
122
+ s1 << ct.define_struct("union", nil, "value") do |s2|
123
+ self[:tvalues].each_with_index do |tvalue, i|
124
+ next if tvalue[:params].size == 0
125
+ s2 << ct.define_struct("struct", nil, tvalue.struct_name(ct)) do |s3|
126
+ tvalue[:params].each_with_index do |param, i|
127
+ s3 << "#{ct.tref(param)} member#{i};"
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ def constructor_gen(ct)
136
+ return if enum?(ct)
137
+ self[:tvalues].each_with_index do |tvalue, i|
138
+ params = tvalue[:params].each_with_index.map do |param, i|
139
+ [ct.tref(param), "member#{i}"]
140
+ end
141
+ ct.define_func(ref_name(ct), tvalue.constructor_name(ct), params) do |s|
142
+ while_stmts = []
143
+ while_stmts << "#{memory_counter_name(ct)}++;"
144
+ while_stmts << "#{memory_counter_name(ct)} %= #{memory_size_name(ct)};"
145
+ mn = "#{memory_name(ct)}[#{memory_counter_name(ct)}].mark"
146
+ while_stmts << "if (#{mn} < Counter) { x = #{memory_name(ct)} + #{memory_counter_name(ct)}; break; }"
147
+ s << "#{ref_name(ct)} x;"
148
+ s << ct.make_block("while (1) {", while_stmts, "}")
149
+ s << "x->tvalue_id = #{i};" if self[:tvalues].length > 1
150
+ tvalue[:params].each_with_index do |param, i|
151
+ s << "x->value.#{tvalue.struct_name(ct)}.member#{i} = member#{i};"
152
+ end
153
+ s << "return x;"
154
+ end
155
+ end
156
+ end
157
+
158
+ def marker_gen(ct)
159
+ return if enum?(ct)
160
+ params = [[ref_name(ct), "x"], ["int", "mark"]]
161
+ ct.define_func("void", marker_func_name(ct), params) do |x|
162
+ x << "x->mark = mark;" unless self[:static]
163
+ accessor = self[:static] ? "." : "->"
164
+ cases = []
165
+ self[:tvalues].each_with_index do |tvalue, i|
166
+ calls = []
167
+ tvalue[:params].each_with_index do |param, i|
168
+ if ct.tdef(param).is_a?(TypeDef) && !ct.tdef(param).enum?(ct)
169
+ fn = ct.tdef(param).marker_func_name(ct)
170
+ calls << "#{fn}(x#{accessor}value.#{tvalue.struct_name(ct)}.member#{i}, mark);"
171
+ end
172
+ end
173
+ cases << "case #{i}: #{calls.join(" ")} break;" if calls.size > 0
174
+ end
175
+ if cases.size > 0
176
+ switch_exp = self[:tvalues].size == 1 ? "0" : "x#{accessor}tvalue_id"
177
+ x << ct.make_block("switch (#{switch_exp}) {", cases, "}")
178
+ end
179
+ end
180
+ end
181
+
182
+ def enum?(ct)
183
+ self[:tvalues].all?{|x| x[:params].length == 0}
184
+ end
185
+
186
+ def struct_name(ct)
187
+ unless enum?(ct)
188
+ self[:tvalues][0][:typing].to_flatten_uniq_str
189
+ else
190
+ raise
191
+ end
192
+ end
193
+
194
+ def marker_func_name(ct)
195
+ unless enum?(ct)
196
+ "mark_#{struct_name(ct)}"
197
+ else
198
+ raise
199
+ end
200
+ end
201
+
202
+ def ref_name(ct)
203
+ if enum?(ct)
204
+ "int"
205
+ else
206
+ "struct " + struct_name(ct) + (self[:static] ? "" : "*")
207
+ end
208
+ end
209
+
210
+ def memory_name(ct)
211
+ "memory_#{struct_name(ct)}"
212
+ end
213
+
214
+ def memory_size_name(ct)
215
+ "size_#{struct_name(ct)}"
216
+ end
217
+
218
+ def memory_counter_name(ct)
219
+ "counter_#{struct_name(ct)}"
220
+ end
221
+ end
222
+
223
+ class TValue
224
+ def constructor_name(ct)
225
+ self[:name][:desc] + "_" + ct.serial(self[:name][:desc], self).to_s
226
+ end
227
+
228
+ def struct_name(ct)
229
+ self[:name][:desc]
230
+ end
231
+ end
232
+
233
+ class PrimTypeDef
234
+ def codegen(ct)
235
+ # do nothing
236
+ end
237
+
238
+ def ref_name(ct)
239
+ ctype_foreign = self[:foreigns].find{|x| x[:language][:desc] == "c"}
240
+ unless ctype_foreign
241
+ raise "compile error: foreign for c is undefined in #{self[:name][:desc]}"
242
+ end
243
+ ctype_foreign[:desc]
244
+ end
245
+ end
246
+
247
+ class NodeDef
248
+ def func_gen(ct)
249
+ params = self[:params].map{|x| [ct.tref(x), ct.escape_name(x[:as][:desc])]}
250
+ output_param = [ct.tref(self) + "*", "output"]
251
+ ct.define_func("int", node_func_name(ct), params + [output_param]) do |x|
252
+ x << "*output = #{self[:exp].codegen(ct, x)};"
253
+ x << "return 1;"
254
+ end
255
+ end
256
+
257
+ def init_func_gen(ct)
258
+ ct.define_func(ct.tref(self), init_func_name(ct), []) do |x|
259
+ x << "return #{self[:init_exp].codegen(ct, x)};"
260
+ end
261
+ end
262
+
263
+ def node_var_gen(ct)
264
+ ct.define_global_var(ct.tref(self), "#{node_var_name(ct)}[2]")
265
+ end
266
+
267
+ def init_func_name(ct)
268
+ "init_#{ct.escape_name(self[:name][:desc])}"
269
+ end
270
+
271
+ def node_func_name(ct)
272
+ "node_#{ct.escape_name(self[:name][:desc])}"
273
+ end
274
+
275
+ def node_var_name(ct)
276
+ "node_memory_#{ct.escape_name(self[:name][:desc])}"
277
+ end
278
+
279
+ def var_suffix(ct)
280
+ "_nvar#{ct.serial(nil, self)}"
281
+ end
282
+
283
+ def var_name(ct, name)
284
+ ct.escape_name(name)
285
+ end
286
+ end
287
+
288
+ class InputDef
289
+ def init_func_gen(ct)
290
+ ct.define_func(ct.tref(self), init_func_name(ct), []) do |x|
291
+ x << "return #{self[:init_exp].codegen(ct, x)};"
292
+ end
293
+ end
294
+
295
+ def node_var_gen(ct)
296
+ ct.define_global_var(ct.tref(self), "#{node_var_name(ct)}[2]")
297
+ end
298
+
299
+ def init_func_name(ct)
300
+ "init_#{self[:name][:desc]}"
301
+ end
302
+
303
+ def node_var_name(ct)
304
+ "node_memory_#{self[:name][:desc]}"
305
+ end
306
+ end
307
+
308
+ class DataDef
309
+ def codegen(ct)
310
+ t = ct.tref(self)
311
+ ct.define_global_var(t, var_name(ct, self[:name][:desc]))
312
+ ct.define_init_stmt("#{var_name(ct, self[:name][:desc])} = #{init_func_name(ct)}();")
313
+ ct.define_func(t, init_func_name(ct), []) do |x|
314
+ x << "return #{self[:exp].codegen(ct, x)};"
315
+ end
316
+ end
317
+
318
+ def var_name(ct)
319
+ "data_#{self[:name][:desc]}"
320
+ end
321
+
322
+ def init_func_name(ct)
323
+ "init_#{self[:name][:desc]}"
324
+ end
325
+
326
+ def var_name(ct, name)
327
+ ct.escape_name(name)
328
+ end
329
+ end
330
+
331
+ class FuncDef
332
+ def codegen(ct)
333
+ params = self[:params].map{|x| [ct.tref(x), x[:name][:desc]]}
334
+ ct.define_func(ct.tref(self), func_name(ct), params) do |x|
335
+ x << "return #{self[:exp].codegen(ct, x)};"
336
+ end
337
+ end
338
+
339
+ def func_name(ct)
340
+ ct.escape_name(self[:name][:desc]) + "_" + ct.serial(self[:name][:desc], self).to_s
341
+ end
342
+
343
+ def var_name(ct, name)
344
+ ct.escape_name(name)
345
+ end
346
+ end
347
+
348
+ class PrimFuncDef
349
+ def codegen(ct)
350
+ params = self[:params].map{|x| x[:name][:desc]}
351
+ exp = self[:foreigns].find{|x| x[:language][:desc] == "c"}
352
+ raise "assertion error: foreign for c is undefined in #{self[:name][:desc]}" unless exp
353
+ ct.define_macro(func_name(ct), params, exp[:desc])
354
+ end
355
+
356
+ def func_name(ct)
357
+ ct.escape_name(self[:name][:desc])
358
+ end
359
+ end
360
+
361
+ class ParamDef
362
+
363
+ end
364
+ end