Name

SPVM::Document::Language - SPVM Language Specification

Description

The SPVM language specification is described.

Tokenization

The tokenizing the source codes of SPVM language is explained.

Character Encoding of Source Code

The character encoding of SPVM source codes is UTF-8.

Compilation Errors:

The charactor encoding of SPVM source codes must be UTF-8. Otherwise a compilation error occurs.

End of Source Code

A SPVM source code ends with 0x00 NULL in ASCII. If a source code is loaded by a file, \0 is added to the end of the source code.

Line Terminators

The line terminators are 0x2A LF of ASCII.

When a line terminator appears, the current line number is incremented by 1.

Compilation Errors:

The new line of SPVM source codes must be LF. The source code cannot contains CR and CRLF.

Space Character

Space characters are SP, HT, FF of ASCII and the line terminators.

Word Character

The word characters are alphabet(a-zA-Z), number(0-9), and underscore(_) of ASCII.

Symbol Name

A symbol name is the characters that are composed of word characters and ::.

A symbol name cannnot contains __, and cannnot begin with a number 0-9.

A symbol name cannnot begin with ::, and cannnot end with ::.

A symbol name cannnot contains ::::, and cannnot begin with a number 0-9.

# Symbol names
foo
foo_bar2
Foo::Bar

# Invalid symbol names
2foo
foo__bar
::Foo
Foo::
Foo::::Bar

Class Name

A class name is a symbol name.

The part names of a class name must begin uppercase letter. If the class name is Foo:Bar::Baz, part names are Foo, Bar, and Baz.

A class name must be the name that the relative class file path's all / are replaced with :: and the trailing .spvm is removed. For example, If the relative class file path is Foo/Bar/Baz.spvm, the class name must be Foo::Bar::Baz.

# Valid class name in the class file "Foo/Bar/Baz.spvm"
class Foo::Bar::Baz {
  
}

# Invalid class name in the class file "Foo/Bar/Baz.spvm"
class Foo::Bar::Hello {
  
}

Compilation Errors:

If class names are invalid, a compilation error occurs.

Examples:

# Class names
Foo
Foo::Bar
Foo::Bar::Baz3
Foo::bar
Foo_Bar::Baz_Baz

# Invalid class names
Foo
Foo::::Bar
Foo::Bar::
Foo__Bar
Foo::bar

Method Name

A method name is a symbol name that doesn't contains ::.

0-length method name is valid. This is used in the anon method.

Compilation Errors:

If method names are invalid, a compilation error occurs.

Examples:

# Valid method names
FOO
FOO_BAR3
foo
foo_bar
_foo
_foo_bar_

# Invalid method names
foo__bar
3foo

A method name that is the same as a "Keyword" in keyword is allowed.

# "if" is a valid method name
static method if : void () {
  
}

Field Name

A field name is a symbol name that doesn't contains ::.

Compilation Errors:

If field names are invalid, a compilation error occurs.

Examples:

# Field names
FOO
FOO_BAR3
foo
foo_bar
_foo
_foo_bar_

# Invalid field names
foo__bar
3foo
Foo::Bar

The field name that is the same as a "Keyword" in keyword is allowed.

# "if" is a valid field name
has if : int;

Variable Name

A variable name begins with $ and is followed by a symbol name.

Compilation Errors:

The symbol name can be wrapped by { and }. If a opening { exists and the closing } doesn't exists, a compilation error occurs.

Examples:

# Variable names
$name
$my_name
${name}
$Foo::name
$Foo::Bar::name
${Foo::name}

