Skip to content

Commit

Permalink
added 'until' keyword.
Browse files Browse the repository at this point in the history
  • Loading branch information
s-h-r-i committed Aug 31, 2010
1 parent 21732ee commit 515246f
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 8 deletions.
1 change: 0 additions & 1 deletion doc/LOLHALP
@@ -1,7 +1,6 @@
The below things should be fairly straightforward to implement. Just look in
the commit logs at how similar features were implemented.

* 'until' keywords.
* 'loop' keyword. (at least the infinitely looping version is easy.)
* 'repeat' keyword.
* 'ENTER', 'LEAVE', 'FIRST', 'NEXT', and 'LAST' phasers.
Expand Down
17 changes: 12 additions & 5 deletions lib/Yapsi.pm
Expand Up @@ -17,11 +17,11 @@ grammar Yapsi::Perl6::Grammar {
|| <declaration> || <block>
|| <saycall> || <increment> || <decrement> }
token statement_control { <statement_control_if>
|| <statement_control_while>
|| <statement_control_while_until>
|| <statement_control_unless> }
rule statement_control_if { 'if' <expression> <block>
[ 'else' <else=.block> ]? }
rule statement_control_while { 'while' <expression> <block> }
rule statement_control_while_until { $<keyword>=[ 'while' | 'until' ] <expression> <block> }
rule statement_control_unless { 'unless' <expression> <block> }
token lvalue { <declaration> || <variable> || <increment> }
token value { <variable> || <literal> || <declaration> || <saycall>
Expand Down Expand Up @@ -120,7 +120,7 @@ class Yapsi::Compiler {
my $*c = 0; # unique register counter
my $*l = 0; # unique label counter
my @skip = 'block', 'statement_control_if',
'statement_control_while', 'statement_control_unless';
'statement_control_while_until', 'statement_control_unless';
my &sicify = -> $/, $key {
if $m !=== $/ && $key eq 'block' {
my $register = self.unique-register;
Expand Down Expand Up @@ -176,7 +176,7 @@ class Yapsi::Compiler {
"call $register";
push @blocksic, "`label $after-unless";
}
elsif $key eq 'statement_control_while' {
elsif $key eq 'statement_control_while_until' {
my $before-while = self.unique-label;
my $after-while = self.unique-label;
push @blocksic, "`label $before-while";
Expand All @@ -187,7 +187,14 @@ class Yapsi::Compiler {
:action(&sicify)
);
my ($register, $) = $<expression>.ast.list;
push @blocksic, "jf $register, $after-while";
given $<keyword> {
when / while / {
push @blocksic, "jf $register, $after-while";
}
when / until / {
push @blocksic, "jt $register, $after-while";
}
}
my $block-name = $<block>.ast<name>;
$register = self.unique-register;
push @blocksic,
Expand Down
7 changes: 5 additions & 2 deletions t/compiler.t
Expand Up @@ -31,6 +31,9 @@ my @programs-that-compile =
'my $a; if $a {}',
'if my $a {} else { say 42 }',
'my $a; while $a { say $a }',
'unless 0 { say 42 }',
'my $a=0; unless $a { say $a }',
'my $a=0; until $a { say 42; ++$a; }',
;

sub escape($string) { $string.subst("\n", "\\n", :g) }
Expand Down Expand Up @@ -61,8 +64,8 @@ my @programs-that-don't-compile = # '
'if $a {}',
'if 42 { $a }',
'if 5 {} else { $a }',
'unless 0 { say "unless" }',
'unless $a { say $a }'
'unless {} ',
'unless a {} ',
;

for @programs-that-don't-compile -> $program { # '
Expand Down
2 changes: 2 additions & 0 deletions t/runtime.t
Expand Up @@ -36,6 +36,8 @@ my @tests =
'my $a; while $a { say 42 }', "", 'non-executing while loop',
'my $a = 42;unless $a { say 24 }', "", 'non-executing unless block',
'unless 0 { say 42 }', "42\n", 'executing unless block',
'my $a=0; until $a { say 42; ++$a; }',"42\n", 'executing until loop structure',
'until 42 { say 24; }' , "", 'non-executing until loop structure',
# TODO -- Need to "instantiate" lexpads from some kind of "proto-lexpads"
# 'my $a = 3; while --$a { say my $b; $b = 42 }', "Any()\nAny()\n",
# 'each time a block is entered, it gets a fresh lexical pad',
Expand Down

0 comments on commit 515246f

Please sign in to comment.