Files
memex/projects/repl-tool/repl
Amr Gharbeia 18b289dff8 fix: tool bugs found in review audit
repl:  env var was dead code (hardcoded 2s), empty frame gave misleading error
check-tangle: show full SBCL output on compile failure, not filtered
verify-repl: blacklist now configurable via VERIFY_REPL_EXCLUDE env var;
  regex tightened to ';; +REPL-VERIFIED:' from ';;.REPL.VERIFIED:' (ambiguous)
org-eval: 1-based indexing to match repl-block; errors on out-of-range; errors on <1
2026-05-13 13:09:50 -04:00

79 lines
2.0 KiB
Perl
Executable File

#!/usr/bin/env perl
# repl — evaluate Lisp forms against the running Passepartout daemon
# Usage: repl <lisp-form>
# or: echo '<lisp-form>' | repl
#
# Connects to the daemon on 127.0.0.1:9105, sends a repl-eval request
# via the framed TCP protocol, reads and prints the response.
use strict;
use warnings;
use IO::Socket::INET;
my $HOST = $ENV{PASSEPARTOUT_HOST} || "127.0.0.1";
my $PORT = $ENV{PASSEPARTOUT_PORT} || "9105";
my $TIMEOUT = $ENV{PASSEPARTOUT_REPL_TIMEOUT} || 10;
my $expr = join(" ", @ARGV);
if (!$expr) {
$expr = do { local $/; <STDIN> };
}
chomp($expr);
# Quote the expression for embedding in a Lisp string
$expr =~ s/\\/\\\\/g; # backslash → doubled
$expr =~ s/"/\\"/g; # " → \"
if (!$expr) {
die "Usage: repl <lisp-form>\n or: echo '(+ 1 2)' | repl\n";
}
my $sock = IO::Socket::INET->new(
PeerHost => $HOST,
PeerPort => $PORT,
Proto => "tcp",
Timeout => $TIMEOUT
) or die "Cannot connect to $HOST:$PORT: $!\n";
sub read_frame {
my ($sock) = @_;
my $hex;
$sock->read($hex, 6) or return undef;
my $len = hex($hex);
my $content;
$sock->read($content, $len);
return $content;
}
sub write_frame {
my ($sock, $content) = @_;
my $len = sprintf("%06X", length($content));
$sock->send($len . $content);
}
# Read handshake (discard)
my $handshake = read_frame($sock);
# Build framed message
my $msg = '(:TYPE :EVENT :PAYLOAD (:SENSOR :repl-eval :CODE "' . $expr . '"))';
write_frame($sock, $msg);
# Read response
my $response = read_frame($sock);
if (defined $response) {
if ($response eq "") {
print STDERR "Daemon returned empty response\n";
exit 1;
}
if ($response =~ /:VALUE "([^"]*)"/s) {
print "$1\n";
} elsif ($response =~ /:message "([^"]*)"/s) {
print STDERR "$1\n";
exit 1;
} else {
print "Response: $response\n";
}
} else {
print STDERR "No response from daemon (is it running on $HOST:$PORT?)\n";
exit 1;
}
$sock->close();