#!perl use strict; use warnings; use SPVM::Builder::Util; use SPVM::Global; 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.