#!/usr/bin/perl -w

use Term::ReadLine;
my $term = new Term::ReadLine 'Simple Perl calc';
my $prompt = "";
my $OUT = $term->OUT || \*STDOUT;

print "Handy  (c) Petr Baudis <pasky\@ucw.cz> 2006\n";
print "Enter numbers, arithmetic expressions or any Perl expressions.\n";
print "Prefix line with 'e/' to flip endianity.\n";

sub splitbytes($)
{
	my ($val) = @_;
	my @bytes = ();
	while ($val > 0x0) {
		$bytes[$#bytes+1] = $val & 0xff;
		$val >>= 8;
	}
	reverse @bytes;
}

while ( defined ($_ = $term->readline($prompt)) ) {
	last if /^\s*quit\s*$/i;
	next if /^\s*$/;
	my $endianity = 0;
	if (s/^\s*e\///) {
		$endianity = 1;
	}
	my $res = eval($_);
	warn $@ if $@;

	my @bytes = splitbytes($res);
	if ($endianity) {
		$res = 0;
		@bytes = reverse @bytes;
		foreach my $byte (@bytes) {
			$res = ($res << 8) | $byte;
		}
	}

	my $charrep = '';
	foreach my $byte (@bytes) {
		if ($byte < 32) {
			if ($#bytes > 0) {
				# Don't lose the chars in case of multichar stuff
				$charrep .= '.';
			}
		} else {
			$charrep .= chr($byte);
		}
	}

	printf $OUT '%d  0x%x  0%o  0b%b  %s'."\n", $res, $res, $res, $res, ($charrep ? "'$charrep'" : "") unless $@;
	$term->addhistory($_) if /\S/;
}
