Skip to content

Commit ee184fe

Browse files
committed
rubyish - line spanning of parenthesised lists; checks on '<%' .. '%>' placement
1 parent 3c7ac10 commit ee184fe

File tree

3 files changed

+73
-27
lines changed

3 files changed

+73
-27
lines changed

examples/rubyish/rubyish.nqp

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,28 @@ grammar Rubyish::Grammar is HLL::Grammar {
2929
:my $*TOP_BLOCK := $*CUR_BLOCK;
3030
:my $*CLASS_BLOCK := $*CUR_BLOCK;
3131
:my $*IN_TEMPLATE := 0;
32+
:my $*LINE_SPAN := 0;
3233
:my %*SYM := self.sym-init();
3334
^ ~ $ <stmtlist>
3435
|| <.panic('Syntax error')>
3536
}
3637

37-
rule stmt-sep { \n | ';' }
38+
rule separator { \n | ';' }
3839
token template { [<tmpl-unesc>|<tmpl-hdr>] <text=.template-content>* [<tmpl-esc>|$] }
3940
proto token template-content {*}
4041
token template-content:sym<interp> { <interp> }
4142
token template-content:sym<plain-text> { [<!before [<tmpl-esc>|'#{'|$]> .]+ }
4243

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+
}
4651

4752
rule stmtlist {
48-
[ <stmt=.stmtish>? ] *%% [<.stmt-sep>|<stmt=.template>]
53+
[ <stmt=.stmtish>? ] *%% [<.separator>|<stmt=.template>]
4954
}
5055

5156
token stmtish {
@@ -66,7 +71,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
6671

6772
rule defbody {
6873
:my $*CUR_BLOCK := QAST::Block.new(QAST::Stmts.new());
69-
<operation> <signature>? <stmt-sep>?
74+
<operation> <signature>? <separator>?
7075
<stmtlist>
7176
}
7277

@@ -91,7 +96,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
9196
rule classbody {
9297
:my $*CUR_BLOCK := QAST::Block.new(QAST::Stmts.new());
9398
:my $*CLASS_BLOCK := $*CUR_BLOCK;
94-
<ident> <stmt-sep>
99+
<ident> <separator>
95100
<stmtlist>
96101
}
97102

@@ -100,24 +105,25 @@ grammar Rubyish::Grammar is HLL::Grammar {
100105

101106
token term:sym<call> {
102107
<!keyword>
103-
<operation> ['(' ~ ')' <call-args>?
108+
<operation> ['(' ~ ')' <call-args=.paren-args>?
104109
| \h* <call-args>? <?{%*SYM{~$<operation>} eq 'def'}> ]
105110
}
106111

107112
token term:sym<nqp-op> {
108-
'nqp::'<ident> ['(' ~ ')' <call-args>? | <call-args>? ]
113+
'nqp::'<ident> ['(' ~ ')' <call-args=.paren-args>? | <call-args>? ]
109114
}
110115

111116
token term:sym<quote-words> {
112117
\% w <?before [.]> <quote_EXPR: ':q', ':w'>
113118
}
114119

115-
token call-args { :s <EXPR>+ % <comma> }
120+
token call-args { :s <EXPR>+ % <comma> }
121+
token paren-args {:my $*LINE_SPAN := 1; <call-args> }
116122

117123
token operation {<ident>[\!|\?]?}
118124

119125
token term:sym<new> {
120-
['new' \h+ :s <ident> | <ident> '.' 'new'] ['(' ~ ')' <call-args>?]?
126+
['new' \h+ :s <ident> | <ident> '.' 'new'] ['(' ~ ')' <call-args=.paren-args>?]?
121127
}
122128

123129
token var {
@@ -140,10 +146,16 @@ grammar Rubyish::Grammar is HLL::Grammar {
140146
| Q <?before [.]> <quote_EXPR: ':qq'>
141147
]
142148
}
149+
150+
token paren-list {
151+
:my $*LINE_SPAN := 1;
152+
<EXPR> *%% <comma>
153+
}
154+
143155
token value:sym<integer> { \+? \d+ }
144156
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> }
147159
token value:sym<nil> { <sym> }
148160
token value:sym<true> { <sym> }
149161
token value:sym<false> { <sym> }
@@ -167,11 +179,9 @@ grammar Rubyish::Grammar is HLL::Grammar {
167179
}
168180

169181
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]*] }
173183
token comment:sym<podish> {[^^'=begin'\n] ~ [^^'=end'\n ] .*?}
174-
token ws { <!ww> \h* | \h+ | <.comment> }
184+
token ws { <!ww>[\h | <.comment> | <?{$*LINE_SPAN}> \n]* }
175185

