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