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