PPI::Token::Number - Token class for a number


PPI documentation Contained in the PPI distribution.

Index


Code Index:

NAME

Top

PPI::Token::Number - Token class for a number

SYNOPSIS

Top

  $n = 1234;       # decimal integer
  $n = 0b1110011;  # binary integer
  $n = 01234;      # octal integer
  $n = 0x1234;     # hexadecimal integer
  $n = 12.34e-56;  # exponential notation ( currently not working )

INHERITANCE

Top

  PPI::Token::Number
  isa PPI::Token
      isa PPI::Element

DESCRIPTION

Top

The PPI::Token::Number class is used for tokens that represent numbers, in the various types that Perl supports.

METHODS

Top

base

The base method is provided by all of the ::Number subclasses. This is 10 for decimal, 16 for hexadecimal, 2 for binary, etc.

literal

Return the numeric value of this token.

CAVEATS

Top

Compared to Perl, the number tokenizer is too liberal about allowing underscores anywhere. For example, the following is a syntax error in Perl, but is allowed in PPI:

   0_b10

TO DO

Top

- Treat v-strings as binary strings or barewords, not as "base-256" numbers

- Break out decimal integers into their own subclass?

- Implement literal()

SUPPORT

Top

See the support section in the main module.

AUTHOR

Top

Adam Kennedy <adamk@cpan.org>

COPYRIGHT

Top


PPI documentation Contained in the PPI distribution.
package PPI::Token::Number;

use strict;
use PPI::Token ();

use vars qw{$VERSION @ISA};
BEGIN {
	$VERSION = '1.215';
	@ISA     = 'PPI::Token';
}

sub base {
	return 10;
}

sub literal {
	return 0 + $_[0]->_literal;
}

sub _literal {
	# De-sugar the string representation
	my $self   = shift;
	my $string = $self->content;
	$string =~ s/^\+//;
	$string =~ s/_//g;
	return $string;
}





#####################################################################
# Tokenizer Methods

sub __TOKENIZER__on_char {
	my $class = shift;
	my $t     = shift;
	my $char  = substr( $t->{line}, $t->{line_cursor}, 1 );

	# Allow underscores straight through
	return 1 if $char eq '_';

	# Handle the conversion from an unknown to known type.
	# The regex covers "potential" hex/bin/octal number.
	my $token = $t->{token};
	if ( $token->{content} =~ /^-?0_*$/ ) {
		# This could be special
		if ( $char eq 'x' ) {
			$t->{class} = $t->{token}->set_class( 'Number::Hex' );
			return 1;
		} elsif ( $char eq 'b' ) {
			$t->{class} = $t->{token}->set_class( 'Number::Binary' );
			return 1;
		} elsif ( $char =~ /\d/ ) {
			# You cannot have 8s and 9s on octals
			if ( $char eq '8' or $char eq '9' ) {
				$token->{_error} = "Illegal character in octal number '$char'";
			}
			$t->{class} = $t->{token}->set_class( 'Number::Octal' );
			return 1;
		}
	}

	# Handle the easy case, integer or real.
	return 1 if $char =~ /\d/o;

	if ( $char eq '.' ) {
		$t->{class} = $t->{token}->set_class( 'Number::Float' );
		return 1;
	}
	if ( $char eq 'e' || $char eq 'E' ) {
		$t->{class} = $t->{token}->set_class( 'Number::Exp' );
		return 1;
	}

	# Doesn't fit a special case, or is after the end of the token
	# End of token.
	$t->_finalize_token->__TOKENIZER__on_char( $t );
}

1;