Emacs-EPL
view release on metacpan or search on metacpan
lib/Emacs/EPL.pm view on Meta::CPAN
BEGIN {
# Set inlinable constants based on feature tests.
local ($@);
if (eval { require B; }) {
if (defined (&B::SVf_IOK)) {
B->import (qw( SVf_IOK SVf_NOK ));
eval ('sub HAVE_B () { 1 }');
}
else {
eval ('sub HAVE_B () { 1 }');
eval ('sub SVf_IOK () { 0x10000 }');
eval ('sub SVf_NOK () { 0x20000 }');
}
}
else {
eval ('sub HAVE_B () { 0 }');
if ($@) { eval ('sub HAVE_B { 0 }'); }
eval ('sub SVf_IOK; sub SVf_NOK;');
}
}
##################################
# Conversion of Perl data to Lisp.
##################################
# Tell whether a scalar is "really" an int, float, or string.
# The Elisp Reference Manual says that integers are 28 bits.
sub guess_lisp_type {
if (HAVE_B()) {
my $fl = B::svref_2object (\$_[0]) ->FLAGS;
if (($fl & SVf_IOK) != 0) {
return ((($_[0] + 0x8000000) & ~0xfffffff) ? 'float' : 'integer');
}
elsif (($fl & SVf_NOK) != 0) {
return ('float');
}
else {
return ('string');
}
}
else {
if ($_[0] =~ m/^-?\d+$/) {
return ((($_[0] + 0x8000000) & ~0xfffffff) ? 'float' : 'integer');
}
elsif ($_[0] =~ m/^-?\d+(?:\.\d+)(?:e-?\d+)$/) {
return ('float');
}
else {
return ('string');
}
}
}
# print_stuff (CALLBACK, VALUE)
sub print_stuff {
my $callback = shift;
# Optimize obviously non-circular cases.
if ($callback eq 'unref') {
# XXX all other callbacks take a single arg.
print( "(epl-cb-unref");
print( " $_") for @{$_[0]};
print( ")");
}
elsif (! (tied ($_[0]) || ref ($_[0]))) {
print( "(epl-cb-$callback ");
&print_recursive;
print( ")");
}
else {
print( "(epl-cb-$callback (let ((epl-x `");
# Could make pos, fixup, and seen globals.
local $$emacs {'pos'} = "epl-x";
local $$emacs {'fixup'} = '';
local $$emacs {'seen'};
&print_recursive;
print( "))$$emacs{'fixup'} epl-x))");
}
}
# Given a reference, return its package (or undef if non-blessed),
# representation type, and unique identifier.
sub get_ref_info {
# This is copied from Data::Dumper.
return (overload::StrVal ($_[0]) =~ /^(?:(.*)\=)?([^=]*)\(([^\(]*)\)$/);
}
sub get_ref_id { return ((&get_ref_info) [2]); }
sub get_ref_types { return ((&get_ref_info) [0, 1]); }
# print_recursive(VALUE)
sub print_recursive {
# Avoid unnecessary FETCH if tied.
# Avoid unnecessary string copy.
my ($ref);
if (tied ($_[0])) {
# This theoretically supports typed scalars.
if (tied ($_[0]) ->can ("PRINT_AS_LISP")) {
tied ($_[0]) ->PRINT_AS_LISP;
return;
}
my $value = $_[0];
$ref = \$value;
}
else {
$ref = \$_[0];
}
if (ref ($$ref)) {
my ($value) = @_;
my ($id, $pos);
$id = get_ref_id ($$ref);
$pos = $emacs->{'seen'}->{$id};
if (defined ($pos)) {
$emacs->{'fixup'}
.= fixup ($emacs->{'pos'}, $pos);
print( "nil");
}
else {
( run in 1.830 second using v1.01-cache-2.11-cpan-5837b0d9d2c )