3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-23 12:29:27 +01:00
pbot/applets/compiler_vm/host/bin/vm-exec

108 lines
2.5 KiB
Perl
Executable File

#!/usr/bin/env perl
# File: vm-exec
#
# Purpose: Process and send commands to the PBot virtual machine on the
# default TCP port (5555). Use the PBOTVM_SERIAL environment variable to
# override the port. E.g., to use port 7777 instead:
#
# $ PBOTVM_SERIAL=7777 vm-exec -lang=sh echo test
# SPDX-FileCopyrightText: 2021 Pragmatic Software <pragma78@gmail.com>
# SPDX-License-Identifier: MIT
use warnings;
use strict;
use File::Basename;
use JSON::XS;
use FindBin qw($RealBin);
use lib "$RealBin/../lib";
use constant {
SERIAL_PORT => $ENV{PBOTVM_SERIAL} // 5555,
};
my $json = join ' ', @ARGV;
my $data = eval { decode_json $json };
if ($@) {
# wasn't JSON; make structure manually
if ($json =~ s/^-lang=([^ ]+)\s+//) {
$data = { lang => $1, code => $json };
} else {
$data = { code => $json };
}
}
if (not exists $data->{code}) {
die "Usage: $0 <code>\n";
}
# set any missing fields to default values
$data->{nick} //= 'vm';
$data->{channel} //= 'vm';
$data->{lang} //= 'c11';
$data->{'vm-port'} //= SERIAL_PORT;
# parse -lang option
if ($data->{code} =~ s/^-lang=([^ ]+)\s+//) {
$data->{lang} = $1;
}
my $language = lc $data->{lang};
eval {
require "Languages/$language.pm";
} or do {
my $found = 0;
my ($languages, $comma) = ('', '');
foreach my $module (sort glob "$RealBin/../lib/Languages/*.pm") {
$module = basename $module;
$module =~ s/.pm$//;
next if $module =~ m/^_/;
require "Languages/$module.pm" or die $!;
my $mod = "Languages::$module"->new;
if (exists $mod->{name} and $mod->{name} eq $language) {
$language = $module;
$found = 1;
last;
}
$module = $mod->{name} if exists $mod->{name};
$languages .= "$comma$module";
$comma = ', ';
}
if (not $found) {
print "Language '$language' is not supported.\nSupported languages are: $languages\n";
exit;
}
};
if (not length $data->{code}) {
if (exists $data->{usage}) {
print "$data->{usage}\n";
} else {
print "Usage: cc [-lang=<language>] [-info] [-paste] [-args \"command-line arguments\"] [compiler/language options] <code> [-stdin <stdin input>]\n";
}
exit;
}
my $lang = "Languages::$language"->new(%$data);
$lang->{local} = $ENV{CC_LOCAL};
$lang->process_interactive_edit;
$lang->process_standard_options;
$lang->process_custom_options;
$lang->process_cmdline_options;
$lang->preprocess_code;
$lang->execute;
$lang->postprocess_output;
$lang->show_output;