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