use Stream qw/node drop list_to_stream/;
my @tokens = (
node( OP => '+' ),
node( VAR => 'x' ),
node( VAL => 3 )
);
my $stream = list_to_stream(@tokens);
use Data::Dumper::Simple;
while (my $node = drop($stream)) {
print Dumper($node, $stream);
}
####
$node = [ 'OP', '+' ];
$stream = [ # AoA
[ 'VAR', 'x' ],
[ 'VAL', 3 ]
];
$node = [ 'VAR', 'x' ];
$stream = [ 'VAL', 3 ]; # not AoA
$node = 'VAL';
$stream = 3; # scalar
####
my $parser = parser {
my $input = shift;
return unless defined $input;
my $next = head($input);
for my $i (0 .. $#$wanted) {
next unless defined $wanted->[$i];
return unless $wanted->[$i] eq $next->[$i];
}
my $wanted_value = $value->($next, $u);
return ($wanted_value, tail($input));
};
####
my $parser = parser {
my $input = shift;
return unless defined $input;
my $next = head($input);
for my $i (0 .. $#$wanted) {
next unless defined $wanted->[$i];
return unless $wanted->[$i] eq $next->[$i];
}
my $wanted_value = $value->($next, $u);
my $tail = tail($input);
# is this the last token from the stream?
if ($tail && 'ARRAY' eq ref $tail && 'ARRAY' ne ref $tail->[0]) {
$tail = [ $tail ];
}
return ($wanted_value, $tail);
};
####
my $parser = concatenate(
lookfor('OP'),
lookfor('VAR'),
);
my ( $parsed, $remainder ) = $parser->($stream);
is_deeply $parsed, [qw/+ x/],
'concatenate should return the parsed values';
is_deeply $remainder, [[ VAL => 3 ]], # AoA, not just an aref
'... and the rest of the stream';
####
$parser = concatenate(
lookfor('OP'),
lookfor('VAR'),
lookfor('VAL'),
);