# New Ticket Created by Stuart Jansen
# Please include the string: [perl #49810]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=49810 >
The lolcode 1.2 spec states: "All variable scope, as of this version, is local
to the enclosing function or to the main program block." And further: "IT's
value remains in local scope and exists until the next time it is replaced with
a bare expression." In other words, IT is lexical, not package.
All functions should return a value. If they don't explicitly return a value
("GTFO" or "FOUND YR"), they should return the local value of IT.
---
languages/lolcode/src/parser/actions.pm | 17 +++++++++---
languages/lolcode/t/02-functions.t | 45 ++++++++++++++++++++++++++++++-
2 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/languages/lolcode/src/parser/actions.pm b/languages/lolcode/src/parser/actions.pm
index 1ab265a..37870a7 100644
--- a/languages/lolcode/src/parser/actions.pm
+++ b/languages/lolcode/src/parser/actions.pm
@@ -18,13 +18,16 @@ value of the comment is passed as the second argument to the method.
class lolcode::Grammar::Actions;
method TOP($/) {
- make $( $<block> );
+ my $block := $( $<block> );
+ my $it := PAST::Var.new( :name( 'IT' ), :scope('lexical'), :viviself('Undef'), :isdecl(1));
+ $block.unshift($it);
+ make $block;
}
method statement ($/, $key) {
if ($key eq 'bare_expression') {
- my $it := PAST::Var.new( :name( 'IT' ), :scope('package'), :viviself('Undef'));
+ my $it := PAST::Var.new( :name( 'IT' ), :scope('lexical'), :viviself('Undef'));
my $past := PAST::Op.new( :pasttype('bind'), :node( $/ ) );
$past.push( $it );
$past.push( $( $<expression> ) );
@@ -81,6 +84,12 @@ method function($/) {
}
}
+ my $it := PAST::Var.new( :name( 'IT' ), :scope('lexical'), :viviself('Undef'), :isdecl(1));
+ $block.unshift($it);
+
+ $it := PAST::Var.new( :name( 'IT' ), :scope('lexical'));
+ $block.push($it);
+
my $past := PAST::Op.new( :pasttype('bind'), :node( $/ ) );
$($<variable>).isdecl(1);
$past.push( $( $<variable> ) );
@@ -116,7 +125,7 @@ method ifthen($/) {
:node( $/ )
);
}
- my $it := PAST::Var.new( :name( 'IT' ), :scope('package'), :viviself('Undef'));
+ my $it := PAST::Var.new( :name( 'IT' ), :scope('lexical'), :viviself('Undef'));
$past.unshift( $it );
my $bind := PAST::Op.new( :pasttype('bind'), :node( $/ ) );
$bind.push( $it );
@@ -174,7 +183,7 @@ method identifier($/) {
method variable ($/) {
if ($<identifier><name> eq 'IT') {
- make PAST::Var.new( :name( 'IT' ), :scope('package'), :viviself('Undef'));
+ make PAST::Var.new( :name( 'IT' ), :scope('lexical'), :viviself('Undef'));
} else {
make PAST::Var.new( :name( ~$<identifier><name> ),
:scope('lexical'),
diff --git a/languages/lolcode/t/02-functions.t b/languages/lolcode/t/02-functions.t
index 1a55131..5f79118 100644
--- a/languages/lolcode/t/02-functions.t
+++ b/languages/lolcode/t/02-functions.t
@@ -1,5 +1,10 @@
HAI 1.2
- VISIBLE "1..1"
+ VISIBLE "1..9"
+
+ OBTW
+ Function names in this file conform to RFC 3092.
+ http://www.faqs.org/rfcs/rfc3092.html
+ TLDR
BTW SANITY CHECK
HOW DUZ I foo
@@ -8,5 +13,43 @@ HAI 1.2
foo
+ BTW FUNCTIONS SHOULD RETURN IT
+ HOW DUZ I bar
+ "ok 3"
+ VISIBLE "ok 2"
+ IF U SAY SO
+
+ VISIBLE bar
+
+ BTW FUNCTIONS SHOULD ONLY BE EVALUATED ONCE
+ HOW DUZ I baz
+ "ok 5"
+ VISIBLE "ok 4"
+ IF U SAY SO
+
+ I HAS A RESULT ITZ baz
+
+ VISIBLE RESULT
+
+ BTW VARIABLES SHOULD BE LOCAL TO A FUNCTION
+ HOW DUZ I qux
+ I HAS A VAR ITZ "nok 7"
+ VISIBLE "ok 6"
+ IF U SAY SO
+
+ I HAS A VAR ITZ "ok 7"
+ qux
+ VISIBLE VAR
+
+ BTW IT SHOULD ALSO BE LOCAL TO A FUNCTION
+ HOW DUZ I quux
+ "nok 9"
+ VISIBLE "ok 8"
+ IF U SAY SO
+
+ "ok 9"
+ VAR R quux
+ VISIBLE IT
+
BTW vim: set filetype=lolcode :
KTHXBYE