The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!perl
#
# This file is part of Language::Befunge.
# Copyright (c) 2001-2009 Jerome Quelin, all rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself.
#
#

# -- stack of stack operations

use strict;
use warnings;

use Test::More tests => 4;
use Test::Output;

use Language::Befunge;
my $bef = Language::Befunge->new;


# the big fat one
$bef->store_code( <<'END_OF_CODE' );
123 2 { ... 3 { .... 0 { 3 .. 987 01- { . 3 u ... 4 u .. v
0u... 456 02- u 56 04- u 163 2 } .......   2 01-u 2 }  v >
..  4 01- u 0 } .. 004 03-u 02- } .. q                 >
END_OF_CODE
my $exp = "";
# (6,0) { new, >0, enough
#   * bef: ( [1 2 3 2] )      Storage (0,0)
#   * aft: ( [2 3] [1 0 0] )  Storage (7,0)
$exp .= "3 2 0 ";
# (14,0) { new, >0, not enough
#   * bef: ( [3] [1 0 0] )            Storage (7,0)
#   * aft: ( [0 0 0] [7 0] [1 0 0] )  Storage (15,0)
$exp .= "0 0 0 0 ";
# (23,0) { new, =0
#   * bef: ( [0] [7 0] [1 0 0] )        Storage (15,0)
#   * aft: ( [] [15 0] [7 0] [1 0 0] )  Storage (24,0)
$exp .= "3 0 ";
# (37,0) { new, <0
#   * bef: ( [9 8 7 -1] [15 0] [7 0] [1 0 0] )        Storage (24,0)
#   * aft: ( [] [9 8 7 0 24 0] [15 0] [7 0] [1 0 0] ) Storage (38,0)
$exp .= "0 ";
# (44,0) u transfer, >0, enough
#   * bef: ( [3] [9 8 7 0 24 0] [15 0] [7 0] [1 0 0] ) Storage (38,0)
#   * aft: ( [0 24 0] [9 8 7] [15 0] [7 0] [1 0 0] )
$exp .= "0 24 0 ";
# (51,0) u transfer, >0, not enough
#   * bef: ( [6] [9 8 7] [15 0] [7 0] [1 0 0] )  Storage (38,0)
#   * aft: ( [7 8 9 0] [] [15 0] [7 0] [1 0 0] )
$exp .= "0 9 ";
# (1,1) u transfer, =0
#   * bef: ( [7 8 0] [] [15 0] [7 0] [1 0 0] ) Storage (38,0)
#   * aft: ( [7 8] [] [15 0] [7 0] [1 0 0] )
$exp .= "8 7 0 ";
# (14,1) u transfer, <0, enough
#   * bef: ( [4 5 6 -2] [] [15 0] [7 0] [1 0 0] ) Storage (38,0)
#   * aft: ( [4] [6 5] [15 0] [7 0] [1 0 0] )
# (23,1) u transfer, <0, not enough
#   * bef: ( [4 5 6 -4] [6 5] [15 0] [7 0] [1 0 0] ) Storage (38,0)
#   * aft: ( [] [6 5 6 5 4 0] [15 0] [7 0] [1 0 0] )
# (31,1) } destroy, >0, enough
#   * bef: ( [1 6 3 2] [6 5 6 5 4 0] [15 0] [7 0] [1 0 0] ) Storage (38,0)
#   * aft: ( [6 5 6 5 6 3] [15 0] [7 0] [1 0 0] )           Storage (4,0)
$exp .= "3 6 5 6 5 6 0 ";
# (52,1) } destroy, >0, not enough
#   * bef: ( [2] [15 0 2] [7 0] [1 0 0] ) Storage (4,0)
#   * aft: ( [] [7 0] [1 0 0] )         Storage (0,2)
$exp .= "0 0 ";
# (14,2) } destroy, =0
#   * bef: ( [0] [7 0 4] [1 0 0] ) Storage (0,2)
#   * aft: ( [7] [1 0 0] )         Storage (0,4)
$exp .= "7 0 ";
# (32,2) } destroy, <0
#   * bef: ( [-2] [1 0 0 4 0 0] ) Storage (0,4)
#   * aft: ( [1 0] )          Storage (0,0)
$exp .= "0 1 ";
stdout_is { $bef->run_code } $exp, 'stack of stack operations';


# checking storage offset
$bef->store_code( <<'END_OF_CODE' );
0      {  01+a*1+a*8+ 11p v
    q.2                   <
         >  1.q
END_OF_CODE
stdout_is { $bef->run_code } '1 ', 'new storage offset';
$bef->store_code( <<'END_OF_CODE' );
0      { 22+ 0 } 01+a*1+a*8+ 61p v
 q.2                             <
      >  1.q
END_OF_CODE
stdout_is { $bef->run_code } '1 ', 'retrieving old storage offset';


# checking invalid end-of-block.
$bef->store_code( <<'END_OF_CODE' );
   #v  } 2.q
    > 1.q
END_OF_CODE
stdout_is { $bef->run_code } '1 ', 'invalid end of block';