The Perl Toolchain Summit 2025 Needs You: You can help 🙏 Learn more

#!perl
use strict;
use FindBin;
SPVM::Builder::Util::getopt
# spvmcc and spvm shared
'h|help' => \my $help,
'v|version' => \my $show_version,
'I|include-dir=s' => \my @include_dirs,
'B|build-dir=s' => \my $build_dir,
'w' => \my $warning,
# spvm only
'E=s' => \my $source,
'e=s' => \my $source_in_main,
'-M=s' => \my @use_class_names,
'-c' => \my $syntax_ok,
;
if ($help) {
print SPVM::Builder::Util::extract_usage;
exit 0;
}
elsif ($show_version) {
my $version_string = "spvm v$SPVM::VERSION";
print "$version_string\n";
exit 0;
}
if (defined $build_dir) {
$ENV{SPVM_BUILD_DIR} = $build_dir;
}
my $script_name = shift;
if (!defined $script_name && !defined $source_in_main && !defined $source) {
die SPVM::Builder::Util::extract_usage;
}
if (defined $script_name && defined $source_in_main) {
die "[spvm command]Specifying both SCRIPT_NAME and -e option is not allowed.";
}
if (defined $script_name && defined $source) {
die "[spvm command]Specifying both SCRIPT_NAME and -E option is not allowed.";
}
if (defined $source_in_main && defined $source) {
die "[spvm command]Specifying both -E option and -e option is not allowed.";
}
if (defined $source_in_main) {
$0 = "-e";
$source = "
class {
static method main : void () {
#line 1
$source_in_main
}
}
";
}
elsif (defined $script_name) {
$0 = $script_name;
open my $script_fh, '<', $script_name
or die "Can't open file \"$script_name\":$!";
$source = do { local $/; <$script_fh> };
$source = "#file \"$script_name\"\x{A}$source";
}
FindBin::again();
my $include_dirs_by_lib_directive = SPVM::Builder::Util::parse_lib_directive($source, $FindBin::Bin);
unshift @INC, map { $_ =~ s/[\\\/]SPVM$//; $_; } @include_dirs, @$include_dirs_by_lib_directive;
if ($warning) {
$^W = 1;
}
for my $use_class_name (@use_class_names) {
SPVM::Global::build_class($use_class_name, __FILE__, __LINE__);
}
SPVM::Global::build_class('Native', __FILE__, __LINE__);
SPVM::Global::build_class('Native::MethodCall', __FILE__, __LINE__);
my $anon_class_name = SPVM::Global::build_anon_class($source, __FILE__, __LINE__);
SPVM::Native->check_bootstrap_method($anon_class_name);
my $spvm_anon_class_name = "SPVM::$anon_class_name";
if ($syntax_ok) {
print STDERR "syntax OK\n";
exit 0;
}
$spvm_anon_class_name->main;
=encoding utf8
=head1 Name
spvm - Executing SPVM programs
=head1 Description
The spvm command executes SPVM programs.
=head1 Usage
Usage: spvm [OPTIONS] SCRIPT_NAME
spvm myapp.spvm
Options:
-h, --help Shows this message
-v, --version Shows the version
-I, --include-dir DIRECTORY Adds a include directory
-B, --build-dir DIRECTORY Build diretory
-e SOURCE Executes a program source code in main method.
-c Check syntx only
=head1 Details
spvm [OPTIONS] SCRIPT_NAME
The C<spvm> command executes a SPVM program.
I<OPTIONS> are L<options|/"Options">.
I<SCRIPT_NAME> is a script name that contains a L<bootstrap method|SPVM::Document::Language::Class/"Bootstrap Method"> in an L<anon class|SPVM::Document::Language::Class/"Anon Class">.
class {
static method main : void () {
}
}
See L<Class Search Directories|SPVM::Document::Language::Class/"Class Search Directories"> about default class search directories.
See L<SPVM::Document::EnvironmentVariables> about available environment variables.
=head1 Options
=head2 --help
Outputs how to use the C<spvm> command to standard output.
=head2 -h
-h
Same as L</"--help">.
=head2 --version
Outputs the version of the C<spvm> command to standard output. This version is the same as the version of L<SPVM>.
=head2 -v
-v
Same as L</"--version">.
=head2 --include-dir
--include-dir DIRECTORY
Prepends I<DIRECTORY> to L<class search directories|SPVM::Document::Language::Class/"Class Search Directories">
This option can be specified multiple times.
--include-dir dir1 --include-dir dir2
In this case, class search directories becomes the following.
[dir1, dir2, default_dirs]
=head2 -I
-I DIRECTORY
Same as L</"--include-dir">.
=head2 --build-dir
--build-dir DIRECTORY
Sets L<SPVM_BUILD_DIR|SPVM::Document::EnvironmentVariables/"SPVM_BUILD_DIR"> environment variable to I<DIRECTORY>.
=head2 -B
-B DIRECTORY
Same as L</"--build-dir">.
=head2 -E
-E SOURCE
Executes a source code I<SOURCE>.
Examples:
spvm -E 'class { static method main : void () { say "Hello World!"; } }';
=head2 -e
-e SOURCE
Executes a source code I<SOURCE> in C<main> method.
Examples:
spvm -e 'say "Hello World!";';
=head2 -c
-c
Checks syntax only.
=head2 -w
-w
Enables warning flag.
Implementation:
Sets L<CommandInfo#WARNING|SPVM::CommandInfo> class variable to 1.
=head1 lib Directive
If the source code specified by I<SCRIPT_NAME>, C<-E>, or C<-e> option contains lib directives, The directories specified by lib directive is prepeneded to L<class search directories|SPVM::Document::Language::Class/"Class Search Directories">.
#lib "$FindBin::Bin/lib"
class {
}
This directories specified by lib directive is placed after the directories specified by L</"--include-dir"> option.
=head1 Copyright & License
Copyright 2023 Yuki Kimoto. All Rights Reserved.
MIT License.