fancy 0.3.0

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 (242) hide show
  1. data/AUTHORS +7 -0
  2. data/LICENSE +19 -0
  3. data/README +173 -0
  4. data/Rakefile +255 -0
  5. data/bin/fancy +40 -0
  6. data/bin/fdoc +23 -0
  7. data/bin/fyi +22 -0
  8. data/bin/ifancy +46 -0
  9. data/boot/README +12 -0
  10. data/boot/code_loader.rb +165 -0
  11. data/boot/compile.fy +3 -0
  12. data/boot/fancy_ext.rb +13 -0
  13. data/boot/fancy_ext/block_env.rb +29 -0
  14. data/boot/fancy_ext/class.rb +26 -0
  15. data/boot/fancy_ext/kernel.rb +12 -0
  16. data/boot/fancy_ext/module.rb +89 -0
  17. data/boot/fancy_ext/object.rb +34 -0
  18. data/boot/fancy_ext/string_helper.rb +10 -0
  19. data/boot/load.rb +72 -0
  20. data/boot/rbx-compiler/README +12 -0
  21. data/boot/rbx-compiler/compiler.rb +24 -0
  22. data/boot/rbx-compiler/compiler/ast.rb +23 -0
  23. data/boot/rbx-compiler/compiler/ast/README +11 -0
  24. data/boot/rbx-compiler/compiler/ast/array_literal.rb +13 -0
  25. data/boot/rbx-compiler/compiler/ast/assign.rb +57 -0
  26. data/boot/rbx-compiler/compiler/ast/block.rb +70 -0
  27. data/boot/rbx-compiler/compiler/ast/class_def.rb +35 -0
  28. data/boot/rbx-compiler/compiler/ast/expression_list.rb +57 -0
  29. data/boot/rbx-compiler/compiler/ast/hash_literal.rb +11 -0
  30. data/boot/rbx-compiler/compiler/ast/identifier.rb +120 -0
  31. data/boot/rbx-compiler/compiler/ast/match.rb +81 -0
  32. data/boot/rbx-compiler/compiler/ast/message_send.rb +71 -0
  33. data/boot/rbx-compiler/compiler/ast/method_def.rb +116 -0
  34. data/boot/rbx-compiler/compiler/ast/node.rb +6 -0
  35. data/boot/rbx-compiler/compiler/ast/range_literal.rb +22 -0
  36. data/boot/rbx-compiler/compiler/ast/require.rb +20 -0
  37. data/boot/rbx-compiler/compiler/ast/return.rb +29 -0
  38. data/boot/rbx-compiler/compiler/ast/ruby_args.rb +35 -0
  39. data/boot/rbx-compiler/compiler/ast/script.rb +56 -0
  40. data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +39 -0
  41. data/boot/rbx-compiler/compiler/ast/string_literal.rb +14 -0
  42. data/boot/rbx-compiler/compiler/ast/super.rb +25 -0
  43. data/boot/rbx-compiler/compiler/ast/try_catch_block.rb +220 -0
  44. data/boot/rbx-compiler/compiler/ast/tuple_literal.rb +33 -0
  45. data/boot/rbx-compiler/compiler/command.rb +39 -0
  46. data/boot/rbx-compiler/compiler/compiler.rb +83 -0
  47. data/boot/rbx-compiler/compiler/stages.rb +99 -0
  48. data/boot/rbx-compiler/parser.rb +2 -0
  49. data/boot/rbx-compiler/parser/README +15 -0
  50. data/boot/rbx-compiler/parser/Rakefile +54 -0
  51. data/boot/rbx-compiler/parser/extconf.rb +3 -0
  52. data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
  53. data/boot/rbx-compiler/parser/fancy_parser.c +46 -0
  54. data/boot/rbx-compiler/parser/fancy_parser.h +8 -0
  55. data/boot/rbx-compiler/parser/lexer.lex +180 -0
  56. data/boot/rbx-compiler/parser/parser.rb +356 -0
  57. data/boot/rbx-compiler/parser/parser.y +711 -0
  58. data/boot/rsexp_pretty_printer.rb +76 -0
  59. data/doc/api/fancy.css +93 -0
  60. data/doc/api/fancy.jsonp +1 -0
  61. data/doc/api/fdoc.js +187 -0
  62. data/doc/api/index.html +57 -0
  63. data/doc/api/underscore-min.js +18 -0
  64. data/doc/features.md +228 -0
  65. data/examples/argv.fy +8 -0
  66. data/examples/arithmetic.fy +7 -0
  67. data/examples/armstrong_numbers.fy +33 -0
  68. data/examples/array.fy +52 -0
  69. data/examples/blocks.fy +15 -0
  70. data/examples/boolean.fy +24 -0
  71. data/examples/call_with_receiver.fy +9 -0
  72. data/examples/class.fy +68 -0
  73. data/examples/closures.fy +24 -0
  74. data/examples/constant_access.fy +15 -0
  75. data/examples/default_args.fy +17 -0
  76. data/examples/define_methods.fy +15 -0
  77. data/examples/documentation.fy +57 -0
  78. data/examples/documentation_formatters.fy +25 -0
  79. data/examples/echo.fy +16 -0
  80. data/examples/empty_catch.fy +4 -0
  81. data/examples/exception.fy +9 -0
  82. data/examples/factorial.fy +12 -0
  83. data/examples/fibonacci.fy +16 -0
  84. data/examples/files.fy +23 -0
  85. data/examples/finally.fy +5 -0
  86. data/examples/game_of_life.fy +148 -0
  87. data/examples/hashes.fy +7 -0
  88. data/examples/hello_world.fy +6 -0
  89. data/examples/html_generator.fy +54 -0
  90. data/examples/implicit_return.fy +3 -0
  91. data/examples/matchers.fy +6 -0
  92. data/examples/methods.fy +29 -0
  93. data/examples/nested_classes.fy +27 -0
  94. data/examples/nested_try.fy +9 -0
  95. data/examples/numbers.fy +12 -0
  96. data/examples/pattern_matching.fy +40 -0
  97. data/examples/person.fy +65 -0
  98. data/examples/project-euler/01.fy +8 -0
  99. data/examples/project-euler/02.fy +21 -0
  100. data/examples/project-euler/28.fy +33 -0
  101. data/examples/rbx/and_or.fy +7 -0
  102. data/examples/rbx/blocks.fy +22 -0
  103. data/examples/rbx/classes.fy +32 -0
  104. data/examples/rbx/hello.fy +8 -0
  105. data/examples/rbx/include.fy +12 -0
  106. data/examples/rbx/inherit.fy +11 -0
  107. data/examples/rbx/methods.fy +15 -0
  108. data/examples/rbx/nested_classes.fy +9 -0
  109. data/examples/rbx/require.fy +3 -0
  110. data/examples/rbx/strings.fy +5 -0
  111. data/examples/regex.fy +7 -0
  112. data/examples/require.fy +7 -0
  113. data/examples/retry.fy +12 -0
  114. data/examples/return.fy +13 -0
  115. data/examples/ruby_require.fy +7 -0
  116. data/examples/ruby_send.fy +3 -0
  117. data/examples/singleton_methods.fy +21 -0
  118. data/examples/stupid_quicksort.fy +12 -0
  119. data/examples/threads.fy +18 -0
  120. data/examples/tuple.fy +8 -0
  121. data/examples/webserver/webserver.fy +18 -0
  122. data/lib/argv.fy +36 -0
  123. data/lib/array.fy +207 -0
  124. data/lib/block.fy +88 -0
  125. data/lib/boot.fy +41 -0
  126. data/lib/class.fy +106 -0
  127. data/lib/compiler.fy +14 -0
  128. data/lib/compiler/ast.fy +40 -0
  129. data/lib/compiler/ast/assign.fy +96 -0
  130. data/lib/compiler/ast/block.fy +84 -0
  131. data/lib/compiler/ast/class_def.fy +33 -0
  132. data/lib/compiler/ast/expression_list.fy +47 -0
  133. data/lib/compiler/ast/identifier.fy +113 -0
  134. data/lib/compiler/ast/literals.fy +122 -0
  135. data/lib/compiler/ast/match.fy +88 -0
  136. data/lib/compiler/ast/message_send.fy +110 -0
  137. data/lib/compiler/ast/method_def.fy +90 -0
  138. data/lib/compiler/ast/node.fy +7 -0
  139. data/lib/compiler/ast/range.fy +16 -0
  140. data/lib/compiler/ast/require.fy +15 -0
  141. data/lib/compiler/ast/return.fy +23 -0
  142. data/lib/compiler/ast/script.fy +52 -0
  143. data/lib/compiler/ast/singleton_method_def.fy +35 -0
  144. data/lib/compiler/ast/super.fy +17 -0
  145. data/lib/compiler/ast/try_catch.fy +176 -0
  146. data/lib/compiler/ast/tuple_literal.fy +34 -0
  147. data/lib/compiler/command.fy +51 -0
  148. data/lib/compiler/compiler.fy +73 -0
  149. data/lib/compiler/stages.fy +81 -0
  150. data/lib/directory.fy +17 -0
  151. data/lib/documentation.fy +115 -0
  152. data/lib/enumerable.fy +269 -0
  153. data/lib/eval.fy +31 -0
  154. data/lib/fancy_spec.fy +202 -0
  155. data/lib/fdoc.fy +359 -0
  156. data/lib/fdoc_hook.fy +10 -0
  157. data/lib/file.fy +54 -0
  158. data/lib/hash.fy +56 -0
  159. data/lib/main.fy +80 -0
  160. data/lib/method.fy +22 -0
  161. data/lib/nil_class.fy +56 -0
  162. data/lib/number.fy +87 -0
  163. data/lib/object.fy +170 -0
  164. data/lib/package.fy +61 -0
  165. data/lib/package/dependency.fy +24 -0
  166. data/lib/package/installer.fy +180 -0
  167. data/lib/package/specification.fy +55 -0
  168. data/lib/package/uninstaller.fy +15 -0
  169. data/lib/parser.fy +4 -0
  170. data/lib/parser/ext/README +15 -0
  171. data/lib/parser/ext/ext.c +42 -0
  172. data/lib/parser/ext/ext.h +8 -0
  173. data/lib/parser/ext/extconf.rb +3 -0
  174. data/lib/parser/ext/lexer.lex +187 -0
  175. data/lib/parser/ext/parser.y +744 -0
  176. data/lib/parser/methods.fy +297 -0
  177. data/lib/rbx.fy +37 -0
  178. data/lib/rbx/array.fy +237 -0
  179. data/lib/rbx/bignum.fy +23 -0
  180. data/lib/rbx/block.fy +9 -0
  181. data/lib/rbx/class.fy +129 -0
  182. data/lib/rbx/code_loader.fy +192 -0
  183. data/lib/rbx/console.fy +63 -0
  184. data/lib/rbx/directory.fy +46 -0
  185. data/lib/rbx/documentation.fy +64 -0
  186. data/lib/rbx/environment_variables.fy +3 -0
  187. data/lib/rbx/exception.fy +30 -0
  188. data/lib/rbx/false_class.fy +58 -0
  189. data/lib/rbx/fiber.fy +25 -0
  190. data/lib/rbx/file.fy +191 -0
  191. data/lib/rbx/fixnum.fy +25 -0
  192. data/lib/rbx/float.fy +14 -0
  193. data/lib/rbx/hash.fy +38 -0
  194. data/lib/rbx/integer.fy +15 -0
  195. data/lib/rbx/io.fy +30 -0
  196. data/lib/rbx/match_data.fy +9 -0
  197. data/lib/rbx/method.fy +22 -0
  198. data/lib/rbx/name_error.fy +3 -0
  199. data/lib/rbx/no_method_error.fy +15 -0
  200. data/lib/rbx/object.fy +117 -0
  201. data/lib/rbx/range.fy +15 -0
  202. data/lib/rbx/regexp.fy +9 -0
  203. data/lib/rbx/string.fy +63 -0
  204. data/lib/rbx/symbol.fy +12 -0
  205. data/lib/rbx/system.fy +37 -0
  206. data/lib/rbx/tcp_server.fy +6 -0
  207. data/lib/rbx/tcp_socket.fy +7 -0
  208. data/lib/rbx/thread.fy +75 -0
  209. data/lib/rbx/tuple.fy +37 -0
  210. data/lib/set.fy +61 -0
  211. data/lib/stack.fy +51 -0
  212. data/lib/string.fy +58 -0
  213. data/lib/struct.fy +13 -0
  214. data/lib/symbol.fy +23 -0
  215. data/lib/true_class.fy +43 -0
  216. data/lib/tuple.fy +68 -0
  217. data/lib/version.fy +6 -0
  218. data/tests/argv.fy +13 -0
  219. data/tests/array.fy +343 -0
  220. data/tests/assignment.fy +53 -0
  221. data/tests/block.fy +103 -0
  222. data/tests/class.fy +409 -0
  223. data/tests/control_flow.fy +79 -0
  224. data/tests/documentation.fy +24 -0
  225. data/tests/exception.fy +115 -0
  226. data/tests/file.fy +86 -0
  227. data/tests/hash.fy +101 -0
  228. data/tests/method.fy +131 -0
  229. data/tests/nil_class.fy +55 -0
  230. data/tests/number.fy +128 -0
  231. data/tests/object.fy +125 -0
  232. data/tests/parsing/sexp.fy +50 -0
  233. data/tests/pattern_matching.fy +82 -0
  234. data/tests/range.fy +11 -0
  235. data/tests/set.fy +10 -0
  236. data/tests/stack.fy +22 -0
  237. data/tests/string.fy +102 -0
  238. data/tests/symbol.fy +17 -0
  239. data/tests/true_class.fy +63 -0
  240. data/tests/tuple.fy +21 -0
  241. data/tools/fancy-mode.el +63 -0
  242. metadata +321 -0