# Invalid variable names
$::name
$name::
$Foo::::name
$my__name
${name

Class Variable Name

A class variable name is a variable name.

Compilation Errors:

If class variable names are invalid, a compilation error occurs.

Examples:

# Class variable names
$NAME
$MY_NAME
${NAME}
$FOO::NAME
$FOO::BAR::NAME
${FOO::NAME_BRACE}
$FOO::name

# Invalid class variable names
$::NAME
$NAME::
$FOO::::NAME
$MY__NAME
$3FOO
${NAME

Local Variable Name

A local variable name is a variable name that doesn't contain ::.

Examples:

# Local variable names
$name
$my_name
${name_brace}
$_name
$NAME

# Invalid local variable names
$::name
$name::
$Foo::name
$Foo::::name
$my__name
${name
$3foo

Current Class

& before method name means the current class. & is replaced with CURRENT_CLASS_NAME->.

Examples:

class Foo {
  
  static method test : void () {
    # This means Foo->sum(1, 2)
    my $ret = &sum(1, 2);
  }

  static method sum : int ($num1 : int, $num2 : int) {
    return $num1 + $num2;
  }
  
}

Keyword

The list of keywords:

alias
allow
as
basic_type_id
break
byte
can
case
cmp
class
compile_type_name
copy
default
die
div_uint
div_ulong
double
dump
elsif
else
enum
eq
eval
eval_error_id
extends
for
float
false
gt
ge
has
if
interface
int
interface_t
isa
isa_error
isweak
is_compile_type
is_type
is_error
is_read_only
args_width
last
length
lt
le
long
make_read_only
my
mulnum_t
method
mod_uint
mod_ulong
mutable
native
ne
next
new
new_string_len
of
our
object
print
private
protected
public
precompile
pointer
return
require
required
rw
ro
say
static
switch
string
short
scalar
true
type_name
undef
unless
unweaken
use
version
void
warn
while
weaken
wo
INIT
__END__
__PACKAGE__
__FILE__
__LINE__

Operator for Tokenization

The list of the operators for tokenization:

!
!=
$
%
&
&&
&=
=
==
^
^=
|
||
|=
-
--
-=
~
@
+
++
+=
*
*=
<
<=
>
>=
<=>
%
%=
<<
<<=
>>=
>>
>>>
>>>=
.
.=
/
/=
\
(
)
{
}
[
]
;
:
,
->
=>

Note that the operators for tokenization are different from the operators that are explained in operators. The operators for tokenization are only for tokenization.

Comment

A comment begins with # and ends with a line terminator.

# Comment

Comments have no meaning in source codes.

Line directives take precedence over comments.

Line Directive

A line directive begins with #line and positive 32bit integer and ends with a line terminator.

#line 39

A line directive change the current line of the source code.

Line directives take precedence over comments.

Compilation Errors:

A line directive must begin from the beggining of the line. Otherwise an compilation error occurs.

A line directive must end with "\n". Otherwise an compilation error occurs.

A line directive must have a line number. Otherwise an compilation error occurs.

The line number given to a line directive must be a positive 32bit integer. Otherwise an compilation error occurs.

POD

POD(Plain Old Document) is a syntax to write documents in source codes.

The biginning of POD begins with =, and is followed by any string that is composed of ASCII printable characters, and end with a line terminator.

The previous line of the biginning of POD must need a line terminator

The lator line of the biginning of POD must need a line terminator

=pod

=head1

=item * foo

The end of POD begins with =, and is followed by cut, and ends with a line terminator.

The previous line of the end of POD must need a line terminator

The lator line of the end of POD must need a line terminator

=cut

Examples:

=pod

Multi-Line
Comment

=cut

=head1

Multi-Line
Comment

=cut

POD has no meaning in source codes.

Literal

A literal is the way to write a constant value in source codes.

Literals are numeric literals, the floating point literal, the character literal, the string literal and the bool literal.

Numeric Literal

A numeric literal is the way to write a constant value that type is a numeric type in source codes.

Numeric literals are the integer literal and the floating point literal.

Integer Literal

A interger literal is a "Numeric Literal" in numeric literal to write a constant value that type is an integer type in source codes.

Integer Literal Decimal Notation

The interger literal decimal notation is the way to write an integer literal using decimal numbers 0-9.

A minus - can be at the beginning, and is followed by one or more of 0-9.

_ can be used as a separator at the any positions after the first 0-9. _ has no meaning.

The suffix L or l can be at the end.

If the suffix L or l exists, the return type is the long type. Otherwise the return type is the int type.

Compilation Errors:

If the return type is the int type and the value is greater than the max value of int type or less than the minimal value of int type, a compilation error occurs.

If the return type is the long type and the value is greater than the max value of long type or less than the minimal value of long type, a compilation error occurs.

Examples:

123
-123
123L
123l
123_456_789
-123_456_789L

Integer Literal Hexadecimal Notation

The interger literal hexadecimal notation is the way to write an integer literal using hexadecimal numbers 0-9a-zA-Z.

A minus - can be at the beginning, and is followed by 0x or 0X, and is followed by one or more 0-9a-zA-Z.

_ can be used as a separator at the any positions after 0x or 0X. _ has no meaning.

The suffix L or l can be at the end.

If the suffix L or l exists, the return type is the long type. Otherwise the return type is the int type.

If the return type is the int type, the value that is except for - is interpreted as unsigned 32 bit integer uint32_t type in the C language, and the following conversion is performed.

uint32_t value_uint32_t;
int32_t value_int32_t = (int32_t)value_uint32_t;

And if - exists, the following conversion is performed.

value_int32_t = -value_int32_t;

For example, 0xFFFFFFFF is the same as -1, -0xFFFFFFFF is the same as 1.

If the return type is the long type, the value that is except for - is interpreted as unsigned 64 bit integer uint64_t type in the C language, and the following conversion is performed.

uint64_t value_uint64_t;
value_int64_t = (int64_t)value_uint64_t;

And if - exists, the following conversion is performed.

value_int64_t = -value_int64_t;

For example, 0xFFFFFFFFFFFFFFFFL is the same as -1L, -0xFFFFFFFFFFFFFFFFL is the same as 1L.

Compilation Errors:

If the return type is the int type and the value that is except for - is greater than hexadecimal FFFFFFFF, a compilation error occurs.

If the return type is the long type and the value that is except for - is greater than hexadecimal FFFFFFFFFFFFFFFF, a compilation error occurs.

Examples:

0x3b4f
0X3b4f
-0x3F1A
0xDeL
0xFFFFFFFF
0xFF_FF_FF_FF
0xFFFFFFFFFFFFFFFFL

Integer Literal Octal Notation

The interger literal octal notation is the way to write an integer literal using octal numbers 0-7.

A minus - can be at the beginning, and is followed by 0, and is followed by one or more 0-7.

_ can be used as a separator at the any positions after 0. _ has no meaning.

The suffix L or l can be at the end.

If the suffix L or l exists, the return type is the long type. Otherwise the return type is the int type.

If the return type is the int type, the value that is except for - is interpreted as unsigned 32 bit integer uint32_t type in the C language, and the following conversion is performed.

uint32_t value_uint32_t;
int32_t value_int32_t = (int32_t)value_uint32_t;

And if - exists, the following conversion is performed.

value_int32_t = -value_int32_t;

For example, 037777777777 is the same as -1, -037777777777 is the same as 1.

If the return type is the long type, the value that is except for - is interpreted as unsigned 64 bit integer uint64_t type in the C language, and the following conversion is performed.

uint64_t value_uint64_t;
value_int64_t = (int64_t)value_uint64_t;

And if - exists, the following conversion is performed.

value_int64_t = -value_int64_t;

For example, 01777777777777777777777L is the same as -1L, -01777777777777777777777L is the same as 1L.

Compilation Errors:

If the return type is the int type and the value that is except for - is greater than octal 37777777777, a compilation error occurs.

If the return type is the long type and the value that is except for - is greater than octal 1777777777777777777777, a compilation error occurs.

Examples:

0755
-0644
0666L
0655_755

Integer Literal Binary Notation

The interger literal binary notation is the way to write an integer literal using binary numbers 0 and 1.

A minus - can be at the beginning, and is followed by 0b or 0B, and is followed by one or more 0 and 1.

_ can be used as a separator at the any positions after 0b or 0B. _ has no meaning.

The suffix L or l can be at the end.

If the suffix L or l exists, the return type is the long type. Otherwise the return type is the int type.

If the return type is the int type, the value that is except for - is interpreted as unsigned 32 bit integer uint32_t type in the C language, and the following conversion is performed.

uint32_t value_uint32_t;
int32_t value_int32_t = (int32_t)value_uint32_t;

And if - exists, the following conversion is performed.

value_int32_t = -value_int32_t;

For example, 0b11111111111111111111111111111111 is the same as -1, -0b11111111111111111111111111111111 is the same as 1.

If the return type is the long type, the value that is except for - is interpreted as unsigned 64 bit integer uint64_t type in the C language, and the following conversion is performed.

uint64_t value_uint64_t;
value_int64_t = (int64_t)value_uint64_t;

And if - exists, the following conversion is performed.

value_int64_t = -value_int64_t;

For example, 0b1111111111111111111111111111111111111111111111111111111111111111L is the same as -1L, -0b1111111111111111111111111111111111111111111111111111111111111111L is the same as 1L.

Compilation Errors:

If the return type is the int type and the value that is except for - is greater than binary 11111111111111111111111111111111, a compilation error occurs.

If the return type is the long type and the value that is except for - is greater than binary 1111111111111111111111111111111111111111111111111111111111111111, a compilation error occurs.

Examples:

0b0101
-0b1010
0b110000L
0b10101010_10101010

Floating Point Literal

The floating point litral is a "Numeric Literal" in numeric literal to write a constant value that type is a floating point type in source codes.

Floating Point Literal Decimal Notation

The floating point litral decimal notation is the way to write a floating point literal using decimal numbers 0-9 in source codes.

A minus - can be at the beginning, and is followed by one or more 0-9

_ can be used as a separator at the any positions after the first 0-9.

And can be followed by a floating point part.

A floating point part is . and is followed by one or more 0-9.

And can be followed by an exponent part.

An exponent part is e or E and is followed by +, -, or "", and followed by one or more 0-9.

And can be followed by a suffix is f, F, d, or D.

one of a floating point part, an exponent part, or a suffix must exist.

If the suffix f or F exists, the return type is the float type. Otherwise the return type is the double type.

Compilation Errors:

If the return type is the float type, the floating point literal is parsed by the strtof function of the C language. If the parsing fails, a compilation error occurs.

If the return type is the double type, the floating point literal is parsed by the strtod function of the C language. If the parsing fails, a compilation error occurs.

Examples:

1.32
-1.32
1.32f
1.32F
1.32d
1.32D
1.32e3
1.32e-3
1.32E+3
1.32E-3
12e7

Floating Point Literal Hexadecimal Notation

The floating point litral hexadecimal notation is the way to write a floating point literal using hexadecimal numbers 0-9a-zA-Z in source codes.

A minus - can be at the beginning, and is followed by 0x or 0X, and is followed by one or more 0-9a-zA-Z.

_ can be used as a separator at the any positions after 0x or 0X.

And can be followed by a floating point part.

A floating point part is . and is followed by one or more 0-9a-zA-Z.

And can be followed by an exponent part.

An exponent part is p or P and is followed by +, -, or "", and followed by one or more decimal numbers 0-9.

And can be followed by a suffix f, F, d, or D if an exponent part exist.

one of a floating point part or an exponent part must exist.

If the suffix f or F exists, the return type is the float type. Otherwise the return type is the double type.

Compilation Errors:

If the return type is the float type, the floating point literal is parsed by the strtof function of the C language. If the parsing fails, a compilation error occurs.

If the return type is the double type, the floating point literal is parsed by the strtod function of the C language. If the parsing fails, a compilation error occurs.

Examples:

0x3d3d.edp0
0x3d3d.edp3
0x3d3d.edP3
0x3d3d.edP+3
0x3d3d.edP-3f
0x3d3d.edP-3F
0x3d3d.edP-3d
0x3d3d.edP-3D
0x3d3dP+3

Character Literal

A character literal is a literal to write a constant value that type is the byte type in source codes.

A character literal represents an ASCII character.

A character literal begins with '.

And is followed by a printable ASCII character 0x20-0x7e or an character literal escape character.

And ends with '.

The return type is the byte type.

Compilation Errors:

If the format of the character literal is invalid, a compilation error occurs.

Character Literal Escape Characters

The list of character literal escape characters.

Character literal escape characters ASCII characters
\0 0x00 NUL
\a 0x07 BEL
\t 0x09 HT
\n 0x0A LF
\f 0x0C FF
\r 0x0D CR
\" 0x22 "
\' 0x27 '
\\ 0x5C \
Octal Escape Character An ASCII character
Hexadecimal Escape Character An ASCII character

Examples:

# Charater literals
'a'
'x'
'\a'
'\t'
'\n'
'\f'
'\r'
'\"'
'\''
'\\'
'\0'
' '
'\xab'
'\xAB'
'\x0D'
'\x0A'
'\xD'
'\xA'
'\xFF'
'\x{A}'

String Literal

A string literal is a literal to write a constant value that type is the string type in source codes.

The return type is the string type.

A character literal begins with ".

And is followed by zero or more than zero UTF-8 character, or string literal escape characters, or variable expansions.

And ends with ".

Compilation Errors:

If the format of the string literal is invalid, a compilation error occurs.

Examples:

# String literals
"abc";
"あいう"
"hello\tworld\n"
"hello\x0D\x0A"
"hello\xA"
"hello\x{0A}"
"AAA $foo BBB"
"AAA $FOO BBB"
"AAA $$foo BBB"
"AAA $foo->{x} BBB"
"AAA $foo->[3] BBB"
"AAA $foo->{x}[3] BBB"
"AAA $@ BBB"
"\N{U+3042}\N{U+3044}\N{U+3046}"

String Literal Escape Characters

String literal escape characters Descriptions
\0 ASCII 0x00 NUL
\a ASCII 0x07 BEL
\t ASCII 0x09 HT
\n ASCII 0x0A LF
\f ASCII 0x0C FF
\r ASCII 0x0D CR
\" ASCII 0x22 "
\$ ASCII 0x24 $
\' ASCII 0x27 '
\\ ASCII 0x5C \
Octal Escape Character An ASCII character
Hexadecimal Escape Character An ASCII character
Unicode escape character An UTF-8 character
Raw escape character The value of raw escape character

Unicode Escape Character

The Unicode escape character is the way to write an UTF-8 character using an Unicode code point that is written by hexadecimal numbers 0-9a-fA-F.

The Unicode escape character can be used as an escape character of the string literal.

The Unicode escape character begins with N{U+.

And is followed by one or more 0-9a-fA-F.

And ends with }.

Compilation Errors:

If the Unicode code point is not a Unicode scalar value, a compilation error occurs.

Examples:

# あいう
"\N{U+3042}\N{U+3044}\N{U+3046}"

# くぎが
"\N{U+304F}\N{U+304E}\N{U+304c}"

Raw Escape Character

The raw escape character is the escapa character that <\> has no effect and \ is interpreted as ASCII \.

For example, \s is ASCII chracters \s, \d is ASCII chracters <\d>.

The raw escape character can be used as an escape character of the string literal.

The raw escape character is designed to be used by regular expression classes such as Regex.

The list of raw escape characters.

# Raw excape literals
\! \# \% \& \( \) \* \+ \, \- \. \/
\: \; \< \= \> \? \@
\A \B \D \G \H \K \N \P \R \S \V \W \X \Z
\[ \] \^ \_ \`
\b \d \g \h \k \p \s \v \w \z
\{ \| \} \~

Octal Escape Character

The octal escape character is the way to write an ASCII code using octal numbers 0-7.

The octal escape character can be used as an escape character of the string literal and the character literal.

The octal escape character begins with \o{, and it must be followed by one to three 0-7, and ends with }.

Or the octal escape character begins with \0, \1, \2, \3, \4, \5, \6, \7, and it must be followed by one or two 0-7.

# Octal escape ch1racters in ch1racter literals
'\0'
'\012'
'\003'
'\001'
'\03'
'\01'
'\077'
'\377'

# Octal escape ch1racters in ch1racter literals
'\o{0}'
'\o{12}'
'\o{03}'
'\o{01}'
'\o{3}'
'\o{1}'
'\o{77}'
'\o{377}'

# Octal escape ch1racters in string literals
"Foo \0 Bar"
"Foo \012 Bar"
"Foo \003 Bar"
"Foo \001 Bar"
"Foo \03  Bar"
"Foo \01  Bar"
"Foo \077 Bar"
"Foo \377 Bar"

# Octal escape ch1racters in string literals
"Foo \o{12} Bar"
"Foo \o{12} Bar"
"Foo \o{03} Bar"
"Foo \o{01} Bar"
"Foo \o{3}  Bar"
"Foo \o{1}  Bar"
"Foo \o{77} Bar"
"Foo \o{377} Bar"

Hexadecimal Escape Character

The hexadecimal escape character is the way to write an ASCII code using hexadecimal numbers 0-9a-fA-F.

The hexadecimal escape character can be used as an escape character of the string literal and the character literal.

The hexadecimal escape character begins with \x.

And is followed by one or two 0-9a-fA-F.

The hexadecimal numbers can be sorrounded by { and }.

# Hexadecimal escape characters in character literals
'\xab'
'\xAB'
'\x0D'
'\x0A'
'\xD'
'\xA'
'\xFF'
'\x{A}'

# Hexadecimal escape characters in string literals
"Foo \xab  Bar"
"Foo \xAB  Bar"
"Foo \x0D  Bar"
"Foo \x0A  Bar"
"Foo \xD   Bar"
"Foo \xA   Bar"
"Foo \xFF  Bar"
"Foo \x{A} Bar"

Single-Quoted String Literal

A single-quoted string literal represents a constant string value in source codes.

The return type is the string type.

A character literal begins with q'.

And is followed by zero or more than zero UTF-8 character, or escape characters.

And ends with '.

Compilation Errors:

A single-quoted string literal must be end with '. Otherwise a compilation error occurs.

If the escape character in a single-quoted string literal is invalid, a compilation error occurs.

Examples:

# Single-quoted string literals
q'abc';
q'abc\'\\';

Single-Quoted String Literal Escape Characters

Single-quoted string literal escape characters Descriptions
\\ ASCII 0x5C \
\' ASCII 0x27 '

Bool Literal

The bool literal is a literal to represent a bool value in source codes.

true

true is the alias for the TRUE method of Bool.

true

Examples:

# true
my $is_valid = true;

false

false is the alias for FALSE method of Bool.

false

Examples:

# false
my $is_valid = false;

Variable Expansion

The variable expasion is the feature to embed getting local variable, getting class variables, dereference, "Getting Field" in getting field, getting array element, "Getting Exception Variable" in getting exception variable into the string literal.

"AAA $foo BBB"
"AAA $FOO BBB"
"AAA $$foo BBB"
"AAA $foo->{x} BBB"
"AAA $foo->[3] BBB"
"AAA $foo->{x}[3] BBB"
"AAA $foo->{x}->[3] BBB"
"AAA $@ BBB"
"AAA ${foo}BBB"

The above codes are convarted to the following codes.

"AAA " . $foo . " BBB"
"AAA " . $FOO . " BBB"
"AAA " . $$foo . " BBB"
"AAA " . $foo->{x} . " BBB"
"AAA " . $foo->[3] . " BBB"
"AAA " . $foo->{x}[3] . " BBB"
"AAA " . $foo->{x}->[3] . " BBB"
"AAA " . $@ . "BBB"
"AAA " . ${foo} . "BBB"

The getting field doesn't contain space characters between { and }.

The index of getting array element must be a constant value. The getting array doesn't contain space characters between [ and ].

The end $ is not interpreted as a variable expansion.

"AAA$"

Fat Comma

The fat comma => is a separator.

=>

The fat comma is an alias for Comma ,.

# Comma
["a", "b", "c", "d"]

# Fat Comma
["a" => "b", "c" => "d"]

If the characters of LEFT_OPERAND of the fat camma is not wrapped by " and the characters are a symbol name that does'nt contain ::, the characters are treated as a string literal.

# foo_bar2 is treated as "foo_bar2"
[foo_bar2 => "Mark"]

["foo_bar2" => "Mark"]

Here Document

Here document is syntax to write a string literal in multiple lines without escapes and variable expansions.

<<'HERE_DOCUMENT_NAME';
line1
line2
line...
HERE_DOCUMENT_NAME

Here document syntax begins with <<'HERE_DOCUMENT_NAME'; + a line terminator. HERE_DOCUMENT_NAME is a here document name.

A string begins from the next line.

Here document syntax ends with the line that begins HERE_DOCUMENT_NAME + a line terminator.

Compilation Errors:

<<'HERE_DOCUMENT_NAME' cannot contains spaces. If so, a compilation error occurs.

Examples:

# Here document
my $string = <<'EOS';
Hello
World
EOS

# No escapes and variable expaneions are performed.
my $string = <<'EOS';
$foo
\t
\
EOS

Here Document Name

Here document name is composed of a-z, A-Z, _, 0-9.

Compilaition Errors:

The length of a here document name must be greater than or equal to 0. Otherwise a compilation error occurs.

A here document name cannot start with a number. If so, a compilation error occurs.

A here document name cannot contain __. If so, a compilation error occurs.

Syntax Parsing

The SPVM language is assumed to be parsed by yacc/bison.

Syntax Parsing Definition

The definition of syntax parsing of SPVM language. This is written by yacc/bison syntax.

%token <opval> CLASS HAS METHOD OUR ENUM MY USE AS REQUIRE ALIAS ALLOW CURRENT_CLASS MUTABLE
%token <opval> ATTRIBUTE MAKE_READ_ONLY INTERFACE EVAL_ERROR_ID ARGS_WIDTH VERSION_DECL
%token <opval> IF UNLESS ELSIF ELSE FOR WHILE LAST NEXT SWITCH CASE DEFAULT BREAK EVAL
%token <opval> SYMBOL_NAME VAR_NAME CONSTANT EXCEPTION_VAR
%token <opval> UNDEF VOID BYTE SHORT INT LONG FLOAT DOUBLE STRING OBJECT TRUE FALSE END_OF_FILE
%token <opval> FATCAMMA RW RO WO INIT NEW OF BASIC_TYPE_ID EXTENDS SUPER
%token <opval> RETURN WEAKEN DIE WARN PRINT SAY CURRENT_CLASS_NAME UNWEAKEN '[' '{' '('
%type <opval> grammar
%type <opval> opt_classes classes class class_block version_decl
%type <opval> opt_definitions definitions definition
%type <opval> enumeration enumeration_block opt_enumeration_values enumeration_values enumeration_value
%type <opval> method anon_method opt_args args arg use require alias our has has_for_anon_list has_for_anon
%type <opval> opt_attributes attributes
%type <opval> opt_statements statements statement if_statement else_statement
%type <opval> for_statement while_statement foreach_statement
%type <opval> switch_statement case_statement case_statements opt_case_statements default_statement
%type <opval> block eval_block init_block switch_block if_require_statement
%type <opval> unary_operator binary_operator comparison_operator isa isa_error is_type is_error is_compile_type
%type <opval> call_method
%type <opval> array_access field_access weaken_field unweaken_field isweak_field convert array_length
%type <opval> assign inc dec allow can
%type <opval> new array_init die warn opt_extends
%type <opval> var_decl var interface union_type
%type <opval> operator opt_operators operators opt_operator logical_operator void_return_operator
%type <opval> field_name method_name alias_name is_read_only
%type <opval> type qualified_type basic_type array_type class_type opt_class_type
%type <opval> array_type_with_length ref_type  return_type type_comment opt_type_comment
%right <opval> ASSIGN SPECIAL_ASSIGN
%left <opval> LOGICAL_OR
%left <opval> LOGICAL_AND
%left <opval> BIT_OR BIT_XOR
%left <opval> BIT_AND
%nonassoc <opval> NUMEQ NUMNE STREQ STRNE
%nonassoc <opval> NUMGT NUMGE NUMLT NUMLE STRGT STRGE STRLT STRLE ISA ISA_ERROR IS_TYPE IS_ERROR IS_COMPILE_TYPE NUMERIC_CMP STRING_CMP CAN
%left <opval> SHIFT
%left <opval> '+' '-' '.'
%left <opval> '*' DIVIDE DIVIDE_UNSIGNED_INT DIVIDE_UNSIGNED_LONG MODULO  MODULO_UNSIGNED_INT MODULO_UNSIGNED_LONG
%right <opval> LOGICAL_NOT BIT_NOT '@' CREATE_REF DEREF PLUS MINUS CONVERT SCALAR STRING_LENGTH ISWEAK REFCNT TYPE_NAME COMPILE_TYPE_NAME DUMP NEW_STRING_LEN IS_READ_ONLY COPY
%nonassoc <opval> INC DEC
%left <opval> ARROW

grammar
  : opt_classes

opt_classes
  : /* Empty */
  | classes

classes
  : classes class
  | class

class
  : CLASS opt_class_type opt_extends class_block END_OF_FILE
  | CLASS opt_class_type opt_extends ':' opt_attributes class_block END_OF_FILE
  | CLASS opt_class_type opt_extends ';' END_OF_FILE
  | CLASS opt_class_type opt_extends ':' opt_attributes ';' END_OF_FILE

opt_class_type
  : /* Empty */
  | class_type

opt_extends
  : /* Empty */
  | EXTENDS basic_type

class_block
  : '{' opt_definitions '}'

opt_definitions
  : /* Empty */
  | definitions

definitions
  : definitions definition
  | definition

definition
  : version_decl
  | use
  | alias
  | allow
  | interface
  | init_block
  | enumeration
  | our
  | has ';'
  | method

init_block
  : INIT block

version_decl
  : VERSION_DECL CONSTANT ';'

use
  : USE basic_type ';'
  | USE basic_type AS alias_name ';'

require
  : REQUIRE basic_type

alias
  : ALIAS basic_type AS alias_name ';'

allow
  : ALLOW basic_type ';'

interface
  : INTERFACE basic_type ';'

enumeration
  : opt_attributes ENUM enumeration_block

enumeration_block
  : '{' opt_enumeration_values '}'

opt_enumeration_values
  : /* Empty */
  | enumeration_values

enumeration_values
  : enumeration_values ',' enumeration_value
  | enumeration_values ','
  | enumeration_value

enumeration_value
  : method_name
  | method_name ASSIGN CONSTANT

our
  : OUR VAR_NAME ':' opt_attributes qualified_type opt_type_comment ';'

has
  : HAS field_name ':' opt_attributes qualified_type opt_type_comment

method
  : opt_attributes METHOD method_name ':' return_type '(' opt_args ')' block
  | opt_attributes METHOD method_name ':' return_type '(' opt_args ')' ';'
  | opt_attributes METHOD ':' return_type '(' opt_args ')' block
  | opt_attributes METHOD ':' return_type '(' opt_args ')' ';'

anon_method
  : opt_attributes METHOD ':' return_type '(' opt_args ')' block
  | '[' has_for_anon_list ']' opt_attributes METHOD ':' return_type '(' opt_args ')' block

opt_args
  : /* Empty */
  | args

args
  : args ',' arg
  | args ','
  | arg

arg
  : var ':' qualified_type opt_type_comment
  | var ':' qualified_type opt_type_comment ASSIGN operator

has_for_anon_list
  : has_for_anon_list ',' has_for_anon
  | has_for_anon_list ','
  | has_for_anon

has_for_anon
  : HAS field_name ':' opt_attributes qualified_type opt_type_comment
  | HAS field_name ':' opt_attributes qualified_type opt_type_comment ASSIGN operator
  | var ':' opt_attributes qualified_type opt_type_comment

opt_attributes
  : /* Empty */
  | attributes

attributes
  : attributes ATTRIBUTE
  | ATTRIBUTE

opt_statements
  : /* Empty */
  | statements

statements
  : statements statement
  | statement

statement
  : if_statement
  | for_statement
  | foreach_statement
  | while_statement
  | block
  | switch_statement
  | case_statement
  | default_statement
  | eval_block
  | if_require_statement
  | LAST ';'
  | NEXT ';'
  | BREAK ';'
  | RETURN ';'
  | RETURN operator ';'
  | operator ';'
  | void_return_operator ';'
  | ';'
  | die ';'

die
  : DIE operator
  | DIE
  | DIE type operator
  | DIE type
  | DIE operator ',' operator

void_return_operator
  : warn
  | PRINT operator
  | SAY operator
  | weaken_field
  | unweaken_field
  | MAKE_READ_ONLY operator

warn
  : WARN operator
  | WARN

for_statement
  : FOR '(' opt_operator ';' operator ';' opt_operator ')' block

foreach_statement
  : FOR var_decl '(' '@' operator ')' block
  | FOR var_decl '(' '@' '{' operator '}' ')' block

while_statement
  : WHILE '(' operator ')' block

switch_statement
  : SWITCH '(' operator ')' switch_block

switch_block
  : '{' opt_case_statements '}'
  | '{' opt_case_statements default_statement '}'

opt_case_statements
  : /* Empty */
  | case_statements

case_statements
  : case_statements case_statement
  | case_statement

case_statement
  : CASE operator ':' block
  | CASE operator ':'

default_statement
  : DEFAULT ':' block
  | DEFAULT ':'

if_require_statement
  : IF '(' require ')' block
  | IF '(' require ')' block ELSE block

if_statement
  : IF '(' operator ')' block else_statement
  | UNLESS '(' operator ')' block else_statement

else_statement
  : /* NULL */
  | ELSE block
  | ELSIF '(' operator ')' block else_statement

block
  : '{' opt_statements '}'

eval_block
  : EVAL block

opt_operators
  : /* Empty */
  | operators

opt_operator
  : /* Empty */
  | operator

operator
  : var
  | EXCEPTION_VAR
  | CONSTANT
  | UNDEF
  | call_method
  | field_access
  | array_access
  | convert
  | new
  | array_init
  | array_length
  | var_decl
  | unary_operator
  | binary_operator
  | assign
  | inc
  | dec
  | '(' operators ')'
  | CURRENT_CLASS_NAME
  | isweak_field
  | comparison_operator
  | isa
  | isa_error
  | is_type
  | is_error
  | is_compile_type
  | TRUE
  | FALSE
  | is_read_only
  | can
  | logical_operator
  | BASIC_TYPE_ID type
  | EVAL_ERROR_ID
  | ARGS_WIDTH

operators
  : operators ',' operator
  | operators ','
  | operator

unary_operator
  : '+' operator %prec PLUS
  | '-' operator %prec MINUS
  | BIT_NOT operator
  | REFCNT operator
  | TYPE_NAME operator
  | COMPILE_TYPE_NAME operator
  | STRING_LENGTH operator
  | DUMP operator
  | DEREF var
  | CREATE_REF operator
  | NEW_STRING_LEN operator
  | COPY operator

is_read_only
  : IS_READ_ONLY operator

inc
  : INC operator
  | operator INC

dec
  : DEC operator
  | operator DEC

binary_operator
  : operator '+' operator
  | operator '-' operator
  | operator '*' operator
  | operator DIVIDE operator
  | operator DIVIDE_UNSIGNED_INT operator
  | operator DIVIDE_UNSIGNED_LONG operator
  | operator MODULO operator
  | operator MODULO_UNSIGNED_INT operator
  | operator MODULO_UNSIGNED_LONG operator
  | operator BIT_XOR operator
  | operator BIT_AND operator
  | operator BIT_OR operator
  | operator SHIFT operator
  | operator '.' operator

comparison_operator
  : operator NUMEQ operator
  | operator NUMNE operator
  | operator NUMGT operator
  | operator NUMGE operator
  | operator NUMLT operator
  | operator NUMLE operator
  | operator NUMERIC_CMP operator
  | operator STREQ operator
  | operator STRNE operator
  | operator STRGT operator
  | operator STRGE operator
  | operator STRLT operator
  | operator STRLE operator
  | operator STRING_CMP operator

isa
  : operator ISA type

isa_error
  : operator ISA_ERROR type

is_type
  : operator IS_TYPE type

is_error
  : operator IS_ERROR type

is_compile_type
  : operator IS_COMPILE_TYPE type

logical_operator
  : operator LOGICAL_OR operator
  | operator LOGICAL_AND operator
  | LOGICAL_NOT operator

assign
  : operator ASSIGN operator
  | operator SPECIAL_ASSIGN operator

new
  : NEW basic_type
  | NEW array_type_with_length
  | anon_method

array_init
  : '[' opt_operators ']'
  | '{' operators '}'
  | '{' '}'

convert
  : '(' qualified_type ')' operator %prec CONVERT
  | operator ARROW '(' qualified_type ')' %prec CONVERT

call_method
  : CURRENT_CLASS SYMBOL_NAME '(' opt_operators  ')'
  | CURRENT_CLASS SYMBOL_NAME
  | basic_type ARROW method_name '(' opt_operators  ')'
  | basic_type ARROW method_name
  | operator ARROW method_name '(' opt_operators ')'
  | operator ARROW method_name
  | operator ARROW '(' opt_operators ')'

array_access
  : operator ARROW '[' operator ']'
  | array_access '[' operator ']'
  | field_access '[' operator ']'

field_access
  : operator ARROW '{' field_name '}'
  | field_access '{' field_name '}'
  | array_access '{' field_name '}'

weaken_field
  : WEAKEN var ARROW '{' field_name '}'

unweaken_field
  : UNWEAKEN var ARROW '{' field_name '}'

isweak_field
  : ISWEAK var ARROW '{' field_name '}'

can
  : operator CAN method_name
  | operator CAN CONSTANT

array_length
  : '@' operator
  | '@' '{' operator '}'
  | SCALAR '@' operator
  | SCALAR '@' '{' operator '}'

var_decl
  : MY var ':' qualified_type opt_type_comment
  | MY var

var
  : VAR_NAME

qualified_type
  : type
  | MUTABLE type {

type
  : basic_type
  | array_type
  | ref_type

class_type
  : basic_type

basic_type
  : SYMBOL_NAME
  | BYTE
  | SHORT
  | INT
  | LONG
  | FLOAT
  | DOUBLE
  | OBJECT
  | STRING

ref_type
  : basic_type '*'

array_type
  : basic_type '[' ']'
  | array_type '[' ']'

array_type_with_length
  : basic_type '[' operator ']'
  | array_type '[' operator ']'

return_type
  : qualified_type opt_type_comment
  | VOID

opt_type_comment
  : /* Empty */
  | type_comment

type_comment
  : OF union_type

union_type
  : union_type BIT_OR type
  | type

field_name
  : SYMBOL_NAME

method_name
  : SYMBOL_NAME

alias_name
  : SYMBOL_NAME

Syntax Parsing Token

The list of syntax parsing tokens:

TokensKeywords or operators
ALIASalias
ALLOWallow
ARROW->
ASas
ASSIGN=
BIT_AND&
BASIC_TYPE_IDbasic_type_id
BIT_NOT~
BIT_OR|
BIT_XOR^
BREAKbreak
BYTEbyte
CASEcase
CLASSclass
VAR_NAMEA variable name
COMPILE_TYPE_NAMEcompile_type_name
CONSTANTLiteral
CONVERT(TypeName)
COPYcopy
CURRENT_CLASS&
CURRENT_CLASS_NAME__PACKAGE__
DEC--
DEFAULTdefault
DEREF$
ATTRIBUTEThe name of a attribute
DIEdie
DIVIDE/
DIVIDE_UNSIGNED_INTdiv_uint
DIVIDE_UNSIGNED_LONGdiv_ulong
DOUBLEdouble
DUMPdump
ELSEelse
ELSIFelsif
END_OF_FILEThe end of the file
ENUMenum
EVAL_ERROR_IDeval_error_id
EXTENDSextends
EVALeval
EXCEPTION_VAR$@
FATCAMMA=>
FLOATfloat
FORfor
HAShas
CANcan
IFif
INTERFACEinterface
INC++
INITINIT
INTint
ISAisa
ISWEAKisweak
IS_TYPEis_type
IS_READ_ONLYis_read_only
LASTlast
LENGTHlength
LOGICAL_AND&&
LOGICAL_NOT!
LOGICAL_OR||
LONGlong
MAKE_READ_ONLYmake_read_only
METHODmethod
MINUS-
MUTABLEmutable
MYmy
SYMBOL_NAMEA symbol name
NEWnew
NEW_STRING_LENnew_string_len
OFof
NEXTnext
NUMEQ==
NUMERIC_CMP<=>
NUMGE>=
NUMGT>
NUMLE<=
NUMLT<
NUMNE!=
OBJECTobject
OURour
PLUS+
PRINTprint
REF\
TYPE_NAMEtype_name
MODULO%
MODULO_UNSIGNED_INTmod_uint
MODULO_UNSIGNED_LONGmod_ulong
REQUIRErequire
RETURNreturn
ROro
RWrw
SAYsay
SCALARscalar
SELFself
SHIFT<< >> >>>
SHORTshort
SPECIAL_ASSIGN+= -= *= /= &= |= ^= %= <<= >>= >>>= .=
SRING_CMPcmp
STREQeq
STRGEge
STRGTgt
STRINGstring
STRLEle
STRLTlt
STRNEne
SWITCHswitch
UNDEFundef
UNLESSunless
UNWEAKENunweaken
USEuse
VARvar
VERSIONversion
VOIDvoid
WARNwarn
WEAKENweaken
WHILEwhile
WOwo

Unary Operator

The unary operator is the operator that has an operand.

UNARY_OPERATOR OPERAND

Binary Operator

The binary operator is the operator that has LEFT_OPERAND and RIGHT_OPERAND.

LEFT_OPERAND BINARY_OPERATOR RIGHT_OPERAND

Operator Precidence

The definition of the precidence of operators. This is written by yacc/bison syntax.

The bottom is the highest precidence and the top is the lowest precidence.

%right <opval> ASSIGN SPECIAL_ASSIGN
%left <opval> LOGICAL_OR
%left <opval> LOGICAL_AND
%left <opval> BIT_OR BIT_XOR
%left <opval> BIT_AND
%nonassoc <opval> NUMEQ NUMNE STREQ STRNE
%nonassoc <opval> NUMGT NUMGE NUMLT NUMLE STRGT STRGE STRLT STRLE ISA ISA_ERROR IS_TYPE IS_ERROR IS_COMPILE_TYPE NUMERIC_CMP STRING_CMP CAN
%left <opval> SHIFT
%left <opval> '+' '-' '.'
%left <opval> '*' DIVIDE DIVIDE_UNSIGNED_INT DIVIDE_UNSIGNED_LONG MODULO  MODULO_UNSIGNED_INT MODULO_UNSIGNED_LONG
%right <opval> LOGICAL_NOT BIT_NOT '@' CREATE_REF DEREF PLUS MINUS CONVERT SCALAR STRING_LENGTH ISWEAK REFCNT TYPE_NAME COMPILE_TYPE_NAME DUMP NEW_STRING_LEN IS_READ_ONLY COPY
%nonassoc <opval> INC DEC
%left <opval> ARROW

See also syntax parsing token to know real operators.

The operator precidence can be increased using ().

#  a * b is calculated at first
a * b + c

# b + c is calculated at first
a * (b + c)

Class

A class defines its class type, its class variables, its fields and its methods.

The object can be created from a class using new operator.

Class Definition

The class keyword defines a class. A class has a class block.

# Class definition
class CLASS_NAME {

}

The class name must follow the naming rule of the class name.

Examples:

# Class definition
class Point {

}

Class attributes are written after :.

class CLASS_NAME : CLASS_ATTRIBUTE {

}

class CLASS_NAME : CLASS_ATTRIBUTE1 CLASS_ATTRIBUTE2 CLASS_ATTRIBUTE3 {

}

Compilation Errors:

If more than one class is defined in a class file, a compilation error occurs.

Examples:

# Class attributes
class Point : public {

}

class Point : public pointer {

}

Version Declaration

The version keyword declares the version string of a module.

version VERSION_STRING;

The operand VERSION_STRING is a version string.

A version string is the string type.

It is composed of numbers 0-9, ..

The following checks are performed.

The version string is saved to the version information of the module.

Compilation Errors:

If the version string has already been declared, a compilation error occurs.

A character in a version string must be a number or .. Otherwise a compilation error occurs.

The number of . in a version string must be less than or equal to 1. Otherwise a compilation error occurs.

A version string must begin with a number. Otherwise a compilation error occurs.

A version string must end with a number. Otherwise a compilation error occurs.

The number of . in a version string must be less than or equal to 1. Otherwise a compilation error occurs.

The length of characters after . in a version string must be divisible by 3. Otherwise a compilation error occurs.

A version number must be able to be parsed by the strtod C function. Otherwise a compilation error occurs.

Examples:

class Foo {
  version "1";
}

class Foo {
  version "20080903";
}

class Foo {
  version "1.001";
}

class Foo {
  version "10.001003";
}

Version String

The version string is the string represented version of a module.

It is declared by the version declaration.

Version Number

The version number is a floating point number created by the following way.

A "Version Declaration" in version string is converted to a floating point number by the strtod C function.

Class Attribute

The list of class attributes.

Class attributes Descriptions
public This class is public. In other classes, this class can be used as I of new operator.
private This class is private. In other classes, this class cannot be used as I of new operator. This is default.
protected This class is protected. In other classes except for the child classes, this class cannot be used as I of new operator.
interface_t This class is an interface type. The class definition is interpreted as an interface definiton.
mulnum_t This class is a multi-numeric type. The class definition is interpreted as an multi-numeric type definiton.
pointer The class is a pointer class.
precompile Perform precompile to all methods in this class, except for getter methods, setter methods, and enumurations.

Compilation Errors:

Only one of class attributes private, protected or public can be specified. Otherwise a compilation error occurs.

If more than one of interface_t, mulnum_t, and pointer are specified, a compilation error occurs.

Destructor

A class can have a destructor.

method DESTROY : void () {

}

The destructor is the method that is called when the object is destroyed by the garbage collection.

The name of the destructor must be DESTROY.

A destructor cannnot have its arguments.

The retrun type must be void type.

A destructor must be an instance method.

If an exception occurs in the destructor, the exception is not thrown. Instead, a warnings message is printed to STDERR.

Compilation Errors:

If the definition of the destructor is invalid, a compilation error occurs.

Examples:

# Destructor
class Foo {
  method DESTROY : void () {
    print "DESTROY";
  }
}

The child class inherits the destructor of the parent class if the destructor of the current class doesn't eixst.

allow Statement

Private methods, private fields, and private class variables cannot be accessed except from the current class.

A private class cannot be OPERAND of the new operator except from the current class.

The allow statemenet allows the private access from the other classes.

allow CLASS_NAME;

The allow statemenet must be defined directory under the class definition.

The class that is OPERAND of the allow statemenet is loaded by the same way as the use statement.

Examples:

# Allowing private access
class Foo {
  allow Bar;
}

interface Statement

The interface statement guarantees the following things.

interface INTERFACE_NAME;

1. If the class has methods that are definied the the interface, each method must have the Method Compatibility of each interface method in the interface definition.

2. The class must have methods that defined as required interface methods in the the interface.

Compilation Errors:

If not, a compilation error occurs.

Examples:

class Point {
  interface Stringable;
  
  method to_string : string () {
    my $x = $self->x;
    my $y = $self->y;
    
    my $string = "($x,$y)";
    
    return $string;
  }
}

my $stringable = (Stringable)Point->new(1, 2);
my $string = $stringable->to_string;

Method Compatibility

(TODO)

Anon Class

The anon class is the class that do not has its class name.

class {

}

But internally an anon class has its name, such as eval::anon::0.

An anon class is also defined by the anon method.

A anon class for an anon method has its unique class name corresponding to the class name, the line number and the position of columns the anon class is defined.

A anon class for an anon method has the same access control as its outer class.

A anon class for an anon method has the same alias names as its outer class.

Examples:

# Anon class
class {
  static method sum : int ($num1 : int, $num2 : int) {
    return $num1 + $num2;
  }
}

# Anon method
class Foo::Bar {
  method sum : void () {
    my $anon_method = method : string () {
      
    }
 }
}

# The name of the anon class
Foo::Bar::anon::3::23;

Pointer Class

The pointer class is the class that has the class attribute pointer.

# Pointer Class
class Foo : pointer {

}

The type of a pointer class is the class type.

A object of a pointer class has the pointer to a native address.

Inheritance

A class inherits a class using the extends keyword.

class CLASS_NAME extends PARENT_CLASS_NAME {
  
}

The parts of the definitions of the fields of the all super classes are copied to the class.

The copied parts of the definitions are the field name, the type, the access controll.

The the definitions of the interfaces of the all super classes are copied to the class.

The copied order is from the beginning of the super class at the top level to the current class.

The class can call instance methods of the super classes. The searching order is from the current class to the super class at the top level.

Compilation Errors:

The parant class must be a class type. Otherwise a compilation error occurs.

The name of the parant class must be different from the name of the class. Otherwise a compilation error occurs.

The all super classes must be different from its own class. Otherwise a compilation error occurs.

The field that name is the same as the field of the super class cannnot be defined. Otherwise a compilation error occurs.

Examples:

class Point3D extends Point {
  
  has z : rw protected int;
  
  static method new : Point3D ($x : int = 0, $y : int = 0, $z : int = 0) {
    my $self = new Point3D;
    
    $self->{x} = $x;
    $self->{y} = $y;
    $self->{z} = $z;
    
    return $self;
  }
  
  method clear : void () {
    $self->SUPER::clear;
    $self->{z} = 0;
  }
  
  method to_string : string () {
    my $x = $self->x;
    my $y = $self->y;
    my $z = $self->z;
    
    my $string = "($x,$y,$z)";
    
    return $string;
  }
  
  method clone : object () {
    my $self_clone = Point3D->new($self->x, $self->y, $self->z);
    
    return $self_clone;
  }
}

Interface

The interface syntax is described.

Interface Definition

An interface is defined using a class definition with a "Class Attribute" in class attribute interface_t.

class Stringable: interface_t {
  required method to_string : string ();
  method foo : int ($num : long);
}

An interface can have interface methods. An interface method does not need its method block.

An interface can have required interface methods by using the method attribute required.

The type of the interface is the interface type.

An interface can have interface statements.

class TestCase::Pointable : interface_t {
  interface Stringable;
  
  method x : int ();
  method y : int();
  method to_string : string ();
}

An interface method can have its method block.

class Stringable: interface_t {
  method to_string : string ();
  method call_to_string : string () {
    return "foo " . $self->to_string;
  }
}

This method is only called by the static instance method call.

$self->Stringable::call_to_string;

Compilation Errors:

An interface cannnot have field definitions. If so, an compilation error occurs.

An interface cannnot have class variable definitions. If so, an compilation error occurs.

Duck Typing

The duck typing is supported.

class Stringable: interface_t {
  method to_string : string ();
}

class Point {
  
  method to_string : string () {
    my $x = $self->x;
    my $y = $self->y;
    
    my $string = "($x,$y)";
    
    return $string;
  }
}

my $stringable = (Stringable)Point->new(1, 2);
my $string = $stringable->to_string;

The Point class have no interfaces, but A object of the Point class can be assigned to a Stringable interface because the to_string method in the Point class has the method compatibility of the to_string method in the Strigable interface.

Class File Name

A class must be written in the following class file.

Change :: to /. Add ".spvm" at the end.

SPVM/Foo.spvm
SPVM/Foo/Bar.spvm
SPVM/Foo/Bar/Baz.spvm

use Statement

The use statemenet loads a class.

use Foo;

Classes are loaded at compile-time.

The use statemenet must be defined directly under the class definition.

class Foo {
  use Foo;
}

Compilation Errors:

If the class does not exist, a compilation error occurs.

alias Statement

The alias statemenet creates an alias name for a class name.

# Create alias
alias Foo::Bar as FB;

FB is used as Foo::Bar alias in class method calls.

# This means Foo::Bar->sum(1, 2);
FB->sum(1, 2);

alias syntax must be defined directly under the class definition.

class Foo {
  alias Foo::Bar as FB;
}

You can create an alias at the same time as loading a class by the use statement.

use Foo::Bar as FB;

require Statement

If the require statement that loads a class only if it exists in the class path, and if it does not exist, the block does not exist.

It was designed to implement a part of features of "#ifdef" in the C language.

if (require Foo) {

}

if require Statement can be followed by else Statement.

if (require Foo) {

}
else {

}

Note that elsif Statement cannot be followed.

Let's look at an example. if Foo does not exist, no a compilation error occurs and it is assumed that there is no if block

Therefore, "$foo = new Foo;" does not result in a compilation error because it is assumed that there is no if block.

In the other hand, the else block exists, so a warning is issued.

my $foo : object;
if (require Foo) {
  $foo = new Foo;
}
else {
  warn "Warning: Can't load Foo";
}

Default Loaded Classes

The following classes are loaded by default. These classes are deeply related to the features of SPVM language itself, such as type conversion.

Class Variable

A class variable is a global variable that has the name space.

Class Variable Definition

our keyword defines a class variable.

our CLASS_VARIABLE_NAME : TYPE;

A Class variable must be defined directly under the class definition.

The type must be a numeric type or an object type.

Class variable attributes can be specified.

our CLASS_VARIABLE_NAME : ATTRIBUTE TYPE;
our CLASS_VARIABLE_NAME : ATTRIBUTE1 ATTRIBUTE2 ATTRIBUTE3 TYPE;

Compilation Errors:

The class variable mame must follow the rule defined in the class variable name, and must not contain ::. Otherwise a compilation error occurs.

If a class name with the same name is defined, a compilation error occurs.

Examples:

class Foo {
  our $NUM1 : byte;
  our $NUM2 : short;
  our $NUM3 : int;
  our $NUM4 : long;
  our $NUM5 : float;
  our $NUM6 : double;

  our $NUM_PUBLIC : public int;
  our $NUM_RO : ro int;
  our $NUM_WO : wo int;
  our $NUM_RW : rw int;
}

Class Variable Attribute

The list of class variable attributes.

Class Variable Attributes Descriptions
public The class variable is public. The class variable can be accessed from other classes.
private The class variable is private. The class variable cannnot be accessed from other classes. This is default setting.
protected The class variable is protected. The class variable cannnot be accessed from other classes except for the child classes.
ro The class variable has its getter method.
wo The class variable has its setter method.
rw The class variable has its getter method and setter method.

Compilation Errors:

Only one of class variable attributes private, protected or public can be specified. Otherwise a compilation error occurs.

If more than one of ro, wo, and rw are specified, a compilation error occurs

Class Variable Accessor

A class variable method is a method that gets and sets a class variable.

Class Variable Getter Method

A class variable getter method is a method to perform the getting class variable.

It has no arguments. The return type is the same as the type of the class variable except that the type of the field is the byte type or the short type.

If the type of the class variable is the byte type or the short type, the return type is the int type.

It is defined by the ro or rw class variable attributes.

It is a method that name is the same as the class variable name removing $. For example, if the class variable name is $FOO, its getter method name is FOO.

Examples:

# Class variable getter method
class Foo {
  our $NUM : ro int;
  
  static method main : void {
    my $num = Foo->NUM;
  }
}

Class Variable Setter Method

A class variable setter method is a method to perform the setting class variable.

The return type is the void type.

It has an argument that type is the same as the type of the class variableexcept that the type of the field is the byte type or the short type.

If the type of the class variable is the byte type or the short type, the argument type is the int type.

It is defined by the wo or rw class variable attributes.

It is a method that name is the same as the class variable name removing $ and adding SET_ to the beginning. For example, if the class variable name is $FOO, its setter method name is SET_FOO.

Examples:

# Class variable setter method
class Foo {
  our $NUM : wo int;
  
  static method main : void {
    Foo->SET_NUM(3);
  }
}

Class Variable Initial Value

Each class variable is initialized with the "Initial Value" in initial value just after the program starts.

This initial value can be changed by using the INIT block.

# Change the initial value of the class variable using INIT block.
class Foo {
  our $VAR : int;

  INIT {
    $VAR = 3;
  }
}

Class Variable Access

The class variable access is an operator to set or get a class variable.

See the getting class varialbe and the setting class varialbe.

Field

Fields are the data that an object has.

Field Definition

The has keyword defines a field.

# The field definition
has FIELD_NAME : OPT_ATTRIBUTES TYPE;

# An examples
has name : string;
has age : protected int;
has max : protected rw int

The field is defined directly under the class block.

class MyClass {
  has name : string;
}

Field attributes can be specified.

Compilation Errors:

The field definition needs the type. The type must be a numeric type or an object type. Otherwise a compilation error occurs.

The field names must follows the rule of the field name. Otherwise a compilation error occurs.

Field names cannot be duplicated. If so, a compilation error occurs.

Field Attribute

The list of field attributes.

Attributes Descriptions
private This field is private. This field cannnot be accessed from other class. This is default setting.
protected This field is protected. This field cannnot be accessed from other class except for the child classes.
public This field is public. This field can be accessed from other class.
ro This field has its getter method. The getter method name is the same as the field name. For example, If the field names is foo, The getter method name is C.
wo This field has its setter method. The setter method name is the same as field names adding set_ to top. For example, If the field names is foo, The setter method name is set_foo.
rw This field has its getter method and its setter method.

A field getter method is an instance method. It has no arguments. The return type of a field getter method is the same as its field type, except for the byte and short type.

If the type of the field is the byte or short type, The return type of a field getter method is the int type.

A field setter method is an instance method. It has an argument. The type of the argument is the same as the field type. The return type is the void type.

If the type of the field is the byte or short type, The argument type of a field setter method is the int type.

Compilation Errors:

Only one of field attributes private, protected or public can be specified. Otherwise a compilation error occurs.

If more than one of ro, wo, and rw are specified at the same time, a compilation error occurs

Examples:

class Foo {
  has num1 : byte;
  has num2 : short;
  has num3 : int;
  has num4 : long;
  has num5 : float;
  has num6 : double;

  has num_public : public int;
  has num_ro : ro int;
  has num_wo : wo int;
  has num_rw : rw int;
}

Field Access

The field access is an operator to get or set the field.

INVOCANT->{FIELD_NAME}

The field access has three different syntax.

Compilation Errors:

If the invocant is different from the following three field access, a compilation error occurs.

If the field name does not found, a compilation error occurs

Field Access of the class

The field access of the class.

my $point = new Point;
$point->{x} = 1;
my $x = $point->{x};

See "Getting Field" to get the field of the class.

See "Setting Field" to set the field of the class.

Field Access of thethe multi-numeric type

The field access of the multi-numeric type.

my $z : Complex_2d;
$z->{re} = 1;
my $re = $z->{re};

See "Getting Multi-Numeric Field" to get the field of the multi-numeric type.

See "Setting Multi-Numeric Field" to set the field of multi-numeric type.

Field Access of the Multi-Numeric Reference via Derefernce

The field access of the multi-numeric reference via derefernce.

my $z : Complex_2d;
my $z_ref = \$z;
$z_ref->{re} = 1;
my $re = $z_ref->{re};

See "Getting Multi-Numeric Field via Dereference" to get the field of the multi-numeric reference via dereference.

See "Setting Multi-Numeric Field via Dereference" to set the field of the multi-numeric reference via dereference.

Method

a.

Method Definition

The method keyword defines a class method or an instance method.

# Static method
static method METHOD_NAME : RETURN_TYPE (ARG_NAME1 : ARG_TYPE1, ARG_NAME2 : ARG_TYPE2, ...) {
  
}

# Instance method
method METHOD_NAME : RETURN_TYPE (ARG_NAME1 : ARG_TYPE1, ARG_NAME2 : ARG_TYPE2, ...) {
  
}

Methods must be defined directly under the class definition.

Method names must be follow the rule of "Method Name".

The argument names must be follow the rule of "Local Variable Name".

The minimal length of arguments is 0. The max length of arguments is 255.

Defined methods can be called using "Method Call" syntax.

A method can have method attributes.

ATTRIBUTES static method METHOD_NAME : RETURN_TYPE (ARG_NAME1 : ARG_TYPE1, ARG_NAME2 : ARG_TYPE2, ...) {

}

A method has "Method Block" except for the case that the method has the native method attributes.

Compilation Errors:

The types of the arguments must be a numeric type, the multi-numeric type, an object type, or a reference type. Otherwise a compilation error occurs.

The type of the return value must be the void type, a numeric type, the multi-numeric type or an object type. Otherwise a compilation error occurs.

Optional Argument

The optional argument is the syntax to specify optional arguments.

static method METHOD_NAME : RETURN_TYPE (ARG_NAME1 : ARG_TYPE1, ARG_NAME2 : ARG_TYPE2 = DEFAULT_VALUE) {

}

# Deprecated
static method METHOD_NAME : RETURN_TYPE (ARG_NAME1 : ARG_TYPE1, ARG_NAME2 = DEFAULT_VALUE : ARG_TYPE2) {

}

Examples:

static method substr ($string : string, $offset : int, $length : int = -1) {
  # ...
}

my $string = "abc";
my $offset = 1;
my $substr = &substr($string, $offset);

# This is the same as the following code
my $string = "abc";
my $offset = 1;
my $length = -1;
my $substr = &substr($string, $offset, $length);

Class Method

A class method is defined with the static keyword.

static method sum : int ($num1 : int, $num2 : int) {
  # ...
}

A class method can be called from the class name.

# Call a class method
my $total = Foo->sum(1, 2);

If the class method is belong to the current class, a class method can be called using & syntax.

# Call a class method using C<&>
my $total = &sum(1, 2);

Instance Method

An instance method is defined without the static keyword.

method add_chunk : void ($chunk : string) {
  # ...
}

An instance method can be called from the object.

# Call an instance method
my $point = Point->new;
$point->set_x(3);

Method Attributes

Method attributes are attributes used in a method definition.

Attributes Descriptions
private This method is private. This method can not be accessed from other classes.
protected This method is protected. This method can not be accessed from other classes except for the child classes.
public This method is public. This method can be accessed from other classes. This is default setting.
precompile This method is a precompile method.
native This method is a native method.
required This method is required.
If C and C attributes cannnot used together. C can be only used in a method of a L. Compilation Errors: Only one of method attributes C, C or C can be specified. Otherwise a compilation error occurs. If the specifed attribute is not found or the way to specify is invalid, a compilation error occurs. Examples: # private method private method : int sum ($num1 : int, $num2 : int) { return $num1 + $num2; } # precompile method precompile method : int sum ($num1 : int, $num2 : int) { return $num1 + $num2; } # native method native method : int sum ($num1 : int, $num2 : int);

Native Method

A native method is the method that is written by native languages such as the C language, C++.

A native method is defined by the native method attribute.

native sum : int ($num1 : int, $num2 : int);

A native method doesn't have its method block.

About the way to write native methods, please see SPVM Native Class and SPVM Native API.

Precompiled Method

If the class has the precompile class attribute, the methods of the class are precompiled.

The source code of each precompiled method is translated to C source code and is compiled to the machine code such as MyMath.o.

And it is linked to a shared library such as MyMath.so on Linux/Unix, MyMath.dll on Windows, or MyMath.dylib on Mac.

And each function in the shared library is bind to the SPVM method.

Precompiled methods need the build directory such as ~/.spvm_build to compile and link them.

Enumeration

The enumeration is the syntx to defines constant values of the int type.

Enumeration Definition

The enum keyword defines an enumeration. An enumeration has definitions of constant values.

# Enumeration Definition
enum {
  FLAG1,
  FLAG2,
  FLAG3
}

An enumeration must be defined directly under the class definition.

class Foo {
  enum {
    FLAG1,
    FLAG2,
    FLAG3
  }
}

The name given to an enumeration value must be a method name.

The first enumeration value is 0. The next enumeration value is incremented by 1, and this is continued in the same way.

In the above example, FLAG1 is 0, FALG2 is 1, and FLAG3 is 2.

The type of an enumeration value is the int type.

, after the last enumeration value can be allowed.

enum {
  FLAG1,
  FLAG2,
  FLAG3,
}

An enumeration value can be set by = explicitly.

enum {
  FLAG1,
  FLAG2 = 4,
  FLAG3,
}

In the above example, FLAG1 is 0, FALG2 is 4, and FLAG3 is 5.

An enumeration value is got by the getting enumeration value.

Compilation Errors:

If an enumeration definition is invalid, a compilation error occurs.

Examples:

class Foo {
  enum {
    FLAG1,
    FLAG2,
    FLAG3,
  }
}

Enumeration Attributes

Attributes can be specified to an enumeration definition.

private enum {
  FLAG1,
  FLAG2 = 4,
  FLAG3,
}

The list of enumeration attributes:

Attributes Descriptions
private This enumeration is private. Each value of this enumeration can not be accessed from other classes.
protected This enumeration is protected. Each value of this enumeration can not be accessed from other classes except for the child classes.
public This enumeration is public. Each value of this enumeration can be accessed from other classes. This is default setting.

Compilation Errors:

Only one of enumeration attributes private, protected or public can be specified. Otherwise a compilation error occurs.

Getting Enumeration Value

A value of the enumeration can be got using the class method call.

my $flag1 = Foo->FLAG1;
my $flag2 = Foo->FLAG2;
my $flag3 = Foo->FLAG3;

A getting enumeration value is replaced to an interger literal at compilation time.

For this, if an enumeration value is changed after first publication to users, the binary compatibility is not kept.

An enumeration value can be used as an operand of the case statement.

switch ($num) {
  case Foo->FLAG1: {
    # ...
  }
  case Foo->FLAG2: {
    # ...
  }
  case Foo->FLAG3: {
    # ...
  }
  default: {
    # ...
  }
}

Local Variable

Local Variable Declaration

Local Variable is a variable that is declared in "Scope Block". Local Variable has the scope. This is the same as Local Variable in C Language.

The local variable is declared using my "Keyword".

my LOCAL_VARIABLE_NAME : TYPE;

The local variable name must be follow the rule of "Local Variable Name".

the type must be specified. Type must be a numeric type, an object type, the multi-numeric type, or a reference type.

# Local Variable Declaration Examples
my $var : int;
my $var : Point;
my $var : Complex_2d;
my $var : int*;

The local variable is initialized by "Local Variable Initial Value".

# Initialized by 0
my $num : int;

# Initialized by 0
my $num : double;

# Initialized by undef
my $point : Point;

# x is initialized by 0. y is initialized by 0.
my $z : Complex_2d;

The initialization of the local variable can be written at the same time as the local variable declaration.

# Initialized by 1
my $num : int = 1;

# Initialized by 2.5
my $num : double = 2.5;

# Initialized by Point object
my $point : Point = new Point;

The type can be omitted using the type inference,

# Type inference - int
my $num = 1;

# Type inference - double
my $num = 1.0;

The local variable declaration returns the value of the local variable. The return type is the type of the local variable.

my $ppp = my $bar = 4;

if (my $bar = 1) {

}

while (my $bar = 1) {

}

See the scope about the scope of the local variable.

Local Variable Initial Value

The local variable is initialized by the "Initial Value" in initial value.

Local Variable Access

The local variable Access is an operator to access Local Variable to get or set the value.

See "Getting Local Variable" to get Local Variable value.

"Setting Local Variable" to get Local Variable value.

If "Class Variable" with the same name as the Local Variable exists, Program uses the variable as Local Variable, not "Class Variable".

Scope

A scope is the part that is surrounded by a scope block.

# Scope block
{
  # Beginning of scope
  
  my $point = Point->new;
  
  # End of scope
}

When a object that is not undef is assigned to a local variable, the reference count is incremented by 1.

At the end of scope, the reference count is decremented by 1. If the reference count becomes 0, the object will be destroyed.

See also garbage collection.

Block

A block is the part that is enclosed by { and }.

Blocks are the class block, the enumeration block, and the scope blocks.

Examples:

# Blocks
{
  1;
}

if (true) {
  
}

while (true) {
  
}

enum {
  ONE,
  TWO,
}

class Foo {
  
}

Class Block

A class block is a block.

# Class block
class Point {

}

Enumeration Block

An enumeration block is a block.

# Enumeration block
enum {
  ONE,
  TWO,
}

Scope Block

A scope block is the block that has the scope. Zero or more statements are written in a scope block.

Scope blocks are the simple block, the method block, the eval block, the if block, the elsif block, the else block, the for block, the while block and the switch block.

Simple Block

The simple block is a scope block.

# Simple block
{
  1;
}

The simple block must have at least one statements. Otherwise it is intepreted as the array initialization.

Method Block

The method block is a scope block.

# Method block
static method foo : int () {

}

eval Block

The eval block is a scope block.

# eval block
eval {

}

if Block

The if block is a scope block.

# if block
if (CONDITION) {

}

elsif Block

The elsif block is a scope block.

# elsif block
elsif (CONDITION) {

}

else Block

The else block is a scope block.

# else block
else {

}

for Block

The for block is a scope block.

# for Block 
for (my $i = 0; $i < 3; $i++) {

}

while Block

The while block is a scope block.

# while block
while (CONDITION) {

}

switch Block

The switch block is a scope block.

# switch block
switch (CONDITION) {

}

case Block

The case block is a scope block.

# case block
switch (CONDITION) {
  case CASE_VALUE1: {
    # ...
  }
}

default Block

The default block is a scope block.

# default block
switch (CONDITION) {
  default: {
    # ...
  }
}

INIT Block

The INIT block is a block to be executed just after the program starts.

INIT {
  
}

The INIT block must be defined directly under the class definition.

class Foo {
  INIT {
    
  }
}

Zero or more statements can be written in a INIT block.

INIT {
  my $foo = 1 + 1;
  my $bar;
}

The return statement cannot be written in INIT block.

If a INIT block is not defined in a class, a default empty INIT block is defined.

An INIT block is editted.

If a parent class exists, the INIT block of the parent class is called at the beginning of the INIT block.

If classes are used by the use statement, the interface statement, and the allow statement, The INIT blocks in the classes are called in order after the above calling.

# Before Editting
class MyClass extends ParentClass {
  use Foo;
  use Bar;
  
  INIT {
    $POINT = Point->new(1, 2);
  }
}

# After Editting
class MyClass extends ParentClass {
  use Point;
  use Fn;
  
  INIT {
    ParentClass->INIT;
    Point->INIT;
    Fn->INIT;
    
    $POINT = Point->new(1, 2);
  }
}

An INIT block is automatically called only once.

The execution order of INIT blocks is not guaranteed. The INIT blocks in the "Default Loaded Classes" in default loaded class are called before INIT blocks of user defined classes.

Examples:

class Foo {
  use Point;
  
  our $NUM : int;
  our $STRING : string;
  our $POINT : Point;
  
  # INIT block
  INIT {
    $NUM = 3;
    $STRING = "abc";
    
    $POINT = Point->new(1, 2);
  }
}

String

SPVM has the string type. A string is created by "String Literal" "String Creating Operator" or "Type Convertion" to the string type.

# Create a string using a string literal
my $string = "Hello";

# Create a string using a string creation operator
my $string = new_string_len 3;

# Create a string using the type cast to the string type
my $bytes = [(byte)93, 94, 95];
my $string = (string)$bytes;

The each charcter can be get using ->[].

# String
my $string = "Hello";
my $char0 = $string->[0];
my $char1 = $string->[1];
my $char2 = $string->[2];

By default, each character cannnot be set.

# a compilation error.
$string_const->[0] = 'd';

If you use mutable type qualifier|/"mutable Type Qualifier", each character can be set.

my $string_mut = (mutable string)$string;
$string_mut->[0] = 'd';

The created string is one more last byte that value is \0 on the internal memory. Although this has no meaning from SPVM language, this has meaning from Native APIs.

The length of the string can be got using a string length operator

# Getting the length of the string
my $message = "Hello"+
my $length = length $message;

Undefined Value

An undefined value is represented by undef.

undef

An undefined value can be assigned to an object type.

In the level of native APIs, undef is defined as (void*)NULL.

(void*)NULL

An undefined value can be compared by the == operator and the != operator. An undefined value is guaranteed not to be equal to the any created object.

The type of undef is undef type

Examples:

# Undefine values
my $string : string = undef;

if (undef) {
  
}

my $message = "Hello";
if ($message == undef) {
  
}

Array

The array is the data structure for multiple values.

There are the following types of array.

  • Numeric Array
  • Object Array
  • Multi-Numeric Array

The numeric array is the array that the type of the element is the numeric type.

The object array is the array that the type of the element is the object type.

The multi-numeric array is the array that the type of the element is the multi-numeric type.

See "Creating Array" to create Array.

Array Access

Array Access is an operator to access the element of Array to get or set the value.

ARRAY->[INDEX]

See "Getting Array Element" to get the element value of Array.

See "Setting Array Element" to set the element value of Array.

Multi-Numeric Value

A multi-numeric value is a value that represents continuous multiple numeric values in memory.

Multi-Numeric Type Definition

A multi-numeric type is defined by the class definition that has the mulnum_t class attribute.

# Continuous two 64bit floating point
class Complex_2d : mulnum_t {
  re : double;
  im : double;
}

The type of a field must be a numeric type.

The types of all fields must be the same types.

The length of the fields must be less than or equal to 255.

The multi-numeric type must end with the following suffix.

_[FieldsLength][TypeSuffix]

The length of the fields in the suffix must be the same as the length of the fields.

The type suffix in the suffix must correspond to the numeric type that is explained in the multi-numeric type suffix.

See the multi-numeric type field access to get and set the field of the multi-numeric type.

Multi-Numeric Type Suffix

The list of the multi-numeric type suffix.

Numeric Type Type Suffix
byte b
short s
int i
long l
float f
double d

Multi-Numeric Type Field Access

The multi-numeric type field access is an syntax to access the field of the multi-numeric value.

MULTI_NUMERIC_VALUE->{FIELD_NAME}

See "Getting Multi-Numeric Field" to get the field of the multi-numeric value.

See "Setting Multi-Numeric Field" to set the field of the multi-numeric value.

Multi-Numeric Array

The multi-numeric values can be the elements of the array.

my $zs = new Complex_2d[3];

The elements of the multi-numeric array is continuous multi-numeric values.

| Complex_2d  | Complex_2d  | Complex_2d  |
|  re  |  im  |  re  |  im  |  re  |  im  |

Multi-Numeric Array Access

The multi-numeric array access is a syntax to access the element of the multi-numeric array.

ARRAY->[INDEX]

See "Getting Array Element" to get the element of the array.

See "Setting Array Element" to set the element of the array.

Reference

The reference is the address of a local variable on the memory.

Creating Reference

The reference operator creates the reference of a local variable.

A reference is assigned to the "Reference Type" in reference type.

The operand of a reference operator must be the variable of a numeric type or a multi-numeric type.

# The reference of numeric type
my $num : int;
my $num_ref : int* = \$num;

# The reference of multi-numeric type
my $z : Complex_2d;
my $z_ref : Complex_2d* = \$z;

The reference type can be used as the types of the arguments of a method.

# Method Definition
static method sum : void ($result_ref : int*, $num1 : int, $num2 : int) {
  $$result_ref = $num1 + $num2;
}

# Method Call
my $num1 = 1;
my $num2 = 2;
my $result_ref = \$result;
sum($result_ref, $num1, $num2);

Dereference

The dereference is the operation to get the value from a reference.

A dereference operator perform a dereference.

# Get the value using a dereference
my $num2 = $$num_ref;

# Set the value using a dereference
$$num_ref = 3;

# Get the value of a multi-numeric type using a dereference
my $z2 = $$z_ref;

# Set the value of a multi-numeric type using a dereference
$$z_ref = $z2;

In the referencec of multi-numeric types, the deference can be performed using the arrow operator ->.

# Get a field of a multi-numeric type using a dereference
my $x = $z_ref->{re};

# Set a field of a multi-numeric type using a dereference
$z_ref->{re} = 1;

Type

SPVM language has data types.

See Data type - Wikipedia about data types.

Initial Value

The list of initial values.

Type Name Initial Value
byte 0
short 0
int 0
long 0
float 0 (All bits are 0)
double 0 (All bits are 0)
Object Type undef
Multi-Numeric Type All fields are set to 0 (All bits are 0)

Numeric Type

The numeric type are an integer type and "Floating Point Type".

Numeric Type Order

a numeric type has the type order. The order is "byte", "short", "int", "long", "float", "double" from the smallest.

Integer Type

Integral types are the following four types.

Type Description Size
byte signed 8-bit integer type 1 byte
short signed 16-bit integer type 2 bytes
int signed 32-bit integer type 4 bytes
long signed 64-bit integer type 8 bytes

Note that SPVM has only singed integer types, and doesn't have unsigned integer types.

Integer Type Within int

The integer type within int is an integer type within the int type.

In other words, the integer types within int are the byte type, the short type, and the int type.

byte Type

byte type is an integer type that represents a signed 8-bit integer. This is the same type as int8_t type of the C language.

short Type

short type is an integer type that represents a signed 16-bit integer. This is the same type as int16_t type of the C language.

int Type

int type is is an integer type that represents signed 32-bit integer. This is the same as int32_t type of the C language.

long Type

long type is an integer type that represents a signed 64-bit integer. This is the same type as int64_t type of the C language.

Floating Point Type

Floating Point Type are the following two.

Type Description Size
float Single precision (32bit) floating point type 4 bytes
double Double precision (64bit) floating point type 8 bytes

float Type

The float type is a floating point type that represents a single precision(32bit) floating point. This is the same type as float type of the C language.

double Type

The double type is a floating point type that represents a double precision(64bit) floating point. This is the same type as double type of the C language.

Class Type

The class type is the type that can create the object using a new operator.

new ClassType;

Basic Object Type

Basic object types are the class type, the array type, the string type, and the any object type.

Object Type

Object types are the basic object types and the array types.

A object type can be assigned to a any object type.

my $object: object = new Foo;
my $object: object = "abc";

Numeric Object Type

A numeric object type is the object type that is corresponding to the numeric type.

The list of numeric object types:

Numeric Object Type Corresponding Numeric Type
Byte byte
Short short
Int int
Long long
Float float
Double double

See also the boxing conversion and "Unboxing Conversion".

undef Type

The undef type is the type of undef value.

Interface Type

The interface type is a type that is defined using a class keyword and a class attribute interface_t.

class Stringable : interface_t {
  method to_string : string ();
}

See also "Interface".

Note that interface types are not class types although they are defined by class keyword.

Any Object Type

Any Object Type is represented by "object". Designed to represent the "void *" Type in C.

my $object: object;

You can methodstitute the value of "Object Type" for Any Object Type.

my $object: object = new Foo;
my $object: object = "abc";
my $object: object = new Foo [3];

void Type

void Type is a special Type that can only be used in the return type of the method definition and indicates the method has no return value.

void

Basic Type

The basic types are numeric types, multi-numeric types, the class type, the any object type, and the string type.

Another definition of basic types are the types that is not array types and can become the element of array types.

Array Type

The array type is the type for the array. The array type is composed of the basic type and the dimension such as [], [][].

# Numeric array
int[]
double[]

# String array
string []

# Class array
Point[]

# Any object array
object[]

# 2 dimensional array
int[][]

# 3 dimensional array
int[][][]

The array type is an object type.

Compilation Errors:

The maximam value of dimesions is 255. Otherwise a compilation error occurs.

Numeric Array Type

The numeric array type is an array type for the array of the numeric type.

The list of the numeric array.

  • byte[]

  • short[]

  • int[]

  • long[]

  • float[]

  • double[]

Each element are initialized by the "Initial Value" in initial value when the creating array is performed.

byte[] Type

The byte[] type is an array type that the element type is byte.

byte[]

Object Array Type

Object array types are the array type that the type of the element is an object type.

Examples:

# Object array types
my $points : Point[];
my $points_2dim : Point[][];
my $stringables : Stringable[];
my $strings : string[];
my $objects : object[];

String Array Type

String array types are the array type that the type of the element is the string type.

Examples:

# String array types
my $strings : string[];

Class Array Type

Class array types are the array type that the type of the element is the class type.

Examples:

# Class array types
my $points : Point[];

Interface Array Type

Interface array types are the array type that the type of the element is the interface type.

Examples:

# Interface array types
my $stringables : Stringable[];

Multi-Dimensional Array Type

The multi-dimensional array type is the array type that the type of the element is an array type.

Examples:

# Multi-dimensional array types
my $nums_2dim : Int[][];

Multi-Numeric Array Type

A multi-numeric array type is an array type that the basic type is a multi-numeric type.

  • Complex_2d[]
  • Complex_2f[]

The byte size of the element is the total byte size of the fields of the multi-numeric type.

For example, The byte size of the element of Complex_2d is 16 bytes (2 * 8 bytes).

The object of the multi-numeric array type can be created by the new operator.

my $complex_nums = new Complex_2d[10];

Any Object Array Type

The any object array type object[] is the type that any object array type can be assigned.

# Any object array Type
my $array : object[] = new Point[3];
my $array : object[] = new object[3];
my $array : object[] = new Point[][3];

Any Object Array Type is an array type.

You can get the array length using the array length operator.

my $array : object[] = new Int[3];

# Getting the length of the element of Any Object Array Type
my $length = @$array;

You can get and set the element using the get array element syntax and the set array element.

# Getting the element of any object array
my $num = (Int)$array->[0];

# Setting the element of any object array
$array->[0] = Int->new(5);

When setting the element of any object array, the element type is checked. If the dimension of the element is not the dimension of the array - 1, an exception is thrown.

Compilation Errors:

If a invalid type is assigned, a compilation error occurs.

string Type

The string type is a type for the "String".

string

string type can be qualified by "mutable Type Qualifier".

mutable string

Examples:

# string type
my $message : string = "Hello";
my $message : mutable string = new_string_len 256;

Multi-Numeric Type

The multi-numeric type is the type to represent a multi-numeric value.

The multi-numeric type can be used as the type of the local variable declaration.

my $z : Complex_2d;

The value is initialized by the "Initial Value" in initial value.

The multi-numeric type can be used as an argument the type in the method definition.

The multi-numeric type can be used as the return type of the method definition.

static method add_double_complex : Complex_2d ($z1 : Complex_2d, $z2 : Complex_2d) { ... }

The multi-numeric type can be used as a basic type of the array type .

my $points = new Complex_2d[5];

The reference can be created for the value of the multi-numeric type.

my $z : Complex_2d;
my $z_ref = \$z;

undef cannot be assigned to the multi-numeric type.

Reference Type

Reference Type is a Type that can store the address of a variable. Add * after a numeric type or the multi-numeric type You can define it.

my $num : int;
my $num_ref : int* = \$num;

my $z : Complex_2d;
my $z_ref : Complex_2d* = \$z;

Only the address of the Local Variable acquired by "Reference Operator" can be assigned to the value of Reference Type.

Reference Type can be used as Type of argument in the method definition.

Reference Type cannot be used as return value Type in the method definition.

Reference Type cannot be used as the field type in the class definition.

Reference Type cannot be used as the type of Class Variable in the class definition.

See "Reference" for a detailed explanation of Reference.

Compilation Errors:

If only Local Variable Declaration of Reference Type is performed, a compilation error occurs

Reference Type can be used as Type of the local variable declaration. The address of the Local Variable must be stored by the Reference Operator. In case of only Local Variable Declaration, a compilation error occurs

If the Reference Type is used at an Invalid location, a compilation error occurs

Reference Type

Reference Type are "Numeric Reference Type" and "Multi-Numeric Reference Type".

Numeric Reference Type

Numeric Reference Type means a numeric type for a reference type. Says.

Multi-Numeric Reference Type

Multi-Numeric Reference Type means a reference type for the multi-numeric type variables. > Means.

Type Qualifier

Type qualifiers qualify the type.

QUALIFIER TYPE

mutable Type Qualifier

The mutable type qualifier is used to allow to set the character of the string.

my $string : mutable string;

Examples:

# Mutable string
my $message = (mutable string)"abc";
$message->[0] = 'd';

Type Inference

Omitting the type when the local variable declaration by Type Inference can. Type Inference is always performed by the type on the Right side of Assignment Operator.

# int
my $num = 1;

# double
my $num = 1.0;

# Foo
my $foo = new Foo;

Assignability

The assignability at compile-time is explained.

Compilation Errors:

The assignability is false, a compilation error occurs.

Assignability to Numeric

Explains the assignability to the numeric types.

Assignability from Numeric to Numeric

If the nemric type order of LEFT_OPERAND is greater than or equal to the nemric type order of RIGHT_OPERAND, the assignability is true.

If the nemric type order of LEFT_OPERAND is greater than the nemric type order of RIGHT_OPERAND, the numeric widening conversion is performed.

AssignabilityToFromImplicite Type Conversion
TruebytebyteNone
TrueshortshortNone
TrueintintNone
TruelonglongNone
TruefloatfloatNone
TruedoubledoubleNone
TrueshortbyteNumeric Widening Conversion
TrueintbyteNumeric Widening Conversion
TruelongbyteNumeric Widening Conversion
TruefloatbyteNumeric Widening Conversion
TruedoublebyteNumeric Widening Conversion
TrueintshortNumeric Widening Conversion
TruelongshortNumeric Widening Conversion
TruefloatshortNumeric Widening Conversion
TruedoubleshortNumeric Widening Conversion
TruelongintNumeric Widening Conversion
TruefloatintNumeric Widening Conversion
TruedoubleintNumeric Widening Conversion
TruefloatlongNumeric Widening Conversion
TruedoublelongNumeric Widening Conversion
TruedoublefloatNumeric Widening Conversion

Examples:

# int to int
my $num : int = 3;

# byte to int
my $num : int = (byte)5;

# double to double
my $num : double = 4.5;

# float to double
my $num : double = 4.5f;

If the nemric type order of LEFT_OPERAND is less than the nemric type order of RIGHT_OPERAND, the assignability is conditional true.

The condition is that RIGHT_OPERAND is a interger literal and the value is between the max and minimal value of the type of LEFT_OPERAND.

If the condition is ture, the numeric narrowing conversion is performed.

AssignabilityToFromImplicite Type Conversion
Conditional TruebyteshortNumeric Narrowing Conversion
Conditional TruebyteintNumeric Narrowing Conversion
Conditional TruebytelongNumeric Narrowing Conversion
FalsebytefloatNone
FalsebytedoubleNone
Conditional TrueshortintNumeric Narrowing Conversion
Conditional TrueshortlongNumeric Narrowing Conversion
FalseshortfloatNone
FalseshortdoubleNone
Conditional TrueintlongNumeric Narrowing Conversion
FalseintfloatNone
FalseintdoubleNone
FalselongfloatNone
FalselongdoubleNone
FalsefloatdoubleNone

Examples:

# int to byte
my $num : byte = 127;

Assignability from NumericObject to Numeric

If the type of LEFT_OPERAND is a numeric type corresponding to the numeric object type of RIGHT_OPERAND and the type of RIGHT_OPERAND is a numeric object type, the assignability is true.

AssignabilityToFromImplicite Type Conversion
TruebyteByteUnboxing Conversion
TrueshortShortUnboxing Conversion
TrueintIntUnboxing Conversion
TruelongLongUnboxing Conversion
TruefloatFloatUnboxing Conversion
TruedoubleDoubleUnboxing Conversion

Examples:

my $int : int = Int->new(3);

my $double : double = Double->new(3.5);

Assignability from Any Object to Numeric

If the type of LEFT_OPERAND is a numeric type and the type of RIGHT_OPERAND is a any object type object, the assignability is true.

The unboxing conversion corresponding to the numeric type is performed.

AssignabilityToFromImplicite Type Conversion
TrueNUMERIC_XobjectUnboxing Conversion

Examples:

my $int : int = (object)Int->new(3);

my $double : double = (object)Double->new(3.5);

Assignability from Others to Numeric

If the type of LEFT_OPERAND is a numeric type and the type of RIGHT_OPERAND is other than the types described above, the assignability is false.

Assignability to Multi-Numeric

If the type of LEFT_OPERAND is a multi-numeric type and the type of RIGHT_OPERAND is the same type of LEFT_OPERAND, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueMULNUM_XMULNUM_XNone
FalseMULNUM_XOTHERNone

Examples:

my $z1 : Complex_2d;
my $z2 : Complex_2d = $z1;

Assignability to Referenece

If the type of LEFT_OPERAND is a reference type and the type of RIGHT_OPERAND is the same type of LEFT_OPERAND, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueREF_XREF_XNone
FalseREF_XOTHERNone

Examples:

my $num : int = 5;
my $num_ref : int* = \num;

Assignability to String

If the type of LEFT_OPERAND is the string type without the mutable type qualifier and the type of RIGHT_OPERAND is the string type, the assignability is true.

If the type of LEFT_OPERAND is the string type with the mutable type qualifier and the type of RIGHT_OPERAND is the string type with the mutable type qualifier, the assignability is true.

If the type of LEFT_OPERAND is the string type with the mutable type qualifier and the type of RIGHT_OPERAND is the string type without the mutable type qualifier, the assignability is false.

If the type of LEFT_OPERAND is the string type and the type of RIGHT_OPERAND is a numeric type or the undef type, the assignability is true.

If the type of RIGHT_OPERAND is a numeric type, the numeric-to-string conversion is performed.

AssignabilityToFromImplicite Type Conversion
TruestringstringNone
Truestringmutable stringNone
Truemutable stringmutable stringNone
Falsemutable stringstringNone
TruestringstringNone
TruestringNUMERIC_Xnumeric-to-string conversion
TruestringundefNone
FalsestringOTHERNone

Examples:

my $string : string = "abc";
my $num_string : string = 3;
my $string : string = undef;

Assignability to NumericObject

If the type of LEFT_OPERAND is a numeric object type and the type of RIGHT_OPERAND is the same type of LEFT_OPERAND, a numeric type that is corresponding to the numeric object type, or the undef type, the assignability is true.

Otherwise, the assignability is false.

If the type of RIGHT_OPERAND is a numeric type, the boxing conversion is performed.

AssignabilityToFromImplicite Type Conversion
TrueNUMERIC_OBJECT_XNUMERIC_OBJECT_XNone
TrueNUMERIC_OBJECT_XNUMERIC_XBoxing Conversion
TrueNUMERIC_OBJECTundefNone
FalseNUMERIC_OBJECTOTHERNone

Examples:

my $num_object : Int = Int->new(3);
my $num_object : Int = 3;
my $num_object : Int = undef;

Assignability to Class

If the type of LEFT_OPERAND is a class type and the type of RIGHT_OPERAND is the same type, or the undef type, the assignability is true.

If the type of LEFT_OPERAND is a super class of the type of RIGHT_OPERAND, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueCLASS_XCLASS_XNone
TrueCLASSundefNone
TrueSUPER_CLASS_XCLASS_YNone
FalseCLASSOTHERNone

Examples:

my $point : Point = Point->new;
my $point : Point = undef;

Assignability to Interface

If the type of LEFT_OPERAND is an interface type and the type of RIGHT_OPERAND is the same type, or the undef type, the assignability is true.

If the type of LEFT_OPERAND is an interface type and the type of RIGHT_OPERAND is a class type and the class has the same interface of LEFT_OPERAND, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueINTERFACE_XINTERFACE_XNone
TrueINTERFACE_XINTERFACE_HAVING_YNone
TrueINTERFACEundefNone
FalseINTERFACEOTHERNone

Examples:

# Point has Stringable interface
my $stringable : Stringable = Point->new(1, 2);
my $stringable : Stringable = undef;

Assignability to Any Object

If the type of LEFT_OPERAND is the any object type and the type of RIGHT_OPERAND is an object type, a numeric type or the undef type, the assignability is true.

Otherwise, the assignability is false.

If the type of RIGHT_OPERAND is a numeric type, the boxing conversion is performed.

AssignabilityToFromImplicite Type Conversion
TrueobjectOBJECT_YNone
TrueobjectNUMERIC_XBoxing Conversion
TrueobjectundefNone
FalseobjectOTHERNone

Examples:

my $object : object = Point->new;
my $num_object : object = 3;
my $object : object = undef;

Assignability to Undefined

If the type of LEFT_OPERAND is the undef type, the assignability is false.

AssignabilityToFromImplicite Type Conversion
Falseundef TypeOTHERNone

Examples:

# The assignability is false
undef = Point->new;

Assignability to Numeric Array

If the type of LEFT_OPERAND is a numeric array type and the type of RIGHT_OPERAND is the same type of LEFT_OPERAND or the undef type, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
Truebyte[]byte[]None
Trueshort[]short[]None
Trueint[]int[]None
Truelong[]long[]None
Truefloat[]float[]None
Truedouble[]double[]None
TrueNUMERIC[]undefNone
FalseNUMERIC[]OTHERNone

Examples:

my $nums : int[] = new int[3];
my $nums : int[] = undef;

Assignability to Multi-Numeric Array

If the type of LEFT_OPERAND is a multi-numeric array type and the type of RIGHT_OPERAND is the same type of LEFT_OPERAND or the undef type, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueMULNUM_X[]MULNUM_X[]None
TrueMULNUM_X[]undefNone
FalseMULNUM_X[]OTHERNone

Examples:

my $nums : Complex_2d[] = new Complex_2d[3];
my $nums : Complex_2d[] = undef;

Assignability to String Array

If the type of LEFT_OPERAND is a string array type and the type of RIGHT_OPERAND is the same type of LEFT_OPERAND or the undef type, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
Truestring[]string[]None
Truestring[]undefNone
Falsestring[]OTHERNone

Examples:

my $strings : string[] = ["abc", "def"];
my $strings : string[] = undef;

Assignability to Class Array

If the type of LEFT_OPERAND is a class array type and the type of RIGHT_OPERAND is the same type of LEFT_OPERAND or the undef type, the assignability is true.

If the basic type of LEFT_OPERAND is an super class of the type of RIGHT_OPERAND, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueCLASS_X[]CLASS_X[]None
TrueSUPER_CLASS_X[]CLASS_Y[]None
TrueCLASS_X[]undefNone
FalseCLASS_X[]OTHERNone

Examples:

my $points : Point[] = new Point[3];
my $points : Point[] = undef;

Assignability to Interface Array

If the type of LEFT_OPERAND is an interface array type and the type of RIGHT_OPERAND is the same type of LEFT_OPERAND or the undef type, the assignability is true.

If the type of LEFT_OPERAND is an interface array type and the type of RIGHT_OPERAND is a class array type and its basic type can assign to the basic type of LEFT_OPERAND, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueINTERFACE_X[]INTERFACE_X[]None
TrueINTERFACE_X[]undefNone
TrueINTERFACE_X[]INTERFACE_HAVING_Y[]None
FalseINTERFACE_X[]OTHERNone

Examples:

my $stringables : Stringable[] = new Stringable[3];

my $stringables : Stringable[] = new Point[3];

my $stringables : Stringable[] = undef;

Assignability to Any Object Array

If the type of LEFT_OPERAND is the any object array type object[] and the type of RIGHT_OPERAND is an object array type or the undef type, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
Trueobject[]OBJECT_ARRAY_YNone
Trueobject[]undefNone
Falseobject[]OTHERNone

Examples:

my $any_objects0 : object[];
my $any_objects : object[] = $any_objects0;

my $points : Point[];
my $any_object : object[] = $points;

my $any_object : object[] = undef;

my $points_2dim : Point[][];
my $any_object : object[] = $points_2dim;

my $stringables : Stringable[];
my $any_object : object[] = $stringables;

my $strings : string[];
my $any_object : object[] = $strings;

Assignability to Multi-Dimensional Array

If the type of LEFT_OPERAND is a multi-dimensional array type and the type of RIGHT_OPERAND is the same type of LEFT_OPERAND or the undef type, the assignability is true.

If the type dimesion of LEFT_OPERAND is equal to the type dimension of RIGHT_OPERAND, and the basic type of LEFT_OPERAND is a super class of the basic type of RIGHT_OPERAND, the assignability is true.

If the type dimesion of LEFT_OPERAND is equal to the type dimension of RIGHT_OPERAND, and the basic type of RIGHT_OPERAND has the basic type of LEFT_OPERAND, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueX[]..[]X[]..[]None
Trueobject[]undefNone
TrueSUPER_CLASS_X[]..[]CLASS_Y[]..[]None
TrueINTERFACE_X[]..[]INTERFACE_HAVING_Y[]..[]None
Falseobject[]OTHERNone

([]..[] means two or more [])

Examples:

my $points_2dim : Point[][];
my $muldim_array : Point[][] = $points_2dim;

my $muldim_array : Point[][] = undef;

my $strings_2dim : String[][];
my $muldim_array : Stringable[][] = $strings_2dim;

{
  my $cb = method : string ($object : object) {
    my $point = (Point)$object;
    return $point->to_string;
  };
  my $muldim_array : Stringer[][] = [[$cb]];
}

Castability

The castability at compile-time is explained.

Compilation Errors:

The castability is false, a compilation error occurs.

Castability to Numeric

The castability to the numeric types is explained.

Castability from Numeric to Numeric

If the type of LEFT_OPERAND is a numeric type and the type of RIGHT_OPERAND is a numeric type, the castability is true.

If the nemric type order of LEFT_OPERAND is greater than the nemric type order of RIGHT_OPERAND, the numeric widening conversion is performed.

If the nemric type order of LEFT_OPERAND is less than the nemric type order of RIGHT_OPERAND, the numeric narrowing conversion is performed.

If the nemric type order of LEFT_OPERAND is equal to the nemric type order of RIGHT_OPERAND, copying is performed.

CastabilityToFromConversion or Type Checking
TruebytebyteNone
TrueshortshortNone
TrueintintNone
TruelonglongNone
TruefloatfloatNone
TruedoubledoubleNone
TrueshortbyteNumeric Widening Conversion
TrueintbyteNumeric Widening Conversion
TruelongbyteNumeric Widening Conversion
TruefloatbyteNumeric Widening Conversion
TruedoublebyteNumeric Widening Conversion
TrueintshortNumeric Widening Conversion
TruelongshortNumeric Widening Conversion
TruefloatshortNumeric Widening Conversion
TruedoubleshortNumeric Widening Conversion
TruelongintNumeric Widening Conversion
TruefloatintNumeric Widening Conversion
TruedoubleintNumeric Widening Conversion
TruefloatlongNumeric Widening Conversion
TruedoublelongNumeric Widening Conversion
TruedoublefloatNumeric Widening Conversion
TruebyteshortNumeric Narrowing Conversion
TruebyteintNumeric Narrowing Conversion
TruebytelongNumeric Narrowing Conversion
TruebytefloatNumeric Narrowing Conversion
TruebytedoubleNumeric Narrowing Conversion
TrueshortintNumeric Narrowing Conversion
TrueshortlongNumeric Narrowing Conversion
TrueshortfloatNumeric Narrowing Conversion
TrueshortdoubleNumeric Narrowing Conversion
TrueintlongNumeric Narrowing Conversion
TrueintfloatNumeric Narrowing Conversion
TrueintdoubleNumeric Narrowing Conversion
TruelongfloatNumeric Narrowing Conversion
TruelongdoubleNumeric Narrowing Conversion
TruefloatdoubleNumeric Narrowing Conversion

Examples:

# int to int
my $num = (int)3;

# byte to int
my $num_byte : byte = 5;
my $num = (int)5;

# double to double
my $num = (double)4.5;

# float to double
my $num = (double)4.5f;

# int to byte
my $num = (byte)127;

# double to int
my $num = (int)2.5;

Castability from NumericObject to Numeric

If the type of LEFT_OPERAND is a numeric type corresponding to the numeric object type of RIGHT_OPERAND and the type of RIGHT_OPERAND is a numeric object type, the castability is true.

CastabilityToFromConversion or Type Checking
TruebyteByteUnboxing Conversion
TrueshortShortUnboxing Conversion
TrueintIntUnboxing Conversion
TruelongLongUnboxing Conversion
TruefloatFloatUnboxing Conversion
TruedoubleDoubleUnboxing Conversion

Examples:

my $int = (int)Int->new(3);

my $double = (double)Double->new(3.5);

Castability from Any Object to Numeric

If the type of LEFT_OPERAND is a numeric type and the type of RIGHT_OPERAND is a any object type object, the castability is true.

The unboxing conversion corresponding to the numeric type is performed.

CastabilityToFromConversion or Type Checking
TrueNUMERIC_XobjectUnboxing Conversion

Examples:

my $object : object = Int->new(3);
my $int = (int)$object;

my $object : object = Double->new(3.5);
my $double = (double)$object;

Castability from Others to Numeric

If the type of LEFT_OPERAND is a numeric type and the type of RIGHT_OPERAND is other than the types described above, the castability is false.

Castability to Multi-Numeric

If the type of LEFT_OPERAND is a multi-numeric type and the type of RIGHT_OPERAND is the same type of LEFT_OPERAND, the castability is true.

Otherwise, the castability is false.

CastabilityToFromConversion or Type Checking
TrueMULNUM_XMULNUM_XNone
FalseMULNUM_XOTHERNone

Examples:

my $z1 : Complex_2d;
my $z2 = (Complex_2d)$z1;

Castability to Referenece

If the type of LEFT_OPERAND is a reference type and the type of RIGHT_OPERAND is the same type of LEFT_OPERAND, the castability is true.

Otherwise, the castability is false.

CastabilityToFromConversion or Type Checking
TrueREF_XREF_XNone
FalseREF_XOTHERNone

Examples:

my $num : int = 5;
my $num_ref = (int*)\num;

Castability to String

If the type of LEFT_OPERAND is the string type and the type of RIGHT_OPERAND is the string type, the castability is true.

If the type of LEFT_OPERAND is the string type with the mutable type qualifier and the type of RIGHT_OPERAND is the string type without the mutable type qualifier, the runtime type checking is performed.

If the type of RIGHT_OPERAND is a numeric type, the numeric-to-string conversion is performed.

If the type of LEFT_OPERAND is the string type and the type of RIGHT_OPERAND is a numeric type, the undef type, or the any object type object, the castability is true.

If the type of RIGHT_OPERAND is a numeric type, the numeric-to-string conversion is performed.

If the type of LEFT_OPERAND is the string type and the type of RIGHT_OPERAND is the any object type object, the castability is true and the runtime type checking is performed.

CastabilityToFromConversion or Type Checking
TruestringstringNone
Truestringmutable stringNone
Truemutable stringmutable stringNone
Truemutable stringstringRuntime type checking
TruestringstringNone
TruestringNUMERIC_XNumeric-to-String Conversion
TruestringobjectRuntime type checking
TruestringundefNone
FalsestringOTHERNone

Examples:

my $string = (string)"abc";
my $num_string = (string)3;
my $string : string = undef;

Castability to NumericObject

If the type of LEFT_OPERAND is a numeric object type and the types of RIGHT_OPERANDs are the following cases:

If the type of RIGHT_OPERAND is the same type of LEFT_OPERAND, a numeric type that is corresponding to the numeric object type, the any object type object, or the undef type, the castability is true.

The type of RIGHT_OPERAND is other than above, the castability is false.

If the type of RIGHT_OPERAND is a numeric type, the boxing conversion is performed.

If the type of LEFT_OPERAND is the type of RIGHT_OPERAND is the any object type object, the runtime type checking is performed.

CastabilityToFromConversion or Type Checking
TrueNUMERIC_OBJECT_XNUMERIC_OBJECT_XNone
TrueNUMERIC_OBJECT_XNUMERIC_XBoxing Conversion
TrueNUMERIC_OBJECTobjectRuntime type checking
TrueNUMERIC_OBJECTundefNone
FalseNUMERIC_OBJECTOTHERNone

Examples:

my $num_object = (Int)Int->new(3);
my $num_object = (Int)3;
my $num_object = (Int)undef;

my $object : object = Int->new(3);
my $num_object = (Int)$object;

Castability to Class

If the type of LEFT_OPERAND is a class type and the types of RIGHT_OPERANDs are the following cases:

If the type of RIGHT_OPERAND is the same type, the any object type object, an interface type or the undef type, the castability is true.

If the type of LEFT_OPERAND is a super class of the type of right operand, the castability is true.

If the type of RIGHT_OPERAND is a super class of the type of left operand, the castability is true.

Otherwise, the castability is false.

If the type of RIGHT_OPERAND is the any object type object or an interface type, the runtime type checking is performed.

CastabilityToFromConversion or Type Checking
TrueCLASS_XCLASS_XNone
TrueSUPER_CLASS_XCLASS_YNone
TrueCLASS_XSUPER_CLASS_YRuntime type checking
TrueCLASS_XINTERFACE_YRuntime type checking
TrueCLASS_XobjectRuntime type checking
TrueCLASSundefNone
FalseCLASSOTHERNone

Examples:

my $point : Point = Point->new;

my $stringable : Stringable;
my $point = (Point)$stringable;

my $stringer : Stringer;
my $point = (Point)$stringer

my $point = (Point)undef;

Castability to Interface

If the type of LEFT_OPERAND is an interface type, and the types of RIGHT_OPERANDs are the following cases:

If the type of RIGHT_OPERAND is the same type, the any object type object , an interface type or the undef type, the castability is true.

If the type of RIGHT_OPERAND is a class type and the class has the interface of LEFT_OPERAND, the castability is true.

Otherwise, the castability is false.

If the type of RIGHT_OPERAND is the any object type object, an interface type, the runtime type checking is performed.

CastabilityToFromConversion or Type Checking
TrueINTERFACE_XINTERFACE_XNone
TrueINTERFACE_XINTERFACE_HAVING_YNone
TrueINTERFACE_XINTERFACE_YRuntime type checking
TrueINTERFACE_XobjectRuntime type checking
TrueINTERFACEundefNone
FalseINTERFACEOTHERNone

Examples:

my $stringable1 : Stringable;
my $stringable2 = (Stringable)$stringable1;

my $cloneable : Cloneable;
my $stringable = (Stringable)$cloneable;

my $stringable  = (Stringable)Point->new(1, 2);

my $object : object  = Point->new(1, 2);
my $stringable  = (Stringable)Point->new(1, 2);

my $stringable : Stringable = undef;

Castability to Any Object

If the type of LEFT_OPERAND is the any object type and the types of RIGHT_OPERANDs are the following cases:

If the type of RIGHT_OPERAND is an object type, a numeric type or the undef type, the castability is true.

Otherwise, the castability is false.

If the type of RIGHT_OPERAND is a numeric type, the boxing conversion is performed.

CastabilityToFromConversion or Type Checking
TrueobjectOBJECT_YNone
TrueobjectNUMERIC_XBoxing Conversion
TrueobjectundefNone
FalseobjectOTHERNone

Examples:

my $object : object = Point->new;
my $num_object : object = 3;
my $object : object = undef;

Castability to Numeric Array

If the type of LEFT_OPERAND is the byte[] type and the type of RIGHT_OPERAND is the string type, the castability is true.

If the type of LEFT_OPERAND is a numeric array type and the types of RIGHT_OPERANDs are the following cases:

If the type of RIGHT_OPERAND is the same type of LEFT_OPERAND, the any object type obejct or the undef type, the castability is true.

Otherwise, the castability is false.

If the type of LEFT_OPERAND is the byte[] type and the type of RIGHT_OPERAND is the string type, "String-to-byte[] Conversion" is performed.

If the type of RIGHT_OPERAND is the any object type obejct, the runtime type checking is performed.

CastabilityToFromConversion or Type Checking
Truebyte[]stringString-to-byte[] Conversion
TrueNUMERIC_X[]NUMERIC_X[]None
TrueNUMERIC[]objectRuntime type checking
TrueNUMERIC[]undefNone
FalseNUMERIC[]OTHERNone

Examples:

my $bytes = (byte[])"abc";

my $nums = (int[])new int[3];

my $object : object = new int[3];
my $nums = (int[])$object;

my $nums = (int[])undef;

Castability to Multi-Numeric Array

If the type of LEFT_OPERAND is a multi-numeric array type and the types of RIGHT_OPERANDs are the following cases:

If the type of RIGHT_OPERAND is the same type of LEFT_OPERAND, the any object type obejct or the undef type, the castability is true.

Otherwise, the castability is false.

If the type of RIGHT_OPERAND is the any object type obejct, the runtime type checking is performed.

CastabilityToFromConversion or Type Checking
TrueMULNUM_X[]MULNUM_X[]None
TrueMULNUM_X[]objectRuntime type checking
TrueMULNUM_X[]undefNone
FalseMULNUM_X[]OTHERNone

Examples:

my $nums = (Complex_2d[])new Complex_2d[3];

my $object : object = new Complex_2d[3];
my $nums = (Complex_2d[])$object;

my $nums = (Complex_2d[])undef;

Castability to String Array

If the type of LEFT_OPERAND is a string array type and the types of RIGHT_OPERANDs are the following cases:

If the type of RIGHT_OPERAND is the same type of LEFT_OPERAND, the any object type obejct, the any object array type obejct[] or the undef type, the castability is true.

Otherwise, the castability is false.

If the type of RIGHT_OPERAND is the any object type obejct, or the any object array type obejct[], the runtime type checking is performed.

CastabilityToFromConversion or Type Checking
Truestring[]string[]None
Truestring[]objectRuntime type checking
Truestring[]object[]Runtime type checking
Truestring[]undefNone
Falsestring[]OTHERNone

Examples:

my $strings = (string[])["abc", "def"];

my $object : object = ["abc", "def"];
my $strings = (string[])$object;

my $objects : object[] = ["abc", "def"];
my $strings = (string[])$object;

my $strings  = (string[])undef;

Castability to Class Array

If the type of LEFT_OPERAND is a class array type and the types of RIGHT_OPERANDs are the following cases:

If the basic type of LEFT_OPERAND is a super class of the basic type of RIGHT_OPERAND, the castability is true.

If the basic type of RIGHT_OPERAND is a super class of the basic type of LEFT_OPERAND, the castability is true.

If the type of RIGHT_OPERAND is the same type of LEFT_OPERAND, the any object type obejct, the any object array type obejct[] or the undef type, the castability is true.

Otherwise, the castability is false.

If the type of RIGHT_OPERAND is the any object type obejct, or the any object array type obejct[], the runtime type checking is performed.

CastabilityToFromConversion or Type Checking
TrueCLASS_X[]CLASS_X[]None
TrueSUPER_CLASS_X[]CLASS_Y[]None
TrueCLASS_X[]SUPER_CLASS_Y[]Runtime type checking
TrueCLASS_X[]objectRuntime type checking
TrueCLASS_X[]object[]Runtime type checking
TrueCLASS_X[]undefNone
FalseCLASS_X[]OTHERNone

Examples:

my $points = (Point[])new Point[3];

my $object : object = new Point[3];
my $points = (Point[])$object;

my $objects : object[] = new Point[3];
my $points = (Point[])$object;

my $points = (Point[])undef;

Castability to Interface Array

If the type of LEFT_OPERAND is an interface array type and the types of RIGHT_OPERANDs are the following cases:

If the type of RIGHT_OPERAND is a class array type and its basic type has the interface of the basic type of LEFT_OPERAND, the castability is true.

If the type of RIGHT_OPERAND is the same type of LEFT_OPERAND, the castability is true.

If the type of RIGHT_OPERAND is an differnt type of interface array type, the castability is also true.

If the type of RIGHT_OPERAND is the any object type obejct, the any object array type obejct[] or the undef type, the castability is true.

Otherwise, the castability is false.

If the type of RIGHT_OPERAND is an differnt type of interface array type, the runtime type checking is performed.

If the type of RIGHT_OPERAND is the any object type obejct, or the any object array type obejct[], the runtime type checking is performed.

CastabilityToFromConversion or Type Checking
TrueINTERFACE_X[]INTERFAECE_HAVING_Y[]None
TrueINTERFACE_X[]INTERFACE_X[]None
TrueINTERFACE_X[]INTERFACE_Y[]Runtime type checking
TrueINTERFACE_X[]objectRuntime type checking
TrueINTERFACE_X[]object[]Runtime type checking
TrueINTERFACE_X[]undefNone
FalseINTERFACE_X[]OTHERNone

Examples:

my $stringables = (Stringable[])new Stringable[3];

my $stringables = (Stringable[])new Point[3];

my $stringables = (Stringable[])undef;

Castability to Any Object Array

If the type of LEFT_OPERAND is the any object array type object[] and the types of RIGHT_OPERANDs are the following cases:

If the type of RIGHT_OPERAND is an object array type or the undef type, the castability is true.

If the type of RIGHT_OPERAND is an any object type, the castability is true.

Otherwise, the castability is false.

If the type of RIGHT_OPERAND is an any object type, the runtime type checking is performed.

CastabilityToFromConversion or Type Checking
Trueobject[]OBJECT_ARRAY_YNone
Trueobject[]undefNone
Trueobject[]objectRuntime type checking
Falseobject[]OTHERNone

Examples:

my $any_object : object;
my $any_objects = (object[])$any_object;

my $any_objects0 : object[];
my $any_objects = (object[])$any_objects0;

my $points : Point[];
my $any_object = (object[])$points;

my $any_object = (object[])undef;

my $points_2dim : Point[][];
my $any_object = (object[])$points_2dim;

my $stringables : Stringable[];
my $any_object = (object[])$stringables;

my $strings : string[];
my $any_object = (object[])$strings;

Castability to Multi-Dimensional Array

If the type of LEFT_OPERAND is a multi-dimensional array type and and the types of RIGHT_OPERANDs are the following cases:

If the type of RIGHT_OPERAND is the same type of LEFT_OPERAND or the undef type, the castability is true.

If the type of RIGHT_OPERAND is an any object type, the castability is true.

If the type dimesion of LEFT_OPERAND is equal to the type dimension of RIGHT_OPERAND, and the basic type of LEFT_OPERAND is a super class of the basic type of RIGHT_OPERAND, the castability is true.

If the type dimesion of LEFT_OPERAND is equal to the type dimension of RIGHT_OPERAND, and the basic type of RIGHT_OPERAND is a super class of the basic type of LEFT_OPERAND, the castability is true.

If the basic type of the type of LEFT_OPERAND is an interface type and the basic type of the type of RIGHT_OPERAND is a class type and the dimension of the type of RIGHT_OPERAND is the same as the dimension of the type left oerand and the basic type of the type of RIGHT_OPERAND has the interface of the basic type of the type of LEFT_OPERAND , the castability is true.

Otherwise, the castability is false.

CastabilityToFromConversion or Type Checking
TrueANY_X[]..[]ANY_X[]..[]None
TrueANY_X[]..[]objectRuntime type checking
TrueANY_X[]..[]object[]Runtime type checking
TrueANY_X[]..[]undefNone
TrueSUPER_CLASS_X[]..[]CLASS_Y[]..[]None
TrueCLASS_X[]..[]SUPER_CLASS_Y[]..[]Runtime type checking
TrueINTERFACE_X[]..[]INTERFACE_HAVING_Y[]..[]None
Falseobject[]OTHERNone

([]..[] means two or more [])

Examples:

my $points_2dim : Point[][];
my $muldim_array : Point[][] = $points_2dim;

my $muldim_array : Point[][] = undef;

my $strings_2dim : String[][];
my $muldim_array : Stringable[][] = $strings_2dim;

{
  my $cb = method : string ($object : object) {
    my $point = (Point)$object;
    return $point->to_string;
  };
  my $muldim_array : Stringer[][] = [[$cb]];
}

Type Conversion

Type conversion is explained.

Explicite Type Conversion

The explicite type conversion is the type conversion performed by a type cast expicitely.

Examples:

# The explicte type conversion from long to int 
my $num = (int)123L;

# The explicte type conversion from byte[] to string
my $num = (string)new byte[3];

# The explicte type conversion from string to byte[]
my $num = (byte[])"Hello";

Implicite Type Conversion

The implicite type conversion is the type conversion performed implicitly when a value is assigned using assignment operator, pass an argument to a method using a method call, or set a return value using the return statement.

See "Assignability" if you know when implicite type conversion is performed.

Examples:

# The implicite type conversion from int to double 
my $num : double = 5;

# The implicite type conversion from double to Double
my $num_object : Double = 5.1;

# The implicite type conversion from Double to double
my $num : double = Double->new(5.1);

# The implicite type conversion from int to string
my $string : string = 4;

Integer Promotional Conversion

The integer promotional conversion is a type conversion to convert an integer type within int to the int type using the numeric widening conversion.

Numeric Widening Conversion

The numeric widening conversion is a type conversion from a small-order numeric type to a large-order numeric type.

See also numeric types order abount the order of numeric type.

The return value of a converion are same as the return value of the type cast of the C language.

(TYPE)OPERAND

byte to short:

int8_t from = VALUE;
int16_t to = (int16_t)from;

byte to int:

int8_t from = VALUE;
int32_t to = (int32_t)from;

byte to long:

int8_t from = VALUE;
int64_t to = (int64_t)from;

byte to float:

int8_t from = VALUE;
float to = (float)from;

byte to double:

int8_t from = VALUE;
double to = (double)from;

short to int:

int16_t from = VALUE;
int32_t to = (int32_t)from;

short to long:

int16_t from = VALUE;
int64_t to = (int64_t)from;

short to float:

int16_t from = VALUE;
float to = (float)from;

short to double:

int16_t from = VALUE;
double to = (double)from;

int to long:

int32_t from = VALUE;
int64_t to = (int64_t)from;

int to float:

int32_t from = VALUE;
float to = (float)from;

int to double:

int32_t from = VALUE;
double to = (double)from;

long to float:

int64_t from = VALUE;
float to = (float)from;

long to double:

int64_t from = VALUE;
double to = (double)from;

The numeric widening conversion is performed in some of the type casts, the index of the array access, the length of the creating array, OPERAND of the unary plus operator, OPERAND of the unary minus operator, and the left and right operands of the shift operators.

Numeric Narrowing Conversion

The numeric narrowing conversion is a conversion from a wide numeric type to a narrow numeric type.

See also numeric types order abount the order of numeric type.

The return value of a converion are same as the return value of the type cast of the C language.

(TYPE)OPERAND

double to float:

double from = value;
float to = (float)from;

double to long:

double from = value;
int64_t to = (int64_t)from;

double to int:

double from = value;
int32_t to = (int32_t)from;

double to short:

double from = value;
int16_t to = (int16_t)from;

double to byte:

double from = value;
int8_t to = (int8_t)from;

float to long:

float from = value;
int64_t to = (int64_t)from;

float to int:

float from = value;
int32_t to = (int32_t)from;

float to short:

float from = value;
int16_t to = (int16_t)from;

float to byte:

float from = value;
int8_t to = (int8_t)from;

long to int:

int64_t from = value;
int32_t to = (int32_)from;

long to short:

int64_t from = value;
int16_t to = (int16_t)from;

long to byte:

int64_t from = value;
int8_t to = (int8_t)from;

int to short:

int32_t from = value;
int16_t to = (int16_t)from;

int to byte:

int32_t from = value;
int16_t to = (int16_t)from;

short to byte:

int16_t from = value;
int8_t to = (int8_t)from;

The numeric narrowing conversion is performed in some of the type casts.

Binary Numeric Conversion

The binary numeric conversion is a type conversion to upgrade the type of LEFT_OPERAND or RIGHT_OPERAND of the binary operator that operands are numeric types.

The following rules apply in order.

1. If LEFT_OPERAND or RIGHT_OPERAND is the double type, OPERAND of the small type is converted to the big type using the numeric widening conversion.

2. If LEFT_OPERAND or RIGHT_OPERAND is the float type, OPERAND of the small type is converted to the big type using the numeric widening conversion.

3. If LEFT_OPERAND or RIGHT_OPERAND is the long type, OPERAND of the small type is converted to the big type using the numeric widening conversion.

4, Otherwise, both LEFT_OPERAND and RIGHT_OPERAND are converted to the int type using the numeric widening conversion.

Numeric-to-String Conversion

The numeric-to-string conversion is a type conversion from a numeric type to the string type.

# The numeric-to-string conversion
my $byte = (byte)1;
my $short = (short)2;
my $int = 3;
my $long = 4L;
my $float = 2.5f;
my $double = 3.3;

# The string is 1.
my $string_byte = (string)$byte;

# The string is 2.
my $string_short = (string)$short;

# The string is 3.
my $string_int = (string)$int;

# The string is 4.
my $string_long = (string)$long;

# The string is "2.5"
my $string_float = (string)$float;

# The string is "3.3"
my $string_double = (string)$double;

String-to-byte[] Conversion

The String-to-byte[] conversion is a type conversion from the string Type to "byte[] Type".

# The String-to-byte[] conversion
my $string : string = "Hello";
my $bytes : byte[] = (byte[])$string;

A new byte[] object is created and all characters in the string are copied to the elements of byte[] object.

byte[]-to-string Conversion

The byte[]-to-string conversion is a type conversion from the byte[] type to the string Type.

# byte[]-to-string conversion
my $bytes : byte[] = new byte[3];
$bytes->[0] = 'a';
$bytes->[1] = 'b';
$bytes->[2] = 'c';
my $string : string = (string)$bytes;

A new string is created and all elements in the byte[] object are copied to the characters of the string.

Boxing Conversion

The boxing conversion is a type coversion to convert the value of numeric type to the corresponding numeric object type.

Unboxing Conversion

The unboxing conversion is a type coversion to convert the value of the numeric object type to the value of the corresponding numeric type.

Boolean Conversion

The boolean conversion is a type conversion that is performed on the conditional operand.

The boolean conversion returns the following value corresponding to the type of the condional operand.

If the type is the int type, return the value.

If the type is the undef, returns 0.

If the type is the value returned by the TRUE method of Bool, returns 1.

If the type is the value returned by the FALSE method of Bool, returns 0.

If the type is an integer type within int, the integer promotional conversion is performed on OPERAND.

And the following operation in the C language is performed on OPERAND .

!!OPERAND

Compilation Errors:

The type of OPERAND of the boolean conversion must be a numeric type, an object type or an reference type or the undef type. Otherwise a compilation error occurs.

Examples:

if (1) {
  # ok
}

if (0) {
  # not ok
}

if (1.5) {
  # ok
}

if (0.0) {
  # not ok
}

if (true) {
  # ok
}

if (Bool->TRUE) {
  # ok
}

if (false) {
  # not ok
}

if (Bool->FALSE) {
  # not ok
}

my $object = SPVM::Int->new(1);

if ($object) {
  # ok
}

$object = undef;
if ($object) {
  # not ok
}

my $value = 1;
my $ref = \$value;

if ($ref) {
  # ok
}

if (undef) {
  # not ok
}

Conditional Operand

List of conditional operands:

The operand of the if statement:

if (CONDITION) {

}

The operand of the unless statement:

unless (CONDITION) {

}

The second operand of the for statement:

for (INITIALIZEATION;CONDITION;NEXT_VALUE;) {

}

The operand of the while statement:

while (CONDITION) {

}

The left and right operand of the logical AND operator:

CONDITION && CONDITION

The left and right operand of the logical OR operator:

CONDITION || CONDITION

The operand of the logical NOT operator:

!CONDITION

Runtime Type Checking

The runtime type cheking is the type cheking that is performed at runtime.

The type cast operators that operand is an object type performe the runtime type checking by the rule of the "Runtime Assignability" in runtime assignability.

Runtime Assignability

The runtime assignability is the assignability at runtime.

The isa operator checks the "Runtime Assignability" in runtime assignability

The runtime assignability is false, an exception is thrown.

If the type of the distribution is an object type and the type of the source is undef, the runtime assignability is true.

If the type of the distribution is the same as the type of the source, the runtime assignability is true.

If the type of the distribution is the any object type object and the type of the source is an object type, the runtime assignability is true.

If the type of the distribution is the any object array type object[] and the type of the source is an object array type, the runtime assignability is true.

If the type of distribution is an class type, an class array type, an class multi-dimensional array type and the dimention of the type of the distribution is the same as the dimention of the type of the source and the basic type of distribution is a super class of the basic type of the source, the runtime assignability is true.

If the type of distribution is an interface type, an interface array type, an interface multi-dimensional array type and the dimention of the type of the distribution is the same as the dimention of the type of the source and the basic type of distribution has the interface of the basic type of the source, the runtime assignability is true.

Runtime AssignabilityToFrom
TrueOBJECT_Xundef
TrueOBJECT_XOBJECT_X
TrueobjectOBJECT_Y
Trueobject[]OBJECT_ARRAY_Y
TrueSUPER_CLASS_XCLASS_Y
TrueSUPER_CLASS_X[]CLASS_Y[]
TrueSUPER_CLASS_X[]..[]CLASS_Y[]..[]
TrueINTERFACE_XINTERFACE_HAVING_Y
TrueINTERFACE_X[]INTERFACE_HAVING_Y[]
TrueINTERFACE_X[]..[]INTERFACE_HAVING_Y[]..[]
FalseOBJECT_XOTHER

([]..[] means two or more [])

Type Comment

The type comment syntax is supported. The type comment can be written after of keyword.

TYPE of TYPE
TYPE of TYPE1|TYPE2
TYPE of TYPE1|TYPE2|TYPE3

The type comment can be used the type of the field decralation, the class variable definition, the local variable declaration, and the return value and the types of arguments of the method definition.

has points : List of Point;

our $POINTS : List of Point;

my $points : List of Point;

static method foo : List of Point ($arg : List of Point) { ... }

my $replace : object of string|Regex::Replacer;

Type comments have no meanings at runtime.

Compilation Errors:

If the type specified as the type comment is not found, a compilation error occurs.

Statement

Statements are the list of the statement.

Statements are written direct under the scope block.

# Scope block
{
  # Statements
  STATEMENT1
  STATEMENT2
  STATEMENT3
}

Conditional Branch

The conditional branch is explained in the following topics.

if Statement

The if statement is a statement for conditional branch.

if (CONDITION) {

}

First, The boolean conversion is performed on the condition.

Next, if the condition is not 0, the execution position jumps to the beginning of the if block. Otherwise jumps to the end of the if block.

The local variable declartion and the initialization in the condition of the if statement are allowed.

if (my $condition = 1) {

}

This is parsed as the following code.

{
  my $condition = 1;
  if ($condition) {
  
  }
}

Examples:

# if statement.
my $flag = 1;

if ($flag == 1) {
  print "One\n";
}

elsif Statement

The elsif statement is a statement for conditional branch used with the if statement.

if (CONDITION1) {

}
elsif (CONDITION2) {

}

If the condition 1 doesn't match, the execution position jumps to the end of the if block.

Next, The boolean conversion is performed on the condition 2.

Next, if the condition 2 is not 0, the execution position jumps to the beginning of the elsif block. Otherwise jumps to the end of the elsif block

Multiple elsif statements are allowed.

if (CONDITION1) {

}
elsif (CONDITION2) {

}
elsif (CONDITION3) {

}

The local variable declartion and the initialization in the condition of the elsif statement are allowed.

if (my $condition = 1) {

}
elsif (my $condition = 2) {

}

This is parsed as the following code.

{
  my $condition = 1;
  if ($condition) {
    
  }
  else {
    my $condition = 2;
    if ($condition) {
      
    }
  }
}

Examples:

# elsif statement.
my $flag = 2;

if ($flag == 1) {
  print "One\n";
}
elsif ($flag == 2) {
  print "Two\n";
}

else Statement

The else statement is a statement for conditional branch used with the if statement or the elsif statement.

if (CONDITION) {

}
else {

}

If the condition doesn't match, the execution position jumps to the end of the if block.

Next, the execution position jumps to the beginning of the else block.

The elsif statements with the else statement are allowed.

if (CONDITION1) {

}
elsif (CONDITION2) {

}
else {

}

Examples:

# else statement.
my $flag = 3;

if ($flag == 1) {
  print "One\n";
}
elsif ($flag == 2) {
  print "Two\n";
}
else {
  print "Other";
}

unless Statement

The unless statement is a statement for conditional branch that does the opposite of the if statement.

unless (CONDITION) {
  
}

The unless statement is the same as the following if Statement.

if (!CONDITION) {
  
}

The unless statements with the elsif statement and the else statement are allowed.

unless (CONDITION1) {
  
}
elsif (CONDITION2) (
  
}
else {
  
}

Examples:

# unless statement.
my $flag = 1;

unless ($flag == 0) {
  print "Not Zero\n";
}

switch Statement

The switch statement is a statement for conditional branch.

switch (CONDITION) {
  case CASE_VALUE1: {
    # ...
  }
  case CASE_VALUE2: {
    # ...
  }
  case CASE_VALUE3: {
    # ...
  }
  default: {
    # ...
  }
}

The integer promotional conversion is performed on the condition.

The value of the case statement must be one of the character literal, the integer literal or the getting enumeration value.

If it is a character literal, the value is converted to the int type at compile-time.

If the condition matches the value of a case statement, the program jumps to the beginning of the case block.

If the condition doesn't match any case statements and the default statement exists, the program jumps to the beginning the default block.

If the condition doesn't match any case statements and the default statement doesn't exists, the program jumps to the end of the switch block.

The case statements and the default statement can be ommited.

The break statement jumps to the end of the switch block.

switch (CONDITION) {
  case CASE_VALUE1: {
    break;
  }
  case CASE_VALUE2: {
    break;
  }
  case CASE_VALUE3: {
    break;
  }
  default: {
    
  }
}

If the last statment of the case block is not the break statement, a break statement is added to the end of the case block.

# The break statement is ommitted.
switch (CONDITION) {
  case CASE_VALUE1: {
  }
}

# The above becomes the following.
switch (CONDITION) {
  case CASE_VALUE1: {
    break;
  }
}

Multiple case statements before a case block can be specified at once.

switch (CONDITION) {
  case CASE_VALUE1:
  case CASE_VALUE2:
  {
    # ...
  }
}

Compilation Errors:

The condition must be an integer type within int. Otherwise a compilation error occurs.

The values of the case statements cannnot be duplicated. If so, a compilation error occurs.

Examples:

# switch statement
my $code = 2;
my $flag = 1;
switch ($code) {
  case 1: {
    print "1\n";
  }
  case 2: {
    print "2\n";
  }
  case 3: {
    if ($flag) {
      break;
    }
    print "3\n";
  }
  case 4:
  case 5:
  {
    print "4 or 5\n";
  }
  default: {
    print "Other\n";
  }
}

# switch statement using enumeration
class Foo {
  enum {
    ID1,
    ID2,
    ID3,
  }
  
  static method main : int () {
    my $value = 1;
    switch ($value) {
      case Foo->ID1: {
        print "1\n";
      }
      case Foo->ID2: {
        print "2\n";
      }
      case Foo->ID3: {
        if ($flag) {
          break;
        }
        print "3\n";
      }
      default: {
        print "Other\n";
      }
    }
  }
}

case Statement

The case statement is the statement that specifies a case value and a branch of a switch statement.

# The case statement
switch (CONDITION) {
  case CASE_VALUE1: {
    # ...
  }
}

default Statement

The default statement is a statement that specifies a default branch of a switch statement.

# The default statement
switch (CONDITION) {
  default: {
    # ...
  }
}

break Statement

The break statement is a statement to jump to the end of the switch block of the switch statement.

# The break statement
break;

Loop Syntax

while Statement

The while statement is a statement for loop.

while (CONDITION) {

}

First, The boolean conversion is performed on the condition.

Next, If the condition is 0, the program jumps to the end of the while block. Otherwise the program goes to the beginning of the while block.

When the program reaches the end of the while block, it jumps back to the while statement and evaluates the condition again.

Examples:

# The while statement
my $i = 0;
while ($i < 5) {

  print "$i\n";

  $i++;
}

The last statement is used inside the while block. By The last statement, the program jumps to the end of the current while block.

# The last statement
while (1) {
  # The program jumps to the end fo the current while block.
  last;
}

The next statement is used inside the while block. By The last statement, the program goes back to the while statement of the current while block.

my $i = 0;
while ($i < 5) {

  if ($i == 3) {
    $i++;
    
    # the program goes back to the while statement of the current while block.
    next;
  }
  
  print "$i\n";
  $i++;
}

The while statement is enclosed by an inbisible simple block.

# The while statement
while (1) {
  
}

# The above is the same as the following.
{
  while (1) {
    
  }
}

for Statement

The for Statement is a statement to write loop syntax easily.

# The for statement.
for (INIT_STATEMENT; CONDITION; INCREMENT_STATEMENT) {

}

The for statement is the alias for the while statement.

# The above for statemenet is the same as the following while statemenet.
{
  INIT_STATEMENT;
  while (CONDITION) {
    
    # ...
    
    INCREMENT_STATEMENT;
  }
}

Exampels:

# The for statement
for (my $i = 0; $i < 5; $i++) {
  print "$i\n";
}

for-each Statement

The for-each statement is a statement to write loop syntax easily for the simple iteration.

# The for-each statemenet
for my VAR (@ARRAY) {

}

for my VAR (@{ARRAY}) {
  
}

The above for-each statement is the same as the following the for statement.

for (my $i = 0; $i < @ARRAY; $i++) {
  my VAR = ARRAY->[$i];
  
}

Example:

# The for-each statemenet
my $array = [1, 2, 3];
for my $element (@$array) {
  print "$elemenet\n";
}

next Statement

The next statement is a statement to go back to the while statement of the current while block.

next;

See also the while statement.

last Statement

The last statement is a statement to jump to the end of the current while block.

last;

See also the while statement.

return Statement

The return statement is a statement to return a value.

// void
return;

// non-void
return OPERAND;

Compilation Errors:

If the return type of the current method is the void type, OPERAND cannnot exist. If so, a compilation error occurs.

If the return type of the current method is the non-void type, OPERAND must exist. Otherwise a compilation error occurs.

The type of OPERAND must be able to assign to the return type of the current method. Otherwise a compilation error occurs.

die Statement

The die statement throws an exception.

die OPERAND_MESSAGE
die
die ERROR_TYPE OPERAND_MESSAGE
die ERROR_TYPE
die OPERAND_ERROR_ID ',' OPERAND_MESSAGE

OPERAND_MESSAGE is an error message. The error message is set to the exception variable $@.

If an exception is thrown, the program prints the error message to the standard error with the stack traces and finishes with error ID 255.

If OPERAND_MESSAGE is omitted or undef, "Error" is set to the exception variable $@.

ERROR_TYPE is a class type. If ERROR_TYPE is given, the basic type ID of the class is the value got by the "eval_error_id Operator".

OPERAND_ERROR_ID is an integer value within int type. If OPERAND_ERROR_ID is given, it is the value got by the "eval_error_id Operator".

the integer promotional conversion is performed on OPERAND_ERROR_ID.

The return type is the void type.

The following one is an example of a stack trace. Each line of the stack trace constains the class name, the method name, the file name and the line number of the caller.

Error
  TestCase::Minimal->sum2 at SPVM/TestCase/Minimal.spvm line 1640
  TestCase->main at SPVM/TestCase.spvm line 1198

The exception can be caught by the eval block.

Comlication Errors:

OPERAND_MESSAGE must be the string type or the undef type. Otherwise a compilation error occurs.

ERROR_TYPE must be a class type. Otherwise a compilation error occurs.

OPERAND_ERROR_ID must be an integer type within int. Otherwise a compilation error occurs.

Examples:

# Catch the exception
eval {
  # Throw an exception
  die "Error";
}

# Check the exception
if ($@) {
  # ...
}

die Error::System "System Error";

my $error_id = 10;
die $error_id, "Some Error";

Operator Statement

The operator statement is the statement to execute an operator.

A operation statement is composed of an operator and ;.

# The operator statemenet
OPERATOR;

Examples:

1;
$var;
1 + 2;
&foo();
my $num = 1 + 2;

Empty Statement

The empty statement ; is a statement to do nothing.

# The empty statemenet
;

Operator

An operator performs an operation that process something and returns a value.

Unary Plus Operator

The unary plus operator + returns OPERAND.

+OPERAND

Before this operation, the integer promotional conversion is performed on OPERAND.

The return type is the type after the integer promotional conversion has been performed.

Compilation Errors:

The type of OPERAND must be a numeric type. Otherwise a compilation error occurs.

Examples:

# The unary plus operator
my $num = +10;

Unary Minus Operator

-OPERAND

The unary minus operator - returns the negative value of OPERAND.

Before this operation, the integer promotional conversion is performed on OPERAND.

The return type is the type after the integer promotional conversion has been performed.

Compilation Errors:

The type of OPERAND must be a numeric type. Otherwise a compilation error occurs.

Examples:

# A unary minus operator
my $num = -10;

Addition Operator

The addition operator + calculates the addition of LEFT_OPERAND and RIGHT_OPERAND.

LEFT_OPERAND + RIGHT_OPERAND

The addition operator performs the same operation as the following C language operation.

LEFT_OPERAND + RIGHT_OPERAND

Before this operation, The binary numeric conversion is performed on LEFT_OPERAND and RIGHT_OPERAND.

The return type is the type after the binary numeric conversion has been performed.

Compilation Errors:

The type of LEFT_OPERAND must be a numeric type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be a numeric type. Otherwise a compilation error occurs.

Subtraction Operator

The subtraction operator - calculates the subtraction of LEFT_OPERAND and RIGHT_OPERAND.

LEFT_OPERAND - RIGHT_OPERAND

The subtraction operator performs the same operation as the following C language operation.

LEFT_OPERAND - RIGHT_OPERAND

Before this operation, The binary numeric conversion is performed on LEFT_OPERAND and RIGHT_OPERAND.

The return type is the type after the binary numeric conversion has been performed.

Compilation Errors:

The type of LEFT_OPERAND must be a numeric type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be a numeric type. Otherwise a compilation error occurs.

Multiplication Operator

The multiplication operator * calculates the multiplication of LEFT_OPERAND and RIGHT_OPERAND.

LEFT_OPERAND * RIGHT_OPERAND

Before this operation, The binary numeric conversion is performed on LEFT_OPERAND and RIGHT_OPERAND.

The multiplication operator performs the same operation as the following C language operation.

LEFT_OPERAND * RIGHT_OPERAND;

The return type is the type after the binary numeric conversion has been performed.

Compilation Errors:

The type of LEFT_OPERAND must be a numeric type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be a numeric type. Otherwise a compilation error occurs.

Division Operator

The division operator / calculates the division of LEFT_OPERAND and RIGHT_OPERAND.

LEFT_OPERAND / RIGHT_OPERAND

Before this operation, The binary numeric conversion is performed on LEFT_OPERAND and RIGHT_OPERAND.

The division operator performs the same operation as the following C language operation.

LEFT_OPERAND / RIGHT_OPERAND;

The return type is the type after the binary numeric conversion has been performed.

Compilation Errors:

The type of LEFT_OPERAND must be a numeric type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be a numeric type. Otherwise a compilation error occurs.

Exceptions:

If LEFT_OPERAND and RIGHT_OPERAND are integer types and RIGHT_OPERAND is 0, an exception is thrown.

Division Unsigned Int Operator

The division unsigned int operator div_uint calculates the unsigned int division of LEFT_OPERAND and RIGHT_OPERAND.

LEFT_OPERAND div_uint RIGHT_OPERAND

The division unsigned int operator performs the same operation as the following C language operation.

(uint32_t)LEFT_OPERAND / (uint32_t)RIGHT_OPERAND;

The return type is the int type.

Compilation Errors:

The type of LEFT_OPERAND must be a numeric type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be a numeric type. Otherwise a compilation error occurs.

Exceptions:

If RIGHT_OPERAND is 0, an exception is thrown.

Division Unsigned Long Operator

The division unsigned long operator div_ulong calculates the unsigned long division of LEFT_OPERAND and RIGHT_OPERAND.

LEFT_OPERAND div_ulong RIGHT_OPERAND

The division unsigned long operator performs the same operation as the following C language operation.

(uint64_t)LEFT_OPERAND / (uint64_t)RIGHT_OPERAND;

The return type of the division operator is the long type.

Compilation Errors:

The type of LEFT_OPERAND must be the long type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be the long type. Otherwise a compilation error occurs.

Exceptions:

If RIGHT_OPERAND is 0, an exception is thrown.

Modulo Operator

The modulo operator % is calculates a modulo of LEFT_OPERAND and RIGHT_OPERAND.

LEFT_OPERAND % RIGHT_OPERAND

Before this operation, the binary numeric conversion is performed on LEFT_OPERAND and RIGHT_OPERAND.

The modulo operator performs the same operation as the following C language operation.

RETURN_VALUE = LEFT_OPERAND % RIGHT_OPERAND;
if ((LEFT_OPERAND < 0) != (RIGHT_OPERAND < 0) && RETURN_VALUE) { RETURN_VALUE += RIGHT_OPERAND; }

The return type is the type after the binary numeric conversion has been performed.

Compilation Errors:

The type of LEFT_OPERAND must be an integer type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be an integer type. Otherwise a compilation error occurs.

Exceptions:

If RIGHT_OPERAND is 0, an exception is thrown.

Modulo Unsigned Int Operator

The modulo unsigned int operator mod_uint calculates a unsigned int modulo of LEFT_OPERAND and RIGHT_OPERAND.

LEFT_OPERAND mod_uint RIGHT_OPERAND

The modulo unsigned int operator performs the same operation as the following C language operation.

(uint32_t)LEFT_OPERAND % (uint32_t)RIGHT_OPERAND;

The return type is the int type.

Compilation Errors:

The type of LEFT_OPERAND must be the int type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be the int type. Otherwise a compilation error occurs.

Exceptions:

If RIGHT_OPERAND is 0, an exception is thrown.

Modulo Unsigned Long Operator

The modulo unsigned long operator mod_ulong calculates a unsigned long modulo of LEFT_OPERAND and RIGHT_OPERAND.

LEFT_OPERAND mod_ulong RIGHT_OPERAND

The modulo unsigned long operator performs the same operation as the following C language operation.

(uint64_t)LEFT_OPERAND % (uint64_t)RIGHT_OPERAND;

The return type of the modulo unsigned long operator is the long type.

Compilation Errors:

The type of LEFT_OPERAND must be the long type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be the long type. Otherwise a compilation error occurs.

Exceptions:

If RIGHT_OPERAND is 0, an exception is thrown.

Increment Operator

Increment operators are the pre-increment operator and post-increment operator.

Pre-Increment Operator

The pre-increment operator adds 1 to OPERAND and returns the value after the incrementation.

# Pre-increment operator
++OPERAND

The pre-increment operator performs the same operation as the following.

(OPERAND = (TYPE_OF_OPERAND)(OPERAND + 1))

For example, if the type of OPERAND is the byte type, the following operation is performed.

($num = (byte)($num + 1))

Compilation Errors:

The type of OPERAND must be a local variable, a class variable, a field access</a>, an array access, a dereference. Otherwise a compilation error occurs.

Examples:

# Pre-increment of a local variable
++$num;

# Pre-increment of a class variable
++$NUM;

# Pre-increment of an element of an array
++$point->{x};

# Pre-increment of a field
++$nums->[0];

# Pre-increment of a dereferenced value
++$$num_ref;

Post-Increment Operator

The post-increment operator adds 1 to OPERAND and returns the value before the incrementation.

# Post-increment operator
OPERAND++

The post-increment operator performs the same operation as the following.

(my TMP_VARIABLE = OPERAND, OPERAND = (TYPE_OF_OPERAND)(OPERAND + 1), TMP_VARIABLE)

For example, if the type of OPERAND is the byte type, the following operation is performed.

(my $tmp = $num, $num = (byte)($num + 1), $tmp)

Compilation Errors:

The type of OPERAND must be a local variable, a class variable, a field access</a>, an array access, a dereference. Otherwise a compilation error occurs.

Examples:

# Post-increment of a local variable
$num++;

# Post-increment of a class variable
$NUM++;

# Post-increment of an element of an array
$point->{x}++;

# Post-increment of a field
$nums->[0]++;

# Post-increment of a dereferenced value
$$num_ref++;

Decrement Operator

Decrement operators are the pre-decrement operator and post-decrement operator.

Pre-Decrement Operator

The pre-decrement operator subtracts 1 to OPERAND and returns the value after the decrementation.

# Pre-decrement operator
--OPERAND

The pre-decrement operator performs the same operation as the following.

(OPERAND = (TYPE_OF_OPERAND)(OPERAND - 1))

For example, if the type of OPERAND is the byte type, the following operation is performed.

($num = (byte)($num - 1))

Complation Errors:

The type of OPERAND must be a local variable, a class variable, a field access, an array access, a dereference. Otherwise a compilation error occurs.

Examples:

# Pre-decrement of a local variable
--$num;

# Pre-decrement of a class variable
--$NUM;

# Pre-decrement of an element of an array
--$point->{x};

# Pre-decrement of a field
--$nums->[0];

# Pre-decrement of a dereferenced value
--$$num_ref;

Post-Decrement Operator

The post-decrement operator subtracts 1 to OPERAND and returns the value before the decrementation.

# Post-decrement operator
OPERAND--

The post-decrement operator performs the same operation as the following.

(my TMP_VARIABLE = OPERAND, OPERAND = (TYPE_OF_OPERAND)(OPERAND - 1), TMP_VARIABLE)

For example, if the type of OPERAND is the byte type, the following operation is performed.

(my $tmp = $num, $num = (byte)($num - 1), $tmp)

Compilation Errors:

The type of OPERAND must be a local variable, a class variable, a field access</a>, an array access, a dereference. Otherwise a compilation error occurs.

Examples:

# Post-decrement of a local variable
$num--;

# Post-decrement of a class variable
$NUM--;

# Post-decrement of an element of an array
$point->{x}--;

# Post-decrement of a field
$nums->[0]--;

# Post-decrement of a dereferenced value
$$num_ref--;

Bit Operator

Bit operators perform bit operations.

Bit AND Operator

The bit AND operator & performes a bit AND operation.

LEFT_OPERAND & RIGHT_OPERAND

Before this operation, the binary numeric conversion is performed.

The return value is the same as the follwoing operation of the C language.

LEFT_OPERAND & RIGHT_OPERAND;

The return type is the type after the binary numeric widening conversion is performed.

Compilation Errors:

LEFT_OPERAND and RIGHT_OPERAND must be an "Integer Type" in integer type. Otherwise a compilation error occurs.

Examples:

# The bit AND operator
my $num1 = 0xff;
my $num2 = 0x12;
my $result = $num1 & $num2;

Bit OR Operator

The bit OR operator | performes a bit OR operation.

LEFT_OPERAND | RIGHT_OPERAND

Before this operation, the binary numeric conversion is performed.

The return value is the same as the follwoing operation of the C language.

LEFT_OPERAND | RIGHT_OPERAND;

The return type is the type after the binary numeric widening conversion is performed.

Compilation Errors:

LEFT_OPERAND and RIGHT_OPERAND must be an "Integer Type" in integer type. Otherwise a compilation error occurs.

Examples:

# The bit OR operator
my $num1 = 0xff;
my $num2 = 0x12;
my $result = $num1 | $num2;

Bit NOT Operator

The bit NOT operator ~ is an operator to perform the bit NOT operation.

~OPERAND

The numeric widening conversion is performed.

The return value is the same as the follwoing operation of the C language.

~OPERAND

The return type is the type that the numeric widening conversion is performed.

Compilation Errors:

The type of OPERAND must is an integer type. Otherwise a compilation error occurs.

Examples:

# The bit NOT operator
my $num = ~0xFF0A;

Shift Operator

Shift operators perform bit shift operations.

Left Shift Operator

The left shift operator << performs the left bit shift.

LEFT_OPERAND << RIGHT_OPERAND

Before this operation, the "Numeric Widening Conversion" in numeric widening conversion is performed on LEFT_OPERAND.

Before this operation, the "Numeric Widening Conversion" in numeric widening conversion is performed on RIGHT_OPERAND.

The left shift operator performs the same operation as the following C language operation.

LEFT_OPERAND << RIGHT_OPERAND;

The return type is the same as the type of LEFT_OPERAND.

Compilation Erorrs:

The type of LEFT_OPERAND must be an integer type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be an integer type within int. Otherwise a compilation error occurs.

Arithmetic Right Shift Operator

The arithmetic right shift operator >> performs the arithmetic right bit shift.

LEFT_OPERAND >> RIGHT_OPERAND

Before this operation, the "Numeric Widening Conversion" in numeric widening conversion is performed on LEFT_OPERAND.

Before this operation, the "Numeric Widening Conversion" in numeric widening conversion is performed on RIGHT_OPERAND.

The operation result of the arithmetic right shift Operator is the operation that exactly same as the following operation in the C language.

LEFT_OPERAND >> RIGHT_OPERNAD;

The return type is the same as the type of LEFT_OPERAND.

Compilation Errors:

The type of LEFT_OPERAND must be an integer type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be an integer type within int. Otherwise a compilation error occurs.

Logical Right Shift Operator

The logical right shift operator >>> performs the logical right bit shift.

LEFT_OPERAND >>> RIGHT_OPERAND

Before this operation, the "Numeric Widening Conversion" in numeric widening conversion is performed on LEFT_OPERAND.

Before this operation, the "Numeric Widening Conversion" in numeric widening conversion is performed on RIGHT_OPERAND.

The operation result of logical right shift Operator is the same as the following calculation in the C language.

// The type of LEFT_OPERAND is the int type
(uint32_t)LEFT_OPERAND >> RIGHT_OPERAND;

// The type of LEFT_OPERAND is the long type
(uint64_t)LEFT_OPERAND >> RIGHT_OPERAND;

The return type is the same as the type of LEFT_OPERAND.

Compilation Errors:

The type of LEFT_OPERAND must be an integer type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be an integer type within int. Otherwise a compilation error occurs.

Comparison Operator

Comparison operators compare LEFT_OPERAND and RIGHT_OPERAND.

Numeric Comparison Operator

Numeric comparison operators compare LEFT_OPERAND and RIGHT_OPERAND in the numeric order.

LEFT_OPERAND == RIGHT_OPERAND
LEFT_OPERAND != RIGHT_OPERAND
LEFT_OPERAND > RIGHT_OPERAND
LEFT_OPERAND >= RIGHT_OPERAND
LEFT_OPERAND < RIGHT_OPERAND
LEFT_OPERAND <= RIGHT_OPERAND
LEFT_OPERAND <=> RIGHT_OPERAND
Operator Description
== If LEFT_OPERAND is equal to RIGHT_OPERNAD in the numeric order, returns 1, otherwise returns 0. The comparation of operands of object types and reference types are also available.
!= If LEFT_OPERAND is not equal to RIGHT_OPERNAD in the numeric order, returns 1, otherwise returns 0. The comparation of operands of object types and reference types are also available.
> If LEFT_OPERAND is greater than RIGHT_OPERNAD in the numeric order, returns 1, otherwise returns 0.
>= If LEFT_OPERAN is greater than or equal to RIGHT_OPERNAD in the numeric order, returns 1, otherwise returns 0.
< If LEFT_OPERAND is less than RIGHT_OPERNAD in the numeric order, returns 1, otherwise returns 0.
<= If LEFT_OPERAND is less than or equal to RIGHT_OPERNAD in the numeric order, returns 1, otherwise returns 0.
<=> If LEFT_OPERAND is greater than RIGHT_OPERNAD in the numeric order, returns 1. If LEFT_OPERAND is less than RIGHT_OPERNAD in the numeric order, return -1. If LEFT_OPERAND is equals to RIGHT_OPERNAD in the numeric order, returns 0.

Before this operation, the binary numeric conversion is performed on LEFT_OPERAND and RIGHT_OPERAND.

The numeric comparison operators performed the same operations as the following C language operations.

(int32_t)(LEFT_OPERAND == RIGHT_OPERAND);
(int32_t)(LEFT_OPERAND != RIGHT_OPERAND);
(int32_t)(LEFT_OPERAND > RIGHT_OPERAND);
(int32_t)(LEFT_OPERAND >= RIGHT_OPERAND);
(int32_t)(LEFT_OPERAND < RIGHT_OPERAND);
(int32_t)(LEFT_OPERAND <= RIGHT_OPERAND);
(int32_t)(LEFT_OPERAND > RIGHT_OPERAND ? 1 : LEFT_OPERAND < RIGHT_OPERAND ? -1 : 0);

The return type is the int type.

Compilation Errors:

The type of LEFT_OPERAND of the == operator and the != operator must be a numeric type, an object type, or an reference type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND of the == operator and the != operator must be a numeric type, an object type, or an reference type. Otherwise a compilation error occurs.

If the type of RIGHT_OPERAND of the == operator and the != operator is an object type or an reference type, and the type of LEFT_OPERAND is different from the type of RIGHT_OPERAND, a compilation error occurs.

The type of LEFT_OPERAND of the > operator, the >= operator, the < operator, the <= operator, and the <=> operator must be a numeric type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND of the > operator, the >= operator, the < operator, the <= operator, and the <=> operator must be a numeric type. Otherwise a compilation error occurs.

String Comparison Operator

String comparison operators compare LEFT_OPERAND and RIGHT_OPERAND in the dictionary order.

LEFT_OPERAND eq RIGHT_OPERAND
LEFT_OPERAND ne RIGHT_OPERAND
LEFT_OPERAND gt RIGHT_OPERAND
LEFT_OPERAND ge RIGHT_OPERAND
LEFT_OPERAND lt RIGHT_OPERAND
LEFT_OPERAND le RIGHT_OPERAND
LEFT_OPERAND cmp RIGHT_OPERAND
Operators Descriptions
eq If LEFT_OPERAND is equal to RIGHT_OPERNAD in the dictionary order, returns 1, otherwise returns 0.
ne If LEFT_OPERAND is not equal to RIGHT_OPERNAD in the dictionary order, returns 1, otherwise returns 0.
gt If LEFT_OPERAND is greater than RIGHT_OPERNAD in the dictionary order, returns 1, otherwise returns 0.
ge If LEFT_OPERAND is greater than or equal to RIGHT_OPERNAD in the dictionary order, returns 1, otherwise returns 0.
lt If LEFT_OPERAND is less than RIGHT_OPERNAD in the dictionary order, returns 1, otherwise returns 0.
le If LEFT_OPERAND is less than or equal to RIGHT_OPERNAD in the dictionary order, returns 1, otherwise returns 0.
cmp If LEFT_OPERAND is greater than RIGHT_OPERNAD in the dictionary order, returns 1. If LEFT_OPERAND is less than RIGHT_OPERNAD in the dictionary order, return -1. If LEFT_OPERAND is equal to RIGHT_OPERNAD in the dictionary order, returns 0.

The return type is the int type.

Compilation Errors.

The type of LEFT_OPERAND must be the string type or the byte[] type. Otherwise a compilation error occurs.

The type of RIGHT_OPERAND must be the string type or the byte[] type. Otherwise a compilation error occurs.

isa Operator

The isa operator checks whether LEFT_OPERAND can be assigned to the right type.

LEFT_OPERAND isa RIGHT_TYPE

If the right type is a numeric type, a multi-numeric type, a reference type, the any object type, the any object array type, this operator checks the assignability.

If the assignability without implicite convertion is true, it returns 1, otherwise returns 0.

If the right type is another object type, this operator checks the runtime assignability.

If the runtime assignability is true, it returns 1, otherwise returns 0.

The return type is the int type.

Compilation Errors:

If the runtime assignability is checked, LEFT_OPERAND of the isa operator must be an object type. Otherwise a compilation error occurs.

Examples:

if ($value isa int) {
  
}

if ($value isa Point) {
  
}

if ($value isa Point3D) {
  
}

if ($value isa Stringable) {
  
}

if ($value isa int) {
  
}

isa_error Operator

The isa_error operator checks whether the basic type ID given by LEFT_OPERAND can be assigned to the right type.

LEFT_OPERAND isa RIGHT_TYPE

The return type is int type.

If the assignability is true, returns 1. Otherwise returns 0.

Compilation Errors:

LEFT_OPERAND of the isa_error operator must be an integer type within int. Otherwise a compilation error occurs.

RIGHT_OPERAND of the isa_error operator must be a class type. Otherwise a compilation error occurs.

Examples:

if (eval_error_id isa_error Error) {
  
}

if (eval_error_id isa_error Error::System) {
  
}

is_type Operator

The is_type operator checks whether the type of LEFT_OPERAND is equal to the right type.

LEFT_OPERAND is_type RIGHT_TYPE

If the right type is a numeric type, a multi-numeric type, a reference type, the any object type, the any object array type, this operator checks the compile type of LEFT_OPERAND is equal to the right type.

If the check is true, it returns 1, otherwise returns 0.

If the right type is another object type, this operator checks the runtime type of LEFT_OPERAND is equal to the right type.

If the runtime check is true, it returns 1, otherwise returns 0.

The return type is int type.

Compilation Errors:

If the runtime check is performed, LEFT_OPERAND of the is_type operator must be an object type. Otherwise a compilation error occurs.

Examples:

if ($object is_type int) {
  
}

if ($object is_type Point) {
  
}

if ($object is_type int[]) {
  
}

if ($object is_type Stringable[]) {
  
}

is_error Operator

The is_error operator checks whether the basic type ID given by LEFT_OPERAND is the basic type of the right type.

LEFT_OPERAND isa RIGHT_TYPE

The return type is int type.

If it is ok, returns 1. Otherwise returns 0.

Compilation Errors:

LEFT_OPERAND of the is_error operator must be an integer type within int. Otherwise a compilation error occurs.

RIGHT_OPERAND of the is_error operator must be a class type. Otherwise a compilation error occurs.

Examples:

if (eval_error_id is_error Error) {
  
}

if (eval_error_id is_error Error::System) {
  
}

is_compile_type Operator

The is_compile_type operator is a comparison operator to check whether the compilation-time type of LEFT_OPERAND is the right type.

LEFT_OPERAND is_compile_type RIGHT_TYPE

If the compilation-time type of LEFT_OPERAND is the right type, returns 1. Otherwise returns 0.

The return type is int type.

Examples:

{
  my $value : int;
  if ($value is_compile_type int) {
    # Pass
  }
}

{
  my $object : object = new TestCase::Minimal;
  if ($object is_compile_type object) {
    # Pass
  }
}

{
  my $value : Stringer = method : string () { return "aaa"; };
  if ($value is_compile_type Stringer) {
    # Pass
  }
}

type_name Operator

The type_name operator returns the type name of the object.

type_name OPERAND

If OPERAND is defined, returns the type name of the object. Otherwise returns undef.

The return type is the string type.

Compilation Errors.

If OPERAND is not an object type, a compilation error occurs.

Examples:

# "Point"
my $poitn = Point->new;
my $type_name = type_name $point;

compile_type_name Operator

The compile_type_name operator returns the type name at compilation time.

type_name OPERAND

The return type is the string type.

Examples:

# int
my $num = 1;
my $compile_type_name = compile_type_name $num;

dump Operator

The dump operator gets the string representation of the object.

dump OPERAND

It returns the string representation of the object.

The return type is the string type.

The string representation may be changed. Please don't use the dump operator for the purpose of the data serialization.

Compilation Errors:

If OPERAND is not an object type or the undef type, a compilation error occurs.

Logical Operator

The logical operators are the operators to perform logical operations.

The logical operators are the logical AND operator, the logical OR operator, and the logical NOT operator.

Logical AND Operator

The logical AND operator && is a logical operator to perform a logical AND operation.

LEFT_OPERAND && RIGHT_OPERAND

LEFT_OPERAND and RIGHT_OPERAND must be an operator.

The return type of the logical AND operator is the int type.

Thg logical AND operator performs the boolean conversion to LEFT_OPERAND. If the evaluated value is 0, returns 0. Otherwise proceed to the evaluation of RIGHT_OPERAND.

It performs the boolean conversion to RIGHT_OPERAND. If the evaluated value is 0, returns 0. Otherwise return the evaluated value.

Logical OR Operator

The logical OR operator || is a logical operator to performe a logical OR operation.

LEFT_OPERAND || RIGHT_OPERAND

The return type of the logical OR operator is the int type.

Thg logical OR operator performs the boolean conversion to LEFT_OPERAND. If the evaluated value is not 0, return the evaluated value. Otherwise proceed to the evaluation of RIGHT_OPERAND.

It performs the boolean conversion to RIGHT_OPERAND. If the evaluated value is not 0, return the evaluated value. Otherwise returns 0.

Logical NOT Operator

The logical NOT operator ! is a logical operator to performe a logical NOT operation.

!OPERAND

The return type of the logical NOT operator is the int type.

Thg logical NOT operator performs the boolean conversion to OPERAND. If the evaluated value is 0, returns 1. Otherwise returns 0.

String Concatenation Operator

String concatenation operator . is an operator to concat two strings.

LEFT_OPERAND . RIGHT_OPERAND

If the type of OPERAND is numeric type, a numeric-to-string conversion is performed.

The return type is the string type.

A string concatenation operator returns the result to concat two operands.

If both LEFT_OPERAND and RIGHT_OPERAND are a string literal, the two string literals are concatenated at compile-time.

If LEFT_OPERAND or RIGHT_OPERAND is undef, an exception occurs.

Compilation Errors:

LEFT_OPERAND and RIGHT_OPERAND must be the string type, "byte[] Type", or numeric type. Otherwise a compilation error occurs.

Examples:

my $str = "abc" . "def";
my $str = "def" . 34;
my $str = 123 . 456;

Assignment Operator

The assignment operator = is an operator to assign a value.

LEFT_OPERAND = RIGHTH_OPERAND

The assignment operator has different meanings depending on LEFT_OPERAND and RIGHT_OPERAND.

Local Variable Assignment

See "Getting Local Variable" and "Setting Local Variable".

Class Variable Assignment

See the getting class varialbe and the setting class varialbe.

Array Element Assignment

See "Getting Array Element" and "Setting Array Element".

Field Assignment

See "Getting Field" and "Setting Field".

Special Assignment Operator

A special assignment operator is the alias for the combination of an operator and "Assignment Operator" =.

LEFT_OPERAND OPERATOR= RIGHTH_OPERAND

Above is the alias for the following code.

LEFT_OPERAND = (TYPE_OF_LEFT_OPERAND)(LEFT_OPERAND OPERATOR RIGHTH_OPERAND)

For example, See a byte case.

# Addition assignment operator
$x += 1;

# Above is the same as the following code.
$x = (byte)($x + 1)

The following operators are used as the operators of the special assignment operators.

Addition assignment operator +=
Subtraction assignment operator -=
Multiplication assignment operator *=
Division assignment operator /=
Modulo assignment operator %=
Bit AND assignment operator &=
Bit OR assignment operator |=
Left shift assignment operator <<=
Arithmetic right shift assignment operator >>=
Logical right shift assignment operator >>>=
Concatenation assignment operator .=

Examples:

# Special assignment operators
$x += 1;
$x -= 1;
$x *= 1;
$x /= 1;
$x &= 1;
$x |= 1;
$x ^= 1;
$x %= 1;
$x <<= 1;
$x >>= 1;
$x >>>= 1;
$x .= "abc";

Array Length Operator

The array length operator is an operator to get the length of the array.

@OPERAND

The array length operator returns the int type value that is the length of the array.

Array Length Operator returns the operator

Compilation Errors:

The operand must be an operator that type is an the array type. Otherwise a compilation error occurs.

Examples:

# Getting the length of the array.
my $nums = new byte[10];
my $length = @$nums;

# Getting the length of the array with a scalar operator. This is exactly same as the avobe
my $nums = new byte[10];
my $length = scalar @$nums;

Note that SPVM does not have the context different from Perl, and array length operators always return the length of the array.

new_string_len Operator

The new_string_len operator is an operator to create a string with the length.

new_string_len OPERAND

The integer promotional conversion is performed on OPERAND.

The new_string_len operator returns a new string that length is the length specified by OPERAND and all characters are \0.

The character just after the last character is \0. The string created by the new_string_len operator can be used as the C language string ending with \0.

The return type is the string type.

The length specified by OPERAND must be greater than or equal to 0. Otherwise an exception is thrown.

Compilation Errors:

The type of OPERAND must be an integer type within int. Otherwise a compilation error occurs.

Examples:

# New a string with the length
my $message = new_string_len 5;

copy Operator

The copy operator is an operator to copy the object.

copy OPERAND

If the type of operand is none of the string type, a numeric type, a multi-numeric type, An exception is thorwn.

The copy operator returns the copied object.

The return type is the same as the type of operand.

Read-only flag of the string is dropped.

Compilation Errors:

The operand must be an operator that type is a object type. Otherwise a compilation error occurs.

Examples:

# New a string with the length
my $message = copy "abc";

is_read_only Operator

The is_read_only is an operator to check if the string is read-only.

is_read_only OPERAND

If the string is read-only, the is_read_only operator returns 1, otherwise returns 0.

The return type is an int type.

Compilation Errors:

The operand must be the string type. Otherwise a compilation error occurs.

Examples:

# New a string with the length
my $message = "Hello";
my $is_read_only = is_read_only $message;

String Length Operator

The string length operator length is an operator to get the length of the string.

length OPERAND

The returned length is the byte size. Note that the length is not the count of UTF-8 characters.

The return type is the int type.

Compilation Errors:

The type of OPERAND must be the string type. Otherwise a compilation error occurs.

Examples:

# Getting the string length. The length is 5.
my $message = "Hello";
my $length = length $message;

# Getting the string length of UTF-8. The length is 9.
my $message = "あいう";
my $length = length $message;

scalar Operator

The scalar operator is an Operator that returns OPERAND.

scalar OPERAND

Compilation Errors:

The operand must be an "The array Length Operator". Otherwise a compilation error occurs.

Examples:

# Getting the array length 
my $nums = new int[3];
foo(scalar @$nums);

# This is exactlly same as the above.
my $nums = new int[3];
foo(@$nums);

Note that the sclara operator exists only to reduce the confusion.

isweak Operator

The isweak operator checks whether the field is weak reference

isweak OBJECT->{FIELD_NAME};

If the field is weaken, the isweak operator returns 1, otherwise returns 0.

The return type of the isweak operator is the int type.

See "Weak Reference" to know the behavior of the isweak operator.

Compilation Errors:

The type of the object must be the class type. Otherwise a compilation error occurs.

If the field name is not found, a compilation error occurs.

The type of the field targetted by the isweak operator is not an object type, a compilation error occurs.

Examples:

# isweak
my $isweak = isweak $object->{point};

can Operator

The can operator checks if a method can be called.

OPERAND can METHOD_NAME

An empty string "" means an anon method.

If OPERAND can call the method given by METHOD_NAME, returns 1. Otherwise returns 0.

The return type is int type.

Compilation Errors:

The type of OPERAND must be the class type or the interface type. Otherwise a compilation error occurs.

The METHOD_NAME must be a method name or an empty string "". Otherwise a compilation error occurs.

Examples:

my $stringable = (Stringable)Point->new(1, 2);

if ($stringable can to_string) {
  # ...
}

if ($stringable can "") {
  # ...
}

Getting Local Variable

The getting local variable is an operator to get the value of the local variable.

$var

The return value is the value of the local variable.

The return type is the type of the local variable.

Setting Local Variable

The setting local variable is an operator to set the value of "Local Variable" using the assignment operator.

$var = VALUE

The return value is the value after the assignment.

If the type of the assigned value is an object type, the reference count of the object is incremented by 1.

If an object has already been assigned to $var before the assignment, the reference count of the object is decremented by 1.

See the scope to know the garbage collection of local variables.

Compilation Errors:

The assignment of the value must satisfy the assignability. Otherwise a compilation error occurs.

Getting Class Variable

The getting class variable is an operator to get the value of the class variable.

$CLASS_NAME::CLASS_VARIABLE_NAME

CLASS_NAME:: can be omitted if the class variable belongs to the current class.

$CLASS_VARIABLE_NAME

If the class variable is used in an anon method and CLASS_NAME:: can be omitted, its current class means its outer class.

Compilation Errors:

If the class variable does not found, a compilation error occurs.

If the class variable is private and it is accessed outside of the class, a compilation error occurs.

Examples:

class Foo {
  our $VAR : int;

  static method bar : int () {
    my $var1 = $Foo::VAR;
    my $var2 = $VAR;
    
    my $cb = method : void () {
      # $Foo::BAR
      $VAR;
    }
  }
}

Setting Class Variable

Setting Class Variable operator is an operator to set "Class Variable" Value using the assignment operator.

$CLASS_NAME::CLASS_VARIABLE_NAME = VALUE

"CLASS_NAME::" can be omitted when the class Variable belongs to own "Class".

$CLASS_VARIABLE_NAME = VALUE

The return value is the value after the setting.

The return type is the type of the class variable.

If the type of the assigned value is an object type, the reference count of the object is incremented by 1.

If an object has already been assigned to $CLASS_VARIABLE_NAME before the assignment, the reference count of the object is decremented by 1.

If the class variable is used in an anon method and CLASS_NAME:: can be omitted, its current class means its outer class.

Compilation Errors:

If the assignment does not satisfy the assignability, a compilation error occurs.

If the class variable does not found, a compilation error occurs.

If the class variable is private and it is accessed outside of the class, a compilation error occurs.

Examples:

class Foo {
  our $VAR : int;

  static method bar : int () {
    $Foo::VAR = 1;
    $VAR = 3;
  }
  my $cb = method : void () {
    # $Foo::VAR
    $VAR = 5;
  }
}

Getting Exception Variable

The setting exception variable is an operator to get the value of the exception variable.

$@

The return value is the value of exception variable.

The return type is the string type.

Examples:

# Getting the exception variable
my $message = $@;

Setting Exception Variable

The setting exception variable is an operator to set the value of "Exception Variable" using the assignment operator.

$@ = VALUE

The type of the assigned value must be the string type.

The return value is the value after the setting.

The return type is the string type.

The reference count of the assigned value is incremented by 1.

If an string has already been assigned to the exception variable before the assignment, the reference count of the string is decremented by 1.

Examples:

$@ = "Error";

Getting Field

The getting field is an operator to get the field of the object. This is one syntax of the field access.

INVOCANT->{FIELD_NAME}

The type of invocant is a class type.

The retrun type is the type of the field.

Examples:

my $point = Point->new;
my $x = $point->{x};

Setting Field

The setting field is an operator to set the field of the object. This is one syntax of the field access.

INVOCANT->{FIELD_NAME} = VALUE

The type of invocant is a class type.

The return value is the value after the setting.

The return type is the field type.

If the type of assigned value is a basic object type, the reference count of the object is incremented by 1.

If an object has already been assigned to the field before the assignment, the reference count of that object is decremented by 1.

Compilation Errors:

If the assignment does not satisfy the assignability, a compilation error occurs.

Examples:

my $point = Point->new;
$point->{x} = 1;

Getting Multi-Numeric Field

Getting Multi-Numeric Field operator is an operator to get Field of the multi-numeric value. This is one syntax of the field access.

INVOCANT->{FIELD_NAME}

The invocant is the multi-numeric type.

Getting Multi-Numeric Field operator returns the field value in the multi-numeric value.

The retrun type is the type of the field.

Compilation Errors:

If the field names does not found in the "Class", a compilation error occurs

Examples:

my $z : Complex_2d;
my $re = $z->{re};

Setting Multi-Numeric Field

Setting Multi-Numeric Field operator is an operator to set Field of the multi-numeric value using "Assignment Operator". This is one syntax of the field access.

INVOCANT->{FIELD_NAME} = RIGHT_OPERAND

The invocant is the multi-numeric type.

Setting Multi-Numeric Field operator returns the value of the field after setting.

The assignment must satisfy the assignability.

The return type is the field type.

Compilation Errors:

If the field names does not found in the "Class", a compilation error occurs.

Examples:

my $z : Complex_2d;
$z->{re} = 2.5;

Getting Array Element

The getting array element is an operator to get the element of the array.

ARRAY->[INDEX]

The array must be the array type.

The integer promotional conversion is performed on the index.

The getting array element returns the element that is specifed by the index.

The return type is the type of the element.

The array must be defined. Otherwise an exception is thrown.

The index must be greater than or equal to 0. Otherwise an exception is thrown.

Compilation Errors:

The index must be an integer type within int. Otherwise a compilation error occurs.

Examples:

my $nums = new int[3];
my $num = $nums->[1];

my $points = new Point[3];
my $point = $points->[1];

my $objects : object[] = $points;
my $object = (Point)$objects->[1];

Setting Array Element

The setting array element is an operator to set the element of the array using the assignment operator.

ARRAY->[INDEX] = RIGHT_OPERAND

The array must be the array type.

The integer promotional conversion is performed on the index.

RIGHT_OPERAND must be assigned to the element of the array.

The setting array element returns the value of the element that is set.

The array must be defined. Otherwise an exception is thrown.

The index must be greater than or equal to 0. Otherwise an exception is thrown.

If RIGHT_OPERAND is an object type, the reference count of the object is incremented by 1.

If an object has already been assigned to the field before the assignment, the reference count of the object is decremented by 1.

Compilation Errors:

The index must be an integer type within int. Otherwise a compilation error occurs.

Examples:

my $nums = new int[3];
$nums->[1] = 3;

my $points = new Point[3];
$points->[1] = Point->new(1, 2);

my $objects : object[] = $points;
$objects->[2] = Point->new(3, 5);

new Operator

The new operator is an operator to create an object or an array.

Creating Object

The creating object is an operator to create an object using the new operator.

new CLASS_NAME;

The class name must be the name of the class defined by the class definition.

The fields of the created object are initialized by the initial value.

The reference count of the created object is 0. If the object is assigned to a local variable, a class variable, or a field by "Assignment Operator", the reference count is incremented by 1.

Examples:

my $object = new Foo;

Creating Array

The creating array is an operator to create an array using the new operator.

new BasicType[LENGTH]

The type must be a basic type.

The integer promotional conversion is performed on the length.

The length must be greater than or equal to 0. Otherwise an exception is thrown.

All elements of the array are initialized by the initial value.

The type of the created array is the array type.

Compilation Errors:

The length must be an integer type within int. Otherwise a compilation error occurs.

Examples:

my $nums = new int[3];
my $objects = new Foo[3];
my $objects = new object[3];
my $values = new Complex_2d[3]

Creating Multi-Dimensional Array

Multi dimensional arrays can be created using the new operator.

new BasicType[][LENGTH]
new BasicType[]..[][LENGTH]

([]..[] means two or more [])

Examples:

# 2 dimentional int array
my $nums = new int[][3];

# 3 dimentional int array
my $nums = new int[][][3];

The max dimention is 255.

Array Initialization

The array initialization is an operator to create an array and initialize the array easily.

[]
[ELEMENT1, ELEMENT2, ELEMENT3]

The array initialization create an array that has the length of the elements.

And the array is initialized by the elements.

And the created array is returned.

The type of the created array is the type that 1 dimension is added to the type of the first element.

If no element is specified, the type of the create array becomes any object type.

Examples:

# int array
my $nums = [1, 2, 3];

# double array
my $nums = [1.5, 2.6, 3.7];

# string array
my $strings = ["foo", "bar", "baz"];

The first example is the same as the following codes.

# int array
my $nums = new int[3];
$nums->[0] = 1;
$nums->[1] = 2;
$nums->[2] = 3;

The array initialization has another syntax using {}.

{}
{ELEMENT1, ELEMENT2, ELEMENT3, ELEMENT4}

This is the same as above array init syntax, but the type of the created array is always "Any Object Array Type" object[].

Compilation Errors:

If the length of the elements is odd number, a compilation error occurs.

Examples:

# Key values empty
my $key_values = {};

# Key values
my $key_values = {foo => 1, bar => "Hello"};

Reference Operator

The reference operator \ is the operator to create a reference.

\OPERAND

The return type is the reference type of OPERAND.

Compilation Errors:

The operand must be a local variable that type is a numeric type or a multi-numeric type. Otherwise a compilation error occurs.

Examples:

# Create the reference of a numeric type
my $num : int;
my $num_ref : int* = \$num;

# Create the reference of a multi-numeric type
my $z : Complex_2d;
my $z_ref : Complex_2d* = \$z;

Dereference Operator

The dereference operators are the operatoers to perform a deference.

Getting value by Dereference

Obtaining a value by Dereference is an operator to obtain the actual value from Reference. It was designed to realize the C joint operator *.

$VARIABLE

The value obtained by Dereference returns the operator.

Compilation Errors:

The variable Type must be Reference Type. Otherwise a compilation error occurs.

Examples:

my $num : int;
my $num_ref : int* = \$num;
my $num_deref : int = $$num_ref;

my $z : Complex_2d;
my $z_ref : Complex_2d* = \$z;
my $z_deref : Complex_2d = $$z_ref;

Setting the value with Dereference

Setting a value with Dereference is an operator to set the actual value from Reference. It was designed to realize the C joint operator *.

$VARIABLE = OPERAND

Setting a value with Dereference returns the set value. This is the operator.

Compilation Errors:

The variable Type must be Reference Type. Otherwise a compilation error occurs.

The type of operator must match the type of the variable when dereferenced. Otherwise a compilation error occurs.

Examples:

my $num : int;
my $num_ref : int* = \$num;
$$num_ref = 1;

my $z : Complex_2d;
my $z_ref : Complex_2d* = \$z;

my $z2 : Complex_2d;

$$z_ref = $z2;

Getting Multi-Numeric Field via Dereference

Getting Multi-Numeric Field via Dereference operator is an operator to get Field of the multi-numeric value via "Dereference". This is one syntax of the field access

INVOCANT->{FIELD_NAME}

The invocant is "Multi-Numeric Reference Type".

The getting multi-numeric field via dereference operator returns the field value in the multi-numeric value.

The retrun type is the type of the field.

Compilation Errors:

If the field names does not found in the "Class", a compilation error occurs

Examples:

my $z : Complex_2d;
my $z_ref = \$z;
my $re = $z_ref->{re};

Setting Multi-Numeric Field via Dereference

The setting multi-numeric field via dereference operator is an operator to set Field of the multi-numeric value via "Dereference" using "Assignment Operator". This is one syntax of the field access.

INVOCANT->{FIELD_NAME} = RIGHT_OPERAND

The invocant is "Multi-Numeric Reference Type".

The setting multi-numeric field via dereference operator returns the value of the field after setting.

The assignment must satisfy the assignability.

The return type is the field type.

Compilation Errors:

If the field names does not found in the "Class", a compilation error occurs

Examples:

my $z : Complex_2d;
my $z_ref = \$z;
$z_ref->{re} = 2.5;

Getting Current Class Name

The __PACKAGE__ operator gets the current class name.

__PACKAGE__

The return type is the string type.

If the __PACKAGE__ operator is used in anon method, it returns its outer class.

Examples:

class Foo::Bar {
  static method baz : void () {
    # Foo::Bar
    my $current_class_name = __PACKAGE__;
    
    my $cb = method : void () {
      # Foo::Bar
      my $current_class_name = __PACKAGE__;
    };
  }
}

Getting Current File Name

The getting current file name __FILE__ is an operator to get the current file name.

__FILE__

The current file name means the relative path from the base path of the class file. For example, if the class loaded path is /mypath and the class name is Foo::Bar, the absolute path is /mypath/SPVM/Foo/Bar.spvm and the relative path is SPVM/Foo/Bar.spvm. SPVM/Foo/Bar.spvm is the current file name.

Examples:

# SPVM/Foo/Bar.spvm
class Foo::Bar {
  static method baz : void () {
    # Get the current file name - SPVM/Foo/Bar.spvm
    my $file_name == __FILE__;
  }
}
class Foo::Bar2 {
  static method baz : void () {
    # Get the current file name - SPVM/Foo/Bar.spvm
    my $file_name == __FILE__;
  }
}

Getting Current Line Number

The getting current line number __LINE__ is an operator to get the current line number of the current file.

__LINE__

Examples:

class Foo::Bar {
  static method baz : void () {
    # Get the current line number - 4
    my $line = __LINE__;
  }
}

Anon Method

The anon method is an operator to define an anon calss and an instance method that doesn't has its method name.

It creates an object object from the anon class by the new operator and returns the object.

# Anon method
method : TYPE  (VAR1 : TYPE1, VAR2 : TYPE2, ...) {

}

The way to define the method is the same as the method definition.

Examples:

# Anon method
class Foo::Bar {
  method some_method : void () {
    my $comparator = (Comparator)method : int ($x1 : object, $x2 : object) {
      my $point1 = (Point)$x1;
      my $point2 = (Point)$x2;
      
      return $point1->x <=> $point2->x;
    };
  }
}

See also Comparator.

The above example is the same as the following codes.

# Foo/Bar.spvm
class Foo::Bar {
  method some_method : void () {
    my $comparator = (Comparator)new Foo::Bar::anon::3::31;
  }
}

# Foo/Bar/anon/3/31.spvm
class Foo::Bar::anon::3::31 : public {
  method : int ($x1 : object, $x2 : object) {
    my $point1 = (Point)$x1;
    my $point2 = (Point)$x2;
    
    return $point1->x <=> $point2->x;
  }
}

Anon Method Field Definition

The anon method field definition is the syntax to define the field of the anon class of the anon method.

# Anon method field definitions
[has FIELD_NAME : TYPE1, has FIELD_NAME : TYPE2, ...] ANON_METHOD_DEFINITION

# Anon method field definitions with field default values
[has FIELD_NAME : TYPE1 = OPERAND1, has FIELD_NAME : TYPE2 = OPERAND2, ...] ANON_METHOD_DEFINITION

[VAR1 : TYPE1, VAR2 : TYPE2, ...] ANON_METHOD_DEFINITION

Examples:

class Foo::Bar {
  method some_method : void () {
    my $foo = 1;
    my $bar = 5L;
    
    my $comparator = (Comparator)[has foo : int = $foo, has bar : long = $bar] method : int ($x1 : object, $x2 : object) {
      my $foo = $self->{foo};
      my $bar = $self->{bar};
      
      print "$foo\n";
      print "$bar\n";
    };
  }
}

Same as avobe but more simple:

class Foo::Bar {
  method some_method : void () {
    my $foo = 1;
    my $bar = 5L;
    
    my $comparator = (Comparator)[$foo : int, $bar : long] method : int ($x1 : object, $x2 : object) {
      print "$foo\n";
      print "$bar\n";
    };
  }
}

The above example is the same as the following codes.

# Foo/Bar.spvm
class Foo::Bar {
  method some_method : void () {
    # Externally defined local variables
    my $foo = 1;
    my $bar = 5L;
    
    my $anon = new Foo::Bar::anon::5::61;
    $anon->{foo} = $foo;
    $anon->{bar} = $bar;
    
    my $comparator = (Comparator)$anon;
  }
}

# Foo/Bar/anon/5/61.spvm
class Foo::Bar::anon::5::61 : public {
  has foo : public int;
  has bar : public long;
  
  method : int ($x1 : object, $x2 : object) {
    my $foo = $self->{foo};
    my $bar = $self->{bar};
    
    print "$foo\n";
    print "$bar\n";
  }
}

basic_type_id Operator

The basic_type_id operator gets the basic type ID from a type.

basic_type_id TYPE

The return value is the basic type ID.

The return type is the int type.

Examples:

my $basic_type_id = basic_type_id int;

my $basic_type_id = basic_type_id int[];

my $error_basic_type_id = basic_type_id Error;

eval_error_id Operator

The eval_error_id operatoer gets the error ID of the exception caught by an eval block.

eval_error_id

This value is set to 0 at the beginning of the eval block.

Type Cast

The type cast is the operator to perform an explicite type conversion.

# Type Cast
(TYPE)OPERAND

# Postfix Type Cast
OPERAND->(TYPE)

A type cast performs a type conversion, merely copying, or copying with a runtime type checking.

The behaviors of type casts are explained in "Castability".

Compilation Errors:

If the type cast doesn't have the castability, a compilation error occurs.

Examples:

# The explicte type conversion from long to int 
my $num = (int)123L;

# The explicte type conversion from byte[] to string
my $num = (string)new byte[3];

# The explicte type conversion from string to byte[]
my $num = (byte[])"Hello";

# Postfix type cast
my $point = Point->new;
my $stringable = $point->(Stringable);

Sequential Operator

The sequential operator , is an operator like the following.

(OPERAND1, OPERAND2, ..., OPERNADN)

The operands are evaluated from the left to the right, and return the evaluated value of the last operand.

Exampless:

# 3 is assigned to $foo
my $foo = (1, 2, 3);

# $x is 3, $ret is 5
my $x = 1;
my $y = 2;
my $ret = ($x += 2, $x + $y);

warn Operator

The warn operator prints a message to the standard error.

warn OPERNAD;
warn;

If OPERAND is omitted or OPERAND is undef, OPERAND is set to the string "Warning".

The return type is the void type.

If the end character of the OPERNAD is \n, the warn operator prints the OPERNAD itself.

Otherwise the current file name and the current line number by the format "\n at $file_name line $line\n" are added to the end of the OPERNAD.

The buffer of the standard error is flushed after the printing.

Compilation Errors:

The OPERNAD must be the string type or the undef type. Otherwise a compilation error occurs.

Examples:

warn "Something is wrong.";

The print operator prints a string to the standard output.

print OPERAND;

OPERAND must be the string type.

The return type is the void type.

If OPERAND is an undef, print nothing.

say Operator

The say operator prints a string with a line break \n to the standard output.

say OPERAND;

OPERAND must be the string type.

The return type is the void type.

If OPERAND is an undef, print \n.

make_read_only Operator

The make_read_only operator makes the string read-only.

make_read_only OPERAND;

OPERAND must be the string type.

The return type is the void type.

Read-only strings cannnot be cast to string type qualified by mutable.

# A string
my $string = new_string_len 3;

# Make the string read-only
make_read_only $string;

# The conversion to the string type qualified by mutable throw an exception.
my $string_mut = (mutable string)$string;

weaken Operator

The weaken operator creates a weak reference.

weaken OBJECT->{FIELD_NAME};

The return type is the void type.

See "Weak Reference" to know the behavior of the weaken statement.

Compilation Errors:

The type of the object must be the class type. Otherwise a compilation error occurs.

If the field name is not found, a compilation error occurs.

The type of the field targetted by the weaken statement is not an object type, a compilation error occurs.

Examples:

# weaken
weaken $object->{point};

unweaken Operator

The unweaken operator unweakens a weak reference.

unweaken OBJECT->{FIELD_NAME};

The return type is the void type.

See "Weak Reference" to know the behavior of the unweaken statement.

Compilation Errors:

The type of the object must be the class type. Otherwise a compilation error occurs.

If the field name is not found, a compilation error occurs.

The type of the field targetted by the unweaken statement is not an object type, a compilation error occurs.

Examples:

# unweaken
unweaken $object->{point};

Method Call

The method call calls a method.

Class Method Call

A method defined as the class method can be called using the class method call.

ClassName->MethodName(ARGS1, ARGS2, ...);

&MethodName(ARGS1, ARGS2, ...);

& means the current class.

If & is used in anon method, it means its outer class.

Compilation Errors:

If the number of arguments does not correct, a compilation error occurs.

If the types of arguments have no type compatible, a compilation error occurs.

Examples:

class Foo {
  
  static method main : void () {
    
    my $ret = Foo->bar(1, 2, 3);
    
    # Same as Foo->bar
    my $ret = &bar(1, 2, 3);
    
    my $cb = method : void () {
      # Same as Foo->bar;
      my $ret = &foo;
    };
  }
  
  static method foo : int () {
    return 5;
  }
}

Instance Method Call

A method defined as the instance method can be called using the instance method call.

Instance->MethodName(ARGS1, ARGS2, ...);

The called method is resolved from the type of the instance.

Compilation Errors:

If the number of arguments does not correct, a compilation error occurs.

If the types of arguments have no type compatible, a compilation error occurs.

Examples:

$object->bar(5, 3. 6);

The SUPER:: qualifier calls the method of the super class of the current class.

$object->SUPER::bar(5, 3. 6);

A instance method can be called statically by specifing the calss name.

$point3d->Point::clear;

args_width Operator

The args_width operator gets the stack length of the arguments passed to the method.

args_width

Note that the stack length of the arguments is different from the length of the arguments.

If the method call is the instance method call, the stack length of the arguments is the length of the arguments + 1 for the invocant.

If an argument is a multi-numeric type, the stack length of the argument becomes the length of the fields.

Examples:

static method my_static_method : int ($args : int, $bar : int = 0) {
  my $args_width = args_width;
  
  return $args_width;
};

# 1
&my_static_method(1);

# 2
&my_static_method(1, 2);

static method my_instance_method : int ($args : int, $bar : int = 0) {
  my $args_width = args_width;
  
  return $args_width;
};

# 2 (1 + the invocant)
&my_instance_method(1);

# 3 (2 + the invocant)
&my_instance_method(1, 2);

static method my_mulnum_method : int ($z : Complex_2d, $bar : int = 0) {
  my $args_width = args_width;
  
  return $args_width;
};

# 2 (The length of the fields of Complex_2d)
my $z : Complex_2d;
&my_mulnum_method($z);

# 3 (The length of the fields of Complex_2d + 1)
my $z : Complex_2d;
&my_mulnum_method($z, 2);

Exception

Explains exceptions.

Throwing Exception

You can throw an exception using the die statement.

die OPERAND;

Examples:

# Throw an exception
die "Error";

Exception Catching

You can catch an exception using an eval block.

eval {
  die "Error";
}

The undef is set to the exception variable $@ at the top of the eval block.

The error message is set to the exception variable $@ when the exception is thrown.

Examples:

# Catch the exception
eval {
  # Throw an exception
  die "Error";
}

# Check the error message
if ($@) {
  # ...
}

Exception Variable

Exception Variable is a global variable that is represented by "$@"

$@

See the setting class varialbe to get Exception Variable Value.

See "Setting Exception Variable" to set Exception Variable Value.

Garbage Collection

The object is destroyed when the reference count becomes 0.

If the object is an Array that has Object Type values ​​as elements, the reference count of all Array elements that are not Undefined Value is decremented by 1 before Garbage Collection

When an object is a class type and has a field of Object Type, the reference count of the objects owned by all fields of Object Type that are not Undefined Value is decremented by 1 before Garbage Collection. If Weak Reference is set to the object saved in Field, Weak Reference is destroyed before the reference count is decremented by 1.

When the object has Back references of Weak Reference, Undefined Value is assigned to all fields registered as back References and all back References are deleted.

The above process is done recursively.

Weak Reference

Weak Reference is a reference that does not increase the reference count. Weak Reference can be used to solve the problem of circular references.

SPVM has GC of the reference count Type. In the GC of the reference count Type, the object is automatically destroyed when the reference count becomes 0, but when the circular reference occurs, the reference count does not become 0 and the object is automatically destroyed. not.

This is an example when the field of the object is circularly referenced.

{
  my $foo = new Foo;
  my $bar = new Bar;

  $foo->{bar} = $bar;
  $bar->{foo} = $foo;
}

In this case, both objects are not destroyed when the Scope ends. This is because a circular reference has occurred and the reference count does not become 0.

Weak Reference is a function to correctly destroy objects when a circular reference occurs in a programming language that has the reference count GC.

In such a case, it is possible to release correctly by setting one Field to Weak Reference using the "weaken Operator" in weaken operator.

{
  my $foo = new Foo;
  my $bar = new Bar;

  $foo->{bar} = $bar;
  $bar->{foo} = $foo;

  weaken $foo->{bar};
}

Before the weaken statement is executed, $foo has the reference count of 2 and $bar has the reference count of 2.

If there is no weaken statement, the reference count of $foo and the reference count of $bar will not be 0 and will not be destroyed even if the scope ends.

When a weaken statement is executed, $foo has the reference count of 2 and $bar has the reference count of 1.

When the Scope ends, the reference count of $bar is decremented by 1 and becomes 0, so it is destroyed correctly.

Even if there are 3 circular references, you can release them correctly by setting Weak Reference in 1 Field.

{
  my $foo = new Foo;
  my $bar = new Bar;
  my $baz = new Baz;

  $foo->{bar} = $bar;
  $bar->{baz} = $baz;
  $baz->{foo} = $foo;

  weaken $foo->{bar};
}

As a syntax related to Weak Reference, Weak Reference can be destroyed the "weaken Operator" in weaken operator, and it can be confirmed whether Field is Weak Reference the isweak operator.

Standard IO

stdin, stdout, stderr in the C language is set to the binary mode on all systems.

This means the escape character of the string literal "\n" is not coverted to "\r\n" when it is got from stdin and it is printed to stdout and stderr.

stdin, stdout, stderr can be changed to the text mode using the native class, but don't do that.

Copyright & License

Copyright (c) 2023 Yuki Kimoto

MIT License