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

=head1 Name
SPVM::Document::Language::Statements - Statements in the SPVM Language
=head1 Description
This document describes statements in the SPVM language.
=head1 Statements
A statement is a basic instruction that tells the program what to do.
Statements can be written direct under L<scope block|SPVM::Document::Language::Class/"Scope Block">.
# Scope block
{
# Statements
STATEMENT1
STATEMENT2
STATEMENT3
}
=head2 Conditional Statements
=head3 if Statement
C<if> statement is a conditional statement with the following syntax.
if (CONDITION1) {
}
elsif (CONDITION2) {
}
elsif (CONDITIONn) {
}
else {
}
C<elsif> statement and the C<else> statement are optional.
At first, all C<elsif> statements are expanded to the following code using C<if> - C<else> statements.
if (CONDITION1) {
}
else {
if (CONDITION2) {
}
else {
if (CONDITIONn) {
}
else {
}
}
}
C<if> statement is converted to simple C<if> - C<else> statements, so see a simple C<if> - C<else> statement.
if (CONDITION) {
}
else {
}
The L<condition evaluation|SPVM::Document::Language::Operators/"Condition Evaluation"> is performed on the condition I<CONDITION>.
If the evaluated value is not 0, the program jumps to the beginning of the C<if> block.
If the evaluated value is 0 and there is the C<else> block, the program jumps to the beginning of the C<else> block.
If the evaluated value is 0 and there is no C<else> block, the program jumps to the end of the C<if> block.
A C<if> - C<else> statement is enclosed by an invisible simple block.
{
if (CONDITION) {
}
else {
}
}
Examples:
# if statement.
my $flag = 1;
if ($flag == 1) {
say "One";
}
# if statement with elsif and else
my $flag = 2;
if ($flag == 1) {
say "One";
}
elsif ($flag == 2) {
say "Two";
}
elsif ($flag == 3) {
say "Three";
}
else {
say "Other";
}
=head3 else Statement
C<else> statement is a conditional statement used in L<if statement|/"if Statement">.
if (CONDITION) {
}
else {
}
=head3 elsif Statement
C<elsif> statement is a conditional statement used in L<if statement|/"if Statement">.
if (CONDITION1) {
}
elsif (CONDITION2) {
}
=head3 unless Statement
C<unless> statement is a conditional statement with the following syntax.
unless (CONDITION) {
}
C<unless> statement is expanded to the following code.
if (!CONDITION) {
}
Examples:
# unless statement.
my $flag = 1;
unless ($flag == 0) {
say "Not Zero";
}
=head3 switch Statement
C<switch> statement is a conditional statement with the following syntax.
# switch statement
switch (CONDITION) {
case CASE1: {
# ...
}
case CASE2: {
# ...
}
case CASEn: {
# ...
}
default: {
# ...
}
}
The L<integer promotional conversion|SPVM::Document::Language::Operators/"Integer Promotional Conversion"> is performed on the condition I<CONDITION>.
The operand of the case statement I<CASEn> must be a L<character literal|SPVM::Document::Language::Tokenization/"Character Literal">, an L<integer literal|SPVM::Document::Language::Tokenization/"Integer Literals"> and an L<inline-expaned class method call to get an enumeration value|SPVM::Document::Language::Class/"Inline Expansion of Method Call to Get an Enuemration Value">.
If I<CASEn> is a L<character literal|SPVM::Document::Language::Tokenization/"Character Literal">, the value is converted to int type at compile-time.
C<case> statements and the C<default> statement are optional.
If I<CONDITION> matches I<CASEn>, the program jumps to the beginning of the case block of I<CASEn>.
If there are no case statements and no default statement, the program jumps to the end of the C<switch> block.
If there is the C<default> statement and I<CONDITION> dose not matches I<CASEn>, the program jumps to the beginning of the C<default> block.
If there is no C<default> statement and I<CONDITION> dose not matches I<CASEn>, the program jumps to the end of the C<switch> block.
A L<break|/"break Statement"> statement is implicitly added to the end of the statements in every C<case> block.
case CASEn: {
# A break statement is added implicitly to the end of the statements
break;
}
It is allowed to jump multiple case statements into a single block.
switch (CONDITION) {
case CASE1:
case CASE2:
{
# ...
}
}
Compilation Errors:
I<CONDITION> must be an integer type within int. Otherwise, a compilation error occurs.
The values of the case statements must not be duplicated. Otherwise, a compilation error occurs.
Examples:
# switch statement
my $code = 2;
my $flag = 1;
switch ($code) {
case 1: {
say "1";
}
case 2: {
say "2";
}
case 3: {
if ($flag) {
break;
}
say "3";
}
case 4:
case 5:
{
say "4 or 5";
}
default: {
say "Other";
}
}
# switch statement with enumeration
class Foo {
enum {
ID1,
ID2,
ID3,
}
static method main : int () {
my $value = 1;
switch ($value) {
case Foo->ID1: {
say "1";
}
case Foo->ID2: {
say "2";
}
case Foo->ID3: {
if ($flag) {
break;
}
say "3";
}
default: {
say "Other";
}
}
}
}
=head4 case Statement
C<case> statement specifies a case in L<switch statement|/"switch Statement">.
# case statement
switch (CONDITION) {
case CASEn: {
# ...
}
}
=head4 default Statement
C<default> statement specifies a default case in L<switch statement|/"switch Statement">.
# default statement
switch (CONDITION) {
default: {
# ...
}
}
=head4 break Statement
C<break> statement makes the program jump to the end of L<switch|/"switch Statement"> block.
# break statement
break;
Examples:
my $code = 2;
my $flag = 1;
switch ($code) {
case 3: {
if ($flag) {
# break statement makes the program jump to the end of the switch block
break;
}
say "3";
}
default: {
say "Other";
}
}
# end of the switch block
=head2 Loop Statements
=head3 while Statement
C<while> statement is a loop statement with the following syntax.
# while statement
while (CONDITION) {
}
The L<condition evaluation|SPVM::Document::Language::Operators/"Condition Evaluation"> is performed on the condition I<CONDITION>.
If the evaluated value is 0, the program jumps to the end of the C<while> block. Otherwise, the program jumps to the beginning of the C<while> block.
When the program reaches the end of the C<while> block, it jumps to the beginning of the C<while> statement.
Examples:
# while statement
my $i = 0;
while ($i < 5) {
say "$i";
$i++;
}
C<while> statement is enclosed by an invisible simple block.
{
while (CONDITION) {
}
}
=head3 next Statement
C<next> statement makes the program jump to the beginning of the current L<while statement|/"while Statement">.
# next statement
next;
Examples:
my $i = 0;
# beginning of the while statement
while ($i < 5) {
if ($i == 3) {
$i++;
# next statement makes the program jump to the beginning of the current while statement.
next;
}
say "$i";
$i++;
}
=head3 last Statement
C<last> statement makes the program jump to the end of the current L<while statement|/"while Statement">.
# last statement
last;
Examples:
while (1) {
# last statement makes the program jump to the end fo the current while statement.
last;
}
# end fo the while statement
=head3 for Statement
C<for> statement is a loop statement with the following syntax.
# for statement
for (INIT; CONDITION; INCREMENT) {
}
A C<for> statement is expanded to the following code using a L<while statement|/"while Statement">.
{
INIT;
while (CONDITION) {
# ...
INCREMENT;
}
}
Exampels:
# for statement
for (my $i = 0; $i < 5; $i++) {
say "$i";
}
=head3 for-each Statement
The for-each statement is a loop statement with the following syntax.
# for-each statemenet
for my VAR (@ARRAY) {
}
for my VAR (@{ARRAY}) {
}
A for-each statement is expanded to the following code using a L<for statement|/"for Statement">.
for (my $i = 0; $i < @{ARRAY}; $i++) {
my VAR = ARRAY->[$i];
}
Example:
# for-each statemenet
my $array = [1, 2, 3];
for my $element (@$array) {
say "$elemenet";
}
=head2 return Statement
The return statement causes the program to return to its caller. And it set the return value.
// void
return;
// non-void
return OPERAND;
This statement causes the program to return to its caller.
If I<OPERAND> is specified, the return vlaue is set to I<OPERAND>.
I<OPERAND> is an an L<operator|SPVM::Document::Language::Operators/"Operators">.
This is because leave scope operations must not destroy I<OPERAND>.
Compilation Errors:
If the return type of the current method is the void type, I<OPERAND> must not exist. Otherwise, a compilation error occurs.
If the return type of the current method is the non-void type, I<OPERAND> must exist. Otherwise, a compilation error occurs.
The type of I<OPERAND> must satisfy L<assignment requirement|SPVM::Document::Language::Types/"Assignment Requirement"> to the return type of the current method. Otherwise, a compilation error occurs.
=head2 die Statement
C<die> statement throws an L<exception|SPVM::Document::Language::ExceptionHandling/"Throwing Exception">.
# die statement
die
die OPERAND_MESSAGE
# die statement with an error class
die ERROR_CLASS
die ERROR_CLASS OPERAND_MESSAGE
# die statement with the basic type ID of an error class
die OPERAND_ERROR_ID, OPERAND_MESSAGE
I<OPERAND_MESSAGE> is a string of string type for an error message. If the exception thrown by the C<die> statement is catched, L<exception variable|SPVM::Document::Language::ExceptionHandling/"Exception Variable"> C<$@> is set to I<OPERAND_MESSAGE> with stack traces added.
If the exception is not catched, the program prints it to L<SPVM's standard error|SPVM::Document::Language::System/"Standard Streams">, and finishes the program with an error ID.
The following is an example of stack traces of an exception message.
Error
TestCase::Minimal->sum2 at SPVM/TestCase/Minimal.spvm line 1640
TestCase->main at SPVM/TestCase.spvm line 1198
If I<OPERAND_MESSAGE> is not given or C<undef>, I<OPERAND_MESSAGE> is set to C<"Error">.
I<ERROR_CLASS> is a class name, normally of L<Error|SPVM::Error> class, or its child class. If the exception thrown by the C<die> statement is catched, L<eval_error_id|SPVM::Document::Language::Operators/"eval_error_id Operator"> is set to the basic type ID of I<ERROR_CLASS>.
The L<integer promotional conversion|SPVM::Document::Language::Operators/"Integer Promotional Conversion"> is performed on I<OPERAND_ERROR_ID>.
I<OPERAND_ERROR_ID> is an integer value within int type. If it is given and the exception thrown by the C<die> statement is catched, L<eval_error_id|SPVM::Document::Language::Operators/"eval_error_id Operator"> is set to I<OPERAND_ERROR_ID>.
See also L<Exception Handling|SPVM::Document::Language::ExceptionHandling> for exception handling using the C<die> statement.
Comlication Errors:
I<OPERAND_MESSAGE> must be string type or the undef type. Otherwise, a compilation error occurs.
I<ERROR_CLASS> must be a class type. Otherwise, a compilation error occurs.
I<OPERAND_ERROR_ID> must be an integer type within int. Otherwise, a compilation error occurs.
Examples:
# die statement with exception handling
eval {
die "Error";
}
if ($@) {
# ...
}
# die statement with an error class
die Error::System "System Error";
# die statement with the basic type ID of an error class
my $error_id = Fn->get_basic_type_id("Error::System");
die $error_id, "System Error";
=head2 Operator Statement
The operator statement operates an L<operator|SPVM::Document::Language::Operators/"Operators">.
# operator statemenet
OPERATOR;
Examples:
1;
$var;
1 + 2;
&foo();
my $num = 1 + 2;
=head2 Empty Statement
The empty statement operates nothing.
# empty statemenet
;
=head2 require Statement
C<require> statement loads a class only if it is found.
if (require BASIC_TYPE) {
}
if (require BASIC_TYPE) {
}
else {
}
This statement searches for the type I<BASIC_TYPE> in L<class search directories|SPVM::Document::Language::Class/"Class Search Directories"> from the beginning, and if found, it loads I<BASIC_TYPE> at compilation time.
If I<BASIC_TYPE> is found, the C<if> block is converted to a L<simple block|SPVM::Document::Language::Class/"Simple Block"> and the C<else> block(if it eixsts) is removed at compilation time.
If I<BASIC_TYPE> is not found, a compilation error does not occur.
If I<BASIC_TYPE> is not found, the C<else> block (if it eixstgs) is converted to a L<simple block|SPVM::Document::Language::Class/"Simple Block"> and the C<if> block is removed at compilation time.
Examples:
my $foo : object;
if (require MyClass) {
$foo = new MyClass;
}
else {
warn "Warning: Can't load MyClass";
}
=head1 See Also
=over 2
=item * L<SPVM::Document::Language::Class>
=item * L<SPVM::Document::Language::Operators>
=item * L<SPVM::Document::Language>
=item * L<SPVM::Document>
=back
=head1 Copyright & License
Copyright (c) 2023 Yuki Kimoto
MIT License