# 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

Reply via email to