176186
# Operator precedence levels
177187
INIT {
@@ -244,7 +254,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
244254

245255
# Statement control
246256
rule xblock {
247-
<EXPR> [ <stmt-sep> [:s 'then']? | 'then' | <?before <tmpl-unesc>>] <stmtlist>
257+
<EXPR> [ <separator> [:s 'then']? | 'then' | <?before <tmpl-unesc>>] <stmtlist>
248258
}
249259

250260
token stmt:sym<if> {
@@ -267,7 +277,7 @@ grammar Rubyish::Grammar is HLL::Grammar {
267277
<sym> :s <ident> :s 'in' <EXPR> <do> <stmtlist> 'end'
268278
}
269279

270-
token do { <stmt-sep> [:s 'do']? | 'do' | <?before <tmpl-unesc>>}
280+
token do { <separator> [:s 'do']? | 'do' | <?before <tmpl-unesc>>}
271281

272282
token term:sym<code> {
273283
'begin' ~ 'end' <stmtlist>
@@ -378,6 +388,10 @@ class Rubyish::Actions is HLL::Actions {
378388
make $args;
379389
}
380390

391+
method paren-args($/) {
392+
make $<call-args>.ast;
393+
}
394+
381395
my $tmpsym := 0;
382396

383397
method term:sym<new>($/) {
@@ -578,23 +592,27 @@ class Rubyish::Actions is HLL::Actions {
578592
make QAST::NVal.new( :value(+$/.Str) )
579593
}
580594

581-
method value:sym<array>($/) {
582-
my $array := QAST::Op.new( :op<list> );
595+
method paren-list($/) {
596+
my @list;
583597
if $<EXPR> {
584-
$array.push($_.ast) for $<EXPR>
598+
@list.push($_.ast) for $<EXPR>
585599
}
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;
586606
make $array;
587607
}
588608

589609
method term:sym<quote-words>($/) {
590610
make $<quote_EXPR>.ast;
591611
}
592612

593-
method value:sym<hash>($/) {
613+
method value:sym<hash>($/) {
594614
my $hash := QAST::Op.new( :op<hash> );
595-
if $<EXPR> {
596-
$hash.push($_.ast) for $<EXPR>
597-
}
615+
$hash.push($_) for $<paren-list>.ast;
598616
make $hash;
599617
}
600618
method value:sym<nil>($/) {

examples/rubyish/t/line-spanning.t

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
puts "1..4"
2+
3+
a=[10,
4+
20]
5+
6+
puts "#{a[1]? 'ok' : 'nok'} 1 - array spanning lines"
7+
8+
9+
b = [30 # some comments
10+
,
11+
40
12+
13+
]
14+
puts "#{b[1]? 'ok' : 'nok'} 2 - array spanning lines"
15+
16+
h = {"a" => 10,
17+
"b"
18+
, 20
19+
, "c" => 30
20+
}
21+
puts "#{h<c>? 'ok' : 'nok'} 3 - hash spanning lines"
22+
23+
24+
puts(
25+
26+
"ok 4 - call args spanning lines"
27+
28+
)

examples/rubyish/t/template.t

100644100755
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ nok 6 - if block (true)
2020
nok 7 - if block (false)
2121
<%elsif n == 20 %>
2222
nok 7 - if block (false)
23-
<%else %>
23+
<%else%>
2424
ok 7 - if block (false)
2525
<% end %>
2626
<%for test in [8, 9] do %>

0 commit comments

Comments
 (0)