@@ -29,23 +29,28 @@ grammar Rubyish::Grammar is HLL::Grammar {
29
29
:my $ * TOP_BLOCK := $ * CUR_BLOCK ;
30
30
:my $ * CLASS_BLOCK := $ * CUR_BLOCK ;
31
31
:my $ * IN_TEMPLATE := 0;
32
+ :my $ * LINE_SPAN := 0;
32
33
:my % * SYM := self. sym-init();
33
34
^ ~ $ <stmtlist >
34
35
|| <.panic (' Syntax error' )>
35
36
}
36
37
37
- rule stmt-sep { \n | ';' }
38
+ rule separator { \n | ';' }
38
39
token template { [<tmpl - unesc >| <tmpl - hdr >] <text = .template - content >* [<tmpl - esc >| $ ] }
39
40
proto token template-content {* }
40
41
token template-content :sym <interp > { <interp > }
41
42
token template-content :sym <plain-text > { [<! before [<tmpl - esc >| '#{' | $ ]> . ]+ }
42
43
43
- token tmpl-hdr { '<%rbi>' \h * \n ? <?{ $ * IN_TEMPLATE := 1 }> }
44
- token tmpl-esc {\h * '<%' }
45
- token tmpl-unesc { '%>' \h * \n ? }
44
+ token tmpl-hdr {'<%rbi>' \h * \n ? <?{ $ * IN_TEMPLATE := 1 }> }
45
+ token tmpl-esc {\h * '<%'
46
+ [<?{ $ * IN_TEMPLATE }> || <.panic (' Template directive precedes "<%rbi>"' )>]
47
+ }
48
+ token tmpl-unesc { '%>' \h * \n ?
49
+ [<?{ $ * IN_TEMPLATE }> || <.panic (' Template directive precedes "<%rbi>"' )>]
50
+ }
46
51
47
52
rule stmtlist {
48
- [ <stmt = .stmtish >? ] *%% [<.stmt - sep >| <stmt = .template >]
53
+ [ <stmt = .stmtish >? ] *%% [<.separator >| <stmt = .template >]
49
54
}
50
55
51
56
token stmtish {
@@ -66,7 +71,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
66
71
67
72
rule defbody {
68
73
:my $ * CUR_BLOCK := QAST::Block . new(QAST::Stmts . new());
69
- <operation > <signature >? <stmt - sep >?
74
+ <operation > <signature >? <separator >?
70
75
<stmtlist >
71
76
}
72
77
@@ -91,7 +96,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
91
96
rule classbody {
92
97
:my $ * CUR_BLOCK := QAST::Block . new(QAST::Stmts . new());
93
98
:my $ * CLASS_BLOCK := $ * CUR_BLOCK ;
94
- <ident > <stmt - sep >
99
+ <ident > <separator >
95
100
<stmtlist >
96
101
}
97
102
@@ -100,24 +105,25 @@ grammar Rubyish::Grammar is HLL::Grammar {
100
105
101
106
token term :sym <call > {
102
107
<!keyword >
103
- <operation > ['(' ~ ')' <call - args >?
108
+ <operation > ['(' ~ ')' <call - args = .paren - args >?
104
109
| \h * <call - args >? <?{ % * SYM {~ $ < operation > } eq ' def' }> ]
105
110
}
106
111
107
112
token term :sym <nqp-op > {
108
- 'nqp::' <ident > ['(' ~ ')' <call - args >? | <call - args >? ]
113
+ 'nqp::' <ident > ['(' ~ ')' <call - args = .paren - args >? | <call - args >? ]
109
114
}
110
115
111
116
token term :sym <quote-words > {
112
117
\% w <? before [. ]> <quote_EXPR : ':q' , ':w' >
113
118
}
114
119
115
- token call-args { :s <EXPR >+ % <comma > }
120
+ token call-args { :s <EXPR >+ % <comma > }
121
+ token paren-args {:my $ * LINE_SPAN := 1; <call - args > }
116
122
117
123
token operation {<ident >[\!| \? ]? }
118
124
119
125
token term :sym <new > {
120
- ['new' \h + :s <ident > | <ident > '.' 'new' ] ['(' ~ ')' <call - args >? ]?
126
+ ['new' \h + :s <ident > | <ident > '.' 'new' ] ['(' ~ ')' <call - args = .paren - args >? ]?
121
127
}
122
128
123
129
token var {
@@ -140,10 +146,16 @@ grammar Rubyish::Grammar is HLL::Grammar {
140
146
| Q <? before [. ]> <quote_EXPR : ':qq' >
141
147
]
142
148
}
149
+
150
+ token paren-list {
151
+ :my $ * LINE_SPAN := 1;
152
+ <EXPR > *%% <comma >
153
+ }
154
+
143
155
token value :sym <integer > { \+? \d + }
144
156
token value :sym <float > { \+? \d + '.' \d + }
145
- token value :sym <array > { '[' ~ ']' [< EXPR > *%% < comma >] }
146
- token value :sym <hash > { '{' ~ '}' [< EXPR > *%% < comma >] }
157
+ token value :sym <array > {'[' ~ ']' < paren - list > }
158
+ token value :sym <hash > {'{' ~ '}' < paren - list > }
147
159
token value :sym <nil > { <sym > }
148
160
token value :sym <true > { <sym > }
149
161
token value :sym <false > { <sym > }
@@ -167,11 +179,9 @@ grammar Rubyish::Grammar is HLL::Grammar {
167
179
}
168
180
169
181
proto token comment {* }
170
- token comment :sym <code > { '#' <?{ ! $ * IN_TEMPLATE }> \N * }
171
- # in a template directive: <%# .... %>
172
- token comment :sym <templ > { '#' <?{ $ * IN_TEMPLATE }> [<! before '%>' >\N ]* }
182
+ token comment :sym <line > { '#' [<?{ ! $ * IN_TEMPLATE }> \N * || [<! before '%>' >\N ]* ] }
173
183
token comment :sym <podish > {[^^ '=begin' \n ] ~ [^^ '=end' \n ] .*? }
174
- token ws { <!ww > \h * | \h + | <.comment > }
184
+ token ws { <!ww >[ \h | < .comment > | <?{ $ * LINE_SPAN }> \n ] * }
175
185
176
186
# Operator precedence levels
177
187
INIT {
@@ -244,7 +254,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
244
254
245
255
# Statement control
246
256
rule xblock {
247
- <EXPR > [ <stmt - sep > [:s 'then' ]? | 'then' | <? before <tmpl - unesc >>] <stmtlist >
257
+ <EXPR > [ <separator > [:s 'then' ]? | 'then' | <? before <tmpl - unesc >>] <stmtlist >
248
258
}
249
259
250
260
token stmt :sym <if > {
@@ -267,7 +277,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
267
277
<sym > :s <ident > :s 'in' <EXPR > <do > <stmtlist > 'end'
268
278
}
269
279
270
- token do { <stmt - sep > [:s 'do' ]? | 'do' | <? before <tmpl - unesc >>}
280
+ token do { <separator > [:s 'do' ]? | 'do' | <? before <tmpl - unesc >>}
271
281
272
282
token term :sym <code > {
273
283
'begin' ~ 'end' <stmtlist >
@@ -378,6 +388,10 @@ class Rubyish::Actions is HLL::Actions {
378
388
make $ args ;
379
389
}
380
390
391
+ method paren-args ($/ ) {
392
+ make $ < call-args > . ast;
393
+ }
394
+
381
395
my $ tmpsym := 0 ;
382
396
383
397
method term :sym <new >($/ ) {
@@ -578,23 +592,27 @@ class Rubyish::Actions is HLL::Actions {
578
592
make QAST ::NVal. new ( : value(+ $/ . Str ) )
579
593
}
580
594
581
- method value : sym < array > ($/ ) {
582
- my $ array := QAST ::Op . new ( : op< list > ) ;
595
+ method paren-list ($/ ) {
596
+ my @ list ;
583
597
if $ < EXPR > {
584
- $ array . push ($ _ . ast) for $ < EXPR >
598
+ @ list . push ($ _ . ast) for $ < EXPR >
585
599
}
600
+ make @ list ;
601
+ }
602
+
603
+ method value :sym <array >($/ ) {
604
+ my $ array := QAST ::Op. new ( : op<list > );
605
+ $ array . push ($ _ ) for $ < paren-list > . ast;
586
606
make $ array ;
587
607
}
588
608
589
609
method term :sym <quote-words >($/ ) {
590
610
make $ < quote_EXPR > . ast;
591
611
}
592
612
593
- method value :sym <hash >($/ ) {
613
+ method value :sym <hash >($/ ) {
594
614
my $ hash := QAST ::Op. new ( : op<hash > );
595
- if $ < EXPR > {
596
- $ hash . push ($ _ . ast) for $ < EXPR >
597
- }
615
+ $ hash . push ($ _ ) for $ < paren-list > . ast;
598
616
make $ hash ;
599
617
}
600
618
method value :sym <nil >($/ ) {
0 commit comments