AI-Prolog
view release on metacpan or search on metacpan
lib/AI/Prolog/Engine/Primitives.pm view on Meta::CPAN
$PRIMITIVES[31] = sub { # help/0
_load_builtins();
if ( not $HELP_OUTPUT ) {
$HELP_OUTPUT = "Help is available for the following builtins:\n\n";
my @predicates = sort keys %DESCRIPTION_FOR;
my $length = length $LONGEST_PREDICATE;
my $columns = 5;
my $format = join ' ' => ("%-${length}s") x $columns;
while (@predicates) {
my @row;
for ( 1 .. $columns ) {
push @row => @predicates
? shift @predicates
: '';
}
$HELP_OUTPUT .= sprintf $format => @row;
$HELP_OUTPUT .= "\n";
}
$HELP_OUTPUT .= "\n";
}
AI::Prolog::Engine::_print($HELP_OUTPUT);
CONTINUE;
};
$PRIMITIVES[32] = sub { # help/1
my ( $self, $term, $c ) = @_;
my $predicate = $term->getarg(0)->to_string;
_load_builtins();
if ( my $description = $DESCRIPTION_FOR{$predicate} ) {
AI::Prolog::Engine::_print($description);
}
else {
AI::Prolog::Engine::_print("No help available for ($predicate)\n\n");
$PRIMITIVES[31]->();
}
CONTINUE;
};
my $gensym_int = 0;
$PRIMITIVES[33] = sub { # gemsym/1
my ( $self, $term, $c ) = @_;
my $t2 = Term->new( 'v' . $gensym_int++, 0 );
return $t2->unify( $term->getarg(0), $self->{_stack} )
? CONTINUE
: FAIL;
};
use constant UNDEFINED_SUBROUTINE_ERROR => do {
eval {
no strict 'refs'; ## no critic NoStrict
&{'---'};
};
my $e = $@;
# Undefined subroutine &main::--- called at .../Primitives.pm line 12.
my ($msg) = $e =~ / \A
(.+) # 'Undefined subroutine'
(?<=\s) # ' '
\S* # &main::
---/mx
or die q[Perl's error message changed! Damn! Fix this regex.];
$msg;
};
$PRIMITIVES[34] = sub { # perlcall2/2
my ( $self, $term ) = @_;
# Get a function name...
my $function_term = $term->getarg(0);
if ( not $function_term->is_bound ) {
return FAIL;
}
my $function_name = $function_term->to_string;
# Lookup a fully qualified function name...
my $function_ref;
if ( $function_name =~ /[:\']/mx ) {
$function_ref = $function_name;
}
elsif ( defined( my $package = $self->{_perlpackage} ) ) {
$function_name = "$package\::$function_name";
}
# Search the call stack...
if ( not defined $function_ref ) {
my $cx = 1;
my %packages;
CX:
while ( my $package = caller $cx ) {
# Don't retry packages...
next if exists $packages{$package};
$packages{$package} = undef;
# AUTOLOAD using packages are expected to provide a
# ->can() that works. I don't know if that's a widely
# known expectation but it's what I'm going to go
# with. Hash::AsObject gets this wrong.
if (do {
no strict 'refs'; ## no critic NoStrict
defined &{"$package\::$function_name"};
}
or $package->can($function_name)
)
{
$function_ref = "$package\::$function_name";
last CX;
}
}
continue {
++$cx;
}
}
# We got nuthin! Damn! I'll try for the first AUTOLOAD.
if ( not defined $function_ref ) {
my $cx = 1;
my %packages;
AUTOLOAD_CX:
while ( my ($package) = caller $cx ) {
( run in 1.054 second using v1.01-cache-2.11-cpan-39bf76dae61 )