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,386 +1,386 @@
1
- require 'parser_combinator/string_parser'
2
-
3
- module Emfrp
4
- class Parser < ParserCombinator::StringParser
5
-
6
- # Expression
7
- # --------------------
8
-
9
- parser :exp do
10
- if_exp ^ builtin_operation
11
- end
12
-
13
- # Builtin Operator Expression
14
- # --------------------
15
-
16
- parser :if_exp do
17
- seq(
18
- symbol("if").name(:keyword),
19
- many1(ws),
20
- exp.err("if-exp", "valid conditional exp").name(:cond),
21
- many1(ws),
22
- str("then"),
23
- many1(ws),
24
- exp.err("if-exp", "valid then exp").name(:then),
25
- many1(ws),
26
- str("else"),
27
- many1(ws),
28
- exp.err("if-exp", "valid then exp").name(:else),
29
- ).map do |x|
30
- true_sym = SSymbol.new(:desc => "True")
31
- true_pat = ValuePattern.new(:name => true_sym, :args => [], :ref => nil, :type => nil)
32
- true_case = Case.new(:pattern => true_pat, :exp => x[:then])
33
- false_sym = SSymbol.new(:desc => "False")
34
- false_pat = ValuePattern.new(:name => false_sym, :args => [], :ref => nil, :type => nil)
35
- false_case = Case.new(:pattern => false_pat, :exp => x[:else])
36
- MatchExp.new(:exp => x[:cond], :cases => [true_case, false_case])
37
- end
38
- end
39
-
40
- parser :builtin_operation do
41
- x = match_with_indent_case_group_op ^ match_with_liner_case_group_op
42
- seq(
43
- operator_exp.name(:exp),
44
- many_fail(many1(ws) > x).name(:builtin_ops)
45
- ).map do |x|
46
- x[:builtin_ops].inject(x[:exp]) do |acc, ep|
47
- ep.call(acc)
48
- end
49
- end
50
- end
51
-
52
- parser :match_with_indent_case_group_op do
53
- seq(
54
- str("of:"),
55
- many(ws),
56
- case_group.err("match-exp", "valid case statement").name(:cases)
57
- ).map do |x|
58
- proc{|e| MatchExp.new(x.to_h, :exp => e)}
59
- end
60
- end
61
-
62
- parser :match_with_liner_case_group_op do
63
- seq(
64
- str("of"),
65
- many1(ws),
66
- many1_fail(
67
- seq(
68
- pattern.name(:pattern).name(:pattern),
69
- many1(ws),
70
- str("->").err("lienr-match-exp", "->"),
71
- many1(ws),
72
- exp.err("liner-match-exp", "invalid exp").name(:exp)
73
- ).map{|x| Case.new(x.to_h)},
74
- comma_separator
75
- ).name(:cases)
76
- ).map do |x|
77
- proc{|e| MatchExp.new(x.to_h, :exp => e)}
78
- end
79
- end
80
-
81
- parser :case_group do
82
- cs = seq(
83
- many1_fail(pattern, or_separator).name(:patterns),
84
- many1(ws).err("case-exp", "space"),
85
- str("->").err("case-exp", "'to'"),
86
- many1(ws),
87
- exp.err("match-exp", "invalid exp").name(:exp)
88
- ).map do |x|
89
- x[:patterns].map{|pat| Case.new(:pattern => pat, :exp => x[:exp].deep_copy)}
90
- end
91
- many1_fail(cs, many1(ws)).map(&:flatten) < many1(ws) < str(":endcase")
92
- end
93
-
94
- parser :pattern do
95
- pat = dont_care_pattern ^ name_pattern ^ recursive_pattern ^ no_arg_pattern ^ tuple_pattern ^ integral_pattern
96
- seq(
97
- pat.name(:pattern),
98
- opt_fail(
99
- many(ws) > str(":") > many(ws) >
100
- type.err("param-def", "type")
101
- ).to_nil.name(:type)
102
- ).map do |x|
103
- x[:pattern][:type] = x[:type]
104
- x[:pattern]
105
- end
106
- end
107
-
108
- parser :dont_care_pattern do
109
- symbol("_").map do |c|
110
- AnyPattern.new(:ref => nil, :keyword => c)
111
- end
112
- end
113
-
114
- parser :name_pattern do
115
- ident_begin_lower.map do |n|
116
- AnyPattern.new(:ref => n)
117
- end
118
- end
119
-
120
- parser :recursive_pattern do
121
- seq(
122
- tvalue_symbol.name(:name),
123
- many(ws),
124
- str("("),
125
- many(ws),
126
- many1_fail(pattern, comma_separator).name(:args),
127
- many(ws),
128
- symbol(")").name(:keyword),
129
- opt_fail(
130
- many(ws) > str("as") > many1(ws) > var_name.err("pattern", "invalid name")
131
- ).to_nil.name(:ref)
132
- ).map{|x| ValuePattern.new(x.to_h)}
133
- end
134
-
135
- parser :no_arg_pattern do
136
- seq(
137
- tvalue_symbol.name(:name),
138
- opt_fail(
139
- many1(ws) > str("as") > var_name.err("pattern", "invalid name")
140
- ).to_nil.name(:ref)
141
- ).map{|x| ValuePattern.new(x.to_h, :args => [])}
142
- end
143
-
144
- parser :tuple_pattern do
145
- seq(
146
- symbol("(").name(:keyword1),
147
- many(ws),
148
- pattern.name(:arg_head),
149
- many(ws),
150
- str(","),
151
- many(ws),
152
- many1_fail(pattern, comma_separator).name(:arg_tail),
153
- many(ws),
154
- symbol(")").name(:keyword2),
155
- opt_fail(
156
- many(ws) > str("as") > many1(ws) > var_name.err("tuple-pattern", "invalid name")
157
- ).to_nil.name(:ref)
158
- ).map do |x|
159
- args = [x[:arg_head]] + x[:arg_tail]
160
- ValuePattern.new(
161
- :name => SSymbol.new(:desc => "Tuple" + args.size.to_s),
162
- :args => args,
163
- :ref => x[:ref],
164
- :keyword1 => x[:keyword1],
165
- :keyword2 => x[:keyword2]
166
- )
167
- end
168
- end
169
-
170
- parser :integral_pattern do
171
- integral_literal.map{|n| IntegralPattern.new(:val => n, :ref => nil)}
172
- end
173
-
174
- # Operator Expression
175
- # --------------------
176
-
177
- parser :operator_exp do
178
- opexp = operator_general.map do |op|
179
- proc do |l, r|
180
- if l.is_a?(OperatorSeq)
181
- OperatorSeq.new(:seq => l[:seq] + [op, r])
182
- else
183
- OperatorSeq.new(:seq => [l, op, r])
184
- end
185
- end
186
- end
187
- binopl_fail(primary, many(ws) > opexp < many(ws))
188
- end
189
-
190
- # Lower Expression
191
- # --------------------
192
-
193
- parser :primary do
194
- atom >> proc{|a|
195
- many(many(ws) > method_call).map do |cs|
196
- if cs == [] then a else cs.inject(a){|acc, p| p.call(acc)} end
197
- end
198
- }
199
- end
200
-
201
- parser :method_call do
202
- seq(
203
- symbol(".").name(:keyword1),
204
- many(ws),
205
- ident_begin_lower.err("method_call", "invalid method name").name(:name),
206
- opt_fail(
207
- seq(
208
- many(ws_without_newline),
209
- symbol("(").name(:keyword2),
210
- many(ws),
211
- many_fail(exp, comma_separator).name(:args),
212
- many(ws),
213
- symbol(")").name(:keyword3)
214
- )
215
- ).to_nil.name(:args)
216
- ).map do |x|
217
- proc do |receiver|
218
- if x[:args]
219
- FuncCall.new(
220
- :name => x[:name],
221
- :keywords => [x[:keyword1], x[:args][:keyword2], x[:args][:keyword3]],
222
- :args => [receiver] + x[:args][:args]
223
- )
224
- else
225
- FuncCall.new(
226
- :name => x[:name],
227
- :keyword => x[:keyword1],
228
- :args => [receiver]
229
- )
230
- end
231
- end
232
- end
233
- end
234
-
235
- parser :atom do
236
- literal_exp ^ single_op ^ func_call ^ block_exp ^ value_cons ^ skip ^ var_ref
237
- end
238
-
239
- parser :single_op do
240
- seq(operator, many(ws), atom).map do |x|
241
- name = x[0].update(:desc => "@" + x[0][:desc])
242
- FuncCall.new(:name => x[0], :args => [x[2]])
243
- end
244
- end
245
-
246
- parser :func_call do
247
- seq(
248
- func_name.name(:name),
249
- many(ws_without_newline),
250
- symbol("(").name(:keyword1),
251
- many(ws),
252
- many1_fail(exp, comma_separator).name(:args),
253
- many(ws),
254
- symbol(")").name(:keyword2)
255
- ).map do |x|
256
- FuncCall.new(x.to_h)
257
- end
258
- end
259
-
260
- parser :block_exp do
261
- seq(
262
- symbol("{").name(:keyword1),
263
- many(ws),
264
- many_fail(many(ws) > assign).name(:assigns),
265
- many(ws),
266
- exp.err("block-exp", "valid return-exp").name(:exp),
267
- many(ws),
268
- symbol("}").name(:keyword2)
269
- ).map do |x|
270
- x[:assigns].reverse.inject(x[:exp]) do |acc, a|
271
- c = Case.new(:pattern => a[:pattern], :exp => acc)
272
- MatchExp.new(:cases => [c], :exp => a[:exp])
273
- end
274
- end
275
- end
276
-
277
- parser :assign do # -> Hash
278
- seq(
279
- pattern.name(:pattern),
280
- many(ws),
281
- str("="),
282
- many(ws),
283
- exp.err("assign", "invalid assign statement").name(:exp)
284
- ).map do |x|
285
- x.to_h
286
- end
287
- end
288
-
289
- parser :value_cons do # -> ValueConst
290
- seq(
291
- tvalue_symbol.name(:name),
292
- opt_fail(
293
- seq(
294
- many(ws_without_newline),
295
- str("("),
296
- many(ws),
297
- many_fail(exp, comma_separator).name(:args),
298
- many(ws),
299
- symbol(")").name(:keyword)
300
- ).name(:args)
301
- ).to_nil.err("value-construction", "invalid form of argument").name(:args)
302
- ).map do |x|
303
- if x[:args]
304
- ValueConst.new(:name => x[:name], :args => x[:args][:args], :keyword => x[:args][:keyword])
305
- else
306
- ValueConst.new(:name => x[:name], :args => [])
307
- end
308
- end
309
- end
310
-
311
- parser :skip do
312
- symbol("skip").map do |x|
313
- SkipExp.new(:keyword => x)
314
- end
315
- end
316
-
317
- parser :var_ref do
318
- var_name_allow_last.map do |s|
319
- VarRef.new(:name => s)
320
- end
321
- end
322
-
323
- # Literal Expression
324
- # --------------------
325
-
326
- parser :literal_exp do
327
- char_literal ^ parenth_or_tuple_literal ^ floating_literal ^ integral_literal
328
- end
329
-
330
- parser :char_literal do
331
- seq(
332
- symbol("'").name(:keyword1),
333
- ((backslash > item) | item).map{|i| i.item}.name(:entity),
334
- symbol("'").name(:keyword2),
335
- ).map do |x|
336
- LiteralChar.new(x.to_h)
337
- end
338
- end
339
-
340
- parser :parenth_or_tuple_literal do
341
- seq(
342
- symbol("(").name(:keyword1),
343
- many(ws),
344
- many1_fail(exp, comma_separator).name(:entity),
345
- many(ws),
346
- symbol(")").name(:keyword2)
347
- ).map do |x|
348
- if x[:entity].size == 1
349
- ParenthExp.new(
350
- :exp => x[:entity].first,
351
- :keyword1 => x[:keyword1],
352
- :keyword2 => x[:keyword2]
353
- )
354
- else
355
- ValueConst.new(
356
- :name => SSymbol.new(:desc => "Tuple" + x[:entity].size.to_s),
357
- :args => x[:entity],
358
- :parent_begin => x[:keyword1],
359
- :parent_end => x[:keyword2]
360
- )
361
- end
362
- end
363
- end
364
-
365
- parser :integral_literal do
366
- (positive_integer | zero_integer).map do |x|
367
- LiteralIntegral.new(:entity => x)
368
- end
369
- end
370
-
371
- parser :floating_literal do
372
- seq(
373
- integral_literal.name(:prefix),
374
- char("."),
375
- many1(digit).name(:suffix)
376
- ).map do |x|
377
- sym = SSymbol.new(:desc => x[:prefix][:entity][:desc] + "." + x[:suffix].map(&:item).join)
378
- LiteralFloating.new(
379
- :entity => sym,
380
- :start_pos => x[:prefix][:entity][:start_pos],
381
- :end_pos => x[:suffix][-1].tag
382
- )
383
- end
384
- end
385
- end
386
- end
1
+ require 'parser_combinator/string_parser'
2
+
3
+ module Emfrp
4
+ class Parser < ParserCombinator::StringParser
5
+
6
+ # Expression
7
+ # --------------------
8
+
9
+ parser :exp do
10
+ if_exp ^ builtin_operation
11
+ end
12
+
13
+ # Builtin Operator Expression
14
+ # --------------------
15
+
16
+ parser :if_exp do
17
+ seq(
18
+ symbol("if").name(:keyword),
19
+ many1(ws),
20
+ exp.err("if-exp", "valid conditional exp").name(:cond),
21
+ many1(ws),
22
+ str("then"),
23
+ many1(ws),
24
+ exp.err("if-exp", "valid then exp").name(:then),
25
+ many1(ws),
26
+ str("else"),
27
+ many1(ws),
28
+ exp.err("if-exp", "valid then exp").name(:else),
29
+ ).map do |x|
30
+ true_sym = SSymbol.new(:desc => "True")
31
+ true_pat = ValuePattern.new(:name => true_sym, :args => [], :ref => nil, :type => nil)
32
+ true_case = Case.new(:pattern => true_pat, :exp => x[:then])
33
+ false_sym = SSymbol.new(:desc => "False")
34
+ false_pat = ValuePattern.new(:name => false_sym, :args => [], :ref => nil, :type => nil)
35
+ false_case = Case.new(:pattern => false_pat, :exp => x[:else])
36
+ MatchExp.new(:exp => x[:cond], :cases => [true_case, false_case])
37
+ end
38
+ end
39
+
40
+ parser :builtin_operation do
41
+ x = match_with_indent_case_group_op ^ match_with_liner_case_group_op
42
+ seq(
43
+ operator_exp.name(:exp),
44
+ many_fail(many1(ws) > x).name(:builtin_ops)
45
+ ).map do |x|
46
+ x[:builtin_ops].inject(x[:exp]) do |acc, ep|
47
+ ep.call(acc)
48
+ end
49
+ end
50
+ end
51
+
52
+ parser :match_with_indent_case_group_op do
53
+ seq(
54
+ str("of:"),
55
+ many(ws),
56
+ case_group.err("match-exp", "valid case statement").name(:cases)
57
+ ).map do |x|
58
+ proc{|e| MatchExp.new(x.to_h, :exp => e)}
59
+ end
60
+ end
61
+
62
+ parser :match_with_liner_case_group_op do
63
+ seq(
64
+ str("of"),
65
+ many1(ws),
66
+ many1_fail(
67
+ seq(
68
+ pattern.name(:pattern).name(:pattern),
69
+ many1(ws),
70
+ str("->").err("lienr-match-exp", "->"),
71
+ many1(ws),
72
+ exp.err("liner-match-exp", "invalid exp").name(:exp)
73
+ ).map{|x| Case.new(x.to_h)},
74
+ comma_separator
75
+ ).name(:cases)
76
+ ).map do |x|
77
+ proc{|e| MatchExp.new(x.to_h, :exp => e)}
78
+ end
79
+ end
80
+
81
+ parser :case_group do
82
+ cs = seq(
83
+ many1_fail(pattern, or_separator).name(:patterns),
84
+ many1(ws).err("case-exp", "space"),
85
+ str("->").err("case-exp", "'to'"),
86
+ many1(ws),
87
+ exp.err("match-exp", "invalid exp").name(:exp)
88
+ ).map do |x|
89
+ x[:patterns].map{|pat| Case.new(:pattern => pat, :exp => x[:exp].deep_copy)}
90
+ end
91
+ many1_fail(cs, many1(ws)).map(&:flatten) < many1(ws) < str(":endcase")
92
+ end
93
+
94
+ parser :pattern do
95
+ pat = dont_care_pattern ^ name_pattern ^ recursive_pattern ^ no_arg_pattern ^ tuple_pattern ^ integral_pattern
96
+ seq(
97
+ pat.name(:pattern),
98
+ opt_fail(
99
+ many(ws) > str(":") > many(ws) >
100
+ type.err("param-def", "type")
101
+ ).to_nil.name(:type)
102
+ ).map do |x|
103
+ x[:pattern][:type] = x[:type]
104
+ x[:pattern]
105
+ end
106
+ end
107
+
108
+ parser :dont_care_pattern do
109
+ symbol("_").map do |c|
110
+ AnyPattern.new(:ref => nil, :keyword => c)
111
+ end
112
+ end
113
+
114
+ parser :name_pattern do
115
+ ident_begin_lower.map do |n|
116
+ AnyPattern.new(:ref => n)
117
+ end
118
+ end
119
+
120
+ parser :recursive_pattern do
121
+ seq(
122
+ tvalue_symbol.name(:name),
123
+ many(ws),
124
+ str("("),
125
+ many(ws),
126
+ many1_fail(pattern, comma_separator).name(:args),
127
+ many(ws),
128
+ symbol(")").name(:keyword),
129
+ opt_fail(
130
+ many(ws) > str("as") > many1(ws) > var_name.err("pattern", "invalid name")
131
+ ).to_nil.name(:ref)
132
+ ).map{|x| ValuePattern.new(x.to_h)}
133
+ end
134
+
135
+ parser :no_arg_pattern do
136
+ seq(
137
+ tvalue_symbol.name(:name),
138
+ opt_fail(
139
+ many1(ws) > str("as") > var_name.err("pattern", "invalid name")
140
+ ).to_nil.name(:ref)
141
+ ).map{|x| ValuePattern.new(x.to_h, :args => [])}
142
+ end
143
+
144
+ parser :tuple_pattern do
145
+ seq(
146
+ symbol("(").name(:keyword1),
147
+ many(ws),
148
+ pattern.name(:arg_head),
149
+ many(ws),
150
+ str(","),
151
+ many(ws),
152
+ many1_fail(pattern, comma_separator).name(:arg_tail),
153
+ many(ws),
154
+ symbol(")").name(:keyword2),
155
+ opt_fail(
156
+ many(ws) > str("as") > many1(ws) > var_name.err("tuple-pattern", "invalid name")
157
+ ).to_nil.name(:ref)
158
+ ).map do |x|
159
+ args = [x[:arg_head]] + x[:arg_tail]
160
+ ValuePattern.new(
161
+ :name => SSymbol.new(:desc => "Tuple" + args.size.to_s),
162
+ :args => args,
163
+ :ref => x[:ref],
164
+ :keyword1 => x[:keyword1],
165
+ :keyword2 => x[:keyword2]
166
+ )
167
+ end
168
+ end
169
+
170
+ parser :integral_pattern do
171
+ integral_literal.map{|n| IntegralPattern.new(:val => n, :ref => nil)}
172
+ end
173
+
174
+ # Operator Expression
175
+ # --------------------
176
+
177
+ parser :operator_exp do
178
+ opexp = operator_general.map do |op|
179
+ proc do |l, r|
180
+ if l.is_a?(OperatorSeq)
181
+ OperatorSeq.new(:seq => l[:seq] + [op, r])
182
+ else
183
+ OperatorSeq.new(:seq => [l, op, r])
184
+ end
185
+ end
186
+ end
187
+ binopl_fail(primary, many(ws) > opexp < many(ws))
188
+ end
189
+
190
+ # Lower Expression
191
+ # --------------------
192
+
193
+ parser :primary do
194
+ atom >> proc{|a|
195
+ many(many(ws) > method_call).map do |cs|
196
+ if cs == [] then a else cs.inject(a){|acc, p| p.call(acc)} end
197
+ end
198
+ }
199
+ end
200
+
201
+ parser :method_call do
202
+ seq(
203
+ symbol(".").name(:keyword1),
204
+ many(ws),
205
+ ident_begin_lower.err("method_call", "invalid method name").name(:name),
206
+ opt_fail(
207
+ seq(
208
+ many(ws_without_newline),
209
+ symbol("(").name(:keyword2),
210
+ many(ws),
211
+ many_fail(exp, comma_separator).name(:args),
212
+ many(ws),
213
+ symbol(")").name(:keyword3)
214
+ )
215
+ ).to_nil.name(:args)
216
+ ).map do |x|
217
+ proc do |receiver|
218
+ if x[:args]
219
+ FuncCall.new(
220
+ :name => x[:name],
221
+ :keywords => [x[:keyword1], x[:args][:keyword2], x[:args][:keyword3]],
222
+ :args => [receiver] + x[:args][:args]
223
+ )
224
+ else
225
+ FuncCall.new(
226
+ :name => x[:name],
227
+ :keyword => x[:keyword1],
228
+ :args => [receiver]
229
+ )
230
+ end
231
+ end
232
+ end
233
+ end
234
+
235
+ parser :atom do
236
+ literal_exp ^ single_op ^ func_call ^ block_exp ^ value_cons ^ skip ^ var_ref
237
+ end
238
+
239
+ parser :single_op do
240
+ seq(operator, many(ws), atom).map do |x|
241
+ name = x[0].update(:desc => "@" + x[0][:desc])
242
+ FuncCall.new(:name => x[0], :args => [x[2]])
243
+ end
244
+ end
245
+
246
+ parser :func_call do
247
+ seq(
248
+ func_name.name(:name),
249
+ many(ws_without_newline),
250
+ symbol("(").name(:keyword1),
251
+ many(ws),
252
+ many1_fail(exp, comma_separator).name(:args),
253
+ many(ws),
254
+ symbol(")").name(:keyword2)
255
+ ).map do |x|
256
+ FuncCall.new(x.to_h)
257
+ end
258
+ end
259
+
260
+ parser :block_exp do
261
+ seq(
262
+ symbol("{").name(:keyword1),
263
+ many(ws),
264
+ many_fail(many(ws) > assign).name(:assigns),
265
+ many(ws),
266
+ exp.err("block-exp", "valid return-exp").name(:exp),
267
+ many(ws),
268
+ symbol("}").name(:keyword2)
269
+ ).map do |x|
270
+ x[:assigns].reverse.inject(x[:exp]) do |acc, a|
271
+ c = Case.new(:pattern => a[:pattern], :exp => acc)
272
+ MatchExp.new(:cases => [c], :exp => a[:exp])
273
+ end
274
+ end
275
+ end
276
+
277
+ parser :assign do # -> Hash
278
+ seq(
279
+ pattern.name(:pattern),
280
+ many(ws),
281
+ str("="),
282
+ many(ws),
283
+ exp.err("assign", "invalid assign statement").name(:exp)
284
+ ).map do |x|
285
+ x.to_h
286
+ end
287
+ end
288
+
289
+ parser :value_cons do # -> ValueConst
290
+ seq(
291
+ tvalue_symbol.name(:name),
292
+ opt_fail(
293
+ seq(
294
+ many(ws_without_newline),
295
+ str("("),
296
+ many(ws),
297
+ many_fail(exp, comma_separator).name(:args),
298
+ many(ws),
299
+ symbol(")").name(:keyword)
300
+ ).name(:args)
301
+ ).to_nil.err("value-construction", "invalid form of argument").name(:args)
302
+ ).map do |x|
303
+ if x[:args]
304
+ ValueConst.new(:name => x[:name], :args => x[:args][:args], :keyword => x[:args][:keyword])
305
+ else
306
+ ValueConst.new(:name => x[:name], :args => [])
307
+ end
308
+ end
309
+ end
310
+
311
+ parser :skip do
312
+ symbol("skip").map do |x|
313
+ SkipExp.new(:keyword => x)
314
+ end
315
+ end
316
+
317
+ parser :var_ref do
318
+ var_name_allow_last.map do |s|
319
+ VarRef.new(:name => s)
320
+ end
321
+ end
322
+
323
+ # Literal Expression
324
+ # --------------------
325
+
326
+ parser :literal_exp do
327
+ char_literal ^ parenth_or_tuple_literal ^ floating_literal ^ integral_literal
328
+ end
329
+
330
+ parser :char_literal do
331
+ seq(
332
+ symbol("'").name(:keyword1),
333
+ ((backslash > item) | item).map{|i| i.item}.name(:entity),
334
+ symbol("'").name(:keyword2),
335
+ ).map do |x|
336
+ LiteralChar.new(x.to_h)
337
+ end
338
+ end
339
+
340
+ parser :parenth_or_tuple_literal do
341
+ seq(
342
+ symbol("(").name(:keyword1),
343
+ many(ws),
344
+ many1_fail(exp, comma_separator).name(:entity),
345
+ many(ws),
346
+ symbol(")").name(:keyword2)
347
+ ).map do |x|
348
+ if x[:entity].size == 1
349
+ ParenthExp.new(
350
+ :exp => x[:entity].first,
351
+ :keyword1 => x[:keyword1],
352
+ :keyword2 => x[:keyword2]
353
+ )
354
+ else
355
+ ValueConst.new(
356
+ :name => SSymbol.new(:desc => "Tuple" + x[:entity].size.to_s),
357
+ :args => x[:entity],
358
+ :parent_begin => x[:keyword1],
359
+ :parent_end => x[:keyword2]
360
+ )
361
+ end
362
+ end
363
+ end
364
+
365
+ parser :integral_literal do
366
+ (positive_integer | zero_integer).map do |x|
367
+ LiteralIntegral.new(:entity => x)
368
+ end
369
+ end
370
+
371
+ parser :floating_literal do
372
+ seq(
373
+ integral_literal.name(:prefix),
374
+ char("."),
375
+ many1(digit).name(:suffix)
376
+ ).map do |x|
377
+ sym = SSymbol.new(:desc => x[:prefix][:entity][:desc] + "." + x[:suffix].map(&:item).join)
378
+ LiteralFloating.new(
379
+ :entity => sym,
380
+ :start_pos => x[:prefix][:entity][:start_pos],
381
+ :end_pos => x[:suffix][-1].tag
382
+ )
383
+ end
384
+ end
385
+ end
386
+ end