parser 0.9.alpha1 → 0.9.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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -3
- data/AST_FORMAT.md +1338 -0
- data/README.md +58 -3
- data/Rakefile +32 -12
- data/bin/benchmark +47 -0
- data/bin/explain-parse +14 -0
- data/bin/parse +6 -0
- data/lib/parser.rb +84 -0
- data/lib/parser/all.rb +2 -0
- data/lib/parser/ast/node.rb +11 -0
- data/lib/parser/ast/processor.rb +8 -0
- data/lib/parser/base.rb +116 -0
- data/lib/parser/builders/default.rb +654 -0
- data/lib/parser/compatibility/ruby1_8.rb +13 -0
- data/lib/parser/diagnostic.rb +44 -0
- data/lib/parser/diagnostic/engine.rb +44 -0
- data/lib/parser/lexer.rl +335 -245
- data/lib/parser/lexer/explanation.rb +37 -0
- data/lib/parser/{lexer_literal.rb → lexer/literal.rb} +22 -12
- data/lib/parser/lexer/stack_state.rb +38 -0
- data/lib/parser/ruby18.y +1957 -0
- data/lib/parser/ruby19.y +2154 -0
- data/lib/parser/source/buffer.rb +78 -0
- data/lib/parser/source/map.rb +20 -0
- data/lib/parser/source/map/operator.rb +15 -0
- data/lib/parser/source/map/variable_assignment.rb +15 -0
- data/lib/parser/source/range.rb +66 -0
- data/lib/parser/static_environment.rb +12 -6
- data/parser.gemspec +23 -13
- data/test/helper.rb +45 -0
- data/test/parse_helper.rb +204 -0
- data/test/racc_coverage_helper.rb +130 -0
- data/test/test_diagnostic.rb +47 -0
- data/test/test_diagnostic_engine.rb +58 -0
- data/test/test_lexer.rb +601 -357
- data/test/test_lexer_stack_state.rb +69 -0
- data/test/test_parse_helper.rb +74 -0
- data/test/test_parser.rb +3654 -0
- data/test/test_source_buffer.rb +80 -0
- data/test/test_source_range.rb +51 -0
- data/test/test_static_environment.rb +1 -4
- metadata +137 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64faf8cbd6623a7268450021e84940620bec4ff0
|
4
|
+
data.tar.gz: 51b535785f972fe51c2be0fb10e13d2aff703d1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ea8e96cc12098f027f4be4fab4884b772259b66499f673026c8f2ee2f76e927f3f5a9e91f1bb6e529d969d9358252bc55ac03d741de578390abd1f0a15d13db
|
7
|
+
data.tar.gz: 57f8ad5890002bdd5e73ba5d67f23136025c200c880e1231203bb3d2a4a0bdbaa28c8e4e277c432d0977145d757cab23935efa1f9a5fb6b731b9583d48dc66d6
|
data/.travis.yml
CHANGED
data/AST_FORMAT.md
ADDED
@@ -0,0 +1,1338 @@
|
|
1
|
+
AST and Source Location RFC
|
2
|
+
===========================
|
3
|
+
|
4
|
+
# Open questions:
|
5
|
+
|
6
|
+
* Should we handle these cases at all? They do not have special syntax associated.
|
7
|
+
1. How to handle lvar-injecting match (`if /(?<a>foo)/ =~ bar`)?
|
8
|
+
1. How to handle magic match (`foo if /bar/`)?
|
9
|
+
1. How to handle sed-like flip-flop?
|
10
|
+
1. How to handle awk-like flip-flop?
|
11
|
+
|
12
|
+
## Literals
|
13
|
+
|
14
|
+
### Singletons
|
15
|
+
|
16
|
+
Format:
|
17
|
+
```
|
18
|
+
(true)
|
19
|
+
"true"
|
20
|
+
~~~~ expression
|
21
|
+
|
22
|
+
(false)
|
23
|
+
"false"
|
24
|
+
~~~~~ expression
|
25
|
+
|
26
|
+
(nil)
|
27
|
+
"nil"
|
28
|
+
~~~ expression
|
29
|
+
```
|
30
|
+
|
31
|
+
### Integer
|
32
|
+
|
33
|
+
Format:
|
34
|
+
```
|
35
|
+
(int 123)
|
36
|
+
"123"
|
37
|
+
~~~ expression
|
38
|
+
```
|
39
|
+
|
40
|
+
### Float
|
41
|
+
|
42
|
+
Format:
|
43
|
+
```
|
44
|
+
(float 1.0)
|
45
|
+
"1.0"
|
46
|
+
~~~ expression
|
47
|
+
```
|
48
|
+
|
49
|
+
### String
|
50
|
+
|
51
|
+
#### Plain
|
52
|
+
|
53
|
+
Format:
|
54
|
+
```
|
55
|
+
(str "foo")
|
56
|
+
"'foo'"
|
57
|
+
^ begin
|
58
|
+
^ end
|
59
|
+
~~~~~ expresion
|
60
|
+
```
|
61
|
+
|
62
|
+
#### With interpolation
|
63
|
+
|
64
|
+
Format:
|
65
|
+
```
|
66
|
+
(dstr (str "foo") (lvar bar) (str "baz"))
|
67
|
+
'"foo#{bar}baz"'
|
68
|
+
^ begin ^ end
|
69
|
+
~~~~~~~~~~~~~~ expression
|
70
|
+
```
|
71
|
+
|
72
|
+
### Symbol
|
73
|
+
|
74
|
+
#### Plain
|
75
|
+
|
76
|
+
Format:
|
77
|
+
```
|
78
|
+
(sym :foo)
|
79
|
+
":foo"
|
80
|
+
~~~~ expresion
|
81
|
+
|
82
|
+
":'foo'"
|
83
|
+
^ begin
|
84
|
+
^ end
|
85
|
+
~~~~~~ expression
|
86
|
+
```
|
87
|
+
|
88
|
+
#### With interpolation
|
89
|
+
|
90
|
+
Format:
|
91
|
+
```
|
92
|
+
(dsym (str "foo") (lvar bar) (str "baz"))
|
93
|
+
':"foo#{bar}baz"'
|
94
|
+
^ begin ^ end
|
95
|
+
~~~~~~~~~~~~~~~ expression
|
96
|
+
```
|
97
|
+
|
98
|
+
### Execute-string
|
99
|
+
|
100
|
+
Format:
|
101
|
+
```
|
102
|
+
(xstr (str "foo") (lvar bar))
|
103
|
+
"`foo#{bar}`"
|
104
|
+
^ begin ^ end
|
105
|
+
~~~~~~~~~~~ expression
|
106
|
+
```
|
107
|
+
|
108
|
+
### Regexp
|
109
|
+
|
110
|
+
#### Options
|
111
|
+
|
112
|
+
Format:
|
113
|
+
```
|
114
|
+
(regopt :i :m)
|
115
|
+
"im"
|
116
|
+
~~ expression
|
117
|
+
```
|
118
|
+
|
119
|
+
#### Regexp
|
120
|
+
|
121
|
+
Format:
|
122
|
+
```
|
123
|
+
(regexp (str "foo") (lvar :bar) (regopt :i))
|
124
|
+
"/foo#{bar}/i"
|
125
|
+
^ begin ^ end
|
126
|
+
~~~~~~~~~~~ expression
|
127
|
+
```
|
128
|
+
|
129
|
+
### Array
|
130
|
+
|
131
|
+
#### Plain
|
132
|
+
|
133
|
+
Format:
|
134
|
+
```
|
135
|
+
(array (int 1) (int 2))
|
136
|
+
|
137
|
+
"[1, 2]"
|
138
|
+
~~~~~~ expression
|
139
|
+
```
|
140
|
+
|
141
|
+
#### Splat
|
142
|
+
|
143
|
+
Can also be used in argument lists: `foo(bar, *baz)`
|
144
|
+
|
145
|
+
Format:
|
146
|
+
```
|
147
|
+
(splat (lvar :foo))
|
148
|
+
"*foo"
|
149
|
+
^ operator
|
150
|
+
~~~~ expression
|
151
|
+
```
|
152
|
+
|
153
|
+
#### With interpolation
|
154
|
+
|
155
|
+
Format:
|
156
|
+
```
|
157
|
+
(array (int 1) (splat (lvar :foo)) (int 2))
|
158
|
+
|
159
|
+
"[1, *foo, 2]"
|
160
|
+
^ begin ^ end
|
161
|
+
~~~~~~~~~~~~ expression
|
162
|
+
```
|
163
|
+
|
164
|
+
### Hash
|
165
|
+
|
166
|
+
#### Pair
|
167
|
+
|
168
|
+
##### With hashrocket
|
169
|
+
|
170
|
+
Format:
|
171
|
+
```
|
172
|
+
(pair (int 1) (int 2))
|
173
|
+
"1 => 2"
|
174
|
+
~~ operator
|
175
|
+
~~~~~~ expression
|
176
|
+
```
|
177
|
+
|
178
|
+
##### With label (1.9)
|
179
|
+
|
180
|
+
Format:
|
181
|
+
```
|
182
|
+
(pair (sym :answer) (int 42))
|
183
|
+
"answer: 42"
|
184
|
+
^ operator (pair)
|
185
|
+
~~~~~~ expression (sym)
|
186
|
+
~~~~~~~~~~ expression (pair)
|
187
|
+
```
|
188
|
+
|
189
|
+
#### Plain
|
190
|
+
|
191
|
+
Format:
|
192
|
+
```
|
193
|
+
(hash (pair (int 1) (int 2)) (pair (int 3) (int 4)))
|
194
|
+
"{1 => 2, 3 => 4}"
|
195
|
+
^ begin ^ end
|
196
|
+
~~~~~~~~~~~~~~~~ expression
|
197
|
+
```
|
198
|
+
|
199
|
+
#### Keyword splat (2.0)
|
200
|
+
|
201
|
+
Can also be used in argument lists: `foo(bar, **baz)`
|
202
|
+
|
203
|
+
Format:
|
204
|
+
```
|
205
|
+
(kwsplat (lvar :foo))
|
206
|
+
"**foo"
|
207
|
+
~~ operator
|
208
|
+
~~~~~ expression
|
209
|
+
```
|
210
|
+
|
211
|
+
#### With interpolation (2.0)
|
212
|
+
|
213
|
+
Format:
|
214
|
+
```
|
215
|
+
(hash (pair (sym :foo) (int 2)) (kwsplat (lvar :bar)))
|
216
|
+
"{ foo: 2, **bar }"
|
217
|
+
^ begin ^ end
|
218
|
+
~~~~~~~~~~~~~~~~~ expression
|
219
|
+
```
|
220
|
+
|
221
|
+
### Range
|
222
|
+
|
223
|
+
#### Inclusive
|
224
|
+
|
225
|
+
Format:
|
226
|
+
```
|
227
|
+
(irange (int 1) (int 2))
|
228
|
+
"1..2"
|
229
|
+
~~ operator
|
230
|
+
~~~~ expression
|
231
|
+
```
|
232
|
+
|
233
|
+
#### Exclusive
|
234
|
+
|
235
|
+
Format:
|
236
|
+
```
|
237
|
+
(erange (int 1) (int 2))
|
238
|
+
"1...2"
|
239
|
+
~~~ operator
|
240
|
+
~~~~~ expression
|
241
|
+
```
|
242
|
+
|
243
|
+
## Access
|
244
|
+
|
245
|
+
### Self
|
246
|
+
|
247
|
+
Format:
|
248
|
+
```
|
249
|
+
(self)
|
250
|
+
"self"
|
251
|
+
~~~~ expression
|
252
|
+
```
|
253
|
+
|
254
|
+
### Local variable
|
255
|
+
|
256
|
+
Format:
|
257
|
+
```
|
258
|
+
(lvar :foo)
|
259
|
+
"foo"
|
260
|
+
~~~ expression
|
261
|
+
```
|
262
|
+
|
263
|
+
### Instance variable
|
264
|
+
|
265
|
+
Format:
|
266
|
+
```
|
267
|
+
(ivar :@foo)
|
268
|
+
"@foo"
|
269
|
+
~~~~ expression
|
270
|
+
```
|
271
|
+
|
272
|
+
### Class variable
|
273
|
+
|
274
|
+
Format:
|
275
|
+
```
|
276
|
+
(cvar :$foo)
|
277
|
+
"$foo"
|
278
|
+
~~~~ expression
|
279
|
+
```
|
280
|
+
|
281
|
+
### Global variable
|
282
|
+
|
283
|
+
Format:
|
284
|
+
```
|
285
|
+
(gvar :$foo)
|
286
|
+
"$foo"
|
287
|
+
~~~~ expression
|
288
|
+
```
|
289
|
+
|
290
|
+
### Constant
|
291
|
+
|
292
|
+
#### Top-level constant
|
293
|
+
|
294
|
+
Format:
|
295
|
+
```
|
296
|
+
(const (cbase) :Foo)
|
297
|
+
"::Foo"
|
298
|
+
~~~ name
|
299
|
+
~~~~~ expression
|
300
|
+
```
|
301
|
+
|
302
|
+
#### Scoped constant
|
303
|
+
|
304
|
+
Format:
|
305
|
+
```
|
306
|
+
(const (lvar :a) :Foo)
|
307
|
+
"a::Foo"
|
308
|
+
~~~ name
|
309
|
+
~~~~~~ expression
|
310
|
+
```
|
311
|
+
|
312
|
+
#### Unscoped constant
|
313
|
+
|
314
|
+
Format:
|
315
|
+
```
|
316
|
+
(const nil :Foo)
|
317
|
+
"Foo"
|
318
|
+
~~~ name
|
319
|
+
~~~ expression
|
320
|
+
```
|
321
|
+
|
322
|
+
### defined?
|
323
|
+
|
324
|
+
Format:
|
325
|
+
```
|
326
|
+
(defined? (lvar :a))
|
327
|
+
"defined? a"
|
328
|
+
~~~~~~~~ keyword
|
329
|
+
~~~~~~~~~~ expression
|
330
|
+
|
331
|
+
"defined?(a)"
|
332
|
+
~~~~~~~~ keyword
|
333
|
+
^ begin
|
334
|
+
^ end
|
335
|
+
~~~~~~~~~~~ expression
|
336
|
+
```
|
337
|
+
|
338
|
+
## Assignment
|
339
|
+
|
340
|
+
### To local variable
|
341
|
+
|
342
|
+
Format:
|
343
|
+
```
|
344
|
+
(lvasgn :foo (lvar :bar))
|
345
|
+
"foo = bar"
|
346
|
+
^ operator
|
347
|
+
~~~~~~~~~ expression
|
348
|
+
```
|
349
|
+
|
350
|
+
### To instance variable
|
351
|
+
|
352
|
+
Format:
|
353
|
+
```
|
354
|
+
(ivasgn :@foo (lvar :bar))
|
355
|
+
"@foo = bar"
|
356
|
+
^ operator
|
357
|
+
~~~~~~~~~~ expression
|
358
|
+
```
|
359
|
+
|
360
|
+
### To class variable
|
361
|
+
|
362
|
+
#### Inside a class scope
|
363
|
+
|
364
|
+
Format:
|
365
|
+
```
|
366
|
+
(cvdecl :@@foo (lvar :bar))
|
367
|
+
"@@foo = bar"
|
368
|
+
^ operator
|
369
|
+
~~~~~~~~~~~ expression
|
370
|
+
```
|
371
|
+
|
372
|
+
#### Inside a method scope
|
373
|
+
|
374
|
+
Format:
|
375
|
+
```
|
376
|
+
(cvasgn :@@foo (lvar :bar))
|
377
|
+
"@@foo = bar"
|
378
|
+
^ operator
|
379
|
+
~~~~~~~~~~~ expression
|
380
|
+
```
|
381
|
+
|
382
|
+
### To global variable
|
383
|
+
|
384
|
+
Format:
|
385
|
+
```
|
386
|
+
(gvasgn :$foo (lvar :bar))
|
387
|
+
"$foo = bar"
|
388
|
+
^ operator
|
389
|
+
~~~~~~~~~~ expression
|
390
|
+
```
|
391
|
+
|
392
|
+
### To constant
|
393
|
+
|
394
|
+
#### Top-level constant
|
395
|
+
|
396
|
+
Format:
|
397
|
+
```
|
398
|
+
(cdecl (cbase) :Foo (int 1))
|
399
|
+
"::Foo = 1"
|
400
|
+
~~~ name
|
401
|
+
~ operator
|
402
|
+
~~~~~~~ expression
|
403
|
+
```
|
404
|
+
|
405
|
+
#### Scoped constant
|
406
|
+
|
407
|
+
Format:
|
408
|
+
```
|
409
|
+
(cdecl (lvar :a) :Foo (int 1))
|
410
|
+
"a::Foo = 1"
|
411
|
+
~~~ name
|
412
|
+
~ operator
|
413
|
+
~~~~~~~~ expression
|
414
|
+
```
|
415
|
+
|
416
|
+
#### Unscoped constant
|
417
|
+
|
418
|
+
Format:
|
419
|
+
```
|
420
|
+
(cdecl nil :Foo (int 1))
|
421
|
+
"Foo = 1"
|
422
|
+
~~~ name
|
423
|
+
~ operator
|
424
|
+
~~~~~~~ expression
|
425
|
+
```
|
426
|
+
|
427
|
+
|
428
|
+
### Multiple assignment
|
429
|
+
|
430
|
+
#### Multiple left hand side
|
431
|
+
|
432
|
+
Format:
|
433
|
+
```
|
434
|
+
(mlhs (lvasgn :a) (lvasgn :b))
|
435
|
+
"a, b"
|
436
|
+
~~~~ expression
|
437
|
+
"(a, b)"
|
438
|
+
^ begin
|
439
|
+
^ end
|
440
|
+
~~~~~~ expression
|
441
|
+
```
|
442
|
+
|
443
|
+
#### Assignment
|
444
|
+
|
445
|
+
Rule of thumb: every node inside `(mlhs)` is "incomplete"; to make
|
446
|
+
it "complete", one could imagine that a corresponding node from the
|
447
|
+
mrhs is "appended" to the node in question. This applies both to
|
448
|
+
side-effect free assignments (`lvasgn`, etc) and side-effectful
|
449
|
+
assignments (`send`).
|
450
|
+
|
451
|
+
Format:
|
452
|
+
```
|
453
|
+
(masgn (mlhs (lvasgn :foo) (lvasgn :bar)) (array (int 1) (int 2)))
|
454
|
+
"foo, bar = 1, 2"
|
455
|
+
^ operator
|
456
|
+
~~~~~~~~~~~~~~~ expression
|
457
|
+
|
458
|
+
(masgn (mlhs (ivasgn :@a) (cvasgn :@@b)) (array (splat (lvar :c))))
|
459
|
+
"@a, @@b = *c"
|
460
|
+
|
461
|
+
(masgn (mlhs (mlhs (lvasgn :a) (lvasgn :b)) (lvasgn :c)) (lvar :d))
|
462
|
+
"a, (b, c) = d"
|
463
|
+
|
464
|
+
(masgn (mlhs (send (self) :a=) (send (self) :[]= (int 1))) (lvar :a))
|
465
|
+
"self.a, self[1] = a"
|
466
|
+
```
|
467
|
+
|
468
|
+
### Binary operator-assignment
|
469
|
+
|
470
|
+
Binary operator-assignment features the same "incomplete assignments" and "incomplete calls" as [multiple assignment](#assignment-1).
|
471
|
+
|
472
|
+
#### Variable binary operator-assignment
|
473
|
+
|
474
|
+
Format:
|
475
|
+
```
|
476
|
+
(op-asgn (lvasgn :a) :+ (int 1))
|
477
|
+
"a += 1"
|
478
|
+
~~ operator
|
479
|
+
~~~~~~ expression
|
480
|
+
|
481
|
+
(op-asgn (ivasgn :a) :+ (int 1))
|
482
|
+
"@a += 1"
|
483
|
+
```
|
484
|
+
|
485
|
+
Ruby_parser output for reference:
|
486
|
+
```
|
487
|
+
"a += 1"
|
488
|
+
s(:lasgn, :a, s(:call, s(:lvar, :a), :+, s(:int, 1)))
|
489
|
+
|
490
|
+
"@a += 1"
|
491
|
+
s(:iasgn, :@a, s(:call, s(:ivar, :@a), :+, s(:int, 1)))
|
492
|
+
```
|
493
|
+
|
494
|
+
#### Method binary operator-assignment
|
495
|
+
|
496
|
+
Format:
|
497
|
+
```
|
498
|
+
(op-asgn (send (ivar :@a) :b) :+ (int 1))
|
499
|
+
"@a.b += 1"
|
500
|
+
~ selector (send)
|
501
|
+
~~~~ expression (send)
|
502
|
+
~~ operator (op-asgn)
|
503
|
+
~~~~~~~~~ expression (op-asgn)
|
504
|
+
|
505
|
+
(op-asgn (send (ivar :@a) :[] (int 0) (int 1))) :+ (int 1))
|
506
|
+
"@a[0, 1] += 1"
|
507
|
+
~~~~~~ selector (send)
|
508
|
+
~~~~~~~~ expression (send)
|
509
|
+
~~ operator (op-asgn)
|
510
|
+
~~~~~~~~~~~~~ expression (op-asgn)
|
511
|
+
```
|
512
|
+
|
513
|
+
Ruby_parser output for reference:
|
514
|
+
```
|
515
|
+
"@a.b += 1"
|
516
|
+
s(:op_asgn2, s(:ivar, :@a), :b=, :+, s(:int, 1))
|
517
|
+
|
518
|
+
"@a[0, 1] += 1"
|
519
|
+
s(:op_asgn1, s(:ivar, :@a), s(:arglist, s(:int, 0), s(:int, 1)), :+, s(:int, 1))
|
520
|
+
```
|
521
|
+
|
522
|
+
### Logical operator-assignment
|
523
|
+
|
524
|
+
Logical operator-assignment features the same "incomplete assignments" and "incomplete calls" as [multiple assignment](#assignment-1).
|
525
|
+
|
526
|
+
#### Variable logical operator-assignment
|
527
|
+
|
528
|
+
Format:
|
529
|
+
```
|
530
|
+
(or-asgn (iasgn :@a) (int 1))
|
531
|
+
"@a ||= 1"
|
532
|
+
~~~ operator
|
533
|
+
~~~~~~~~ expression
|
534
|
+
|
535
|
+
(and-asgn (lasgn :a) (int 1))
|
536
|
+
"a &&= 1"
|
537
|
+
~~~ operator
|
538
|
+
~~~~~~~ expression
|
539
|
+
```
|
540
|
+
|
541
|
+
Ruby_parser output for reference:
|
542
|
+
```
|
543
|
+
"@a ||= 1"
|
544
|
+
s(:op_asgn_or, s(:ivar, :@a), s(:iasgn, :@a, s(:int, 1)))
|
545
|
+
|
546
|
+
"a &&= 1"
|
547
|
+
s(:op_asgn_and, s(:lvar, :a), s(:lasgn, :a, s(:int, 1)))
|
548
|
+
```
|
549
|
+
|
550
|
+
#### Method logical operator-assignment
|
551
|
+
|
552
|
+
Format:
|
553
|
+
```
|
554
|
+
(or-asgn (send (ivar :@foo) :bar) (int 1))
|
555
|
+
"@foo.bar ||= 1"
|
556
|
+
~~~ selector (send)
|
557
|
+
~~~~~~~~ expr (send)
|
558
|
+
~~~ operator (or-asgn)
|
559
|
+
~~~~~~~~~~~~~~ expression (or-asgn)
|
560
|
+
|
561
|
+
(and-asgn (send (lvar :@foo) :bar) (int 1))
|
562
|
+
"foo.bar &&= 1"
|
563
|
+
~~~ selector (send)
|
564
|
+
~~~~~~~ expr (send)
|
565
|
+
~~~ operator (and-asgn)
|
566
|
+
~~~~~~~~~~~~~ expression (and-asgn)
|
567
|
+
|
568
|
+
(or-asgn (send (ivar :@foo) :[] (int 1) (int 2)) (int 1))
|
569
|
+
"@foo[1, 2] ||= 1"
|
570
|
+
~~~~~~ selector (send)
|
571
|
+
~~~~~~~~~~ expr (send)
|
572
|
+
~~~ operator (or-asgn)
|
573
|
+
~~~~~~~~~~~~~~~~ expression (or-asgn)
|
574
|
+
|
575
|
+
```
|
576
|
+
|
577
|
+
Ruby_parser output for reference:
|
578
|
+
```
|
579
|
+
"@foo.bar &&= 1"
|
580
|
+
s(:op_asgn2, s(:ivar, :@foo), :bar=, :"&&", s(:int, 1))
|
581
|
+
|
582
|
+
"@foo[0] ||= 1"
|
583
|
+
s(:op_asgn1, s(:ivar, :@foo), s(:arglist, s(:int, 0)), :"||", s(:int, 1))
|
584
|
+
|
585
|
+
```
|
586
|
+
|
587
|
+
## Class and module definition
|
588
|
+
|
589
|
+
### Module
|
590
|
+
|
591
|
+
Format:
|
592
|
+
```
|
593
|
+
(module (const nil :Foo) (begin))
|
594
|
+
"module Foo; end"
|
595
|
+
~~~~~~ keyword
|
596
|
+
~~~ end
|
597
|
+
```
|
598
|
+
|
599
|
+
### Class
|
600
|
+
|
601
|
+
Format:
|
602
|
+
```
|
603
|
+
(class (const nil :Foo) (const nil :Bar) (begin))
|
604
|
+
"class Foo < Bar; end"
|
605
|
+
~~~~~ keyword ~~~ end
|
606
|
+
|
607
|
+
(class (const nil :Foo) nil (begin))
|
608
|
+
"class Foo; end"
|
609
|
+
~~~~~ keyword
|
610
|
+
~~~ end
|
611
|
+
```
|
612
|
+
|
613
|
+
### Singleton class
|
614
|
+
|
615
|
+
Format:
|
616
|
+
```
|
617
|
+
(sclass (lvar :a) (begin))
|
618
|
+
"class << a; end"
|
619
|
+
~~~~~ keyword
|
620
|
+
~~ operator
|
621
|
+
~~~ end
|
622
|
+
```
|
623
|
+
|
624
|
+
## Method (un)definition
|
625
|
+
|
626
|
+
### Instance methods
|
627
|
+
|
628
|
+
Format:
|
629
|
+
```
|
630
|
+
(def :foo (args) nil)
|
631
|
+
"def foo; end"
|
632
|
+
~~~ keyword
|
633
|
+
~~~ name
|
634
|
+
~~~ end
|
635
|
+
~~~~~~~~~~~~ expression
|
636
|
+
```
|
637
|
+
|
638
|
+
### Singleton methods
|
639
|
+
|
640
|
+
Format:
|
641
|
+
```
|
642
|
+
(defs (self) (args) nil)
|
643
|
+
"def self.foo; end"
|
644
|
+
~~~ keyword
|
645
|
+
~~~ name
|
646
|
+
~~~ end
|
647
|
+
~~~~~~~~~~~~~~~~~ expression
|
648
|
+
```
|
649
|
+
|
650
|
+
### Undefinition
|
651
|
+
|
652
|
+
Format:
|
653
|
+
```
|
654
|
+
(undef (sym :foo) (sym :bar) (dsym (str "foo") (int 1)))
|
655
|
+
"undef foo :bar :"foo#{1}""
|
656
|
+
~~~~~ keyword
|
657
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
658
|
+
```
|
659
|
+
|
660
|
+
## Aliasing
|
661
|
+
|
662
|
+
### Method aliasing
|
663
|
+
|
664
|
+
Format:
|
665
|
+
```
|
666
|
+
(alias (sym :foo) (dsym (str "foo") (int 1)))
|
667
|
+
"alias foo :"foo#{1}""
|
668
|
+
~~~~~ keyword
|
669
|
+
~~~~~~~~~~~~~~~~~~~~ expression
|
670
|
+
```
|
671
|
+
|
672
|
+
### Global variable aliasing
|
673
|
+
|
674
|
+
Format:
|
675
|
+
```
|
676
|
+
(alias (gvar :$foo) (gvar :$bar))
|
677
|
+
"alias $foo $bar"
|
678
|
+
~~~~~ keyword
|
679
|
+
~~~~~~~~~~~~~~~ expression
|
680
|
+
|
681
|
+
(alias (gvar :$foo) (back-ref :$&))
|
682
|
+
"alias $foo $&"
|
683
|
+
~~~~~ keyword
|
684
|
+
~~~~~~~~~~~~~~~ expression
|
685
|
+
```
|
686
|
+
|
687
|
+
## Formal arguments
|
688
|
+
|
689
|
+
Format:
|
690
|
+
```
|
691
|
+
(args (arg :foo))
|
692
|
+
"(foo)"
|
693
|
+
~~~~~ expression
|
694
|
+
```
|
695
|
+
|
696
|
+
### Required argument
|
697
|
+
|
698
|
+
Format:
|
699
|
+
```
|
700
|
+
(arg :foo)
|
701
|
+
"foo"
|
702
|
+
~~~ expression
|
703
|
+
~~~ name
|
704
|
+
```
|
705
|
+
|
706
|
+
### Optional argument
|
707
|
+
|
708
|
+
Format:
|
709
|
+
```
|
710
|
+
(optarg :foo (int 1))
|
711
|
+
"foo = 1"
|
712
|
+
~~~~~~~ expression
|
713
|
+
^ operator
|
714
|
+
~~~ name
|
715
|
+
```
|
716
|
+
|
717
|
+
### Named splat argument
|
718
|
+
|
719
|
+
Format:
|
720
|
+
```
|
721
|
+
(splatarg :foo)
|
722
|
+
"*foo"
|
723
|
+
~~~~ expression
|
724
|
+
~~~ name
|
725
|
+
```
|
726
|
+
|
727
|
+
Begin of the `expression` points to `*`.
|
728
|
+
|
729
|
+
### Unnamed splat argument
|
730
|
+
|
731
|
+
Format:
|
732
|
+
```
|
733
|
+
(splatarg)
|
734
|
+
"*"
|
735
|
+
^ expression
|
736
|
+
```
|
737
|
+
|
738
|
+
### Block argument
|
739
|
+
|
740
|
+
Format:
|
741
|
+
```
|
742
|
+
(blockarg :foo)
|
743
|
+
"&foo"
|
744
|
+
~~~ name
|
745
|
+
~~~~ expression
|
746
|
+
```
|
747
|
+
|
748
|
+
Begin of the `expression` points to `&`.
|
749
|
+
|
750
|
+
### Ruby 1.8 expression arguments
|
751
|
+
|
752
|
+
Ruby 1.8 allows to use arbitrary expressions as block arguments,
|
753
|
+
such as `@var` or `foo.bar`. Such expressions should be treated as
|
754
|
+
if they were on the lhs of a multiple assignment.
|
755
|
+
|
756
|
+
Format:
|
757
|
+
```
|
758
|
+
(args (arg_expr (ivasgn :@bar)))
|
759
|
+
"|@bar|"
|
760
|
+
|
761
|
+
(args (arg_expr (send (send nil :foo) :a=)))
|
762
|
+
"|foo.a|"
|
763
|
+
|
764
|
+
(args (splatarg_expr (ivasgn :@bar)))
|
765
|
+
"|*@bar|"
|
766
|
+
|
767
|
+
(args (blockarg_expr (ivasgn :@bar)))
|
768
|
+
"|&@bar|"
|
769
|
+
```
|
770
|
+
|
771
|
+
### Ruby 1.9 and later block shadow arguments
|
772
|
+
|
773
|
+
Format:
|
774
|
+
```
|
775
|
+
(args (shadowarg :foo) (shadowarg :bar))
|
776
|
+
"|; foo, bar|"
|
777
|
+
```
|
778
|
+
|
779
|
+
### Decomposition
|
780
|
+
|
781
|
+
Format:
|
782
|
+
```
|
783
|
+
(def :f (args (arg :a) (mlhs (arg :foo) (splatarg :bar))))
|
784
|
+
"def f(a, (foo, *bar)); end"
|
785
|
+
^ begin ^ end
|
786
|
+
~~~~~~~~~~~ expression
|
787
|
+
```
|
788
|
+
|
789
|
+
### Keyword argument
|
790
|
+
|
791
|
+
Format:
|
792
|
+
```
|
793
|
+
(kwoptarg :foo (int 1))
|
794
|
+
"foo: 1"
|
795
|
+
~~~~~~ expression
|
796
|
+
~~~~ name
|
797
|
+
```
|
798
|
+
|
799
|
+
### Named keyword splat argument
|
800
|
+
|
801
|
+
Format:
|
802
|
+
```
|
803
|
+
(kwsplat :foo)
|
804
|
+
"**foo"
|
805
|
+
~~~~~ expression
|
806
|
+
~~~ name
|
807
|
+
```
|
808
|
+
|
809
|
+
### Unnamed keyword splat argument
|
810
|
+
|
811
|
+
Format:
|
812
|
+
```
|
813
|
+
(kwsplat)
|
814
|
+
"**"
|
815
|
+
~~ expression
|
816
|
+
```
|
817
|
+
|
818
|
+
## Send
|
819
|
+
|
820
|
+
### To self
|
821
|
+
|
822
|
+
Format:
|
823
|
+
```
|
824
|
+
(send nil :foo (lvar :bar))
|
825
|
+
"foo(bar)"
|
826
|
+
~~~ selector
|
827
|
+
~~~~~~~~ expression
|
828
|
+
```
|
829
|
+
|
830
|
+
### To receiver
|
831
|
+
|
832
|
+
Format:
|
833
|
+
```
|
834
|
+
(send (lvar :foo) :bar (int 1))
|
835
|
+
"foo.bar(1)"
|
836
|
+
~~~ selector
|
837
|
+
~~~~~~~~~~ expression
|
838
|
+
|
839
|
+
(send (lvar :foo) :+ (int 1))
|
840
|
+
"foo + 1"
|
841
|
+
^ selector
|
842
|
+
~~~~~~~ expression
|
843
|
+
|
844
|
+
(send (lvar :foo) :-@)
|
845
|
+
"-foo"
|
846
|
+
^ selector
|
847
|
+
~~~~ expression
|
848
|
+
|
849
|
+
(send (lvar :foo) :a= (int 1))
|
850
|
+
"foo.a = 1"
|
851
|
+
~~~ selector
|
852
|
+
^ operator
|
853
|
+
~~~~~~~~~ expression
|
854
|
+
|
855
|
+
(send (lvar :foo) :[] (int 1))
|
856
|
+
"foo[i]"
|
857
|
+
~~~ selector
|
858
|
+
^ begin
|
859
|
+
^ end
|
860
|
+
~~~~~~ expression
|
861
|
+
|
862
|
+
(send (lvar :bar) :[]= (int 1) (int 2) (lvar :baz))
|
863
|
+
"bar[1, 2] = baz"
|
864
|
+
~~~~~~~~ selector
|
865
|
+
^ begin
|
866
|
+
^ end
|
867
|
+
^ operator
|
868
|
+
~~~~~~~~~~~~~~~ expression
|
869
|
+
|
870
|
+
```
|
871
|
+
|
872
|
+
### To superclass
|
873
|
+
|
874
|
+
Format of super with arguments:
|
875
|
+
```
|
876
|
+
(super (lvar :a))
|
877
|
+
"super a"
|
878
|
+
~~~~~ keyword
|
879
|
+
~~~~~~~ expression
|
880
|
+
|
881
|
+
(super)
|
882
|
+
"super()"
|
883
|
+
^ begin
|
884
|
+
^ end
|
885
|
+
~~~~~ keyword
|
886
|
+
~~~~~~~ expression
|
887
|
+
```
|
888
|
+
|
889
|
+
Format of super without arguments (**z**ero-arity):
|
890
|
+
```
|
891
|
+
(zsuper)
|
892
|
+
"super"
|
893
|
+
~~~~~ keyword
|
894
|
+
~~~~~ expression
|
895
|
+
```
|
896
|
+
|
897
|
+
### To block argument
|
898
|
+
|
899
|
+
Format:
|
900
|
+
```
|
901
|
+
(yield (lvar :foo))
|
902
|
+
"yield(foo)"
|
903
|
+
~~~~~ keyword
|
904
|
+
^ begin
|
905
|
+
^ end
|
906
|
+
~~~~~~~~~~ expression
|
907
|
+
```
|
908
|
+
|
909
|
+
### Passing a literal block
|
910
|
+
|
911
|
+
```
|
912
|
+
(block (send nil :foo) (args (arg :bar)) (begin ...))
|
913
|
+
"foo do |bar|; end"
|
914
|
+
~~ begin
|
915
|
+
~~~ end
|
916
|
+
~~~~~~~~~~~~~ expression
|
917
|
+
```
|
918
|
+
|
919
|
+
### Passing expression as block
|
920
|
+
|
921
|
+
Used when passing expression as block `foo(&bar)`
|
922
|
+
|
923
|
+
```
|
924
|
+
(send nil :foo (int 1) (block-pass (lvar :foo)))
|
925
|
+
"foo(1, &foo)"
|
926
|
+
^ operator
|
927
|
+
~~~~ expression
|
928
|
+
```
|
929
|
+
|
930
|
+
## Control flow
|
931
|
+
|
932
|
+
### Logical operators
|
933
|
+
|
934
|
+
#### Binary (and or && ||)
|
935
|
+
|
936
|
+
Format:
|
937
|
+
```
|
938
|
+
(and (lvar :foo) (lvar :bar))
|
939
|
+
"foo and bar"
|
940
|
+
~~~ operator
|
941
|
+
~~~~~~~~~~~ expression
|
942
|
+
```
|
943
|
+
|
944
|
+
#### Unary (! not) (1.8)
|
945
|
+
|
946
|
+
Format:
|
947
|
+
```
|
948
|
+
(not (lvar :foo))
|
949
|
+
"!foo"
|
950
|
+
^ operator
|
951
|
+
"not foo"
|
952
|
+
~~~ operator
|
953
|
+
```
|
954
|
+
|
955
|
+
### Branching
|
956
|
+
|
957
|
+
#### Without else
|
958
|
+
|
959
|
+
Format:
|
960
|
+
```
|
961
|
+
(if (lvar :cond) (lvar :iftrue) nil)
|
962
|
+
"if cond then iftrue; end"
|
963
|
+
~~ keyword
|
964
|
+
~~~~ begin
|
965
|
+
~~~ end
|
966
|
+
~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
967
|
+
|
968
|
+
"if cond; iftrue; end"
|
969
|
+
~~ keyword
|
970
|
+
~~~ end
|
971
|
+
~~~~~~~~~~~~~~~~~~~~ expression
|
972
|
+
|
973
|
+
"iftrue if cond"
|
974
|
+
~~ keyword
|
975
|
+
~~~~~~~~~~~~~~ expression
|
976
|
+
|
977
|
+
(if (lvar :cond) nil (lvar :iftrue))
|
978
|
+
"unless cond then iftrue; end"
|
979
|
+
~~~~~~ keyword
|
980
|
+
~~~~ begin
|
981
|
+
~~~ end
|
982
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
983
|
+
|
984
|
+
"unless cond; iftrue; end"
|
985
|
+
~~~~~~ keyword
|
986
|
+
~~~ end
|
987
|
+
~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
988
|
+
|
989
|
+
"iftrue unless cond"
|
990
|
+
~~~~~~ keyword
|
991
|
+
~~~~~~~~~~~~~~~~~~ expression
|
992
|
+
```
|
993
|
+
|
994
|
+
#### With else
|
995
|
+
|
996
|
+
Format:
|
997
|
+
```
|
998
|
+
(if (lvar :cond) (lvar :iftrue) (lvar :iffalse))
|
999
|
+
"if cond then iftrue; else; iffalse; end"
|
1000
|
+
~~ keyword
|
1001
|
+
~~~~ begin
|
1002
|
+
~~~~ else
|
1003
|
+
~~~ end
|
1004
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
1005
|
+
|
1006
|
+
"if cond; iftrue; else; iffalse; end"
|
1007
|
+
~~ keyword
|
1008
|
+
~~~~ else
|
1009
|
+
~~~ end
|
1010
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
1011
|
+
|
1012
|
+
(if (lvar :cond) (lvar :iffalse) (lvar :iftrue))
|
1013
|
+
"unless cond then iftrue; else; iffalse; end"
|
1014
|
+
~~~~~~ keyword
|
1015
|
+
~~~~ begin
|
1016
|
+
~~~~ else
|
1017
|
+
~~~ end
|
1018
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
1019
|
+
|
1020
|
+
"unless cond; iftrue; else; iffalse; end"
|
1021
|
+
~~~~~~ keyword
|
1022
|
+
~~~~ else
|
1023
|
+
~~~ end
|
1024
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
1025
|
+
```
|
1026
|
+
|
1027
|
+
#### With elsif
|
1028
|
+
|
1029
|
+
Format:
|
1030
|
+
```
|
1031
|
+
(if (lvar :cond1) (int 1) (if (lvar :cond2 (int 2) (int 3))))
|
1032
|
+
"if cond1; 1; elsif cond2; 2; else 3; end"
|
1033
|
+
~~ keyword (left)
|
1034
|
+
~~~~~ else (left)
|
1035
|
+
~~~ end (left)
|
1036
|
+
~~~~~ keyword (right)
|
1037
|
+
~~~~ else (right)
|
1038
|
+
~~~ end (right)
|
1039
|
+
```
|
1040
|
+
|
1041
|
+
#### Ternary
|
1042
|
+
|
1043
|
+
Format:
|
1044
|
+
```
|
1045
|
+
(if (lvar :cond) (lvar :iftrue) (lvar :iffalse))
|
1046
|
+
"cond ? iftrue : iffalse"
|
1047
|
+
^ question
|
1048
|
+
^ colon
|
1049
|
+
~~~~~~~~~~~~~~~~~~~~~~~ expression
|
1050
|
+
```
|
1051
|
+
|
1052
|
+
### Case matching
|
1053
|
+
|
1054
|
+
#### When clause
|
1055
|
+
|
1056
|
+
Format:
|
1057
|
+
```
|
1058
|
+
(when (regexp "foo" (regopt)) (begin (lvar :bar)))
|
1059
|
+
"when /foo/; bar"
|
1060
|
+
~~~~ keyword
|
1061
|
+
~~~~~~~~~~ expression
|
1062
|
+
|
1063
|
+
(when (int 1) (int 2) (send nil :meth))
|
1064
|
+
"when 1, 2; meth"
|
1065
|
+
|
1066
|
+
(when (int 1) (splat (lvar :foo)) (send nil :meth))
|
1067
|
+
"when 1, *foo; meth"
|
1068
|
+
|
1069
|
+
(when (splat (lvar :foo)) (send nil :meth))
|
1070
|
+
"when *foo; meth"
|
1071
|
+
```
|
1072
|
+
|
1073
|
+
#### Case-expression clause
|
1074
|
+
|
1075
|
+
##### Without else
|
1076
|
+
|
1077
|
+
Format:
|
1078
|
+
```
|
1079
|
+
(case (lvar :foo) (when (str "bar") (lvar :bar)) nil)
|
1080
|
+
"case foo; when "bar"; bar; end"
|
1081
|
+
~~~~ keyword ~~~ end
|
1082
|
+
```
|
1083
|
+
|
1084
|
+
##### With else
|
1085
|
+
|
1086
|
+
Format:
|
1087
|
+
```
|
1088
|
+
(case (lvar :foo) (when (str "bar") (lvar :bar)) (lvar :baz))
|
1089
|
+
"case foo; when "bar"; bar; else baz; end"
|
1090
|
+
~~~~ keyword ~~~~ else ~~~ end
|
1091
|
+
```
|
1092
|
+
|
1093
|
+
#### Case-conditions clause
|
1094
|
+
|
1095
|
+
##### Without else
|
1096
|
+
|
1097
|
+
Format:
|
1098
|
+
```
|
1099
|
+
(case nil (when (lvar :bar) (lvar :bar)) nil)
|
1100
|
+
"case; when bar; bar; end"
|
1101
|
+
~~~~ keyword ~~~ end
|
1102
|
+
```
|
1103
|
+
|
1104
|
+
##### With else
|
1105
|
+
|
1106
|
+
Format:
|
1107
|
+
```
|
1108
|
+
(case nil (when (lvar :bar) (lvar :bar)) (lvar :baz))
|
1109
|
+
"case; when bar; bar; else baz; end"
|
1110
|
+
~~~~ keyword ~~~~ else ~~~ end
|
1111
|
+
|
1112
|
+
(case nil (lvar :baz))
|
1113
|
+
"case; else baz; end"
|
1114
|
+
~~~~ keyword
|
1115
|
+
~~~~ else
|
1116
|
+
~~~ end
|
1117
|
+
```
|
1118
|
+
|
1119
|
+
### Looping
|
1120
|
+
|
1121
|
+
#### With precondition
|
1122
|
+
|
1123
|
+
Format:
|
1124
|
+
```
|
1125
|
+
(while (lvar :condition) (send nil :foo))
|
1126
|
+
"while condition do foo; end"
|
1127
|
+
~~~~~ keyword
|
1128
|
+
~~ begin
|
1129
|
+
~~~ end
|
1130
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
1131
|
+
|
1132
|
+
"while condition; foo; end"
|
1133
|
+
~~~~~ keyword
|
1134
|
+
~~~ end
|
1135
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
1136
|
+
|
1137
|
+
"foo while condition"
|
1138
|
+
~~~~~ keyword
|
1139
|
+
~~~~~~~~~~~~~~~~~~~ expression
|
1140
|
+
|
1141
|
+
(until (lvar :condition) (send nil :foo))
|
1142
|
+
"until condition do foo; end"
|
1143
|
+
~~~~~ keyword
|
1144
|
+
~~ begin
|
1145
|
+
~~~ end
|
1146
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
1147
|
+
|
1148
|
+
(until (lvar :condition) (send nil :foo))
|
1149
|
+
"until condition; foo; end"
|
1150
|
+
~~~~~ keyword
|
1151
|
+
~~~ end
|
1152
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~ expression
|
1153
|
+
|
1154
|
+
"foo until condition"
|
1155
|
+
~~~~~ keyword
|
1156
|
+
~~~~~~~~~~~~~~~~~~~ expression
|
1157
|
+
```
|
1158
|
+
|
1159
|
+
#### With postcondition
|
1160
|
+
|
1161
|
+
Format:
|
1162
|
+
```
|
1163
|
+
(while-post (lvar :condition) (begin (send nil :foo)))
|
1164
|
+
"begin; foo; end while condition"
|
1165
|
+
~~~~~ begin (begin)
|
1166
|
+
~~~ end (begin)
|
1167
|
+
~~~~~ keyword (while-post)
|
1168
|
+
|
1169
|
+
(until-post (lvar :condition) (begin (send nil :foo)))
|
1170
|
+
"begin; foo; end until condition"
|
1171
|
+
~~~~~ begin (begin)
|
1172
|
+
~~~ end (begin)
|
1173
|
+
~~~~~ keyword (until-post)
|
1174
|
+
```
|
1175
|
+
|
1176
|
+
#### For-in
|
1177
|
+
|
1178
|
+
Format:
|
1179
|
+
```
|
1180
|
+
(for (lasgn :a) (lvar :array) (send nil :p (lvar :a)))
|
1181
|
+
"for a in array do p a; end"
|
1182
|
+
~~~ keyword
|
1183
|
+
~~ in
|
1184
|
+
~~ begin
|
1185
|
+
~~~ end
|
1186
|
+
|
1187
|
+
"for a in array; p a; end"
|
1188
|
+
~~~ keyword
|
1189
|
+
~~ in
|
1190
|
+
~~~ end
|
1191
|
+
|
1192
|
+
(for
|
1193
|
+
(mlhs (lasgn :a) (lasgn :b)) (lvar :array)
|
1194
|
+
(send nil :p (lvar :a) (lvar :b)))
|
1195
|
+
"for a, b in array; p a, b; end"
|
1196
|
+
```
|
1197
|
+
|
1198
|
+
#### Break
|
1199
|
+
|
1200
|
+
Format:
|
1201
|
+
```
|
1202
|
+
(break (int 1))
|
1203
|
+
"break 1"
|
1204
|
+
~~~~~ keyword
|
1205
|
+
~~~~~~~ expression
|
1206
|
+
```
|
1207
|
+
|
1208
|
+
#### Next
|
1209
|
+
|
1210
|
+
Format:
|
1211
|
+
```
|
1212
|
+
(next (int 1))
|
1213
|
+
"next 1"
|
1214
|
+
~~~~ keyword
|
1215
|
+
~~~~~~ expression
|
1216
|
+
```
|
1217
|
+
|
1218
|
+
#### Redo
|
1219
|
+
|
1220
|
+
Format:
|
1221
|
+
```
|
1222
|
+
(redo)
|
1223
|
+
"redo"
|
1224
|
+
~~~~ keyword
|
1225
|
+
~~~~ expression
|
1226
|
+
```
|
1227
|
+
|
1228
|
+
### Return
|
1229
|
+
|
1230
|
+
Format:
|
1231
|
+
```
|
1232
|
+
(return (lvar :foo))
|
1233
|
+
"return(foo)"
|
1234
|
+
~~~~~~ keyword
|
1235
|
+
^ begin
|
1236
|
+
^ end
|
1237
|
+
~~~~~~~~~~~ expression
|
1238
|
+
```
|
1239
|
+
|
1240
|
+
### Exception handling
|
1241
|
+
|
1242
|
+
#### Rescue body
|
1243
|
+
|
1244
|
+
Format:
|
1245
|
+
```
|
1246
|
+
(resbody (array (const nil :Exception) (const nil :A)) (lvasgn :bar) (int 1))
|
1247
|
+
"rescue Exception, A => bar; 1"
|
1248
|
+
~~~~~~ keyword ~~ operator
|
1249
|
+
|
1250
|
+
"rescue Exception, A => bar then 1"
|
1251
|
+
~~~~~~ keyword ~~ operator
|
1252
|
+
~~~~ begin
|
1253
|
+
|
1254
|
+
(resbody (array (const nil :Exception)) (ivasgn :bar) (int 1))
|
1255
|
+
"rescue Exception => @bar; 1"
|
1256
|
+
~~~~~~ keyword ~~ operator
|
1257
|
+
|
1258
|
+
(resbody nil (lvasgn :bar) (int 1))
|
1259
|
+
"rescue => bar; 1"
|
1260
|
+
~~~~~~ keyword
|
1261
|
+
~~ operator
|
1262
|
+
|
1263
|
+
(resbody nil nil (int 1))
|
1264
|
+
"rescue; 1"
|
1265
|
+
~~~~~~ keyword
|
1266
|
+
```
|
1267
|
+
|
1268
|
+
#### Rescue statement
|
1269
|
+
|
1270
|
+
##### Without else
|
1271
|
+
|
1272
|
+
Format:
|
1273
|
+
```
|
1274
|
+
(rescue (send nil :foo) (resbody ...) (resbody ...) nil)
|
1275
|
+
"begin; foo; rescue Exception; rescue; end"
|
1276
|
+
~~~~~ begin ~~~ end
|
1277
|
+
```
|
1278
|
+
|
1279
|
+
##### With else
|
1280
|
+
|
1281
|
+
Format:
|
1282
|
+
```
|
1283
|
+
(rescue (send nil :foo) (resbody ...) (resbody ...) (true))
|
1284
|
+
"begin; foo; rescue Exception; rescue; else true end"
|
1285
|
+
~~~~~ begin ~~~~ else ~~~ end
|
1286
|
+
```
|
1287
|
+
|
1288
|
+
#### Ensure statement
|
1289
|
+
|
1290
|
+
Format:
|
1291
|
+
```
|
1292
|
+
(ensure (send nil :foo) (send nil :bar))
|
1293
|
+
"begin; foo; ensure; bar; end"
|
1294
|
+
~~~~~ begin ~~~~~~ keyword
|
1295
|
+
~~~ end
|
1296
|
+
```
|
1297
|
+
|
1298
|
+
#### Rescue with ensure
|
1299
|
+
|
1300
|
+
Format:
|
1301
|
+
```
|
1302
|
+
(ensure (rescue (send nil :foo) (resbody ...) (int 1)) (send nil :bar))
|
1303
|
+
"begin; foo; rescue; nil; else; 1; ensure; bar; end"
|
1304
|
+
~~~~~ begin (rescue)
|
1305
|
+
~~~~~ begin (ensure)
|
1306
|
+
~~~~ else (rescue)
|
1307
|
+
~~~~~~ keyword (ensure)
|
1308
|
+
~~~ end (rescue)
|
1309
|
+
~~~ end (ensure)
|
1310
|
+
```
|
1311
|
+
|
1312
|
+
#### Retry
|
1313
|
+
|
1314
|
+
Format:
|
1315
|
+
```
|
1316
|
+
(retry)
|
1317
|
+
"retry"
|
1318
|
+
~~~~~ keyword
|
1319
|
+
~~~~~ expression
|
1320
|
+
```
|
1321
|
+
|
1322
|
+
### BEGIN and END
|
1323
|
+
|
1324
|
+
Format:
|
1325
|
+
```
|
1326
|
+
(preexe (send nil :puts (str "foo")))
|
1327
|
+
"BEGIN { puts "foo" }"
|
1328
|
+
~~~~~ keyword
|
1329
|
+
^ begin ^ end
|
1330
|
+
~~~~~~~~~~~~~~~~~~~~ expression
|
1331
|
+
|
1332
|
+
(postexe (send nil :puts (str "bar")))
|
1333
|
+
"END { puts "bar" }"
|
1334
|
+
~~~ keyword
|
1335
|
+
^ begin ^ end
|
1336
|
+
~~~~~~~~~~~~~~~~~~ expression
|
1337
|
+
```
|
1338
|
+
|