Permalink
Fetching contributors…
Cannot retrieve contributors at this time
executable file 159 lines (132 sloc) 3.46 KB
#!/usr/bin/env perl
#
# Copyright (c) 2002,2014-2015 Christian Jaeger, copying@christianjaeger.ch
#
# This is free software, offered under either the same terms as perl 5
# or the terms of the Artistic License version 2 or the terms of the
# MIT License (Expat version). See the file COPYING.md that came
# bundled with this file.
#
use strict; use warnings; use warnings FATAL => 'uninitialized';
use Cwd 'abs_path';
our ($mydir, $myname); BEGIN {
my $location= (-l $0) ? abs_path ($0) : $0;
$location=~ /(.*?)([^\/]+?)_?\z/s or die "?";
($mydir, $myname)=($1,$2);
}
use lib "$mydir/../lib";
sub usage {
print "$myname [ calculation(s) ]
Repl-Enhanced PerL
Evaluates the given string(s), or goes into interactive mode if
none given.
Interactive mode tricks:
- uses readline (read up on its features)
- entering nothing re-evaluates the last entry
- 'strict vars' is not active, so there's no need to declare new
globals with 'our'
- global variables and subroutines stay around, lexical ('my')
varibles don't
- you can refer to '\$VAR1' etc. to get the correspondin result from the
previous evaluation (as long as you're using the default ':d'
display mode)
- enter ':?' to get a list of special commands and mode switches
Options:
-t trap exceptions in a repl, too
-H|--no-history do not save history to file (it is still read on
startup.)
-M module use the given module (namespace or path)
-m module same as -M but don't complain about failures
";
exit @_;
}
use Chj::xhome qw(xsafehome);
my $HISTFILE= xsafehome."/.${myname}_history";
my $MAXHISTLEN= 100;
my @files;
my $opt_H;
my @opt_M;
my @opt_m;
my $opt_t;
for (my $i=0; $i<=$#ARGV; $i++) {
local $_=$ARGV[$i];
if (/^--?h(elp)?$/) {
usage
} elsif ($_ eq '--') {
push @files, @ARGV[$i+1..$#ARGV];
last;
} elsif ($_ eq '-H' or $_ eq '--no-history') {
$opt_H=1;
} elsif ($_ eq '-t') {
$opt_t=1;
} elsif (/^-M(.*)/) {
if ($1) {
push @opt_M,$1;
} else {
my $arg= $ARGV[++$i];
defined $arg or usage "missing argument to -M";
push @opt_M,$arg;
}
} elsif (/^-m(.*)/) {
if ($1) {
push @opt_m,$1;
} else {
my $arg= $ARGV[++$i];
defined $arg or usage "missing argument to -m";
push @opt_m,$arg;
}
} elsif (/^-/) {
warn "Unknown option '$_'\n";
usage(1)
} else {
push @files, $_
}
}
eval {
require Chj::BinHexOctDec;
};
warn $@ if $@;
use Chj::Package::OfPath qw(package_of_path_or_package);
use Chj::WithRepl qw(push_withrepl WithRepl_eval WithRepl_eval_e);
push_withrepl (0)
if $opt_t;
sub moduleoption_to_code ($) {
my ($a)=@_;
$a=~ s/([^=]+)//s
or die "invalid -M option '$_'";
my $path_or_package= $1;
my $p= package_of_path_or_package($path_or_package);
"use ".do {
if ($a=~ s/^=//s) {
$p." ".join(", ",map{"'$_'"} split /,/,$a)
} else {
$p
}
}
}
if (@opt_M) {
my $code=
join(";",
map { moduleoption_to_code $_ }
@opt_M);
&WithRepl_eval ("package $myname; "
.$code
."; 1")
or die $@;
}
for my $path_or_package (@opt_m) {
eval moduleoption_to_code $path_or_package;
}
if (@files) {
for (@files) {
my ($res,$e,$is_error)= &WithRepl_eval_e($_, $myname);
die $e if $is_error;
print "$res\n";
}
}
else {
require Chj::repl;
Chj::repl(maybe_historypath=> ($opt_H ? undef : $HISTFILE),
maxhistlen=> $MAXHISTLEN,
maybe_package=> $myname);
}