
package Text::Wigwam::Engine::Fusion::Core;

    use strict;
    use warnings;
    use integer;
    our $VERSION = '0.01';

#    use Text::Wigwam::Const qw( ANY STRING NUM VAR );
    use Text::Wigwam::Engine::Fusion::Const(q/:all/);

    use constant PSTACK => 0; # Program counter stack location
    use constant ISTACK => 1; # Init address stack location
    use constant TOKENZ => 2; # Token zero

sub new {
    my ($class) = @_;
    return bless [
        [ TOKENZ ], # Program counter stack
        [],         # Init address stack
    ], ref($class) || $class;
}

sub set_init_addr {
    my ($self, @iaddr) = @_;
    push( @{$self->[ISTACK]}, @iaddr );
}

sub get_init_addr {
    my ($self) = @_;
    return wantarray
           ? @{$self->[ISTACK]}
           : shift @{$self->[ISTACK]}
    ;
}

sub add_tokens {
    my ($self, @tokens) = @_;
    push( @$self => @tokens );
    return wantarray ? @tokens : $tokens[0];
}

sub stack_addr { scalar @{$_[0]} }

sub curr_addr {
    my ($self, $addr) = @_;
    return
        $addr ? $self->[PSTACK][0] = $addr
              : $self->[PSTACK][0]
}
sub next_token { return $_[0]->[ ++$_[0]->[PSTACK][0] ] }
sub curr_token {
    my ($self) = @_;
    return $self->[ $self->[PSTACK][0] ]
}
sub token_zero { TOKENZ }
sub temp_addr {
    my ($self, $addr) = @_;
     # $addr will never be zero because TOKENZ is > 0
     # so we can assume a false value means undef, thus
     # we pop the stack rather than push $addr onto it.
    $addr ? unshift( @{$self->[PSTACK]}, $addr )
          : shift @{$self->[PSTACK]}
    ;
    return;
}
sub token_count { return scalar @{$_[0]} - TOKENZ }

1;

