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,218 +1,218 @@
1
- module Emfrp
2
- class CodegenContext
3
- SymbolToStr = {
4
- "!" => "_exclamation_",
5
- "#" => "_hash_",
6
- "$" => "_dollar_",
7
- "%" => "_parcent_",
8
- "&" => "_anpersand",
9
- "*" => "_asterisk_",
10
- "+" => "_plus_",
11
- "." => "_dot_",
12
- "/" => "_slash_",
13
- "<" => "_lt_",
14
- "=" => "_eq_",
15
- ">" => "_gt_",
16
- "?" => "_question_",
17
- "@" => "_at_",
18
- "\\" => "_backslash_",
19
- "^" => "_caret_",
20
- "|" => "_vertial_",
21
- "-" => "_minus_",
22
- "~" => "_tilde_",
23
- "(" => "_cpbegin_",
24
- ")" => "_cpend_",
25
- "," => "_comma_"
26
- }
27
-
28
- def initialize(top)
29
- @top = top
30
- @global_vars = []
31
- @funcs = []
32
- @structs = []
33
- @protos = []
34
- @static_protos = []
35
- @macros = []
36
- @init_stmts = []
37
- @templates = []
38
- end
39
-
40
- def code_generate(c_output, h_output, main_output, name)
41
- # generate header-file
42
- h_output << "#ifndef #{name.upcase}_H\n"
43
- h_output << "#define #{name.upcase}_H\n\n"
44
- @protos.each do |x|
45
- h_output.puts x.to_s
46
- end
47
- h_output << "\n#endif /* end of include guard */\n"
48
- # generate library-file
49
- c_output.puts "#include \"#{name}.h\""
50
- c_output.puts "/* Primitive functions (Macros) */"
51
- @macros.each do |x|
52
- c_output.puts x.to_s
53
- end
54
- c_output.puts "/* Data types */"
55
- @structs.each do |x|
56
- c_output.puts x.to_s
57
- end
58
- c_output.puts "/* Global variables */"
59
- @global_vars.each do |x|
60
- c_output.puts x.to_s
61
- end
62
- c_output.puts "/* Static prototypes */"
63
- @static_protos.each do |x|
64
- c_output.puts x.to_s
65
- end
66
- c_output.puts "/* Functions, Constructors, GCMarkers, etc... */"
67
- @funcs.each do |x|
68
- c_output.puts x.to_s
69
- end
70
- # generate main-file
71
- main_output << "#include \"#{name}.h\"\n\n"
72
- main_output << "void Input(#{@top[:inputs].map{|x| "#{tref(x)}* #{x[:name][:desc]}"}.join(", ")}) {\n /* Your code goes here... */\n}\n"
73
- main_output << "void Output(#{@top[:outputs].map{|x| "#{tref(x)}* #{x[:name][:desc]}"}.join(", ")}) {\n /* Your code goes here... */\n}\n"
74
- main_output << "int main() {\n Activate#{@top[:module_name][:desc]}();\n}\n"
75
- end
76
-
77
- def init_stmts
78
- @init_stmts
79
- end
80
-
81
- def func_name(name, ret_utype, arg_utypes)
82
- case f = @top[:dict][:func_space][name].get
83
- when PrimFuncDef
84
- f.func_name(self)
85
- when FuncDef
86
- key = [ret_utype, *arg_utypes].map(&:to_uniq_str) + [name]
87
- @top[:dict][:ifunc_space][key].get.func_name(self)
88
- else
89
- raise "Assertion error: unexpected func type #{f.class}"
90
- end
91
- end
92
-
93
- def constructor_name(name, utype)
94
- @top[:dict][:itype_space][utype.to_uniq_str].get[:tvalues].each do |tval|
95
- if tval[:name][:desc] == name
96
- return tval.constructor_name(self)
97
- end
98
- end
99
- raise "Assertion error: #{name} is not found"
100
- end
101
-
102
- def escape_name(name)
103
- rexp = Regexp.new("[" + Regexp.escape(SymbolToStr.keys.join) + "]")
104
- name.gsub(rexp, SymbolToStr)
105
- end
106
-
107
- def tdef(x)
108
- case x
109
- when Typing::UnionType
110
- key = x.to_uniq_str
111
- if @top[:dict][:type_space][key] && @top[:dict][:type_space][key].get.is_a?(PrimTypeDef)
112
- @top[:dict][:type_space][key].get
113
- elsif @top[:dict][:itype_space][key]
114
- @top[:dict][:itype_space][key].get
115
- else
116
- raise "Assertion error: itype #{x.to_uniq_str} is undefined"
117
- end
118
- when Syntax
119
- tdef(x[:typing])
120
- else
121
- raise "Assertion error"
122
- end
123
- end
124
-
125
- def tref(x)
126
- tdef(x).ref_name(self)
127
- end
128
-
129
- def serial(key, id)
130
- @serials ||= Hash.new{|h, k| h[k] = []}
131
- @serials[key] << id unless @serials[key].find{|x| x == id}
132
- return @serials[key].index{|x| x == id}
133
- end
134
-
135
- def uniq_id_gen
136
- @uniq_ids ||= (0..1000).to_a
137
- @uniq_ids.shift
138
- end
139
-
140
- def define_global_var(type_str, name_str, initial_value_str=nil)
141
- @global_vars << "#{type_str} #{name_str}" + (initial_value_str ? " = #{initial_value_str}" : "") + ";"
142
- end
143
-
144
- def define_macro(name_str, params, body_str)
145
- @macros << "#define #{name_str}(#{params.join(", ")}) (#{body_str})"
146
- end
147
-
148
- def define_func(type_str, name_str, params, accessor=:static, with_proto=true, &block)
149
- elements = []
150
- proc.call(elements)
151
- case accessor
152
- when :none then deco = ""
153
- when :static then deco = "static "
154
- end
155
- define_proto(type_str, name_str, params.map(&:first), accessor) if with_proto
156
- @funcs << Block.new("#{deco}#{type_str} #{name_str}(#{params.map{|a, b| "#{a} #{b}"}.join(", ")}) {", elements, "}")
157
- return nil
158
- end
159
-
160
- def define_proto(type_str, name_str, param_types, accessor=:static)
161
- case accessor
162
- when :none then deco = ""
163
- when :static then deco = "static "
164
- when :extern then deco = "extern "
165
- end
166
- proto = "#{deco}#{type_str} #{name_str}(#{param_types.join(", ")});"
167
- if accessor == :static || accessor == :extern
168
- @static_protos << proto
169
- else
170
- @protos << proto
171
- end
172
- return nil
173
- end
174
-
175
- def define_init_stmt(stmt)
176
- @init_stmts << stmt
177
- end
178
-
179
- def define_struct(kind_str, name_str, var_name_str)
180
- elements = []
181
- proc.call(elements)
182
- x = Block.new("#{kind_str} #{name_str}{", elements, "}#{var_name_str};")
183
- if name_str
184
- @structs << x
185
- return nil
186
- else
187
- return x
188
- end
189
- end
190
-
191
- def make_block(head_str, elements, foot_str)
192
- Block.new(head_str, elements, foot_str)
193
- end
194
-
195
- class Block
196
- T = (0..20).map{|i| " " * i}
197
- def initialize(head_str, elements, foot_str)
198
- @head_str = head_str
199
- @elements = elements
200
- @foot_str = foot_str
201
- end
202
-
203
- def to_s(t=0)
204
- res = ""
205
- res << T[t] + @head_str + "\n"
206
- @elements.each do |e|
207
- case e
208
- when Block
209
- res << e.to_s(t+1) + "\n"
210
- when String
211
- res << T[t+1] + e + "\n"
212
- end
213
- end
214
- res << T[t] + @foot_str
215
- end
216
- end
217
- end
218
- end
1
+ module Emfrp
2
+ class CodegenContext
3
+ SymbolToStr = {
4
+ "!" => "_exclamation_",
5
+ "#" => "_hash_",
6
+ "$" => "_dollar_",
7
+ "%" => "_parcent_",
8
+ "&" => "_anpersand",
9
+ "*" => "_asterisk_",
10
+ "+" => "_plus_",
11
+ "." => "_dot_",
12
+ "/" => "_slash_",
13
+ "<" => "_lt_",
14
+ "=" => "_eq_",
15
+ ">" => "_gt_",
16
+ "?" => "_question_",
17
+ "@" => "_at_",
18
+ "\\" => "_backslash_",
19
+ "^" => "_caret_",
20
+ "|" => "_vertial_",
21
+ "-" => "_minus_",
22
+ "~" => "_tilde_",
23
+ "(" => "_cpbegin_",
24
+ ")" => "_cpend_",
25
+ "," => "_comma_"
26
+ }
27
+
28
+ def initialize(top)
29
+ @top = top
30
+ @global_vars = []
31
+ @funcs = []
32
+ @structs = []
33
+ @protos = []
34
+ @static_protos = []
35
+ @macros = []
36
+ @init_stmts = []
37
+ @templates = []
38
+ end
39
+
40
+ def code_generate(c_output, h_output, main_output, name)
41
+ # generate header-file
42
+ h_output << "#ifndef #{name.upcase}_H\n"
43
+ h_output << "#define #{name.upcase}_H\n\n"
44
+ @protos.each do |x|
45
+ h_output.puts x.to_s
46
+ end
47
+ h_output << "\n#endif /* end of include guard */\n"
48
+ # generate library-file
49
+ c_output.puts "#include \"#{name}.h\""
50
+ c_output.puts "/* Primitive functions (Macros) */"
51
+ @macros.each do |x|
52
+ c_output.puts x.to_s
53
+ end
54
+ c_output.puts "/* Data types */"
55
+ @structs.each do |x|
56
+ c_output.puts x.to_s
57
+ end
58
+ c_output.puts "/* Global variables */"
59
+ @global_vars.each do |x|
60
+ c_output.puts x.to_s
61
+ end
62
+ c_output.puts "/* Static prototypes */"
63
+ @static_protos.each do |x|
64
+ c_output.puts x.to_s
65
+ end
66
+ c_output.puts "/* Functions, Constructors, GCMarkers, etc... */"
67
+ @funcs.each do |x|
68
+ c_output.puts x.to_s
69
+ end
70
+ # generate main-file
71
+ main_output << "#include \"#{name}.h\"\n\n"
72
+ main_output << "void Input(#{@top[:inputs].map{|x| "#{tref(x)}* #{x[:name][:desc]}"}.join(", ")}) {\n /* Your code goes here... */\n}\n"
73
+ main_output << "void Output(#{@top[:outputs].map{|x| "#{tref(x)}* #{x[:name][:desc]}"}.join(", ")}) {\n /* Your code goes here... */\n}\n"
74
+ main_output << "int main() {\n Activate#{@top[:module_name][:desc]}();\n}\n"
75
+ end
76
+
77
+ def init_stmts
78
+ @init_stmts
79
+ end
80
+
81
+ def func_name(name, ret_utype, arg_utypes)
82
+ case f = @top[:dict][:func_space][name].get
83
+ when PrimFuncDef
84
+ f.func_name(self)
85
+ when FuncDef
86
+ key = [ret_utype, *arg_utypes].map(&:to_uniq_str) + [name]
87
+ @top[:dict][:ifunc_space][key].get.func_name(self)
88
+ else
89
+ raise "Assertion error: unexpected func type #{f.class}"
90
+ end
91
+ end
92
+
93
+ def constructor_name(name, utype)
94
+ @top[:dict][:itype_space][utype.to_uniq_str].get[:tvalues].each do |tval|
95
+ if tval[:name][:desc] == name
96
+ return tval.constructor_name(self)
97
+ end
98
+ end
99
+ raise "Assertion error: #{name} is not found"
100
+ end
101
+
102
+ def escape_name(name)
103
+ rexp = Regexp.new("[" + Regexp.escape(SymbolToStr.keys.join) + "]")
104
+ name.gsub(rexp, SymbolToStr)
105
+ end
106
+
107
+ def tdef(x)
108
+ case x
109
+ when Typing::UnionType
110
+ key = x.to_uniq_str
111
+ if @top[:dict][:type_space][key] && @top[:dict][:type_space][key].get.is_a?(PrimTypeDef)
112
+ @top[:dict][:type_space][key].get
113
+ elsif @top[:dict][:itype_space][key]
114
+ @top[:dict][:itype_space][key].get
115
+ else
116
+ raise "Assertion error: itype #{x.to_uniq_str} is undefined"
117
+ end
118
+ when Syntax
119
+ tdef(x[:typing])
120
+ else
121
+ raise "Assertion error"
122
+ end
123
+ end
124
+
125
+ def tref(x)
126
+ tdef(x).ref_name(self)
127
+ end
128
+
129
+ def serial(key, id)
130
+ @serials ||= Hash.new{|h, k| h[k] = []}
131
+ @serials[key] << id unless @serials[key].find{|x| x == id}
132
+ return @serials[key].index{|x| x == id}
133
+ end
134
+
135
+ def uniq_id_gen
136
+ @uniq_ids ||= (0..1000).to_a
137
+ @uniq_ids.shift
138
+ end
139
+
140
+ def define_global_var(type_str, name_str, initial_value_str=nil)
141
+ @global_vars << "#{type_str} #{name_str}" + (initial_value_str ? " = #{initial_value_str}" : "") + ";"
142
+ end
143
+
144
+ def define_macro(name_str, params, body_str)
145
+ @macros << "#define #{name_str}(#{params.join(", ")}) (#{body_str})"
146
+ end
147
+
148
+ def define_func(type_str, name_str, params, accessor=:static, with_proto=true, &block)
149
+ elements = []
150
+ proc.call(elements)
151
+ case accessor
152
+ when :none then deco = ""
153
+ when :static then deco = "static "
154
+ end
155
+ define_proto(type_str, name_str, params.map(&:first), accessor) if with_proto
156
+ @funcs << Block.new("#{deco}#{type_str} #{name_str}(#{params.map{|a, b| "#{a} #{b}"}.join(", ")}) {", elements, "}")
157
+ return nil
158
+ end
159
+
160
+ def define_proto(type_str, name_str, param_types, accessor=:static)
161
+ case accessor
162
+ when :none then deco = ""
163
+ when :static then deco = "static "
164
+ when :extern then deco = "extern "
165
+ end
166
+ proto = "#{deco}#{type_str} #{name_str}(#{param_types.join(", ")});"
167
+ if accessor == :static || accessor == :extern
168
+ @static_protos << proto
169
+ else
170
+ @protos << proto
171
+ end
172
+ return nil
173
+ end
174
+
175
+ def define_init_stmt(stmt)
176
+ @init_stmts << stmt
177
+ end
178
+
179
+ def define_struct(kind_str, name_str, var_name_str)
180
+ elements = []
181
+ proc.call(elements)
182
+ x = Block.new("#{kind_str} #{name_str}{", elements, "}#{var_name_str};")
183
+ if name_str
184
+ @structs << x
185
+ return nil
186
+ else
187
+ return x
188
+ end
189
+ end
190
+
191
+ def make_block(head_str, elements, foot_str)
192
+ Block.new(head_str, elements, foot_str)
193
+ end
194
+
195
+ class Block
196
+ T = (0..20).map{|i| " " * i}
197
+ def initialize(head_str, elements, foot_str)
198
+ @head_str = head_str
199
+ @elements = elements
200
+ @foot_str = foot_str
201
+ end
202
+
203
+ def to_s(t=0)
204
+ res = ""
205
+ res << T[t] + @head_str + "\n"
206
+ @elements.each do |e|
207
+ case e
208
+ when Block
209
+ res << e.to_s(t+1) + "\n"
210
+ when String
211
+ res << T[t+1] + e + "\n"
212
+ end
213
+ end
214
+ res << T[t] + @foot_str
215
+ end
216
+ end
217
+ end
218
+ end