Skip to content

Commit

Permalink
Added 'unless' 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 7674823 commit 21732ee
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 3 deletions.
2 changes: 1 addition & 1 deletion doc/LOLHALP
@@ -1,7 +1,7 @@
The below things should be fairly straightforward to implement. Just look in
the commit logs at how similar features were implemented.

* 'unless' and 'until' keywords.
* 'until' keywords.
* 'loop' keyword. (at least the infinitely looping version is easy.)
* 'repeat' keyword.
* 'ENTER', 'LEAVE', 'FIRST', 'NEXT', and 'LAST' phasers.
Expand Down
28 changes: 26 additions & 2 deletions lib/Yapsi.pm
Expand Up @@ -17,10 +17,12 @@ grammar Yapsi::Perl6::Grammar {
|| <declaration> || <block>
|| <saycall> || <increment> || <decrement> }
token statement_control { <statement_control_if>
|| <statement_control_while> }
|| <statement_control_while>
|| <statement_control_unless> }
rule statement_control_if { 'if' <expression> <block>
[ 'else' <else=.block> ]? }
rule statement_control_while { 'while' <expression> <block> }
rule statement_control_unless { 'unless' <expression> <block> }
token lvalue { <declaration> || <variable> || <increment> }
token value { <variable> || <literal> || <declaration> || <saycall>
|| <increment> }
Expand Down Expand Up @@ -118,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_while', 'statement_control_unless';
my &sicify = -> $/, $key {
if $m !=== $/ && $key eq 'block' {
my $register = self.unique-register;
Expand Down Expand Up @@ -157,6 +159,23 @@ class Yapsi::Compiler {
"`label $after-else";
}
}
elsif $key eq 'statement_control_unless' {
traverse-bottom-up(
$<expression>,
:key<expression>,
:@skip,
:action(&sicify)
);
my ($register, $) = $<expression>.ast.list;
my $block-name = $<block>.ast<name>;
my $after-unless = self.unique-label;
push @blocksic, "jt $register, $after-unless";
$register = self.unique-register;
push @blocksic,
"$register = closure-from-block '$block-name'",
"call $register";
push @blocksic, "`label $after-unless";
}
elsif $key eq 'statement_control_while' {
my $before-while = self.unique-label;
my $after-while = self.unique-label;
Expand Down Expand Up @@ -457,6 +476,11 @@ class Yapsi::Runtime {
$ip = find-label(@sic, ~$1);
}
}
when / ^ 'jt $'(\d+)', '(\S+) $ / {
if reg[+$0] != 0 {
$ip = find-label(@sic, ~$1);
}
}
when / ^ 'jmp '(\S+) $ / {
$ip = find-label(@sic, ~$0);
}
Expand Down
2 changes: 2 additions & 0 deletions t/compiler.t
Expand Up @@ -61,6 +61,8 @@ my @programs-that-don't-compile = # '
'if $a {}',
'if 42 { $a }',
'if 5 {} else { $a }',
'unless 0 { say "unless" }',
'unless $a { say $a }'
;

for @programs-that-don't-compile -> $program { # '
Expand Down
2 changes: 2 additions & 0 deletions t/runtime.t
Expand Up @@ -34,6 +34,8 @@ my @tests =
'my $a = 4; while --$a { say $a }',
"3\n2\n1\n", 'while loop',
'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',
# 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 21732ee

Please sign in to comment.