@@ -41,6 +41,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
41
41
token template-chunk { [<tmpl - unesc >| <tmpl - hdr >] ~ [<tmpl - esc >| $ ] <template - nibble >* }
42
42
proto token template-nibble {* }
43
43
token template-nibble :sym <interp > { <interp > }
44
+ token template-nibble :sym <stray-tag > { [<.tmpl - unesc >| <.tmpl - hdr >] <.panic (" Stray tag, e.g. '%>' or '<?rbi?>'" )> }
44
45
token template-nibble :sym <plain-text > { [<! before [<tmpl - esc >| '#{' | $ ]> . ]+ }
45
46
46
47
token tmpl-hdr {'<?rbi?>' \h * \n ? <?{ $ * IN_TEMPLATE := 1 }> }
@@ -73,14 +74,14 @@ grammar Rubyish::Grammar is HLL::Grammar {
73
74
74
75
rule defbody {
75
76
:my $ * CUR_BLOCK := QAST::Block . new(QAST::Stmts . new());
76
- <operation > <signature >? <separator >?
77
+ <operation > [ '(' ~ ')' <signature >] ? <separator >?
77
78
<stmtlist >
78
79
}
79
80
80
81
token comma { :s [',' | '=>' ] :s }
81
82
82
83
rule signature {
83
- '(' ~ ')' [ :my $ * LINE_SPAN := 1; <param >* %% <comma >]
84
+ :my $ * LINE_SPAN := 1; <param >* %% <comma >
84
85
}
85
86
86
87
token param { <ident > }
@@ -128,6 +129,10 @@ grammar Rubyish::Grammar is HLL::Grammar {
128
129
['new' \h + :s <ident > | <ident > '.' 'new' ] ['(' ~ ')' <call - args = .paren - args >? ]?
129
130
}
130
131
132
+ token term :sym <lambda-call > {
133
+ <ident > '.' 'call' ['(' ~ ')' <call - args = .paren - args >? ]?
134
+ }
135
+
131
136
token var {
132
137
:my $ * MAYBE_DECL := 0;
133
138
[$ < sigil > =[\$ | \@\@? ]| <!keyword >]
@@ -183,7 +188,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
183
188
proto token comment {* }
184
189
token comment :sym <line > { '#' [<?{ ! $ * IN_TEMPLATE }> \N * || [<! before <tmpl - unesc >>\N ]* ] }
185
190
token comment :sym <podish > {[^^ '=begin' \n ] ~ [^^ '=end' \n ] .*? }
186
- token ws { <!ww >[\h | <.comment > | <.continuation > | <?{ $ * LINE_SPAN }> \n ]* }
191
+ token ws { <!ww > [\h | <.comment > | <.continuation > | <?{ $ * LINE_SPAN }> \n ]* }
187
192
188
193
# Operator precedence levels
189
194
INIT {
@@ -288,7 +293,10 @@ grammar Rubyish::Grammar is HLL::Grammar {
288
293
289
294
token term :sym <code > {
290
295
'begin' ~ 'end' <stmtlist >
291
- | '{' ~ '}' <stmtlist >
296
+ }
297
+
298
+ token term :sym <lambda > {
299
+ 'lambda' :s ['{' ['|' ~ '|' <signature >]? ] ~ '}' <stmtlist >
292
300
}
293
301
294
302
method builtin-init () {
@@ -442,6 +450,17 @@ class Rubyish::Actions is HLL::Actions {
442
450
);
443
451
}
444
452
453
+ method term :sym <lambda-call >($/ ) {
454
+ my $ call := QAST ::Op. new ( : op<call >,
455
+ : name(~ $ < ident > ),
456
+ );
457
+ if $ < call-args > {
458
+ $ call . push ($ _ )
459
+ for $ < call-args > . ast;
460
+ }
461
+ make $ call ;
462
+ }
463
+
445
464
method var ($/ ) {
446
465
my $ sigil := ~ $ < sigil > // ' ' ;
447
466
my $ name := $ sigil ~ $ < ident > ;
@@ -507,6 +526,12 @@ class Rubyish::Actions is HLL::Actions {
507
526
508
527
method defbody ($/ ) {
509
528
$ * CUR_BLOCK . name (~ $ < operation > );
529
+ if $ < signature > {
530
+ for $ < signature > . ast {
531
+ $ * CUR_BLOCK [0 ]. push ($ _ );
532
+ $ * CUR_BLOCK . symbol($ _ . name , : declared(1 ));
533
+ }
534
+ }
510
535
$ * CUR_BLOCK . push ($ < stmtlist > . ast);
511
536
if $ * IN_CLASS {
512
537
# it's a method, self will be automatically passed
@@ -520,12 +545,13 @@ class Rubyish::Actions is HLL::Actions {
520
545
}
521
546
522
547
method signature ($/ ) {
548
+ my @ params ;
523
549
for $ < param > {
524
- $ * CUR_BLOCK [ 0 ] . push (QAST ::Var. new (
550
+ @ params . push (QAST ::Var. new (
525
551
: name(~ $ _ ), : scope(' lexical' ), : decl(' param' )
526
552
));
527
- $ * CUR_BLOCK . symbol(~ $ _ , : declared(1 ));
528
553
}
554
+ make @ params ;
529
555
}
530
556
531
557
method stmt :sym <class >($/ ) {
@@ -566,7 +592,6 @@ class Rubyish::Actions is HLL::Actions {
566
592
method stmt :sym <EXPR >($/ ) { make $ < EXPR > . ast; }
567
593
568
594
method term :sym <assign >($/ ) {
569
- my $ sym := ~ $ < OPER > ;
570
595
my $ op := $ < OPER >< O >< op > ;
571
596
make QAST ::Op. new ( : op(' bind' ),
572
597
$ < var > . ast,
@@ -621,6 +646,7 @@ class Rubyish::Actions is HLL::Actions {
621
646
$ hash . push ($ _ ) for $ < paren-list > . ast;
622
647
make $ hash ;
623
648
}
649
+
624
650
method value :sym <nil >($/ ) {
625
651
make QAST ::Op. new ( : op<null > );
626
652
}
@@ -630,7 +656,7 @@ class Rubyish::Actions is HLL::Actions {
630
656
}
631
657
632
658
method value :sym <false >($/ ) {
633
- make QAST ::IVal. new (0 );
659
+ make QAST ::IVal. new ( : value< 0 > );
634
660
}
635
661
636
662
method interp ($/ ) { make $ < stmt > . ast }
@@ -699,6 +725,21 @@ class Rubyish::Actions is HLL::Actions {
699
725
make $ < stmtlist > . ast;
700
726
}
701
727
728
+ method term :sym <lambda >($/ ) {
729
+ my $ block := QAST ::Block. new ();
730
+ if $ < signature > {
731
+ for $ < signature > . ast {
732
+ $ block . push ($ _ );
733
+ $ block . symbol($ _ . name , : declared(1 ));
734
+ }
735
+ }
736
+ $ block . push ($ < stmtlist > . ast);
737
+
738
+ make QAST ::Op. new (: op<takeclosure >,
739
+ $ block ,
740
+ );
741
+ }
742
+
702
743
}
703
744
704
745
class Rubyish::Compiler is HLL::Compiler {
0 commit comments