@@ -0,0 +1,744 @@
1
+ %{
2
+ #include "ruby.h"
3
+
4
+ int yyerror(VALUE, char *s);
5
+ int yylex(VALUE);
6
+
7
+ VALUE fy_terminal_node(VALUE, char *);
8
+ VALUE fy_terminal_node_from(VALUE, char *, char*);
9
+
10
+ extern int yylineno;
11
+ extern char *yytext;
12
+
13
+ %}
14
+
15
+ %lex-param { VALUE self }
16
+ %parse-param { VALUE self }
17
+
18
+ %union{
19
+ VALUE object;
20
+ ID symbol;
21
+ }
22
+
23
+ %start programm
24
+
25
+ %token LPAREN
26
+ %token RPAREN
27
+ %token AT_LCURLY
28
+ %token LCURLY
29
+ %token RCURLY
30
+ %token LBRACKET
31
+ %token RBRACKET
32
+ %token LHASH
33
+ %token RHASH
34
+ %token STAB
35
+ %token ARROW
36
+ %token THIN_ARROW
37
+ %token COMMA
38
+ %token SEMI
39
+ %token NL
40
+ %token COLON
41
+ %token RETURN_LOCAL
42
+ %token RETURN
43
+ %token REQUIRE
44
+ %token TRY
45
+ %token CATCH
46
+ %token FINALLY
47
+ %token RETRY
48
+ %token SUPER
49
+ %token PRIVATE
50
+ %token PROTECTED
51
+ %token CLASS
52
+ %token DEF
53
+ %token DOT
54
+ %token DOLLAR
55
+ %token EQUALS
56
+ %token MATCH
57
+ %token CASE
58
+ %token IDENTIFIER
59
+ %token SELECTOR
60
+ %token RUBY_SEND_OPEN
61
+ %token RUBY_OPER_OPEN
62
+ %token CONSTANT
63
+
64
+ %token INTEGER_LITERAL
65
+ %token HEX_LITERAL
66
+ %token OCT_LITERAL
67
+ %token BIN_LITERAL
68
+ %token DOUBLE_LITERAL
69
+ %token STRING_LITERAL
70
+ %token MULTI_STRING_LITERAL
71
+ %token SYMBOL_LITERAL
72
+ %token REGEX_LITERAL
73
+ %token OPERATOR
74
+
75
+ %left DOT
76
+ %right DOLLAR
77
+
78
+ %type <object> integer_literal
79
+ %type <object> hex_literal
80
+ %type <object> oct_literal
81
+ %type <object> bin_literal
82
+ %type <object> double_literal
83
+ %type <object> string_literal
84
+ %type <object> symbol_literal
85
+ %type <object> regex_literal
86
+ %type <object> operator
87
+ %type <object> selector
88
+
89
+
90
+ %type <object> identifier
91
+ %type <object> any_identifier
92
+ %type <object> constant
93
+ %type <object> literal_value
94
+ %type <object> block_literal
95
+ %type <object> block_args
96
+ %type <object> block_args_without_comma
97
+ %type <object> block_args_with_comma
98
+ %type <object> hash_literal
99
+ %type <object> array_literal
100
+ %type <object> empty_array
101
+ %type <object> tuple_literal
102
+ %type <object> range_literal
103
+
104
+ %type <object> key_value_list
105
+ %type <object> exp_comma_list
106
+
107
+ %type <object> code
108
+ %type <object> expression_list
109
+ %type <object> expression_block
110
+ %type <object> partial_expression_block
111
+ %type <object> exp
112
+ %type <object> primary
113
+ %type <object> assignment
114
+ %type <object> multiple_assignment
115
+ %type <object> identifier_list
116
+ %type <object> return_local_statement
117
+ %type <object> return_statement
118
+ %type <object> require_statement
119
+
120
+ %type <object> def
121
+
122
+ %type <object> const_identifier
123
+ %type <object> class_def
124
+ %type <object> class_no_super
125
+ %type <object> class_super
126
+ %type <object> class_method_w_args
127
+ %type <object> class_method_no_args
128
+
129
+ %type <object> method_def
130
+ %type <object> method_args
131
+ %type <object> method_arg
132
+ %type <object> method_args_default
133
+ %type <object> method_arg_default
134
+ %type <object> method_w_args
135
+ %type <object> method_no_args
136
+ %type <object> operator_def
137
+ %type <object> class_operator_def
138
+
139
+ %type <object> message_send
140
+ %type <object> unary_send
141
+ %type <object> ruby_send_open
142
+ %type <object> ruby_oper_open
143
+ %type <object> ruby_send
144
+ %type <object> ruby_oper_send
145
+ %type <object> ruby_args
146
+ %type <object> operator_send
147
+ %type <object> send_args
148
+ %type <object> arg_exp
149
+
150
+ %type <object> try_catch_block
151
+ %type <object> catch_blocks
152
+ %type <object> finally_block
153
+ %type <object> catch_block
154
+ %type <object> required_catch_blocks
155
+
156
+ %type <object> match_expr
157
+ %type <object> match_body
158
+ %type <object> match_clause
159
+
160
+ %%
161
+
162
+ programm: /*empty*/
163
+ | expression_list {
164
+ rb_funcall(self, rb_intern("body:"), 1, $1);
165
+ }
166
+ ;
167
+
168
+ delim: nls
169
+ | SEMI
170
+ | delim delim
171
+ ;
172
+
173
+ nls: NL
174
+ | nls NL
175
+ ;
176
+
177
+ space: /* */
178
+ | nls
179
+ ;
180
+
181
+ code: statement
182
+ | exp
183
+ ;
184
+
185
+ expression_list: code {
186
+ $$ = rb_funcall(self, rb_intern("ast:exp_list:"), 2, INT2NUM(yylineno), $1);
187
+ }
188
+ | expression_list code {
189
+ $$ = rb_funcall(self, rb_intern("ast:exp_list:into:"), 3, INT2NUM(yylineno), $2, $1);
190
+ }
191
+ | delim expression_list {
192
+ $$ = $2;
193
+ }
194
+ | expression_list delim {
195
+ $$ = $1;
196
+ }
197
+ ;
198
+
199
+ expression_block: LCURLY space expression_list space RCURLY {
200
+ $$ = $3;
201
+ }
202
+ | LCURLY space RCURLY {
203
+ $$ = rb_funcall(self, rb_intern("ast:exp_list:"), 2, INT2NUM(yylineno), Qnil);
204
+ }
205
+ ;
206
+
207
+ partial_expression_block: AT_LCURLY space expression_list space RCURLY {
208
+ $$ = $3;
209
+ }
210
+ ;
211
+
212
+ statement: assignment
213
+ | return_local_statement
214
+ | return_statement
215
+ | require_statement
216
+ ;
217
+
218
+ primary: any_identifier
219
+ | literal_value
220
+ | LPAREN space exp space RPAREN {
221
+ $$ = $3;
222
+ }
223
+ ;
224
+
225
+ exp: primary
226
+ | method_def
227
+ | class_def
228
+ | try_catch_block
229
+ | match_expr
230
+ | message_send
231
+ | ruby_send
232
+ | ruby_oper_send
233
+ | SUPER { $$ = rb_funcall(self, rb_intern("ast:super_exp:"), 2, INT2NUM(yylineno), Qnil); }
234
+ | RETRY { $$ = rb_funcall(self, rb_intern("ast:retry_exp:"), 2, INT2NUM(yylineno), Qnil); }
235
+ | exp DOT space {
236
+ $$ = $1;
237
+ }
238
+ ;
239
+
240
+ assignment: any_identifier EQUALS space exp {
241
+ $$ = rb_funcall(self, rb_intern("ast:assign:to:"), 3, INT2NUM(yylineno), $4, $1);
242
+ }
243
+ | multiple_assignment
244
+ ;
245
+
246
+ multiple_assignment: identifier_list EQUALS exp_comma_list {
247
+ $$ = rb_funcall(self, rb_intern("ast:assign:to:many:"), 4, INT2NUM(yylineno), $3, $1, Qtrue);
248
+ }
249
+ ;
250
+
251
+ operator: OPERATOR {
252
+ $$ = fy_terminal_node(self, "ast:identifier:");
253
+ }
254
+ ;
255
+
256
+ constant: CONSTANT {
257
+ $$ = fy_terminal_node(self, "ast:identifier:");
258
+ }
259
+ ;
260
+
261
+ selector: SELECTOR {
262
+ $$ = fy_terminal_node(self, "ast:identifier:");
263
+ };
264
+
265
+ identifier: IDENTIFIER {
266
+ $$ = fy_terminal_node(self, "ast:identifier:");
267
+ }
268
+ | MATCH {
269
+ $$ = fy_terminal_node_from(self, "ast:identifier:", "match");
270
+ }
271
+ | CLASS {
272
+ $$ = fy_terminal_node_from(self, "ast:identifier:", "class");
273
+ }
274
+ ;
275
+
276
+ any_identifier: const_identifier
277
+ | identifier
278
+ ;
279
+
280
+ identifier_list: any_identifier {
281
+ $$ = rb_funcall(self, rb_intern("ast:concat:"), 2, INT2NUM(yylineno), $1);
282
+ }
283
+ | identifier_list COMMA any_identifier {
284
+ $$ = rb_funcall(self, rb_intern("ast:concat:into:"), 3, INT2NUM(yylineno), $3, $1);
285
+ }
286
+ ;
287
+
288
+ return_local_statement: RETURN_LOCAL exp {
289
+ $$ = rb_funcall(self, rb_intern("ast:return_local_stmt:"), 2, INT2NUM(yylineno), $2);
290
+ }
291
+ | RETURN_LOCAL {
292
+ $$ = rb_funcall(self, rb_intern("ast:return_local_stmt:"), 2, INT2NUM(yylineno), Qnil);
293
+ }
294
+ ;
295
+
296
+ return_statement: RETURN exp {
297
+ $$ = rb_funcall(self, rb_intern("ast:return_stmt:"), 2, INT2NUM(yylineno), $2);
298
+ }
299
+ | RETURN {
300
+ $$ = rb_funcall(self, rb_intern("ast:return_stmt:"), 2, INT2NUM(yylineno), Qnil);
301
+ }
302
+ ;
303
+
304
+ require_statement: REQUIRE string_literal {
305
+ $$ = rb_funcall(self, rb_intern("ast:require_:"), 2, INT2NUM(yylineno), $2);
306
+ }
307
+ | REQUIRE any_identifier {
308
+ $$ = rb_funcall(self, rb_intern("ast:require_:"), 2, INT2NUM(yylineno), $2);
309
+ }
310
+ ;
311
+
312
+ class_def: class_no_super
313
+ | class_super
314
+ ;
315
+
316
+ const_identifier: constant {
317
+ $$ = rb_funcall(self, rb_intern("ast:identity:"), 2, INT2NUM(yylineno), $1);
318
+ }
319
+ | const_identifier constant {
320
+ $$ = rb_funcall(self, rb_intern("ast:constant:parent:"), 3, INT2NUM(yylineno), $2, $1);
321
+ }
322
+ ;
323
+
324
+ def: DEF PRIVATE { $$ = rb_intern("private"); }
325
+ | DEF PROTECTED { $$ = rb_intern("protected"); }
326
+ | DEF { $$ = rb_intern("public"); }
327
+ ;
328
+
329
+ class_no_super: CLASS const_identifier expression_block {
330
+ $$ = rb_funcall(self, rb_intern("ast:class:parent:body:"), 4, INT2NUM(yylineno), $2, Qnil, $3);
331
+ }
332
+ ;
333
+
334
+ class_super: CLASS const_identifier COLON const_identifier expression_block {
335
+ $$ = rb_funcall(self, rb_intern("ast:class:parent:body:"), 4, INT2NUM(yylineno), $2, $4, $5);
336
+ }
337
+ ;
338
+
339
+ method_def: method_w_args
340
+ | method_no_args
341
+ | class_method_w_args
342
+ | class_method_no_args
343
+ | operator_def
344
+ | class_operator_def
345
+ ;
346
+
347
+ method_arg: selector identifier {
348
+ $$ = rb_funcall(self, rb_intern("ast:param:var:"), 3, INT2NUM(yylineno), $1, $2);
349
+ }
350
+ ;
351
+
352
+ method_args: method_arg {
353
+ $$ = rb_funcall(self, rb_intern("ast:concat:"), 2, INT2NUM(yylineno), $1);
354
+ }
355
+ | method_args method_arg {
356
+ $$ = rb_funcall(self, rb_intern("ast:concat:into:"), 3, INT2NUM(yylineno), $2, $1);
357
+ }
358
+ | method_args method_args_default {
359
+ $$ = rb_funcall(self, rb_intern("ast:concat:into:"), 3, INT2NUM(yylineno), $2, $1);
360
+ }
361
+ ;
362
+
363
+ method_arg_default: selector identifier LPAREN space exp space RPAREN {
364
+ $$ = rb_funcall(self, rb_intern("ast:param:var:default:"), 4, INT2NUM(yylineno), $1, $2, $5);
365
+ }
366
+ ;
367
+
368
+ method_args_default: method_arg_default {
369
+ $$ = rb_funcall(self, rb_intern("ast:concat:"), 2, INT2NUM(yylineno), $1);
370
+ }
371
+ | method_args_default space method_arg_default {
372
+ $$ = rb_funcall(self, rb_intern("ast:concat:into:"), 3, INT2NUM(yylineno), $3, $1);
373
+ }
374
+ ;
375
+
376
+ method_w_args: def method_args expression_block {
377
+ $$ = rb_funcall(self, rb_intern("ast:method:expand:access:"), 4, INT2NUM(yylineno), $2, $3, $1);
378
+ }
379
+ ;
380
+
381
+
382
+ method_no_args: def identifier expression_block {
383
+ $$ = rb_funcall(self, rb_intern("ast:method:body:access:"), 4, INT2NUM(yylineno), $2, $3, $1);
384
+ }
385
+ ;
386
+
387
+
388
+ class_method_w_args: def any_identifier method_args expression_block {
389
+ $$ = rb_funcall(self, rb_intern("ast:method:expand:access:owner:"), 5, INT2NUM(yylineno), $3, $4, $1, $2);
390
+ }
391
+ ;
392
+
393
+ class_method_no_args: def any_identifier identifier expression_block {
394
+ $$ = rb_funcall(self, rb_intern("ast:method:body:access:owner:"), 5, INT2NUM(yylineno), $3, $4, $1, $2);
395
+ }
396
+ ;
397
+
398
+ operator_def: def operator identifier expression_block {
399
+ $$ = rb_funcall(self, rb_intern("ast:oper:arg:body:access:"), 5, INT2NUM(yylineno), $2, $3, $4, $1);
400
+ }
401
+ | def LBRACKET RBRACKET identifier expression_block {
402
+ $$ = rb_funcall(self, rb_intern("ast:oper:arg:body:access:"), 5,
403
+ INT2NUM(yylineno), fy_terminal_node_from(self, "ast:identifier:", "[]"), $4, $5, $1);
404
+ }
405
+ ;
406
+
407
+ class_operator_def: def any_identifier operator identifier expression_block {
408
+ $$ = rb_funcall(self, rb_intern("ast:oper:arg:body:access:owner:"), 6, INT2NUM(yylineno), $3, $4, $5, $1, $2);
409
+ }
410
+ | def any_identifier LBRACKET RBRACKET identifier expression_block {
411
+ $$ = rb_funcall(self, rb_intern("ast:oper:arg:body:access:owner:"), 6,
412
+ INT2NUM(yylineno), fy_terminal_node_from(self, "ast:identifier:", "[]"), $5, $6, $1, $2);
413
+ }
414
+ ;
415
+
416
+ unary_send: exp identifier {
417
+ $$ = rb_funcall(self, rb_intern("ast:send:to:"), 3, INT2NUM(yylineno), $2, $1);
418
+ }
419
+ | unary_send identifier {
420
+ $$ = rb_funcall(self, rb_intern("ast:send:to:"), 3, INT2NUM(yylineno), $2, $1);
421
+ }
422
+ ;
423
+
424
+ operator_send: exp operator arg_exp {
425
+ $$ = rb_funcall(self, rb_intern("ast:oper:arg:to:"), 4, INT2NUM(yylineno), $2, $3, $1);
426
+ }
427
+ | exp operator DOT space arg_exp {
428
+ $$ = rb_funcall(self, rb_intern("ast:oper:arg:to:"), 4, INT2NUM(yylineno), $2, $5, $1);
429
+ }
430
+ | exp LBRACKET exp RBRACKET {
431
+ $$ = rb_funcall(self, rb_intern("ast:oper:arg:to:"), 4,
432
+ INT2NUM(yylineno), fy_terminal_node_from(self, "ast:identifier:", "[]"), $3, $1);
433
+ }
434
+ | operator arg_exp {
435
+ $$ = rb_funcall(self, rb_intern("ast:oper:arg:"), 3, INT2NUM(yylineno), $1, $2);
436
+ }
437
+ ;
438
+
439
+ message_send: unary_send
440
+ | operator_send
441
+ | exp send_args {
442
+ $$ = rb_funcall(self, rb_intern("ast:send:to:"), 3, INT2NUM(yylineno), $2, $1);
443
+ }
444
+ | send_args {
445
+ $$ = rb_funcall(self, rb_intern("ast:send:"), 2, INT2NUM(yylineno), $1);
446
+ }
447
+ ;
448
+
449
+ send_args: selector arg_exp {
450
+ $$ = rb_funcall(self, rb_intern("ast:send:arg:"), 3, INT2NUM(yylineno), $1, $2);
451
+ }
452
+ | selector space arg_exp {
453
+ $$ = rb_funcall(self, rb_intern("ast:send:arg:"), 3, INT2NUM(yylineno), $1, $3);
454
+ }
455
+ | send_args selector arg_exp {
456
+ $$ = rb_funcall(self, rb_intern("ast:send:arg:ary:"), 4, INT2NUM(yylineno), $2, $3, $1);
457
+ }
458
+ | send_args selector space arg_exp {
459
+ $$ = rb_funcall(self, rb_intern("ast:send:arg:ary:"), 4, INT2NUM(yylineno), $2, $4, $1);
460
+ }
461
+ ;
462
+
463
+ arg_exp: any_identifier {
464
+ $$ = $1;
465
+ }
466
+ | LPAREN exp RPAREN {
467
+ $$ = $2;
468
+ }
469
+ | literal_value {
470
+ $$ = $1;
471
+ }
472
+ | DOLLAR exp {
473
+ $$ = $2;
474
+ }
475
+ ;
476
+
477
+
478
+ /* ruby_send_open is just an identifier immediatly followed by a left-paren
479
+ NO SPACE ALLOWED between the identifier and the left-paren. that's why we
480
+ need a parse rule.
481
+ */
482
+ ruby_send_open: RUBY_SEND_OPEN {
483
+ // remove the trailing left paren and create an identifier.
484
+ $$ = fy_terminal_node(self, "ast:ruby_send:");
485
+ };
486
+ ruby_oper_open: RUBY_OPER_OPEN {
487
+ // remove the trailing left paren and create an identifier.
488
+ $$ = fy_terminal_node(self, "ast:ruby_send:");
489
+ };
490
+
491
+ ruby_send: exp ruby_send_open ruby_args {
492
+ $$ = rb_funcall(self, rb_intern("ast:send:to:ruby:"), 4, INT2NUM(yylineno), $2, $1, $3);
493
+ }
494
+ | ruby_send_open ruby_args {
495
+ $$ = rb_funcall(self, rb_intern("ast:send:to:ruby:"), 4, INT2NUM(yylineno), $1, Qnil, $2);
496
+ }
497
+ ;
498
+
499
+ /*
500
+ The closing part of ruby_send_open.
501
+ We explicitly require parens for ALL ruby sends now, so there will always be
502
+ a closing paren.
503
+ */
504
+ ruby_args: RPAREN block_literal {
505
+ $$ = rb_funcall(self, rb_intern("ast:ruby_args:block:"), 3, INT2NUM(yylineno), Qnil, $2);
506
+ }
507
+ | exp_comma_list RPAREN block_literal {
508
+ $$ = rb_funcall(self, rb_intern("ast:ruby_args:block:"), 3, INT2NUM(yylineno), $1, $3);
509
+ }
510
+ | RPAREN {
511
+ $$ = rb_funcall(self, rb_intern("ast:ruby_args:"), 2, INT2NUM(yylineno), Qnil);
512
+ }
513
+ | exp_comma_list RPAREN {
514
+ $$ = rb_funcall(self, rb_intern("ast:ruby_args:"), 2, INT2NUM(yylineno), $1);
515
+ }
516
+ ;
517
+
518
+ ruby_oper_send: exp ruby_oper_open ruby_args {
519
+ $$ = rb_funcall(self, rb_intern("ast:send:to:ruby:"), 4, INT2NUM(yylineno), $2, $1, $3);
520
+ }
521
+ ;
522
+
523
+
524
+ try_catch_block: TRY expression_block catch_blocks finally_block {
525
+ $$ = rb_funcall(self, rb_intern("ast:try_block:ex_handlers:finally_block:"), 4, INT2NUM(yylineno), $2, $3, $4);
526
+ }
527
+ | TRY expression_block required_catch_blocks {
528
+ $$ = rb_funcall(self, rb_intern("ast:try_block:ex_handlers:"), 3, INT2NUM(yylineno), $2, $3);
529
+ }
530
+ ;
531
+
532
+ catch_block: CATCH expression_block {
533
+ $$ = rb_funcall(self, rb_intern("ast:ex_handler:"), 2, INT2NUM(yylineno), $2);
534
+ }
535
+ | CATCH exp expression_block {
536
+ $$ = rb_funcall(self, rb_intern("ast:ex_handler:cond:"), 3, INT2NUM(yylineno), $3, $2);
537
+ }
538
+ | CATCH exp ARROW identifier expression_block {
539
+ $$ = rb_funcall(self, rb_intern("ast:ex_handler:cond:var:"), 4, INT2NUM(yylineno), $5, $2, $4);
540
+ }
541
+ ;
542
+
543
+ required_catch_blocks: catch_block {
544
+ $$ = rb_funcall(self, rb_intern("ast:concat:"), 2, INT2NUM(yylineno), $1);
545
+ }
546
+ | required_catch_blocks catch_block {
547
+ $$ = rb_funcall(self, rb_intern("ast:concat:into:"), 3, INT2NUM(yylineno), $2, $1);
548
+ }
549
+ ;
550
+
551
+ catch_blocks: catch_block {
552
+ $$ = rb_funcall(self, rb_intern("ast:concat:"), 2, INT2NUM(yylineno), $1);
553
+ }
554
+ | catch_blocks catch_block {
555
+ $$ = rb_funcall(self, rb_intern("ast:concat:into:"), 3, INT2NUM(yylineno), $2, $1);
556
+ }
557
+ | /* empty */ {
558
+ $$ = rb_funcall(self, rb_intern("ast:concat:"), 2, INT2NUM(yylineno), Qnil);
559
+ }
560
+ ;
561
+
562
+ finally_block: FINALLY expression_block {
563
+ $$ = $2;
564
+ }
565
+ ;
566
+
567
+ integer_literal: INTEGER_LITERAL {
568
+ $$ = fy_terminal_node(self, "ast:fixnum:");
569
+ }
570
+ ;
571
+ double_literal: DOUBLE_LITERAL {
572
+ $$ = fy_terminal_node(self, "ast:number:");
573
+ }
574
+ ;
575
+ string_literal: STRING_LITERAL {
576
+ $$ = fy_terminal_node(self, "ast:string:");
577
+ }
578
+ | MULTI_STRING_LITERAL {
579
+ $$ = fy_terminal_node(self, "ast:string:");
580
+ }
581
+ ;
582
+ symbol_literal: SYMBOL_LITERAL {
583
+ $$ = fy_terminal_node(self, "ast:symbol:");
584
+ }
585
+ ;
586
+ regex_literal: REGEX_LITERAL {
587
+ $$ = fy_terminal_node(self, "ast:regexp:");
588
+ }
589
+ ;
590
+
591
+ hex_literal: HEX_LITERAL {
592
+ $$ = rb_funcall(self, rb_intern("ast:fixnum:base:"), 3,
593
+ INT2NUM(yylineno), rb_str_new2(yytext), INT2NUM(16));
594
+ }
595
+ ;
596
+
597
+ oct_literal: OCT_LITERAL {
598
+ $$ = rb_funcall(self, rb_intern("ast:fixnum:base:"), 3,
599
+ INT2NUM(yylineno), rb_str_new2(yytext), INT2NUM(8));
600
+ }
601
+ ;
602
+
603
+ bin_literal: BIN_LITERAL {
604
+ $$ = rb_funcall(self, rb_intern("ast:fixnum:base:"), 3,
605
+ INT2NUM(yylineno), rb_str_new2(yytext), INT2NUM(2));
606
+ }
607
+ ;
608
+
609
+ literal_value: integer_literal
610
+ | hex_literal
611
+ | oct_literal
612
+ | bin_literal
613
+ | double_literal
614
+ | string_literal
615
+ | symbol_literal
616
+ | hash_literal
617
+ | array_literal
618
+ | regex_literal
619
+ | block_literal
620
+ | tuple_literal
621
+ | range_literal
622
+ ;
623
+
624
+ array_literal: empty_array {
625
+ $$ = $1;
626
+ }
627
+ | LBRACKET space exp_comma_list space RBRACKET {
628
+ $$ = rb_funcall(self, rb_intern("ast:array:"), 2, INT2NUM(yylineno), $3);
629
+ }
630
+ ;
631
+
632
+ exp_comma_list: exp {
633
+ $$ = rb_funcall(self, rb_intern("ast:concat:"), 2, INT2NUM(yylineno), $1);
634
+ }
635
+ | exp_comma_list COMMA space exp {
636
+ $$ = rb_funcall(self, rb_intern("ast:concat:into:"), 3, INT2NUM(yylineno), $4, $1);
637
+ }
638
+ | exp_comma_list COMMA {
639
+ $$ = $1;
640
+ }
641
+ ;
642
+
643
+ empty_array: LBRACKET space RBRACKET {
644
+ $$ = rb_funcall(self, rb_intern("ast:array:"), 2, INT2NUM(yylineno), Qnil);
645
+ }
646
+ ;
647
+
648
+ hash_literal: LHASH space key_value_list space RHASH {
649
+ $$ = rb_funcall(self, rb_intern("ast:hash:"), 2, INT2NUM(yylineno), $3);
650
+ }
651
+ | LHASH space RHASH {
652
+ $$ = rb_funcall(self, rb_intern("ast:hash:"), 2, INT2NUM(yylineno), Qnil);
653
+ }
654
+ ;
655
+
656
+ block_literal: partial_expression_block {
657
+ $$ = rb_funcall(self, rb_intern("ast:partial_block:"), 2, INT2NUM(yylineno), $1);
658
+ }
659
+ | expression_block {
660
+ $$ = rb_funcall(self, rb_intern("ast:block:"), 2, INT2NUM(yylineno), $1);
661
+ }
662
+ | STAB block_args STAB space expression_block {
663
+ $$ = rb_funcall(self, rb_intern("ast:block:args:"), 3, INT2NUM(yylineno), $5, $2);
664
+ }
665
+ ;
666
+
667
+ tuple_literal: LPAREN exp_comma_list RPAREN {
668
+ $$ = rb_funcall(self, rb_intern("ast:tuple:"), 2, INT2NUM(yylineno), $2);
669
+ }
670
+ ;
671
+
672
+ range_literal: LPAREN exp DOT DOT exp RPAREN {
673
+ $$ = rb_funcall(self, rb_intern("ast:range:to:"), 3, INT2NUM(yylineno), $2, $5);
674
+ }
675
+ ;
676
+
677
+ block_args: block_args_with_comma
678
+ | block_args_without_comma
679
+ ;
680
+
681
+ block_args_without_comma: identifier {
682
+ $$ = rb_funcall(self, rb_intern("ast:concat:"), 2, INT2NUM(yylineno), $1);
683
+ }
684
+ | block_args_without_comma identifier {
685
+ $$ = rb_funcall(self, rb_intern("ast:concat:into:"), 3, INT2NUM(yylineno), $2, $1);
686
+ }
687
+ ;
688
+
689
+ block_args_with_comma: identifier {
690
+ $$ = rb_funcall(self, rb_intern("ast:concat:"), 2, INT2NUM(yylineno), $1);
691
+ }
692
+ | block_args_with_comma COMMA identifier {
693
+ $$ = rb_funcall(self, rb_intern("ast:concat:into:"), 3, INT2NUM(yylineno), $3, $1);
694
+ }
695
+ ;
696
+
697
+ key_value_list: exp space ARROW space exp {
698
+ $$ = rb_funcall(self, rb_intern("ast:key:value:into:"), 4, INT2NUM(yylineno), $1, $5, Qnil);
699
+ }
700
+ | key_value_list COMMA space exp space ARROW space exp {
701
+ $$ = rb_funcall(self, rb_intern("ast:key:value:into:"), 4, INT2NUM(yylineno), $4, $8, $1);
702
+ }
703
+ ;
704
+
705
+ match_expr: MATCH exp THIN_ARROW LCURLY space match_body space RCURLY {
706
+ $$ = rb_funcall(self, rb_intern("ast:match_expr:body:"), 3, INT2NUM(yylineno), $2, $6);
707
+ }
708
+ ;
709
+
710
+ match_body: match_clause {
711
+ $$ = rb_funcall(self, rb_intern("ast:concat:"), 2, INT2NUM(yylineno), $1);
712
+ }
713
+ | match_body match_clause {
714
+ $$ = rb_funcall(self, rb_intern("ast:concat:into:"), 3, INT2NUM(yylineno), $2, $1);
715
+ }
716
+ ;
717
+
718
+ match_clause: CASE exp THIN_ARROW expression_list {
719
+ $$ = rb_funcall(self, rb_intern("ast:match_clause:body:"), 3, INT2NUM(yylineno), $2, $4);
720
+ }
721
+ | CASE exp THIN_ARROW STAB block_args STAB expression_list {
722
+ $$ = rb_funcall(self, rb_intern("ast:match_clause:body:args:"), 4, INT2NUM(yylineno), $2, $7, $5);
723
+ }
724
+ ;
725
+
726
+ %%
727
+
728
+
729
+ VALUE fy_terminal_node(VALUE self, char* method) {
730
+ return rb_funcall(self, rb_intern(method), 2,
731
+ INT2NUM(yylineno), rb_str_new2(yytext));
732
+ }
733
+
734
+ VALUE fy_terminal_node_from(VALUE self, char* method, char* text) {
735
+ return rb_funcall(self, rb_intern(method), 2,
736
+ INT2NUM(yylineno), rb_str_new2(text));
737
+ }
738
+
739
+ int yyerror(VALUE self, char *s)
740
+ {
741
+ rb_funcall(self, rb_intern("ast:parse_error:"), 2, INT2NUM(yylineno), rb_str_new2(yytext));
742
+ return 1;
743
+ }
744
+