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,184 +1,184 @@
1
- module Emfrp
2
- class Parser
3
-
4
- # Utils & Commons
5
- # --------------------
6
-
7
- SPChar = {
8
- :space => "\s",
9
- :tab => "\t",
10
- :newline => "\n",
11
- :doublequote => "\"",
12
- :singlequote => "'",
13
- :backslash => "\\",
14
- }
15
- SPChar.each do |name, c|
16
- parser(name){char(c)}
17
- parser("non_#{name}".to_sym){notchar(c)}
18
- end
19
-
20
- parser :key do |keyword| # -> Hash
21
- str(keyword).map do |is|
22
- is[0].tag
23
- end
24
- end
25
-
26
- parser :symbol do |s|
27
- str(s).map do |s|
28
- SSymbol.new(
29
- :desc => s.map(&:item).join,
30
- :start_pos => s[0].tag,
31
- :end_pos => s[-1].tag
32
- )
33
- end
34
- end
35
-
36
- parser :ws do # -> ()
37
- tabspace | newline | commentout
38
- end
39
-
40
- parser :ws_without_newline do
41
- tabspace | commentout
42
- end
43
-
44
- parser :commentout do # -> ()
45
- char("#") > many(non_newline) >> proc{|x|
46
- if x.size == 0 || x[0].item != "@"
47
- ok(nil)
48
- else
49
- fail
50
- end
51
- }
52
- end
53
-
54
- parser :newline do #-> ()
55
- char("\n")
56
- end
57
-
58
- parser :tabspace do # -> ()
59
- char("\s") | char("\t")
60
- end
61
-
62
- parser :comma_separator do # -> ()
63
- many(ws) > str(",") > many(ws)
64
- end
65
-
66
- parser :or_separator do # -> ()
67
- many(ws) > str("|") > many(ws)
68
- end
69
-
70
- parser :end_of_def do # -> ()
71
- many(ws_without_newline) > newline > many(ws)
72
- end
73
-
74
- parser :ident_begin_lower do # -> SSymbol
75
- seq(
76
- lower_alpha.name(:head),
77
- many(lower_alpha | upper_alpha | digit | char("_")).name(:tail)
78
- ).map do |x|
79
- items = [x[:head]] + x[:tail]
80
- SSymbol.new(
81
- :desc => items.map{|i| i.item}.join,
82
- :start_pos => items[0].tag,
83
- :end_pos => items[-1].tag
84
- )
85
- end
86
- end
87
-
88
- parser :ident_begin_upper do # -> SSymbol
89
- seq(
90
- upper_alpha.name(:head),
91
- many(lower_alpha | upper_alpha | digit | char("_")).name(:tail)
92
- ).map do |x|
93
- items = [x[:head]] + x[:tail]
94
- SSymbol.new(
95
- :desc => items.map{|i| i.item}.join,
96
- :start_pos => items[0].tag,
97
- :end_pos => items[-1].tag
98
- )
99
- end
100
- end
101
-
102
- parser :positive_integer do # -> SSymbol
103
- seq(
104
- pdigit.name(:head),
105
- many(digit).name(:tail)
106
- ).map do |x|
107
- items = [x[:head]] + x[:tail]
108
- SSymbol.new(
109
- :desc => items.map{|i| i.item}.join,
110
- :start_pos => items[0].tag,
111
- :end_pos => items[-1].tag
112
- )
113
- end
114
- end
115
-
116
- parser :zero_integer do # -> SSymbol
117
- symbol("0")
118
- end
119
-
120
- parser :digit_symbol do # -> SSymbol
121
- ("0".."9").map{|c| symbol(c)}.inject(&:|)
122
- end
123
-
124
- parser :cfunc_name do # -> SSymbol
125
- ident_begin_lower | ident_begin_upper
126
- end
127
-
128
- parser :func_name do # -> SSymbol
129
- ident_begin_lower
130
- end
131
-
132
- parser :data_name do # -> SSymbol
133
- ident_begin_lower
134
- end
135
-
136
- parser :method_name do # -> SSymbol
137
- operator | ident_begin_lower
138
- end
139
-
140
- parser :var_name do # -> SSymbol
141
- ident_begin_lower
142
- end
143
-
144
- parser :node_instance_name do # -> SSymbol
145
- ident_begin_lower
146
- end
147
-
148
- parser :var_name_allow_last do # -> SSymbol
149
- var_with_last | ident_begin_lower
150
- end
151
-
152
- parser :var_with_last do # -> SSymbol
153
- seq(
154
- ident_begin_lower.name(:prefix),
155
- symbol("@last").name(:suffix)
156
- ).map do |x|
157
- SSymbol.new(x.to_h, :desc => x[:prefix][:desc] + x[:suffix][:desc])
158
- end
159
- end
160
-
161
- OPUsable = "!#$%&*+./<=>?@\\^|-~"
162
-
163
- parser :operator do # -> SSymbol
164
- usable = OPUsable.chars.map{|c| char(c)}.inject(&:|)
165
- ng = ["..", ":", "::", "=", "\\", "|", "<-", "->", "@", "~", "=>", ".", "#", "@@"]
166
- many1(usable) >> proc{|items|
167
- token = items.map{|i| i.item}.join
168
- if ng.include?(token)
169
- fail
170
- else
171
- ok(SSymbol.new(
172
- :desc => token,
173
- :start_pos => items[0].tag,
174
- :end_pos => items[-1].tag
175
- ))
176
- end
177
- }
178
- end
179
-
180
- parser :operator_general do # -> SSymbol
181
- operator ^ (char("`") > func_name < char("`"))
182
- end
183
- end
184
- end
1
+ module Emfrp
2
+ class Parser
3
+
4
+ # Utils & Commons
5
+ # --------------------
6
+
7
+ SPChar = {
8
+ :space => "\s",
9
+ :tab => "\t",
10
+ :newline => "\n",
11
+ :doublequote => "\"",
12
+ :singlequote => "'",
13
+ :backslash => "\\",
14
+ }
15
+ SPChar.each do |name, c|
16
+ parser(name){char(c)}
17
+ parser("non_#{name}".to_sym){notchar(c)}
18
+ end
19
+
20
+ parser :key do |keyword| # -> Hash
21
+ str(keyword).map do |is|
22
+ is[0].tag
23
+ end
24
+ end
25
+
26
+ parser :symbol do |s|
27
+ str(s).map do |s|
28
+ SSymbol.new(
29
+ :desc => s.map(&:item).join,
30
+ :start_pos => s[0].tag,
31
+ :end_pos => s[-1].tag
32
+ )
33
+ end
34
+ end
35
+
36
+ parser :ws do # -> ()
37
+ tabspace | newline | commentout
38
+ end
39
+
40
+ parser :ws_without_newline do
41
+ tabspace | commentout
42
+ end
43
+
44
+ parser :commentout do # -> ()
45
+ char("#") > many(non_newline) >> proc{|x|
46
+ if x.size == 0 || x[0].item != "@"
47
+ ok(nil)
48
+ else
49
+ fail
50
+ end
51
+ }
52
+ end
53
+
54
+ parser :newline do #-> ()
55
+ char("\n")
56
+ end
57
+
58
+ parser :tabspace do # -> ()
59
+ char("\s") | char("\t")
60
+ end
61
+
62
+ parser :comma_separator do # -> ()
63
+ many(ws) > str(",") > many(ws)
64
+ end
65
+
66
+ parser :or_separator do # -> ()
67
+ many(ws) > str("|") > many(ws)
68
+ end
69
+
70
+ parser :end_of_def do # -> ()
71
+ many(ws_without_newline) > newline > many(ws)
72
+ end
73
+
74
+ parser :ident_begin_lower do # -> SSymbol
75
+ seq(
76
+ lower_alpha.name(:head),
77
+ many(lower_alpha | upper_alpha | digit | char("_")).name(:tail)
78
+ ).map do |x|
79
+ items = [x[:head]] + x[:tail]
80
+ SSymbol.new(
81
+ :desc => items.map{|i| i.item}.join,
82
+ :start_pos => items[0].tag,
83
+ :end_pos => items[-1].tag
84
+ )
85
+ end
86
+ end
87
+
88
+ parser :ident_begin_upper do # -> SSymbol
89
+ seq(
90
+ upper_alpha.name(:head),
91
+ many(lower_alpha | upper_alpha | digit | char("_")).name(:tail)
92
+ ).map do |x|
93
+ items = [x[:head]] + x[:tail]
94
+ SSymbol.new(
95
+ :desc => items.map{|i| i.item}.join,
96
+ :start_pos => items[0].tag,
97
+ :end_pos => items[-1].tag
98
+ )
99
+ end
100
+ end
101
+
102
+ parser :positive_integer do # -> SSymbol
103
+ seq(
104
+ pdigit.name(:head),
105
+ many(digit).name(:tail)
106
+ ).map do |x|
107
+ items = [x[:head]] + x[:tail]
108
+ SSymbol.new(
109
+ :desc => items.map{|i| i.item}.join,
110
+ :start_pos => items[0].tag,
111
+ :end_pos => items[-1].tag
112
+ )
113
+ end
114
+ end
115
+
116
+ parser :zero_integer do # -> SSymbol
117
+ symbol("0")
118
+ end
119
+
120
+ parser :digit_symbol do # -> SSymbol
121
+ ("0".."9").map{|c| symbol(c)}.inject(&:|)
122
+ end
123
+
124
+ parser :cfunc_name do # -> SSymbol
125
+ ident_begin_lower | ident_begin_upper
126
+ end
127
+
128
+ parser :func_name do # -> SSymbol
129
+ ident_begin_lower
130
+ end
131
+
132
+ parser :data_name do # -> SSymbol
133
+ ident_begin_lower
134
+ end
135
+
136
+ parser :method_name do # -> SSymbol
137
+ operator | ident_begin_lower
138
+ end
139
+
140
+ parser :var_name do # -> SSymbol
141
+ ident_begin_lower
142
+ end
143
+
144
+ parser :node_instance_name do # -> SSymbol
145
+ ident_begin_lower
146
+ end
147
+
148
+ parser :var_name_allow_last do # -> SSymbol
149
+ var_with_last | ident_begin_lower
150
+ end
151
+
152
+ parser :var_with_last do # -> SSymbol
153
+ seq(
154
+ ident_begin_lower.name(:prefix),
155
+ symbol("@last").name(:suffix)
156
+ ).map do |x|
157
+ SSymbol.new(x.to_h, :desc => x[:prefix][:desc] + x[:suffix][:desc])
158
+ end
159
+ end
160
+
161
+ OPUsable = "!#$%&*+./<=>?@\\^|-~"
162
+
163
+ parser :operator do # -> SSymbol
164
+ usable = OPUsable.chars.map{|c| char(c)}.inject(&:|)
165
+ ng = ["..", ":", "::", "=", "\\", "|", "<-", "->", "@", "~", "=>", ".", "#", "@@"]
166
+ many1(usable) >> proc{|items|
167
+ token = items.map{|i| i.item}.join
168
+ if ng.include?(token)
169
+ fail
170
+ else
171
+ ok(SSymbol.new(
172
+ :desc => token,
173
+ :start_pos => items[0].tag,
174
+ :end_pos => items[-1].tag
175
+ ))
176
+ end
177
+ }
178
+ end
179
+
180
+ parser :operator_general do # -> SSymbol
181
+ operator ^ (char("`") > func_name < char("`"))
182
+ end
183
+ end
184
+ end
@@ -1,72 +1,72 @@
1
- module Emfrp
2
- module NewNodeConvert
3
- extend self
4
-
5
- def parse_module(mod_name, newnode, file_loader)
6
- src_str, file_name = file_loader.load(newnode[:module_path].map{|x| x[:desc]})
7
- top = Parser.parse_src(src_str, file_name, file_loader)
8
- uniq_key = "#{mod_name}(#{newnode[:names].map{|x| x[:desc]}.join(",")})"
9
- rename_nodes(top, uniq_key)
10
- top[:inputs].zip(newnode[:args]).each do |input, arg_exp|
11
- input[:name][:desc] << "##{uniq_key}"
12
- top[:nodes] << NodeDef.new(
13
- :name => input[:name],
14
- :init_exp => nil,
15
- :params => nil,
16
- :type => nil,
17
- :exp => arg_exp,
18
- )
19
- end
20
- top[:inputs] = []
21
- top[:outputs].zip(newnode[:names]).each do |output, newnode_name|
22
- output[:name][:desc] << "##{uniq_key}"
23
- top[:nodes] << NodeDef.new(
24
- :name => newnode_name,
25
- :init_exp => nil,
26
- :params => nil,
27
- :type => nil,
28
- :exp => VarRef.new(:name => output[:name])
29
- )
30
- end
31
- top[:outputs] = []
32
- return top
33
- end
34
-
35
- def rename_nodes(top, uniq_key)
36
- datas = Hash[top[:datas].map{|x| [x[:name][:desc], true]}]
37
- top[:nodes].each do |n|
38
- white_list = {}
39
- n[:name][:desc] << "##{uniq_key}"
40
- if n[:params]
41
- n[:params].each do |pn|
42
- white_list[pn[:as][:desc].clone] = true
43
- pn[:name][:desc] << "##{uniq_key}"
44
- pn[:as][:desc] << "##{uniq_key}"
45
- end
46
- end
47
- rename_node_exp(n[:exp], datas, white_list, uniq_key, {})
48
- end
49
- end
50
-
51
- def rename_node_exp(exp, datas, white_list, uniq_key, local_vars)
52
- case exp
53
- when VarRef
54
- name = exp[:name][:desc]
55
- if !local_vars[name] && (white_list[name] || !datas[name])
56
- if name =~ /^(.*)@last$/
57
- exp[:name][:desc] = "#{$1}##{uniq_key}@last"
58
- else
59
- exp[:name][:desc] << "##{uniq_key}"
60
- end
61
- end
62
- when Case
63
- vs = Hash[exp[:pattern].find_refs.map{|x| [x[:desc], true]}]
64
- rename_node_exp(exp[:exp], datas, white_list, uniq_key, local_vars.merge(vs))
65
- when Syntax
66
- rename_node_exp(exp.values, datas, white_list, uniq_key, local_vars)
67
- when Array
68
- exp.each{|e| rename_node_exp(e, datas, white_list, uniq_key, local_vars)}
69
- end
70
- end
71
- end
72
- end
1
+ module Emfrp
2
+ module NewNodeConvert
3
+ extend self
4
+
5
+ def parse_module(mod_name, newnode, file_loader)
6
+ src_str, file_name = file_loader.load(newnode[:module_path].map{|x| x[:desc]})
7
+ top = Parser.parse_src(src_str, file_name, file_loader)
8
+ uniq_key = "#{mod_name}(#{newnode[:names].map{|x| x[:desc]}.join(",")})"
9
+ rename_nodes(top, uniq_key)
10
+ top[:inputs].zip(newnode[:args]).each do |input, arg_exp|
11
+ input[:name][:desc] << "##{uniq_key}"
12
+ top[:nodes] << NodeDef.new(
13
+ :name => input[:name],
14
+ :init_exp => nil,
15
+ :params => nil,
16
+ :type => nil,
17
+ :exp => arg_exp,
18
+ )
19
+ end
20
+ top[:inputs] = []
21
+ top[:outputs].zip(newnode[:names]).each do |output, newnode_name|
22
+ output[:name][:desc] << "##{uniq_key}"
23
+ top[:nodes] << NodeDef.new(
24
+ :name => newnode_name,
25
+ :init_exp => nil,
26
+ :params => nil,
27
+ :type => nil,
28
+ :exp => VarRef.new(:name => output[:name])
29
+ )
30
+ end
31
+ top[:outputs] = []
32
+ return top
33
+ end
34
+
35
+ def rename_nodes(top, uniq_key)
36
+ datas = Hash[top[:datas].map{|x| [x[:name][:desc], true]}]
37
+ top[:nodes].each do |n|
38
+ white_list = {}
39
+ n[:name][:desc] << "##{uniq_key}"
40
+ if n[:params]
41
+ n[:params].each do |pn|
42
+ white_list[pn[:as][:desc].clone] = true
43
+ pn[:name][:desc] << "##{uniq_key}"
44
+ pn[:as][:desc] << "##{uniq_key}"
45
+ end
46
+ end
47
+ rename_node_exp(n[:exp], datas, white_list, uniq_key, {})
48
+ end
49
+ end
50
+
51
+ def rename_node_exp(exp, datas, white_list, uniq_key, local_vars)
52
+ case exp
53
+ when VarRef
54
+ name = exp[:name][:desc]
55
+ if !local_vars[name] && (white_list[name] || !datas[name])
56
+ if name =~ /^(.*)@last$/
57
+ exp[:name][:desc] = "#{$1}##{uniq_key}@last"
58
+ else
59
+ exp[:name][:desc] << "##{uniq_key}"
60
+ end
61
+ end
62
+ when Case
63
+ vs = Hash[exp[:pattern].find_refs.map{|x| [x[:desc], true]}]
64
+ rename_node_exp(exp[:exp], datas, white_list, uniq_key, local_vars.merge(vs))
65
+ when Syntax
66
+ rename_node_exp(exp.values, datas, white_list, uniq_key, local_vars)
67
+ when Array
68
+ exp.each{|e| rename_node_exp(e, datas, white_list, uniq_key, local_vars)}
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,25 +1,25 @@
1
- require 'parser_combinator'
2
-
3
- module Emfrp
4
- class OpParser < ParserCombinator
5
- def self.make_op_parser(priority_list)
6
- priority_list.reverse.inject(item.map(&:item)) do |contp, x|
7
- op = sat{|i| i.item.is_a?(SSymbol) && i.item[:desc] == x[:sym]}
8
- if x[:dir] == "left"
9
- opp = x[:op].map do |op|
10
- proc{|l, r| FuncCall.new(:name => op, :args => [l, r])}
11
- end
12
- binopl_fail(contp, opp)
13
- elsif x[:dir] == "right"
14
- sp = contp >> proc{|l|
15
- x[:op] >> proc{|op|
16
- sp >> proc{|r|
17
- ok(FuncCall.new(:name => op, :args => [l, r]))
18
- }}} | contp
19
- else
20
- raise "invalid direction"
21
- end
22
- end
23
- end
24
- end
25
- end
1
+ require 'parser_combinator'
2
+
3
+ module Emfrp
4
+ class OpParser < ParserCombinator
5
+ def self.make_op_parser(priority_list)
6
+ priority_list.reverse.inject(item.map(&:item)) do |contp, x|
7
+ op = sat{|i| i.item.is_a?(SSymbol) && i.item[:desc] == x[:sym]}
8
+ if x[:dir] == "left"
9
+ opp = x[:op].map do |op|
10
+ proc{|l, r| FuncCall.new(:name => op, :args => [l, r])}
11
+ end
12
+ binopl_fail(contp, opp)
13
+ elsif x[:dir] == "right"
14
+ sp = contp >> proc{|l|
15
+ x[:op] >> proc{|op|
16
+ sp >> proc{|r|
17
+ ok(FuncCall.new(:name => op, :args => [l, r]))
18
+ }}} | contp
19
+ else
20
+ raise "invalid direction"
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end