NAME
SPVM::Document::LanguageSpecification - SPVM Language Specification
DESCRIPTION
SPVM::Document::LanguageSpecification describes SPVM language specification.
Tokenization
Describes the tokenizing of the SPVM language.
Character Set
SPVM language are written by UTF-8.
Line Terminators
Line terminators are LF
, CR
, and CRLF
of ASCII.
When a line terminator appears, the current line number is incremented. The line terminator is converted to LF
of ASCII .
Space Characters
Space characters are SP
, HT
, FF
of ASCII and "Line Terminators".
Space characters have no meaning in programs.
Identifiers
Identifiers are "Class Names", "Method Names", "Field Names", "Class Variable Names", and "Local Variable Names".
Class Names
A class names consists of one or more alphabet(a-zA-Z
), number(0-9
), underscore(_
) or ::
of ASCII.
The part names of a class name must start uppercase letter. Part names means, for example, "Foo", "Bar", and "Baz" in the class name "Foo:Bar::Baz".
::
cannot be continued twice. The last character cannot end with ::
.
Underscore _
cannot be continued twice.
A class name must be corresponding to the relative name of the module file. If the class name is "Foo::Bar::Baz", the relative name of the module file must be "Foo/Bar/Baz.spvm".
If class names are invalid, a compilation error will occur.
Examples of valid class names:
Foo
Foo::Bar
Foo::Bar::Baz3
Foo::bar
Foo_Bar::Baz_Baz
Examples of invalid class names:
Foo
Foo::::Bar
Foo::Bar::
Foo__Bar
Foo::bar
Method Names
A method name consists of one or more alphabet(a-zA-Z
), number(0-9
), or underscore(_
) of ASCII.
The first character must not a number.
Underscore(_
) cannot be continued twice.
If method names are invalid, a compilation error will occur.
Examples of valid method names:
# Valid method names
FOO
FOO_BAR3
foo
foo_bar
_foo
_foo_bar_
Examples of invalid method names:
# Invalid method names
foo__bar
3foo
A method name can be the same as "Keywords".
# "if" is a valid method name although this name is the same as the "if" keyword.
static method if : void () {
}
Field Names
A field name consists of one or more alphabet(a-zA-Z
), number(0-9
), or underscore(_
) of ASCII.
The first character must not number.
Underscore(_
) cannot be continued twice.
If field names are invalid, a compilation error will occur.
Examples of valid field names:
# Valid field names
FOO
FOO_BAR3
foo
foo_bar
_foo
_foo_bar_
Examples of invalid field names:
# Invalid field names
foo__bar
3foo
A field name can be the same as "Keywords".
# "if" is a valid field name although this name is the same as the "if" keyword.
has if : int;
Class Variable Names
A class variable name starts with $
, followed alphabets(a-zA-Z
), numbers(0-9
), underscores(_
) or ::
of ASCII.
The followed character must not start with a number.
::
cannot be continued twice. Last characters cannot end with ::
.
Underscore(_
) cannot be continued twice.
If class variable names are invalid, a compilation error will occur.
Examples of valid class variable names:
# Valid class variable names
$FOO::BAR
$Foo::Bar3
$FOO
$FOO_BAR
$foo
Examples of invalid class variable names:
# Invalid class variable names
$FOO__BAR
$3FOO
Local Variable Names
A local variable name starts with $
, followed alphabets(a-zA-Z
), numbers(0-9
), underscores(_
) of ASCII.
The followed character must not start with a number.
Underscore(_
) cannot be continued twice.
If local variable names are invalid, a compilation error will occur.
Examples of valid local variable names:
# Valid local variable names
$foo
$foo_bar3
$_foo
$FOO
Examples of invalid local variable names:
# Invalid local variable names
$foo__bar
$3foo
Keywords
The list of keywords.
alias
allow
as
break
byte
callback_t
case
cmp
class
copy
default
die
divui
divul
double
dump
elsif
else
enum
eq
eval
for
float
false
gt
ge
has
has_implement
if
isa
isweak
is_read_only
implement
int
interface_t
last
length
lt
le
long
make_read_only
my
mulnum_t
method
mutable
native
ne
next
new
new_string_len
of
our
object
print
private
public
precompile
pointer_t
ref
refcnt
remui
remul
return
require
rw
ro
static
switch
string
short
scalar
true
undef
unless
unweaken
use
void
warn
while
weaken
wo
INIT
__END__
__CLASS__
__FILE__
__LINE__
Operators for Tokenization
The list of operators for tokenization.
!
!=
$
%
&
&&
&=
=
==
^
^=
|
||
|=
-
--
-=
~
@
+
++
+=
*
*=
<
<=
>
>=
<=>
%
%=
<<
<<=
>>=
>>
>>>
>>>=
.
.=
/
/=
\
(
)
{
}
[
]
;
:
,
->
=>
Note that operators for tokenization include those that are not really operators, and do not include operators with names.
Comments
A comment begins with "#" and ends with "Line Terminators".
# Comment
Comments have no meaning in tokenization.
POD
POD(Plain Old Document) is a syntax to write documents easily.
POD starts from the line beginning with =
, followed by any string that consists of ASCII printable characters, and ending with "Line Terminators".
POD ends from the line beginning with =cut
, and ending with "Line Terminators".
Examples of POD:
=pod
Multi-Line
Comment
=cut
=head1
Multi-Line
Comment
=cut
POD has no meaning in tokenization.
Literals
Literals are representations of values in source codes. These are "Integer Literal", "Floating Point Literal", "Character Literal", "String Literal" and "Bool Literal".
Integer Literal
Decimal Representation of Integer Literal
Decimal Representation of Integer Literal is represented by one or more consecutive characters from 0
to 9
.
Can be prefixed with "+" or "-".
"Types" of Integer Literal is "int Type" by default.
If Integer Literal exceeds the range of numbers that can be represented by "int Type", a compilation error will occur.
By suffixing "L" or "l" at the end, that represents "long Type" Integer Literal.
If "long Type" Integer Literal exceeds the range of numbers that can be represented by "long Type", If it exceeds the range, a compilation error will occur.
"_" can be used as a separator. Separator has no meaning.
If Integer Literal is assigned to a "byte Type" variable or passed to "byte Type" Method Argument, and does not exceed the range of numbers that can be represented by "byte Type", the numeric narrowing type conversion is performed and the value converted to "byte Type" value. If it exceeds the range, a compilation error will occur.
If Integer Literal is assigned to a "short Type" variable or passed to "short Type" Method Argument, and does not exceed the range of numbers that can be represented by "short Type", the numeric narrowing type conversion is performed and the value converted to "short Type" value. If it exceeds the range, a compilation error will occur.
Examples of Integer Literal:
123
+123
-123
123L
123l
123_456_789
-123_456_789L
Hexadecimal Representation of Integer Literal
Hexadecimal Representation of Integer Literal is represented by the following rule.
Hexadecimal Representation of Integer Literal starts with 0x
or 0X
.
It is followed by one or more consecutive characters 0
to 9
, a
to f
, or A
to F
.
Other rules are same as Decimal Representation of Integer Literal
Examples of Hexadecimal Representation of Integer Literal:
0x3b4f
-0x3F1A
0xDeL
0xFFFFFFFF_FFFFFFFF
Octal Representation of Integer Literal
Octal Representation of Integer Literal is represented by the following rule.
Octal Representation of Integer Literal starts with 0
.
It is followed by one or more consecutive characters 0
to 7
.
Other rules are same as Decimal Representation of Integer Literal
Examples of Octal Representation of Integer Literal:
0755
-0644
0666L
0655_755
Binary Representation of Integer Literal
Binary Representation of Integer Literal is represented by the following rule.
Binary Representation of Integer Literal starts with 0b
or 0B
.
It is followed by one or more consecutive characters 0
or 1
.
Examples of Binary Representation of Integer Literal:
0b0101
-0b1010
0b110000L
0b10101010_10101010
Floating Point Literal
Floating Point Literal consists of Sign Part, Numeric Part, Exponent Part and Suffix.
# Floating Point Literal
[Sign Part][Numeric Part][Exponent Part][Suffix Part]
Floating Point Literal is Decimal Floating Point Literal or Hexadecimal Floating Point Literal.
Sign Part is represented by "+" or "-". Sign Part is optional.
Numeric Part of Decimal Floating Point Literal starts one or more 0
to 9
.
Numeric Part of Hexadecimal Floating Point Literal starts 0x
or 0X
, and is followed by 0
to 9
, a
to f
, or A
to F
.
For that the Literal is Floating Point Literal, Numeric Part contains .
or, The Literal have Exponent Part, or have Suffix Part.
Numeric part can contain "_". This is just a Numeric Separator and is ignored.
Hexadecimal Floating Point Literal needs Exponent Part.
Exponent Part is consist of Exponential Notation and Signed Decimal Integer.
# Exponent Part
[Exponential Notation][Signed Decimal Integer]
Exponential Notation is e
or E
for Decimal Floating Point Literal, and p
or P
for Hexadecimal Floating Point Literal.
The meaning of Exponent Part is decimal shift for Decimal Floating Point Literal, or binary shift for Hexadecimal Floating Point Literal.
If Suffix Part is f
or F
, the "Types" of Floating Point Literal is "float Type".
If Suffix Part is d
or D
, the "Types" of Floating Point Literal is "double Type".
If Suffix Part is omitted, the "Types" of Floating Point Literal is "double Type".
If Floating Point Literal is "float Type", the Floating Point Literal is converted to float value using C standard "strtof" function. If the conversion fails, a compilation error will occur.
If Floating Point Literal is "double Type", the Floating Point Literal is converted to double value using C standard "strtod" function. If the conversion fails, a compilation error will occur.
Examples of Floating Point Literal:
1.32
-1.32
1.32f
1.32F
1.32e3
1.32e-3
1.32E+3
1.32E-3
0x3d3d.edp0
0x3d3d.edp3
0x3d3d.edP3
0x3d3d.edP-3f
Charater Literal
Charater Literal represents one character of ASCII.
Character Literal is enclosed in single quotes "'".
Content of Character Literal is one printable ASCII character or one Escape Character of Character Literal.
Charater Literal Type is ""byte Type""
"Types" of Charater Literal is "byte Type".
Escape Characters of Character Literal | Description |
---|---|
\0 | ASCII 0 NUL |
\a | ASCII 7 BEL |
\t | ASCII 9 HT |
\n | ASCII 10 LF |
\f | ASCII 12 "FF" |
\r | ASCII 13 CR |
\" | ASCII 34 " |
\' | ASCII 39 ' |
\\ | ASCII 92 \ |
\x + tow hexadecimal numbers | Specify ASCII by hexadecimal. Hexadecimal numbers are "0" to "9", "a" to "z", "A" to "Z". |
Examples of Charater Literal:
Charater Literal represents one character of ASCII.
# Charater Literal
'a'
'x'
# Charater Literal using Escape Character
'\a'
'\t'
'\n'
'\f'
'\r'
'\"'
'\''
'\\'
'\x0D'
'\x0A'
String Literal
The string literal is a literal to represents a string in source codes.
The return type is a string type.
A string literal is written by the characters of UTF-8.
The string Literal is enclosed in double quotes "
.
Examples of string literals:
# String Literal
my $message = "abc";
my $message_utf8 = "あいう"
Escape charaters of String Literal
Escape Character of String Literal | Description |
---|---|
\0 | ASCII 0 NUL |
\a | ASCII 7 BEL |
\t | ASCII 9 HT |
\n | ASCII 10 LF |
\f | ASCII 12 FF |
\r | ASCII 13 CR |
\" | ASCII 34 " |
\' | ASCII 39 ' |
\\ | ASCII 92 \ |
\x + two hexadecimal numbers |
Specify ASCII by hexadecimal. Hexadecimal numbers are "0" to "9", "a" to "z", "A" to "Z". For example, \x0D. |
\N{U+} + hexadecimal numbers after U+ |
Specify the Unicode code point in hexadecimal. Hexadecimal numbers are expressed as "0" to "9", "a" to "f", "A" to "F". For example, \N{U+3046}. The code point is converted to UTF-8. |
Raw escape character (For example, \s is become \s. This represents a sequence of two characters in a character literal '\\' 's') |
\s \S \d \D \w \W \p \P \X \g \k \K \v \V \h \H \R \b \B \A \Z \z \G \N \1 \2 \3 \4 \5 \6 \7 \8 \9 \! \# \@ \% \& \( \) \* \+ \- \. \/ \: \; \< \= \> \? \[ \] \^ \_ \` \{ \| \} \~ \, |
If the espape characters that is not included avobe is used, a compiler error occurs.<br>
Examples of escape characters of string literals:
# Escape characters of string literals
"abc\tdef\n"
"\x0D\x0A"
"\N{U+3042}\N{U+3044}\N{U+3046}"
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 of true:
# true
my $is_valid = true;
false
false
is the alias for FALSE method of Bool.
false
Examples of false:
# false
my $is_valid = false;
Variable Expansion
Variable Expansion applys "Local Variable", "Class Variable", "Dereference", "Field Access", "Array Access", "Exception Variable" in 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 $@ BBB"
The above is expanded as the following.
"AAA" . $foo . "BBB"
"AAA" . $FOO . "BBB"
"AAA" . $$foo . "BBB"
"AAA" . $foo->{x} . "BBB"
"AAA" . $foo->[3] . "BBB"
"AAA" . $foo->{x}[3] . "BBB"
"AAA" . $@ . "BBB"
The variable name can besurround with "{" and "}" to indicate the end of the variable name.
"AAA ${foo}_ccc BBB"
The above is expanded as the following.
"AAA " . ${foo} . "_ccc BBB"
If there is no enclosing "{" and "}", up to the valid part as a variable name is interpreted as a Variable. Dereference interpreting is same as this.
If "->" follows the variable name, it is interpreted as "Field Access" or "Array Access".
[1] If the following Characters are "a-z" "A-Z" "0-9" "_" "{" "[", proceed with the interpretation.
[2] If the Character following [1] is "}", or "]", then if the next Character is "->", "{", or "[", proceed with the interpretation and return back to [1], otherwise stop interpreting.
The trailing $is not treated as the start of Variable Expansion. It is treated as "$".
"AAA$"
Fat Comma
Fat Comma is a "Separators" represented by "=>".
=>
Fat Comma is an alias for Comma ",". Wherever you can use "," you can use Fat Comma instead.
# Comma
["a", "b", "c", "d"]
# Use Fat Comma instead of Comma
["a" => "b", "c" => "d"]
Identifiers other than "Class Variable Names" and "Local Variable Names" placed on the Left of Fat Comma are treated as "String Literal".
# Identifiers placed on the Left of Fat Comma are treated as String Literal
# a is "a", c is "c"
[a => "b", c => "d"]
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> DESCRIPTOR MAKE_READ_ONLY IMPLEMENT
%token <opval> IF UNLESS ELSIF ELSE FOR WHILE LAST NEXT SWITCH CASE DEFAULT BREAK EVAL
%token <opval> 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> DOT3 FATCAMMA RW RO WO INIT NEW OF
%token <opval> RETURN WEAKEN DIE WARN PRINT CURRENT_CLASS_NAME UNWEAKEN '[' '{' '('
%type <opval> grammar
%type <opval> opt_classes classes class class_block
%type <opval> opt_declarations declarations declaration
%type <opval> enumeration enumeration_block opt_enumeration_values enumeration_values enumeration_value
%type <opval> method anon_method opt_args args arg has use require alias our
%type <opval> opt_descriptors descriptors
%type <opval> opt_statements statements statement if_statement else_statement
%type <opval> for_statement while_statement switch_statement case_statement default_statement
%type <opval> block eval_block init_block switch_block if_require_statement
%type <opval> unary_op binary_op comparison_op isa logical_op expression_or_logical_op
%type <opval> call_spvm_method opt_vaarg
%type <opval> array_access field_access weaken_field unweaken_field isweak_field convert array_length
%type <opval> assign inc dec allow has_implement
%type <opval> new array_init
%type <opval> my_var var implement
%type <opval> expression opt_expressions expressions opt_expression case_statements
%type <opval> field_name method_name class_name class_alias_name is_read_only
%type <opval> type qualified_type basic_type array_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 NUMERIC_CMP STRING_CMP
%left <opval> SHIFT
%left <opval> '+' '-' '.'
%left <opval> '*' DIVIDE DIVIDE_UNSIGNED_INT DIVIDE_UNSIGNED_LONG REMAINDER REMAINDER_UNSIGNED_INT REMAINDER_UNSIGNED_LONG
%right <opval> LOGICAL_NOT BIT_NOT '@' CREATE_REF DEREF PLUS MINUS CONVERT SCALAR STRING_LENGTH ISWEAK REFCNT REFOP DUMP NEW_STRING_LEN IS_READ_ONLY COPY HAS_IMPLEMENT
%nonassoc <opval> INC DEC
%left <opval> ARROW
grammar
: opt_classes
opt_classes
: /* Empty */
| classes
classes
: classes class
| class
class
: CLASS basic_type class_block END_OF_FILE
| CLASS basic_type ':' opt_descriptors class_block END_OF_FILE
| CLASS basic_type ';' END_OF_FILE
| CLASS basic_type ':' opt_descriptors ';' END_OF_FILE
class_block
: '{' opt_declarations '}'
opt_declarations
: /* Empty */
| declarations
declarations
: declarations declaration
| declaration
declaration
: has
| method
| enumeration
| our
| use
| allow
| implement
| init_block
| alias
init_block
: INIT block
use
: USE class_name ';'
| USE class_name AS class_alias_name ';'
require
: REQUIRE class_name
alias
: ALIAS class_name AS class_alias_name ';'
allow
: ALLOW class_name ';'
implement
: IMPLEMENT class_name ';'
enumeration
: opt_descriptors 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_descriptors qualified_type opt_type_comment ';'
has
: HAS field_name ':' opt_descriptors qualified_type opt_type_comment ';'
method
: opt_descriptors METHOD method_name ':' return_type '(' opt_args opt_vaarg')' block
| opt_descriptors METHOD method_name ':' return_type '(' opt_args opt_vaarg')' ';'
| opt_descriptors METHOD ':' return_type '(' opt_args opt_vaarg')' block
| opt_descriptors METHOD ':' return_type '(' opt_args opt_vaarg ')' ';'
anon_method
: opt_descriptors METHOD ':' return_type '(' opt_args opt_vaarg')' block
| '[' args ']' opt_descriptors METHOD ':' return_type '(' opt_args opt_vaarg')' block
opt_args
: /* Empty */
| args
args
: args ',' arg
| args ','
| arg
arg
: var ':' qualified_type opt_type_comment
opt_vaarg
: /* Empty */
| DOT3
opt_descriptors
: /* Empty */
| descriptors
descriptors
: descriptors DESCRIPTOR
| DESCRIPTOR
opt_statements
: /* Empty */
| statements
statements
: statements statement
| statement
statement
: if_statement
| for_statement
| while_statement
| block
| switch_statement
| case_statement
| default_statement
| eval_block
| if_require_statement
| expression ';'
| LAST ';'
| NEXT ';'
| BREAK ';'
| RETURN ';'
| RETURN expression ';'
| DIE expression ';'
| WARN expression ';'
| PRINT expression ';'
| weaken_field ';'
| unweaken_field ';'
| ';'
| MAKE_READ_ONLY expression ';'
for_statement
: FOR '(' opt_expression ';' expression_or_logical_op ';' opt_expression ')' block
while_statement
: WHILE '(' expression_or_logical_op ')' block
switch_statement
: SWITCH '(' expression ')' switch_block
switch_block
: '{' case_statements '}'
| '{' case_statements default_statement '}'
case_statements
: case_statements case_statement
| case_statement
case_statement
: CASE expression ':' block
| CASE expression ':'
default_statement
: DEFAULT ':' block
| DEFAULT ':'
if_require_statement
: IF '(' require ')' block
| IF '(' require ')' block ELSE block
if_statement
: IF '(' expression_or_logical_op ')' block else_statement
| UNLESS '(' expression_or_logical_op ')' block else_statement
else_statement
: /* NULL */
| ELSE block
| ELSIF '(' expression_or_logical_op ')' block else_statement
block
: '{' opt_statements '}'
eval_block
: EVAL block ';'
opt_expressions
: /* Empty */
| expressions
opt_expression
: /* Empty */
| expression
expression_or_logical_op
: expression
| logical_op
expression
: var
| EXCEPTION_VAR
| CONSTANT
| UNDEF
| call_spvm_method
| field_access
| array_access
| convert
| new
| array_init
| array_length
| my_var
| unary_op
| binary_op
| assign
| inc
| dec
| '(' expressions ')'
| CURRENT_CLASS_NAME
| isweak_field
| comparison_op
| isa
| TRUE
| FALSE
| is_read_only
| has_implement
expressions
: expressions ',' expression
| expressions ','
| expression
unary_op
: '+' expression %prec PLUS
| '-' expression %prec MINUS
| BIT_NOT expression
| REFCNT var
| REFOP expression
| STRING_LENGTH expression
| DUMP expression
| DEREF var
| CREATE_REF var
| NEW_STRING_LEN expression
| COPY expression
is_read_only
: IS_READ_ONLY expression
inc
: INC expression
| expression INC
dec
: DEC expression
| expression DEC
binary_op
: expression '+' expression
| expression '-' expression
| expression '*' expression
| expression DIVIDE expression
| expression DIVIDE_UNSIGNED_INT expression
| expression DIVIDE_UNSIGNED_LONG expression
| expression REMAINDER expression
| expression REMAINDER_UNSIGNED_INT expression
| expression REMAINDER_UNSIGNED_LONG expression
| expression BIT_XOR expression
| expression BIT_AND expression
| expression BIT_OR expression
| expression SHIFT expression
| expression '.' expression
comparison_op
: expression NUMEQ expression
| expression NUMNE expression
| expression NUMGT expression
| expression NUMGE expression
| expression NUMLT expression
| expression NUMLE expression
| expression NUMERIC_CMP expression
| expression STREQ expression
| expression STRNE expression
| expression STRGT expression
| expression STRGE expression
| expression STRLT expression
| expression STRLE expression
| expression STRING_CMP expression
isa
: expression ISA type
logical_op
: expression_or_logical_op LOGICAL_OR expression_or_logical_op
| expression_or_logical_op LOGICAL_AND expression_or_logical_op
| LOGICAL_NOT expression_or_logical_op
| '(' logical_op ')'
assign
: expression ASSIGN expression
| expression SPECIAL_ASSIGN expression
new
: NEW basic_type
| NEW array_type_with_length
| anon_method
array_init
: '[' opt_expressions ']'
| '{' expressions '}'
| '{' '}'
convert
: '(' qualified_type ')' expression %prec CONVERT
array_access
: expression ARROW '[' expression ']'
| array_access '[' expression ']'
| field_access '[' expression ']'
call_spvm_method
: CURRENT_CLASS NAME '(' opt_expressions ')'
| CURRENT_CLASS NAME
| class_name ARROW method_name '(' opt_expressions ')'
| class_name ARROW method_name
| expression ARROW method_name '(' opt_expressions ')'
| expression ARROW method_name
| expression ARROW '(' opt_expressions ')'
field_access
: expression 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 '}'
has_implement
: HAS_IMPLEMENT var ARROW method_name
array_length
: '@' expression
| '@' '{' expression '}'
| SCALAR '@' expression
| SCALAR '@' '{' expression '}'
my_var
: MY var ':' qualified_type opt_type_comment
| MY var
var
: VAR_NAME
qualified_type
: type
| MUTABLE type {
type
: basic_type
| array_type
| ref_type
basic_type
: 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 '[' expression ']'
| array_type '[' expression ']'
return_type
: qualified_type opt_type_comment
| VOID
opt_type_comment
: /* Empty */
| type_comment
type_comment
: OF type
field_name
: NAME
method_name
: NAME
class_name
: NAME
class_alias_name
: NAME
Syntax Parsing Tokens
The list of syntax parsing tokens:
Tokens | Keywords or Operators |
---|---|
ALIAS | alias |
ALLOW | allow |
ARROW | -> |
AS | as |
ASSIGN | = |
BIT_AND | & |
BIT_NOT | ~ |
BIT_OR | | |
BIT_XOR | ^ |
BREAK | break |
BYTE | byte |
CASE | case |
CLASS | class |
CLASS_VAR_NAME | A class variable name |
CONSTANT | Literal |
CONVERT | (TypeName) |
COPY | copy |
CURRENT_CLASS | & |
CURRENT_CLASS_NAME | __CLASS__ |
DEC | -- |
DEFAULT | default |
DEREF | $ |
DESCRIPTOR | The name of a descriptor |
DIE | die |
DIVIDE | / |
DIVIDE_UNSIGNED_INT | divui |
DIVIDE_UNSIGNED_LONG | divul |
DOT3 | ... |
DOUBLE | double |
DUMP | dump |
ELSE | else |
ELSIF | elsif |
END_OF_FILE | The end of the file |
ENUM | enum |
EVAL | eval |
EXCEPTION_VAR | $@ |
FATCAMMA | => |
FLOAT | float |
FOR | for |
HAS | has |
HAS_IMPLEMENT | has_implement |
IF | if |
IMPLEMENT | implement |
INC | ++ |
INIT | INIT |
INT | int |
ISA | isa |
ISWEAK | isweak |
IS_READ_ONLY | is_read_only |
LAST | last |
LENGTH | length |
LOGICAL_AND | && |
LOGICAL_NOT | ! |
LOGICAL_OR | || |
LONG | long |
MAKE_READ_ONLY | make_read_only |
METHOD | method |
MINUS | - |
MUTABLE | mutable |
MY | my |
NAME | name |
NEW | new |
NEW_STRING_LEN | new_string_len |
OF | of |
NEXT | next |
NUMEQ | == |
NUMERIC_CMP | <=> |
NUMGE | >= |
NUMGT | > |
NUMLE | <= |
NUMLT | < |
NUMNE | != |
OBJECT | object |
OUR | our |
PLUS | + |
REF | \ |
REFCNT | refcnt |
REFOP | ref |
REMAINDER | % |
REMAINDER_UNSIGNED_INT | remui |
REMAINDER_UNSIGNED_LONG | remul |
REQUIRE | require |
RETURN | return |
RO | ro |
RW | rw |
SCALAR | scalar |
SELF | self |
SHIFT | << >> >>> |
SHORT | short |
SPECIAL_ASSIGN | += -= *= /= &= |= ^= %= <<= >>= >>>= .= |
SRING_CMP | cmp |
STREQ | eq |
STRGE | ge |
STRGT | gt |
STRING | string |
STRLE | le |
STRLT | lt |
STRNE | ne |
SWITCH | switch |
UNDEF | undef |
UNLESS | unless |
UNWEAKEN | unweaken |
USE | use |
VAR | var |
VOID | void |
WARN | warn |
WEAKEN | weaken |
WHILE | while |
WO | wo |
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 NUMERIC_CMP STRING_CMP
%left <opval> SHIFT
%left <opval> '+' '-' '.'
%left <opval> '*' DIVIDE DIVIDE_UNSIGNED_INT DIVIDE_UNSIGNED_LONG REMAINDER REMAINDER_UNSIGNED_INT REMAINDER_UNSIGNED_LONG
%right <opval> LOGICAL_NOT BIT_NOT '@' CREATE_REF DEREF PLUS MINUS CONVERT SCALAR STRING_LENGTH ISWEAK REFCNT REFOP DUMP NEW_STRING_LEN IS_READ_ONLY COPY HAS_IMPLEMENT
%nonassoc <opval> INC DEC
%left <opval> ARROW
See also syntax parsing tokens 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
Descriptions of classes.
Class Definition
The class
keyword defins a class. A class has a class block.
class CLASS_NAME {
}
Class names must follow the rule of class names.
Class descriptors can be specified after :
.
class CLASS_NAME : CLASS_DESCRIPTOR {
}
class CLASS_NAME : CLASS_DESCRIPTOR1 CLASS_DESCRIPTOR2 ... CLASS_DESCRIPTORN {
}
Examples of class definitions:
# The definition of a class
class Point {
}
# With class descriptors
class Point : public {
}
Direct children of the class block must be use, our, has, enum, method, allow, implement and INIT block can be defined.
class Foo {
use Point;
our $VAR : int;
has var : int;
enum {
CONST_VAL1,
CONST_VAL2,
}
static method foo : int ($num : int) {
# ...
}
implement Asset;
INIT {
# ...
}
}
If more than one class in a module file, a compilation error will occur.
If the class name is different from the name that the module file /
is replaced with ::
and added .spvm
to the end, a compilation error will occur.
# Valid class name for "Foo/Bar/Baz.spvm"
class Foo::Bar::Baz {
}
# Invalid class name for "Foo/Bar/Baz.spvm"
class Foo::Bar::Hello {
}
Class Descriptors
The list of class descriptors.
Descriptors | Meaning |
---|---|
public | This class is public. Other classes can new the object from this class. |
private | This class is private. Other classes can't new the object from this class. This is default setting. |
callback_t | This class is a callback type. |
interface_t | This class is an interface type. |
mulnum_t | This class is a multi-numeric type. |
pointer_t | This class is a pointer type. |
precompile | Do precompile all methods in this class, except for accessors, and enumurations. |
If both "public" and "private" are specifed, a compilation error will occur.
If more than one of "callback_t", "mulnum_t", "pointer_t" are specified, a compilation error will occur.
Destructor
If a class can has the destructor.
method DESTROY : void () {
}
A destructor is a special method called when the object is destroyed.
A destructor name must be DESTROY
.
A destructor retrun type must be void type, otherwise a compilation error will occur.
A destructor must be an instance method that don't have the arguments, otherwise a compilation error will occur.
If a "Exception" occurs in the destructor, the exception is not thrown, and prints the message to STDERR.
Examples of destructors:
class Foo {
static method new : Foo {
return new Foo;
}
method DESTROY : void () {
print "DESTROY";
}
}
Allow Class Access
By default, private Methods, Fields, and Class Variables cannot be accessed from outside the Class.
Also, Private Class cannot "new Operator" from outside of Class.
If the class allow other class, the other class can access private Methods, Fields, and Class Variables, and can "new Operator" of the class.
allow CLASS_NAME;
allow must be defined directory under "Class Definition".
class Foo {
allow Bar;
}
In this example, Bar can access the private Method, Field, and Class Variable of Foo can be accessed and can new Operator of Foo.
Specifying the module of allow also loads the module by "use" at the same time.
implement Statement
The class that implements interfaces is expected to implement the methods of the interface.
class Asset::Memory {
implement Asset;
method add_chunk : void ($chunk : string) {
# ...
}
method contains : int ($substring : string){
# ...
}
method size : int (){
# ...
}
method is_file : int (){
# ...
}
}
class Asset::File {
implement Asset;
method add_chunk : void ($chunk : string){
# ...
}
method contains : int ($substring : string){
# ...
}
method size : int (){
# ...
}
method is_file : int (){
# ...
}
}
Not that implement
statement doesn't force the implementation of methods of the interface.
class Asset::File {
implement Asset;
method add_chunk : void ($chunk : string){
# ...
}
method contains : int ($substring : string){
# ...
}
# It is OK although size and is_file method is not defined
}
If the method implementation is not found, an exception is thrown at runtime.
The existence of the method implementation can be checked by the has_implement operator.
Anon Class
The anon class is the class that is defined by the creating callback syntax.
A anon class has its unique name.
Interface
Explains interfaces.
Interface Type Definition
A interface is defined using a "Class Descriptors" in class descriptor interface_t
.
class Asset: interface_t {
method add_chunk : void ($chunk : string);
method contains : int ($substring : string);
method size : int ();
method is_file : int ();
}
The type of the interface is "Interface Type".
The object that implements the interface using implement stataments can be assign to the interface.
class Asset::Memory {
implement Asset;
}
class Asset::File {
implement Asset;
}
my $asset : Asset = Asset::Memory->new;
my $asset : Asset = Asset::File->new;
Callback
Explains callbacks.
Callback Type Definition
A callback type can be defined using the class descriptor callback_t
.
# Define a callback type
class Comparator: callback_t {
method : int ($x1 : object, $x2 : object);
}
A callback must have only one method definition. The method must be an instance method.
The method can't have the method block.
A callback type can't have field definitions and class variable definitions.
If the callback type definition is invalid, a compilation error will occur.
A callback can be create using the syntax of "Creating Callback". A callback is an object of a class type.
A callback that have the same method defined in the callback type can be assign to the callback type.
# Create a callback and the callback is assigned to a callback type
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.
Module
Module Summary
Module is a single file that can be read as SPVM source code.
# lib/path/SPVM/Foo/Bar.spvm
class Foo::Bar {
}
Module can contain multiple Classes.
# lib/path/SPVM/Foo/Bar.spvm
class Foo::Bar {
}
class Foo::Bar::Baz {
}
Module File Name
Modules must be placed in the module loading path with the following File Name.
Change "::" to "/". Add ".spvm" at the end.
SPVM/Foo.spvm
SPVM/Foo/Bar.spvm
SPVM/Foo/Bar/Baz.spvm
Load Modules
The use
syntax loads a Module.
# Load a module
use Foo;
If the module does not exist, a compilation error will occur.
Modules are loaded at compile-time.
use
syntax must be defined directly under "Class Definition".
class Foo {
use Foo;
}
Class Alias
alias
syntax create 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 "Class Definition".
class Foo {
alias Foo::Bar as FB;
}
You can create an alias at the same time as loading a module by use
.
use Foo::Bar as FB;
Automatically Loaded Module
The followings are Automatically Loaded Modules. They can be used without "use".
- Byte
- Short
- Int
- Long
- Float
- Double
Load Module Selective
In SPVM, there is an if require Statement that loads a Module only if it exists in the module path, and if it does not exist, the block does not exist.
It was designed to implement a part of features of "#ifdef" in 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 will occur 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 Modules
The following modules are loaded by default. These modules are deeply related to the features of SPVM language itself, such as type conversion.
Class Variable
Class Variable Definition
Class Variable is a global variable that belongs to "Class" and exists from the start to the end of the program execution.
"our" Keyword defines a Class Variable.
our CLASS_VARIABLE_NAME : TYPE;
Class Variable must be defined directly under "Class Definition".
Class Variable Definition must specify "Types". The Type must be "Numeric Types" or "Object Types".
Class variable mames must follows the rule specified in "Class Variable Names", and must not contain "::", otherwise a compilation error will occur.
If more than one Class Variable with the same name is defined, a compilation error will occur.
Class Variable Descriptor can be specified together in Class Variable definition.
our CLASS_VARIABLE_NAME : DESCRIPTOR TYPE;
our CLASS_VARIABLE_NAME : DESCRIPTOR1 DESCRIPTOR2 DESCRIPTORN TYPE;
Class Variable Descriptor
List of Class Variable Descriptors.
Descriptor | Description |
---|---|
public | This Class Variable is public. This Class Variable can be accessed from other class. |
private | This Class Variable is private. This Class Variable can't be accessed from other class. This is default setting of Class Variable. |
ro | This Class Variable has Read Accessor. Read Accessor name is the same as class variable names except removing "$". For example, If the class variable names is "$FOO", Read Accessor name is "FOO". |
wo | This Class Variable has Write Accessor. Write Accessor name is the same as class variable names except removing "$" and adding "SET_" to top. For example, If the class variable names is "$FOO", Read Accessor name is "SET_FOO". |
rw | This Class Variable has Read accessor and Write Accessor. |
If both "public" and "private" Descriptors are specified, a compilation error will occur.
If more than one of "ro", "wo", and "rw" are specified at the same time, a compilation error will occur
Read Accessor of Class Variable has no arguments and the return type is same as the type of Class Variable.
Write Acessor of Class Variable has one argument and the type is same as the type of Class Variable. The return type is "void Type".
Inline Expansion optimization is performed to Read Accessor and Write Accessor. You don't have to worry about the performance penalty of using Class Variable Accessors.
Examples of Class Variable Definition:
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 Initial Value
Class Variable is initialized with "Type Initial Value" after compilation and before execution.
This initial value can be changed by using "INIT Block".
class Foo {
our $VAR : int;
INIT {
$VAR = 3;
}
}
Class Variable Access
Class Variable Access is an operation to access Class Variable to get or set a value.
See "Getting Class Variable" for how to get the value of Class Variable.
See "Setting Class Variable" for the setting of the value of Class Variable.
Field
Field Definition
Field is a data area in a "object created using new keyword"
has
keyword defines a field.
has FIELD_NAME : TYPE;
Field must be defined directly under "Class Definition".
Field Definition must be specify "Types". The Type must be "Numeric Types" or "Object Types".
Field names must follows the rule specified in "Field Names".
Field Type must be "Numeric Types" or "Object Types", otherwise a compilation error will occur.
If more than one field names Variable with the same name is defined, a compilation error will occur.
Field Descriptor can be specified together in Field Definition.
has FIELD_NAME : DESCRIPTOR TYPE_NAME;
has FIELD_NAME : DESCRIPTOR1 DESCRIPTOR2 DESCRIPTORN TYPE_NAME;
Field Descriptor
List of Field Descriptors.
Descriptor | Description |
---|---|
public | This field is public. This field can be accessed from other class. |
private | This field is private. This field can't be accessed from other class. This is default setting. |
ro | This Field has Read Accessor. Read Accessor name is the same as field mames. For example, If the field names is "foo", Read Accessor name is "foo". |
wo | This Field has Write Accessor. Write Accessor name is the same as field names adding "set_" to top. For example, If the field names is "foo", Read Accessor name is "set_foo". |
rw | This Field has Read Accessor and Write Accessor. |
If both "public" and "private" Descriptors are specified, a compilation error will occur.
If more than one of "ro", "wo", and "rw" are specified at the same time, a compilation error will occur
Read Accessor of Field has one argument that is "self Type" and the return type is same as the type of Field.
Write Acessor of Class Variable has two arguments. First argument is "self Type" and second argument is same as the type of Field. The return type is "void Type".
Inline Expansion optimization is performed to Read Accessor and Write Accessor. You don't have to worry about the performance penalty of using Field Accessors.
Examples of Field Definition:
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 expression to get or set the field.
INVOCANT->{FIELD_NAME}
The field access has three different syntax.
If the invocant is different from the following three field access, a compilation error will occur.
If the field name does not found, a compilation error will occur
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 the 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_VALUE_TYPE (ARG_NAME1 : ARG_TYPE1, ARG_NAME2 : ARG_TYPE2, ...) {
}
# Instance method
method METHOD_NAME : RETURN_VALUE_TYPE (ARG_NAME1 : ARG_TYPE1, ARG_NAME2 : ARG_TYPE2, ...) {
}
Methods must be defined directly under "Class Definition".
Method names must be follow the rule of "Method Names".
The argument names must be follow the rule of "Local Variable Names".
The minimal length of arguments is 0
. The max length of arguments is 255
.
The types of the arguments must be "Numeric Types", "Multi-Numeric Types", "Object Types", or "Reference Type", otherwise a compilation error will occur.
The type of the return value must be "void Type", "Numeric Types", "Multi-Numeric Types" or "Object Types", otherwise a compilation error will occur.
Defined methods can be called using "Method Call" syntax.
A method can have method descriptors.
DESCRIPTORS static method METHOD_NAME : RETURN_VALUE_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 descriptors.
Variable Length Arguments
...
after the type of the argument indicates the argument is a variable length argument. Only the last argument can become a variable length argument.
static method METHOD_NAME : RETURN_VALUE_TYPE (ARG_NAME1 : ARG_TYPE1, ARG_NAME2 : ARG_TYPE2...) {
}
The type of the variable length argument must be "Array Types".
A variable length argument can recieve multiple values.
# Definition of variable length argument
static method sprintf : string ($format : string, $values : object[]...) {
}
# Pass multiple values to the a variable length argument
sprintf("Value %d %f", 1, 2.0);
A variable length argument can recieve an array.
# Pass array to a variable lenght argument
sprintf("Value %d %f", [(object)1, 2.0]);
If you want to treat the value as an individual element, cast it to type other than "Array Types"..
sprintf("aaa %p", (object)[(object)1, 2.0]);
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 $asset = Asset->new;
$asset->add_chumk("foo");
Method Descriptors
Method descriptors are descriptors used in a method definition.
Descriptors | Descriptions |
---|---|
public | This method is public. This method can be accessed from other classes. This is default setting. |
private | This method is private. This method can not be accessed from other classes. |
precompile | This method is a precompile method. |
native | This method is a native method. |
Native Method
Native methods are the methods that is written by native languages such as C, C++.
A native method is defined by the native
method descriptor.
native sum : int ($num1 : int, $num2 : int);
A native method doesn't have its method block.
See also the SPVM Native API to implement native methods.
Precompiled Method
If the class has the precompile
class descriptor, 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.
Constant Method
Constant Method is a Method that the return type is "Numeric Types" and returns Constant Value.
static method foo : int () { return 5; }
static method foo : long () { return 5L; }
static method foo : float () { return 5.0f; }
static method foo : double () { return 5.0; }
Inline Expansion optimization is performed to Constant Method.
Note that SPVM does not perform constant convolution optimization, so if a constant is calculated, it will not performe Inline Expansion.
# This is not Constant Method. Inline Expansion is not performed
static method foo : int () { return 5 + 3; }
Signature
A signature is a string that represents the return type and the types of the arguments of a method.
RETURN_TYPE(ARG_TYPE1,ARG_TYPE2,ARG_TYPEn)
It the method is an instance method, the type representation of the first argument is self
.
Examples:
# Method Definition
static method foo : int ($num1 : double, $num2 : long[])
# The signature
int(double,long[])
# Method Definition
static method foo : void ()
# The signature
void()
# Method Definition
method foo : int ($num1 : double, $num2 : long[])
# Signature
int(self,double,long[])
Signatures are used by native APIs.
Enumeration
Explains enumeration.
Enumeration Definition
The enum
keyword defines an enumeration. An enumeration defines constant values.
# Enumeration Definition
enum {
FLAG1,
FLAG2,
FLAG3
}
An enumeration must be defined directly under "Class Definition".
The first value of an enumeration starts with 0
. The next value is incremented by 1
, and this is continued in the same way. In this example, FLAG1
is 0
, FALG2
is 1
, and FLAG3
is 2
.
The type of a value of an enumeration is the int type.
,
after the last value can be allowed.
enum {
FLAG1,
FLAG2,
FLAG3,
}
A value of an enumeration is implemented as a constant method.
static method FLAG1 : int () { return 0; }
static method FLAG2 : int () { return 1; }
static method FLAG3 : int () { return 2; }
The value can be set explicitly.
enum {
FLAG1,
FLAG2 = 4,
FLAG3,
}
In the above example, FLAG1
is 0
, FALG2
is 4
, and FLAG3
is 5
.
If an enumeration definition is invalid, a compilation error will occur.
Examples:
class Foo {
enum {
FLAG1,
FLAG2,
FLAG3,
}
}
Enumeration Descriptors
Descriptors can be specified to an enumeration definition.
private enum {
FLAG1,
FLAG2 = 4,
FLAG3,
}
The list of enumeration descriptors:
Descriptors | Descriptions |
---|---|
public | This enumeration is public. Each value of this enumeration can be accessed from other classes. This is default setting. |
private | This enumeration is private. Each value of this enumeration can not be accessed from other classes. |
If both "public" and "private" descriptors are specified, a compilation error will occur.
Enumeration Call
The value of enumeration called as a class method call.
my $flag1 = Foo->FLAG1;
my $flag2 = Foo->FLAG2;
my $flag3 = Foo->FLAG3;
In special cases, a value of an enumeration can be used as the operand of a case statement.
switch ($num) {
case Foo->FLAG1: {
break;
}
case Foo->FLAG2: {
break:
}
case Foo->FLAG3: {
break:
}
default: {
}
}
INIT Block
INIT Block is a block that is executed immediately after the compilation of program.
INIT Keyword defines INIT Block.
INIT {
}
INIT Block must be defined directly under "Class Definition".
class Foo {
INIT {
}
}
Zero or more "Statements" can be written in INIT Block.
INIT {
my $foo = 1 + 1;
my $bar;
}
"return Statement" cannot be written in INIT Block.
Internally, INIT Block is a "Method" that the return type is "void Type" and has no arguments.
You can define multiple INIT Blocks.
The execution order of INIT Block is not guaranteed. If ohter INIT Block is defined in ohter Class, do not assume that INIT Block of the current class will be executed first.
A common use of INIT Block is to initialize "Class Variable".
class Foo {
use Point;
our $NUM : int;
our $POINT : Point;
INIT {
$NUM = 3;
$POINT = Point->new;
}
}
Local Variable
Local Variable Declaration
Local Variable is a variable that is declared in "Scope Blocks". Local Variable has "Scope". This is same as Local Variable in C Language.
Local Variable is declared using my "Keyword".
my LOCAL_VARIABLE_NAME : TYPE;
The local variable name must be follow the rule of "Local Variable Names".
"Types" must be specified. Type must be "Numeric Types", "Object Types", "Multi-Numeric Types", or "Reference Type".
# Local Variable Declaration Examples
my $var : int;
my $var : Point;
my $var : Complex_2d;
my $var : int*;
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;
Initialization can be done at the same time as 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;
Using "Type Inference", you omit "Types" in Local Variable Declaration.
# int
my $num = 1;
# double
my $num = 1.0;
Local Variable Declaration returns the value of Local Variable. This is a "Expressions".
my $ppp = my $bar = 4;
if (my $bar = 1) {
}
while (my $bar = 1) {
}
See "Scope" about Local Variable Scope.
Local Variable Initial Value
Local Variable is initialized by "Type Initial Value".
Local Variable Access
Local Variable Access is an operation 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
Scope Summary
Scope is a range surrounded by "Scope Blocks".
# Scope Blocks
{
# Start of Scope
# ...
# End of Scope
}
Local Variable Declaration registers the Local Variable that is "Object Types" with Mortal Variable in run-time.
If the object is not "undef", The reference count is added by 1
.
{
# $num become Mortal Variable in run-time
my $num = new Foo;
}
At the end of Scope, the object that is registered as Mortal Variable, Reference Count is reduced by 1 except the object is not "undef".
If the reference count become 0, the object released.
Block
The parts enclosed by {
and }
are called blocks.
# Blocks
{
1;
}
if (true) {
}
while (true) {
}
enum {
ONE,
TWO,
}
class Foo {
}
Scope Blocks
A scope block is the block that create a scope. Zero or more statements can be written in a scope block.
Scope blocks are "Simple Block", "Method Block", "eval Block", "if Block", "elsif Block", "else Block", "for Block", "while Block" and "switch Block".
Simple Block
A simple block is a scope block.
# A simple block
{
}
Method Block
A method
block is a scope block.
# A method block
static method foo : int () {
}
eval Block
a eval
block is a scope block.
# A eval block
eval {
};
if Block
A if
block is a scope block.
# A if block
if (CONDITION) {
}
elsif Block
A elsif
block is a scope block.
# A elsif block
elsif (CONDITION) {
}
else Block
A else
block is a scope block.
# A else Block
else {
}
for Block
A for
block is a scope block.
# A for Block
for (my $i = 0; $i < 3; $i++) {
}
while Block
A while
block is a scope block.
# A while block
while (CONDITION) {
}
switch Block
A switch
block is a scope block.
switch (CONDITION) {
}
String
SPVM has the string type. A string is created by "String Literal" "String Creation 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 a type conversion 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 can't 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 undefined type
Examples of undefined values:
# 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 operation 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
Multi-Numeric Types Definition
Multi-Numeric type represents continuous numeric values. For example, there are three consecutive 32-bit signed integers, two consecutive double-precision floating point numbers. It isplaned to use 3D points, complex numbers, quaternions, etc.
Multi-Numeric Types are defined by specifying mulnum_t "Class Descriptors" in "Class Definition".
# Three consecutive 32bit signed integers
class Point_3i : mulnum_t {
has x : int;
has y : int;
has z : int;
}
# Tow consecutive 64bit floating point numbers
class Complex_2d : mulnum_t {
x : double;
y : double;
}
Multi-Numeric Types must end with "_", Number of Fields, "Multi-Numeric Types Suffix".
The suffix must correspond to "Numeric Types".
All Fields must be the same "Numeric Types".
The maximum number of Fields is 255.
Multi-Numeric Types can be used as "Types" of "Local Variable Declaration".
Multi-Numeric Types can be used as an argument "Types" in "Method Definition" .
Multi-Numeric Types can be used as "Types" of Return Value in "Method Definition".
Multi-Numeric Types can be used as "Basic Type" of "Array Types" .
my $points = new Point_3i[5];
Reference can be created for Multi-Numeric Types value.
my $point : Point_3i;
my $point_ref = \$point;
"Undefined Value" cannot be assigned to Multi-Numeric Types value.
See "Multi-Numeric Types Field Access" to get and set the value of field of Multi-Numeric Types Value.
Multi-Numeric Types Suffix
List of Multi-Numeric Types Suffix.
Numeric Types | Multi-Numeric Types Suffix |
---|---|
byte | b |
short | s |
int | i |
long | l |
float | f |
double | d |
Multi-Numeric Types Usage
To use Multi-Numeric Types, load a Module using "use Statement".
use Point_3i;
use Complex_2d;
Next is "Local Variable Declaration". Local Variable Declaration create continuous area for fields of Multi-Numeric Types Value. All fields of of Multi-Numeric Types Value are initialized by "Type Initial Value".
my $point : Point_3i;
my $z : Complex_2d;
Note that Multi-Numeric Types value are not object, so cannot create a Object by "new" syntax.
Multi-Numeric Types Field Access
Multi-Numeric Types Field Access is an operation to access Multi-Numeric Types Field to get or set a value.
MULTI_NUMERIC_TYPE_VALUE->{FIELD_NAME}
See "Getting Multi-Numeric Field" to get Multi-Numeric Types Field.
See "Setting Multi-Numeric Field" to set Multi-Numeric Types Field.
Multi-Numeric Array
Multi-Numeric Array Summary
"Multi-Numeric Value" can be an element of "Array".
my $points = new Point_3i[5];
my $zs = new Complex_2d[5];
Multi-Numeric Array has continuous Multi-Numeric Values.
The Element Type is "Multi-Numeric Types", not "Object Types".
For example, Point_3i[5] is continuous 15 (= 3 * 5) count "int Type" Value.
"Types" of Multi-Numeric Array is "Array Types".
Multi-Numeric Array Access
Multi-Numeric Array Access is an operation to access Multi-Numeric Array to get and set the element value.
Array->[INDEX]
See "Getting Array Element" to get Array Element Value.
See "Setting Array Element" to get Array Element Value.
Reference
Reference Summary
Reference is data that indicates the location of "Local Variable" in the memory. Reference is a feature corresponding to Pointer in C language.
You can get Reference of Local Variable using "Reference Operator".
"Reference Type" is represented by "Numeric Types" "*" or "Multi-Numeric Types" followed by "*". Reference types are represented by appending an * after "Numeric Types" or "Multi-Numeric Types".
# Numeric Types Reference
my $num : int;
my $num_ref : int* = \$num;
# Multi-Numeric Types Reference
my $point : Point_3d;
my $point_ref : Point_3d* = \$point;
Target of Reference Operator is Variable of "Numeric Types" or "Multi-Numeric Types". "Object Types" Variable or "Literals" can't be target of Reference Operator.
"Reference Type" can be used in Method Argument.
# Method Definition
static method sum : void ($out_ref : int*, $in1 : int, $in2 : int) {
$$out_ref = $in1 + $in2;
}
# Method Call
my $num1 = 1;
my $num2 = 2;
my $out : int;
my $out_ref = \$out;
sum($out_ref, $num1, $num2);
Dereference
Dereference is an operation to get and set the value pointed by Reference.
# Dereference Numeric Types Reference to get the pointed value
my $num2 = $$num_ref;
# Dereference Numeric Types Reference to set the pointed value
$$num_ref = 3;
# Dereference Multi-Numeric Types Reference to get the pointed value
my $point2 = $$point_ref;
# Dereference Multi-Numeric Types Reference to set the pointed value
$$point_ref = $point2;
If the target of Reference Type is "Multi-Numeric Types", the setting and getting of Multi-Numeric Types Field can be done by Arrow Operator.
# If the target of Reference Type is Multi-Numeric Types, get Multi-Numeric Types Field
my $x = $point_ref->{x};
# If the Target of Reference Type is Multi-Numeric Types, set Multi-Numeric Types Field
$point_ref->{x} = 1;
Expressions
Expressions are "Operators", "Undefined Value", "Literals", "Getting Local Variable", "Setting Local Variable", "Getting Class Variable", "Getting Class Variable", "Setting Class Variable", "Getting Exception Variable", "Setting Exception Variable", "Getting Field", "Setting Field", "Getting Multi-Numeric Field", "Setting Multi-Numeric Field", "Getting Multi-Numeric Field via Dereference", "Setting Multi-Numeric Field via Dereference", <"Getting Array Element">, "Setting Array Element" and "Method Call".
A expression returns a value.
Getting Local Variable
The getting local variable is an expression 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 expression to set the value of "Local Variable" using the assignment operator.
$var = VALUE
The assignment of the value must satisfy the type assignability, otherwise a compilation error will occur.
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.
Getting Class Variable
The getting class variable is an expression 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 does not found, a compilation error will occur.
If the class variable is private
and it is accessed outside of the class, a compilation error will occur.
Examples of getting class variable:
class Foo {
our $VAR : int;
static method bar : int () {
my $var1 = $Foo::VAR;
my $var2 = $VAR;
}
}
Setting Class Variable
Setting Class Variable Expression is an expression 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
If the assignment does not satisfy the type assignability, a compilation error will occur.
The return value is the value after the setting.
The return type is the type of the class variable.
If the class variable does not found, a compilation error will occur.
If the class variable is private
and it is accessed outside of the class, a compilation error will occur.
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
.
Examples of setting class variable:
class Foo {
our $VAR : int;
static method bar : int () {
$Foo::VAR = 1;
$VAR = 3;
}
}
Getting Exception Variable
The setting exception variable is an expression 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 of getting exception variable:
# Getting the exception variable
my $message = $@;
Setting Exception Variable
The setting exception variable is an expression to set the value of "Exception Variable" using the assignment operator.
$@ = VALUE
The type of the assigned value must be "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 of setting exception variable:
$@ = "Error";
Getting Field
The getting field is an expression 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 of getting field:
my $point = Point->new;
my $x = $point->{x};
Setting Field
The setting field is an expression 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.
If the assignment does not satisfy the type assignability, a compilation error will occur.
The return value is the value after the setting.
The return type is the type of the field.
If the type of assigned value is a basic object type, Reference Count of the object is incremented by 1
.
If an object has already been assigned to Field before the assignment, the reference count of that object is decremented by 1
.
Examples of Setting Field:
my $point = Point->new;
$point->{x} = 1;
Getting Multi-Numeric Field
Getting Multi-Numeric Field Expression is an expression to get Field of "Multi-Numeric Value". This is one syntax of the field access.
INVOCANT->{FIELD_NAME}
Invocant Expression is "Multi-Numeric Types".
If the field names does not found in the "Class", a compilation error will occur
Getting Multi-Numeric Field Expression returns the field value in the Multi-Numeric Value.
Retrun Type is The "Types" of the Field.
Examples of Getting Multi-Numeric Field:
my $z : Complex_2d;
my $re = $z->{x};
Setting Multi-Numeric Field
Setting Multi-Numeric Field Expression is an expression to set Field of "Multi-Numeric Value" using "Assignment Operator". This is one syntax of the field access.
INVOCANT->{FIELD_NAME} = RIGHT_OPERAND
Invocant Expression is "Multi-Numeric Types".
If the field names does not found in the "Class", a compilation error will occur.
Setting Multi-Numeric Field Expression returns the value of Field after setting.
The assignment must satisfy the type assignability.
Return Value Type is the type of Field.
Examples of Setting Multi-Numeric Field:
my $z : Complex_2d;
$z->{x} = 2.5;
Getting Multi-Numeric Field via Dereference
Getting Multi-Numeric Field via Dereference Expression is an expression to get Field of "Multi-Numeric Value" via "Dereference". This is one syntax of the field access
INVOCANT->{FIELD_NAME}
Invocant Expression is "Multi-Numeric Reference Type".
If the field names does not found in the "Class", a compilation error will occur
Getting Multi-Numeric Field via Dereference Expression returns the field value in the Multi-Numeric Value.
Retrun Type is The "Types" of the Field.
Examples of Getting Multi-Numeric Field via Dereference:
my $z : Complex_2d;
my $z_ref = \$z;
my $re = $z_ref->{x};
Setting Multi-Numeric Field via Dereference
Setting Multi-Numeric Field Expression via Dereference is an expression to set Field of "Multi-Numeric Value" via "Dereference" using "Assignment Operator". This is one syntax of the field access.
INVOCANT->{FIELD_NAME} = RIGHT_OPERAND
Invocant Expression is "Multi-Numeric Reference Type".
If the field names does not found in the "Class", a compilation error will occur
Setting Multi-Numeric Field via Dereference Expression returns the value of Field after setting.
The assignment must satisfy the type assignability.
Return Value Type is the type of Field.
Examples of Setting Multi-Numeric Field via Dereference:
my $z : Complex_2d;
my $z_ref = \$z;
$z_ref->{x} = 2.5;
Getting Array Element
Getting Array Element Expression is an expression to get a Element Value of "Array".
ARRAY_EXPRESSION->[INDEX_EXPRESSION]
Array Expression must be "Array Types".
Index Expression must be "int Type" or the type that become "int Type" by "Unary Numeric Widening Type Conversion".
Getting Array Element Expression returns the Element Value of the Index.
If Array Expression is "Undefined Value", a Runtime Exception occurs.
If Index Expression is lower than 0 or more than the max index of the Array, a Runtime Exception occurs.
Examples of Getting Array Element:
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
Setting Array Element Expression is an expression to set a Element Value of a Array using "Assignment Operator".
ARRAY_EXPRESSION->[INDEX_EXPRESSION] = RIGHT_OPERAND
Array Expression must be "Array Types".
Index Expression must be "int Type" or the type that become "int Type" by "Unary Numeric Widening Type Conversion".
The assignment must satisfy the type assignability.
Setting Array Element Expression returns the value of the element after setting.
If Array Expression is "Undefined Value", a Runtime Exception occurs.
If Index Expression is lower than 0 or more than the max index of the Array, a Runtime Exception occurs.
If the right operand is "Object Types", Reference Count of the object is incremented by 1
.
If an object has already been assigned to Field before the assignment, the reference count of that object is decremented by 1
.
Examples of Setting Array Element:
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 expression to create an object or an array.
Creating Object
The creating object is an expression to create an object using the new
keyword.
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 rule of type 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 of creating object:
my $object = new Foo;
Creating Array
The creating array is an expression to create an array using the new
keyword.
new BasicType[LENGTH]
The type must be a basic type.
The type of length must be the int type or the type that become int type after the unary numeric widening type conversion.
If the length is lower than 0
, an exception is thrown.
All elements of the array are initialized by the rule of type initial value.
The type of created array is the array type.
Examples of creating array:
my $nums = new int[3];
my $objects = new Foo[3];
my $objects = new object[3];
my $values = new Complex_2d[3]
Multi Dimensional Array
Multi dimensional arrays can be created.
new BasicType[][LENGTH]
new BasicType[][]...[LENGTH]
Examples of creating multi dimentional array:
# 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
SPVM has a syntax for Array Initialization to simplify Creating Array. Expression is not required.
[]
[Expression1, Expression2, Expression3]
Array Initialization returns an Array that has the length of the number of elements of Expression.
The type of Array is the type of Expression1 converted to Array Types. If no element is specified, it will be an Array Types of "Any Object Type".
If Expression2 or later does not satisfy the type assignability, a a compilation error will occur.
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"];
Array Initialization has another syntax. This is same as above array init syntax, but always the generated object type is an array Type of "Any Object Type". And if count of expression is odd number, a compile error occurs.
{}
{Expression1, Expression2, Expression3, Expression4}
Examples:
# Key values empty
my $key_values = {};
# Key values
my $key_values = {foo => 1, bar => "Hello"};
Method Calls
Method calls are "Class Method Call" and "Instance Method Call".
Class Method Call
A method defined as the class method can be called using the class method call.
ClassName->MethodName(ARGS1, ARGS2, ...);
If the number of arguments does not correct, a compilation error will occur.
If the types of arguments have no type compatible, a compilation error will occur.
Examples of class method call:
my $ret = Foo->bar(1, 2, 3);
Instance Method Call
A method defined as the instance method can be called using the instance method call.
Object->MethodName(ARGS1, ARGS2, ...);
If the number of arguments does not correct, a compilation error will occur.
If the types of arguments have no type compatible, a compilation error will occur.
Examples of instance method call:
$object->bar(5, 3. 6);
Current Class
& before method name means the current class. You can call method using &
keyword instead of the current class name.
Examples of Current Class:
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;
}
}
Getting value by Dereference
Obtaining a value by Dereference is an operation to obtain the actual value from Reference. It was designed to realize the C joint operator "*".
$VARIABLE
The variable Type must be Reference Type, otherwise a compilation error will occur.
The value obtained by Dereference returns "Expressions".
B<Example of getting value by Dereference>
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 operation to set the actual value from Reference. It was designed to realize the C joint operator "*".
$VARIABLE = Expression
The variable Type must be Reference Type, otherwise a compilation error will occur.
The type of Expression must match the type of the variable when dereferenced, otherwise a compilation error will occur.
Setting a value with Dereference returns the set value. This is "Expressions".
B<Example of setting values with Dereference>
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 Current Class Names
Getting Current class names is an expression to get the current class name by __CLASS__ "Keyword".
__CLASS__
Examples of Getting Current class names:
class Foo::Bar {
static method baz : void () {
# Foo::Bar
my $class_name == __CLASS__;
}
}
Getting Current File Name
Getting Current File Name is an expression to get the current file name by __LINE__ "Keyword".
__FILE__
Current File Name means the relative path from the base path of the module file. For example, if the Module Loaded Path is "/mypath" and the Module 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 Current File Name.
Examples of Getting Current File Name:
# SPVM/Foo/Bar.spvm
class Foo::Bar {
static method baz : void () {
# SPVM/Foo/Bar.spvm
my $file_name == __FILE__;
}
}
class Foo::Bar2 {
static method baz : void () {
# SPVM/Foo/Bar.spvm
my $file_name == __FILE__;
}
}
Getting Current Line Number
Getting Current Line Number is an expression to get the current line number of the current file by __LINE__ "Keyword".
__LINE__
Examples of Getting Current Line Number:
class Foo::Bar {
static method baz : void () {
# 4
my $line = __LINE__;
}
}
Creating Callback
The creating callback is an expression to define the implementation of callback and create a callback.
method : TYPE_NAME (ARGS1 : TYPE1, ARGS2 : TYPE2, ...) {
}
The creating callback returns the object its type is an anon class.
The created callback can be assign to a callback type that has a same signature of the method defined by the creating callback.
Examples of Create Callback:
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.
Capture
In Create Callback, you can use the syntax called Capture to use the variables defined outside the method defined by Create Callback inside the method defined by Create Callback.
# Capture
[VariableName1 : Type1, VariableName2 : Type2] method MethodNames : int ($x1 : object, $x2 : object) {
};
Capture Example.
my $foo = 1;
my $bar = 5L;
my $comparator = [$foo : int, $bar : long] method : int ($x1 : object, $x2 : object) {
print "$foo\n";
print "$bar\n";
};
The variable name used in Capture must be the one with "$" added at the beginning of "Field Names".
The Capture is actually defined as a field of Class. Capture is a field definition and value setting syntax sugar.
If "Local Variable" with the same name as the Capture variable exists in the Scope, access the Local Variable.
If there is a "Class Variable" with the same name as the Capture variable, access the Capture variable.
If you write Create Callback and Capture without using syntax sugar, it will be as follows.
class ComapartorImpl {
has foo : int;
has bar : long;
method : int ($x1 : object, $x2 : object) {
print $self->{foo} . "\n";
print $self->{bar} . "\n";
}
}
my $foo = 1;
my $bar = 5L;
my $comparator = new ComparatorImpl;
$comparator->{foo} = $foo;
$comparator->{bar} = $bar;
Capture is a syntax for writing such a long description short.
Operators
Operators are "Unary Operators", "Binary Operators", "Increment Operator", "Decrement Operator", "Comparison Operator", "Logical Operators", and "Assignment Operator".
Unary Operators
Unary operators are operators have one operand.
UNARY_OPERATOR OPERAND
The operand is an expression.
Unary operators are "Unary Plus Operator", "Unary Minus Operator", "Bit NOT Operator", "Array Length Operator", "String Creation Operator", and "String Length Operator".
Binary Operators
Binary Operator is a operator that have two operands.
LEFT_OPERAND BINARY_OPERATOR RIGHT_OPERAND
Binary operators are "Addition Operator", "Subtraction Operator", "Multiplication Operator", "Division Operator", "Remainder Operator", "Bit AND Operator", "Bit OR Operator", "Shift Operators", and "String Concatenation Operator".
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.
Examples of sequential operators:
# 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);
Arithmetic Operators
Arithmetic Operators is an "Operators" that performs arithmetic.
Arithmetic Operatorss are "Addition Operator", "Subtraction Operator", "Multiplication Operator", "Division Operator", "Division Unsigned Int Operator", , "Division Unsigned Long Operator", "Remainder Operator", "Remainder Unsigned Int Operator", "Remainder Unsigned Long Operator", "Unary Plus Operator", "Unary Minus Operator", "Increment Operator", and "Decrement Operator".
Unary Plus Operator
The unary plus operator +
is an Unary Operator to return the value of the operand.
+OPERAND
The operand must be an expression that type is a numeric type, otherwise a compilation error will occur.
"Unary Numeric Widening Type Conversion" applys to the operand.
returns the value copied from the value of the operand.
the return type of the unary plus pperator is the type that "Unary Numeric Widening Type Conversion" is performed.
Examples of unary plus operators:
# A unary plus operator
my $num = +10;
Unary Minus Operator
The unary minus operator -
is an Unary Operator to return the negative value of the operand.
-OPERAND
The operand must be an expression that type is a numeric type, otherwise a compilation error will occur.
"Unary Numeric Widening Type Conversion" applys to the operand.
the unary minus operator performs the following operation of C language.
-x
Return type of an unary minus operator is the type that "Unary Numeric Widening Type Conversion" is performed.
Examples of unary minus operators:
# A unary minus operator
my $num = -10;
Addition Operator
The addition operator +
is a binary operator to calculate the result of the addition of two numbers.
LEFT_OPERAND + RIGHT_OPERAND
The left operand and the right operand must be a numeric type, otherwise a compilation error will occur.
"Binary Numeric Widening Type Conversion" is performed to the left operand and the right operand.
The addition operator performs the operation that exactly same as the following operation in C language.
x + y;
The return type of the addition operator is the type that "Binary Numeric Widening Type Conversion" is performed.
Subtraction Operator
The subtraction operator -
is a binary operator to calculate the result of the subtraction of two numbers.
LEFT_OPERAND - RIGHT_OPERAND
The left operand and the right operand must be a numeric type, otherwise a compilation error will occur.
"Binary Numeric Widening Type Conversion" is performed to the left operand and the right operand.
The subtraction operator performs the operation that exactly same as the following operation in C language.
x - y;
The return type of the subtraction operator is the type that "Binary Numeric Widening Type Conversion" is performed.
Multiplication Operator
The multiplication operator is a binary operator to calculate the result of multiplication of two numbers.
LEFT_OPERAND * RIGHT_OPERAND
The left operand and the right operand must be a numeric type, otherwise a compilation error will occur.
"Binary Numeric Widening Type Conversion" is performed to the left operand and the right operand.
The multiplication operator performs the operation that exactly same as the following operation in C language.
x * y;
The return type of the multiplication operator is the type after "Binary Numeric Widening Type Conversion" is performed.
Division Operator
The division operator /
is a binary operator to culcurate the division of two numbers.
LEFT_OPERAND / RIGHT_OPERAND
The left operand and the right operand must be "Numeric Types", otherwise a compilation error will occur.
"Binary Numeric Widening Type Conversion" is performed to the left operand and the right operand.
The division operator performs the operation that exactly same as the following operation in C language.
x / y;
The return type of the division operator is the type after "Binary Numeric Widening Type Conversion" is performed.
If the two operands are integral types and the value of the right operand is 0
, an exception is thrown.
Division Unsigned Int Operator
The division unsigned int operator divui
is a binary operator to culcurate the unsigned int division of two numbers.
LEFT_OPERAND divui RIGHT_OPERAND
The left operand and the right operand must be an int type, otherwise a compilation error will occur.
The division unsigned int operator performs the operation that exactly same as the following operation in C language.
(uint32_t)x / (uint32_t)y;
The return type of the division operator is the int type.
If the value of the right operand is 0
, an exception is thrown.
Division Unsigned Long Operator
The division unsigned long operator divul
is a binary operator to culcurate the unsigned long division of two numbers.
LEFT_OPERAND divul RIGHT_OPERAND
The left operand and the right operand must be an long type, otherwise a compilation error will occur.
The division unsigned long operator performs the operation that exactly same as the following operation in C language.
(uint64_t)x / (uint64_t)y;
The return type of the division operator is the long type.
If the value of the right operand is 0
, an exception is thrown.
Remainder Operator
The remainder operator %
is a binary operator to calculate a remainder of two numbers.
LEFT_OPERAND % RIGHT_OPERAND
The left operand and the right operand must be an integral type, otherwise a compilation error will occur.
"Binary Numeric Widening Type Conversion" is performed to the left operand and the right operand.
The remainder operator performs the operation that exactly same as the following operation in C language.
x % y;
the return type of Remainder Operator is the type that "Binary Numeric Widening Type Conversion" is performed.
If the right operand is 0
, the remainder operator throw an exception.
Remainder Unsigned Int Operator
The remainder unsigned int operator remui
is a binary operator to calculate a unsigned int remainder of two numbers.
LEFT_OPERAND remui RIGHT_OPERAND
The left operand and the right operand must be a int type, otherwise a compilation error will occur.
The remainder unsigned int operator performs the operation that exactly same as the following operation in C language.
(uint32_t)x % (uint32_t)y;
The return type of the remainder unsigned int operator is the int type.
If the value of the right operand is 0
, an exception is thrown .
Remainder Unsigned Long Operator
The remainder unsigned long operator remul
is a binary operator to calculate a unsigned long remainder of two numbers.
LEFT_OPERAND remul RIGHT_OPERAND
The left operand and the right operand must be a long type, otherwise a compilation error will occur.
The remainder unsigned long operator performs the operation that exactly same as the following operation in C language.
(ulong64_t)x % (ulong64_t)y;
The return type of the remainder unsigned long operator is the long type.
If the value of the right operand is 0
, an exception is thrown .
Increment Operators
Increment operators are the pre-increment operator and post-increment operator.
Pre-Increment Operator
The pre-increment operator adds 1
to the value of the operand and returns the value after the incrementation.
# Pre-increment operator
++OPERAND
The type of the operand must be a local variable, a class variable, a field access</a>, an array access, a dereference, otherwise a compilation error will occur.
The pre-increment operator performs the same operation as the following.
(OPERAND = (TYPE_OF_OPERAND)(OPERAND + 1))
For example, if the type of the operand is the byte type, the following operation is performed.
($num = (byte)($num + 1))
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 the value of the operand and returns the value before the incrementation.
# Post-increment operator
OPERAND++
The type of the operand must be a local variable, a class variable, a field access</a>, an array access, a dereference, otherwise a compilation error will occur.
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 the operand is the byte type, the following operation is performed.
(my $tmp = $num, $num = (byte)($num + 1), $tmp)
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 Operators
Decrement operators are the pre-decrement operator and post-decrement operator.
Pre-Decrement Operator
The pre-decrement operator subtracts 1
to the value of the operand and returns the value after the decrementation.
# Pre-decrement operator
--OPERAND
The type of the operand must be a local variable, a class variable, a field access</a>, an array access, a dereference, otherwise a compilation error will occur.
The pre-decrement operator performs the same operation as the following.
(OPERAND = (TYPE_OF_OPERAND)(OPERAND - 1))
For example, if the type of the operand is the byte type, the following operation is performed.
($num = (byte)($num - 1))
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 the value of the operand and returns the value before the decrementation.
# Post-decrement operator
OPERAND--
The type of the operand must be a local variable, a class variable, a field access</a>, an array access, a dereference, otherwise a compilation error will occur.
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 the operand is the byte type, the following operation is performed.
(my $tmp = $num, $num = (byte)($num - 1), $tmp)
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 Operators
Bit operators are operators to perform bit operations.
Bit operators are the bit AND operator, the bit OR operator, or the bit NOT operator.
Bit AND Operator
The bit AND operator &
is an operator to performe a bit AND operation.
LEFT_OPERAND & RIGHT_OPERAND
The left operand and the right operand must be an "Integral Types" in integral type, otherwise a compilation error will occur.
A binary numeric widening type conversion is performed.
The return value is the same as the follwoing operation of C language
.
x & y;
The return type is the type after the binary numeric widening type conversion is performed.
Examples:
# The bit AND operator
my $num1 = 0xff;
my $num2 = 0x12;
my $result = $num1 & $num2;
Bit OR Operator
The bit OR operator |
is an operator to performe a bit OR operation.
LEFT_OPERAND | RIGHT_OPERAND
The left operand and the right operand must be an "Integral Types" in integral type, otherwise a compilation error will occur.
A binary numeric widening type conversion is performed.
The return value is the same as the follwoing operation of C language
.
x | y;
The return type is the type after the binary numeric widening type conversion is performed.
Examples:
# The bit OR operator
my $num1 = 0xff;
my $num2 = 0x12;
my $result = $num1 | $num2;
Bit NOT Operator
The bit NOT operator ~
is an unary operator to perform the bit NOT operation.
~OPERAND
The type of the operand must is an integral type, otherwise a compilation error will occur.
The unary numeric widening type conversion is performed.
The return value is the same as the follwoing operation of C language
.
~x
The return type is the type that the unary numeric widening type conversion is performed.
Examples:
# The bit NOT operator
my $num = ~0xFF0A;
Shift Operators
Shift operators are operators that performs bit shift operations. These are "Left Shift Operator", "Arithmetic Right Shift Operator", and "Logical Right Shift Operator".
Left Shift Operator
The left shift operator <<
is a binary operator to perform the left bit shift.
LEFT_OPERAND << RIGHT_OPERAND
The left operand must be "Integral Types", otherwise a compilation error will occur.
"Unary Numeric Widening Type Conversion" is performed to the left operand.
The right operand must be "Integral Types" except for the long type, otherwise a compilation error will occur.
"Unary Numeric Widening Type Conversion" is performed to the right operand.
The return type is same as the type of the left operand.
The calculation result of the left shift operator is the same as the following calculation in C language.
x << y;
Arithmetic Right Shift Operator
The arithmetic right shift operator >>
is a binary operator to perform the arithmetic right bit shift.
LEFT_OPERAND >> RIGHT_OPERAND
The left operand must be "Integral Types", otherwise a compilation error will occur.
"Unary Numeric Widening Type Conversion" is performed to the left operand.
The right operand must be "Integral Types" except for the long type, otherwise a compilation error will occur.
"Unary Numeric Widening Type Conversion" is performed to the right operand.
The return type is same as the type of the left operand.
The operation result of the arithmetic right shift Operator is the operation that exactly same as the following operation in C language.
x >> y;
Logical Right Shift Operator
The logical right shift operator >>>
is a binary operator to perform the logical right bit shift.
LEFT_OPERAND >>> RIGHT_OPERAND
The left operand must be "Integral Types", otherwise a compilation error will occur.
"Unary Numeric Widening Type Conversion" is performed to the left operand.
The right operand must be "Integral Types" except for the long type, otherwise a compilation error will occur.
"Unary Numeric Widening Type Conversion" is performed to the right operand.
The return type is same as the type of the left operand.
The operation result of logical right shift Operator is the same as the following calculation in C language.
// In the case that the left operand is a int type
(uint32_t)x >> y;
// In the case that the left operand is a long type
(uint64_t)x >> y;
Comparison Operator
Comparison Operator is an operator that is placed between The left operand and the right operand to compare the size, and return True/False Value.
LEFT_OPERAND COMPARISON_OPERATOR RIGHT_OPERAND
Comparison Operators are "Numeric Comparison Operator", "String Comparison Operator", and "isa Operator".
Numeric Comparison Operator
Numeric Comparison Operator is a "Comparison Operator" that is placed between The left operand and the right operand to compare the size of number or check the equqlity of objects.
LEFT_OPERAND NUMERIC_COMPARISON_OPERATOR RIGHT_OPERAND
A list of Numeric Comparison Operators.
Operator | Allowing Type | Description |
---|---|---|
LEFT_OPERAND == RIGHT_OPERAND | The left operand and the right operand are Numeric Types, The left operand and the right operand are Object Type (including Undefined Value) | The left operand and the right operand are equal |
LEFT_OPERAND != RIGHT_OPERAND | The left operand and the right operand are Numeric Types, The left operand and the right operand are Object Type (including Undefined Value) | The left operand and the right operand are not equal |
LEFT_OPERAND > RIGHT_OPERAND | The left operand and the right operand are Numeric Types | The left operand is greater than the right operand |
LEFT_OPERAND >= RIGHT_OPERAND | The left operand and the right operand are Numeric Types | The left operand is greater than or equal to the right operand |
LEFT_OPERAND < RIGHT_OPERAND | The left operand and the right operand are Numeric Types | The left operand is less than the right operand |
LEFT_OPERAND <= RIGHT_OPERAND | The left operand and the right operand are Numeric Types | The left operand is less than or equal to the right operand |
LEFT_OPERAND <=> RIGHT_OPERAND | The left operand and the right operand are Numeric Types | If The left operand is greater than Right expression, return 1. If The left operand is lower than Right expression, return -1. If The left operand is equals to Right expression, return 0. |
The Types of The left operand and the right operand Comparable Types, otherwise a compilation error will occur.
In Numeric Types Comparison, "Binary Numeric Widening Type Conversion" is performed for The left operand and the right operand.
the Numeric Comparison Operation is performed that exactly same as the following operation in C language.
# Numeric Types Comparison, Object Type Comparison
(int32_t)(x == y);
(int32_t)(x != y);
# Numeric Types Comparison
(int32_t)(x > y);
(int32_t)(x >= y);
(int32_t)(x < y);
(int32_t)(x <= y);
(int32_t)(x > y ? 1 : x < y ? -1 : 0);
For Numeric Types Operation(==, !=, >, >=, <, <=), "int Type" Operation, "long Type" Operation, "float Type" Operation, "double Type" Operation is defined.
And Object Type Operation(==, !=) is defined.
The return type of the Numeric Comparison Operator is "int Type".
String Comparison Operator
String Comparison Operator is a "Comparison Operator" that compares the bytes in the tow string.
LEFT_OPERAND STRING_COMPARISON_OPERATOR RIGHT_OPERAND
The left operand and the right operand must be "String Type" or byte[] type.
A list of String Comparison Operators.
Operator | Description |
---|---|
LEFT_OPERAND eq RIGHT_OPERAND | The left operand and the right operand are equal |
LEFT_OPERAND ne RIGHT_OPERAND | The left operand and the right operand are not equal |
LEFT_OPERAND gt RIGHT_OPERAND | The left operand is greater than the right operand in dictionary Expression order. |
LEFT_OPERAND ge RIGHT_OPERAND | The left operand is greater than or equal to the right operand compared in dictionary Expression order |
LEFT_OPERAND lt RIGHT_OPERAND | The left operand is smaller than the right operand when compared in dictionary Expression order |
LEFT_OPERAND le RIGHT_OPERAND | The left operand is less than or equal to the right operand compared in dictionary Expression order |
LEFT_OPERAND cmp RIGHT_OPERAND | If The left operand is greater than Right expression, return 1. If The left operand is lower than Right expression, return -1. If The left operand is equals to Right expression, return 0. |
The return type of the String Comparison Operator is "int Type". If the condition is met, returns 1, otherwise 0.
isa Operator
isa Operator is a "Comparison Operator" to check whether The left operand satisfies Right Type.
LEFT_OPERAND isa RIGHT_TYPE
isa Operator has three behaviors, depending on Right Type.
1. If Right Type is "Numeric Types", "Multi-Numeric Types", "Any Object Type", "Reference Type", isa operator checks whether the type of The left operand is same as Right Type. This check is done at compile time and isa operator is replaced by "int Type" value. If their types is same, replaced by 1, otherwise by 0.
2. If the Right Type is "Class Type", isa operator checks whether the type of The left operand is same as Right Type at Run Time. If their types are same, "int Type" 1 is return, otherwise 0. The type of The left operand must be "Object Types", otherwise a compilation error will occur.
3. If the Right Type is "Callback Type", isa Operator checks whether the type of The left operand satisfy the Callback Type at Run Time. If The left operand satisfies the Callback Type, returns "int Type" 1, otherwise 0. The type of The left operand must be "Object Types", otherwise a compilation error will occur.
ref Operator
ref Operator is a Operator to get type name of the object.
ref OPERAND
ref Operator return type name if the object defined. Otherwise return undef.
If OPERAND is not a object type, a compile error occurs.
dump Operator
dump Operator is a Operator to dump object value.
dump OPERAND
dump Operator return the dump string.
If OPERAND is not a object type, a compile error occurs.
The contents of the dumped string may vary from SPVM version to version. Please use dump operator only for viewing the content of object data.
Logical Operators
Logical Operators are "Operators" that performs a logical operation. These are "Logical AND Operator", "Logical OR Operator", and "Logical NOT Operator".
Logical AND Operator
The logical AND operator &&
returns the result of a logical AND operation.
LEFT_OPERAND && RIGHT_OPERAND
The left operand and the right operand must be a logical operator or an expression.
The return type of logical AND operator is "int Type".
Thg logical AND operator performs "Bool Type Conversion" to the left operand. If the evaluated value is 0
, the logical AND operator returns 0
. If the value is 1
, the right operand is evaluated.
Next, Thg logical AND operator performs "Bool Type Conversion" to the right operand. If the evaluated value is 0
, the logical AND operator returns 0
, otherwise returns 1
.
Logical AND operators can be only used as conditions. Note that these can't be used as expressions.
Logical OR Operator
The logical OR operator ||
returns the result of a logical OR operation.
LEFT_OPERAND || RIGHT_OPERAND
The left operand and the right operand must be a logical operator or an expression.
The return type of logical OR operator is "int Type".
Thg logical OR operator performs "Bool Type Conversion" to the left operand. If the evaluated value is 1
, the logical OR operator returns 1
. If the value is 0
, the right operand is evaluated.
Next, Thg logical OR operator performs "Bool Type Conversion" to the right operand. If the evaluated value is 1
, the logical OR operator returns 1
, otherwise returns 0
.
Logical OR operators can be only used as conditions. Note that these can't be used as expressions.
Logical NOT Operator
The logical NOT operator !
returns the result of a logical NOT operation.
!OPERAND
The operand must be a logical operator or an expression.
The return type of logical NOT operator is "int Type".
Thg logical NOT operator performs "Bool Type Conversion" to the operand. If the evaluated value is 1
, the logical NOT operator returns 0
. If the evaluated value is 0
, returns 1
.
Logical NOT operators can be only used as conditions. Note that these can't be used as expressions.
String Concatenation Operator
String concatenation operator .
is a binary operator to concat two strings.
LEFT_OPERAND . RIGHT_OPERAND
The left operand and the right operand must be a string type, "byte[] Type", or numeric type, otherwise a compilation error will occur.
If the type of the operand is numeric type, a numeric to string type conversion is performed.
The return type is a string type.
A string concatenation operator returns the result to concat two operands.
If both the left operand and the right operand are a string literal, the two string literals are concatenated at compile time.
If the left operand or the right operand is undef, an exception occurs.
Examples of string concatenation operators:
my $str = "abc" . "def";
my $str = "def" . 34;
my $str = 123 . 456;
Assignment Operator
Assignment Operator is a "Binary Operators" for assignment, expressed in "=".
LEFT_OPERAND = RIGHTH_OPERAND
Assignment Operator has multiple meanings depending on the Right and Left sides. Please refer to each item.
In Assignment Operator, the The left operand is evaluated after the right operand is evaluated. This is with the exception of expression being executed from Left to Right as a rule.
Special Assignment Operator
Special Assignment Operator is a "Assignment Operator"the type assignability ,a compilation error will occur
List of Special Assignment Operators
List of Special Assignment Operators
Addition Assignment Operator | += |
Subtraction Assignment Operator | -= |
Multiplication Assignment Operator | *= |
Division Assignment Operator | /= |
Remainder Assignment Operator | %= |
Bit AND Assignment Operator | &= |
Bit OR Assignment Operator | |= |
Left Shift Assignment Operator | <<= |
Arithmetic Right Shift Assignment Operator | >>= |
Logical Right Shift Operator | >>>= |
Concatenation Operator | .= |
The Special Assignment Operator is deployed as follows:
# Before unexpanding
LEFT_OPERAND SPECIAL_ASSIGNMENT_OPERATOR RIGHT_OPERAND
# After unwinding
LEFT_OPERAND ASSIGNMENT_OPERATOR (LEFT_OPERAND TYPE CAST)(LEFT_OPERAND SPECIFIC_OPERATOR RIGHT_OPERAND)
For example, for add assignment Operator, it is expanded as follows:
# Before unexpanding x is L</"byte Type">
$x += 1;
# After unwinding
$x = (byte)($x + 1)
Examples of Special Assignment Operator:
Special Assignment Operator Example
$x += 1;
$x -= 1;
$x *= 1;
$x /= 1;
$x &= 1;
$x |= 1;
$x ^= 1;
$x %= 1;
$x <<= 1;
$x >>= 1;
$x >>>= 1;
$x .= "abc";
Reference Operator
The Reference Operator is an operator that retrieves the address of a variable for "Numeric Types" or "Multi-Numeric Types". Designed to achieve c address Operator "*".
\VARIABLE
If the variable is not numeric type or Multi-Numeric Types, a compilation error will occur
Reference Operator returns expression. The type returned is "Reference Type".
Examples of Reference Operator:
my $num : int;
my $num_ref : int* = \$num;
my $z : Complex_2d;
my $z_ref : Complex_2d* = \$z;
For a detailed description of Reference, see "Reference".
Array Length Operator
The array length operator is an Unary Operator to get the length of the array.
@OPERAND
The operand must be a Expression that type is an "Array Types", otherwise a compilation error will occur.
The array length operator returns a "int Type" value that is the length of the "Array".
Array Length Operator returns "Expressions"
Examples of array length operators:
# 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.
String Creation Operator
The string creation operator new_string_len
is an Unary Operator to create a string with the length.
new_string_len OPERAND
The operand must be an expression that type is a "Integral Type" except for a long type, otherwise a compilation error will occur.
The string creation operator returns the string that is created with the lenght.
The return type is a string type.
Examples of string creation operators:
# New a string with the length
my $message = new_string_len 5;
copy Operator
The copy
operator is an Unary Operator to copy the object.
copy OPERAND
The operand must be an expression that type is a object type, otherwise a compilation error will occur.
If the type of operand is none of a string type, a numeric type, a multi-numeric type, An exception is thorwn.
The copy
operator returns the copied object.
The return type is same as the type of operand.
Read-only flag of the string is dropped.
Examples of string creation operators:
# New a string with the length
my $message = copy "abc";
is_read_only Operator
The is_read_only
is an Unary Operator to check if the string is read-only.
is_read_only OPERAND
The operand must be a string type, otherwise a compilation error will occur.
If the string is read-only, the is_read_only
operator returns 1
, otherwise returns 0
.
The return type is an int type.
Examples of is_read_only operators:
# New a string with the length
my $message = "Hello";
my $is_read_only = is_read_only $message;
String Length Operator
The string length operator is an Unary Operator to get the length of the string.
length OPERAND
The operand must be an expression that type is a "String Type", otherwise a compilation error will occur.
The string length operator returns a "int Type" value that is the length of the "String".
Note that the returned length is byte size, not the count of the characters of the string that is encoded to a specific character set.
Examples of string length operators:
# Getting the string length. The result is 5
my $message = "Hello";
my $length = length $message;
# Getting the string length of UTF-8. The result is 9, not 3
my $message = "あいう";
my $length = length $message;
scalar Operator
The scalar
operator is an Operator that returns the value of the operand.
scalar OPERAND
The operand must be an "Array Length Operator", otherwise a compilation error will occur.
Examples of scalar operators:
# 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};
The type of the object must be the class type, otherwise a compilation error will occur.
If the field name is not found, a compilation error will occur.
The type of the field targetted by the isweak
operator is not an object type, a compilation error will occur.
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.
Examples:
# isweak
my $isweak = isweak $object->{point};
has_implement Operator
The has_implement
operator checks the existence of the method implementation.
has_implement OPERAND->METHOD_NAME
The operand must the object that has a class type or an interface type, otherwise a compilation error will occur.
The method name must be a method name, otherwise a compilation error will occur.
The return type is int type.
If the class of the object has the method implementation, returns 1
, otherwise returns 0
.
Type Cast
The type cast is the operator to perform an explicite type conversion.
# Type Cast
(TYPE)OPERAND
# Postfix Type Cast
OPERAND->(TYPE)
To | From | Type Conversion |
---|---|---|
byte, short, int, long, float, double | byte, short, int, long, float, double | Numeric type conversion |
Byte | byte | Boxing type conversion |
Short | short | Boxing type conversion |
Int | int | Boxing type conversion |
Long | long | Boxing type conversion |
Float | float | Boxing type conversion |
Double | double | Boxing type conversion |
object | byte, short, int, long, float, double | Boxing type conversion |
Numeric Types | Numeric Object Type | L is performed. Numeric Types represented by Numeric Types and Numeric Object Type must be the same. For example, if Numeric Types are int, Numeric Object Type must be Int Type. |
Numeric Types | Any Object Type | L is performed. |
String Type | Numeric Types | The number is converted to a string using the "%g" format of the C standard sprintf function. |
byte[] | string | String-to-byte[] Type Conversion |
string | byte[] | byte[]-to-String Type Conversion |
Examples:
# Explicte long to int type conversion
my $num = (int)123L;
# Explicte byte[] to string type conversion
my $num = (string)new byte[3];
# Explicte string to byte[]
my $num = (byte[])"Hello";
Statements
Statements are the parts of syntax that can be written directly under "Scope Blocks".
empty Statement
An empty statement is a statement that do nothing and ends with just ;
.
;
expression Statement
The expression statement is a statement that consisting of an expression and ;
.
Expression;
Examples of expression statements:
1;
$var;
1 + 2;
foo();
my $num = 1 + 2;
if Statement
The if
statement is a statement for conditional branching.
if (CONDITION) {
}
The condition "Bool Type Conversion" is executed and Block is executed if the value is non-zero.
If you want to write more than one condition, you can continue with "elsif Statement". The condition determination is performed from above, and each Expression is "Bool Type Conversion" is executed, and a corresponding Block is executed if the value is non-zero.
if (CONDITION) {
}
elsif(CONDITION) {
}
You can use else
statement to describe what happens if or if the elsif Statement does not meet the criteria. If the if statement and elsif statement condition determination are all false, the statement inside the elseBlock is executed. Elsif Statement does not have to be.
if (CONDITION) {
}
elsif (CONDITION) {
}
else {
}
Examples of if statements:
# An example of if Statement.
my $flag = 1;
if ($flag == 1) {
print "One \ n";
}
elsif ($flag == 2) {
print "Tow \ n";
}
else {
print "Other";
}
The if
Statement is internally surrounded by an invisible Simple Block.
{
if (CONDITION) {
}
}
elsif
is internally expanded into if
Statement and else
Statement.
#Before deployment
if (CONDITION1) {
}
elsif (CONDITION2) {
}
else {
}
#After deployment
if (CONDITION1) {
}
else {
if (CONDITION2) {
}
else {
}
}
When a variable is declared in the conditional part of if Statement, it must be surrounded by invisible "Simple Block". Be aware that elsif is internally expanded into if Statement and else Statement.
#Before deployment
my $num = 1;
if (my $num = 2) {
}
elsif (my $num = 3) {
}
else {
}
#After deployment
my $num = 1;
{
if (my $num = 2) {
}
else {
{
if (my $num = 3) {
}
else {
}
}
}
}
unless Statement
The unless
statement is a statement for conditional branches.
unless (CONDITION) {
}
This is the same as the following if Statement.
if (!CONDITION) {
}
switch Statement
The switch
statement is a statement for conditional branching with an integer of "int Type" as a condition. Faster than if Statement if the condition is an integer of "int Type" and there are many branches.
switch (CONDITION) {
case constant 1: (
break;
}
case constant 2: {
break;
}
case constant n: {
break;
}
default: {
}
}
As the condition Expression, "Expressions" can be specified. "Bool Type Conversion" is executed for the condition Expression.
The constants specified in "case Statement" are "byte Type" or "int Type" constants. must be. For a constant of "byte Type", type conversion to "int Type" at compile time. Will be done. The value of enumType and Constant Method of "int Type" are constants of "int Type". As it is expanded at the time of syntax analysis, it can be used.
The constants specified in the case statement must not overlap. If there are duplicates, a compilation error will occur
If the value specified in the condition Expression matches the value specified in the case statement, jump to the position of that case statement.
If there is no match and a default statement is specified, jump to the default statement position. If no default statement is specified, switch block will not be executed.
A switch statement requires at least one case statement, otherwise a compilation error will occur.
The default Statement is optional.
Only case statement and default statement can be described directly under switch block.
The case and default Blocks can be omitted.
switch (CONDITION) {
case constant 1:
case constant 2:
{
break;
}
default:
}
If you use break Statement, you can exit from the switch block.
switch (CONDITION) {
case constant 1: (
break;
}
case constant 2: {
break;
}
case constant n: {
break;
}
default: {
}
}
If a case Block exists, the last Statement must be a break Statement or a returnl Statement, otherwise a compilation error will occur.
Examples of switch statements:
# switch statements.
my $code = 2;
switch ($code) {
case 1: {
print "1 \ n";
break;
}
case 2: {
print "2 \ n";
break;
}
case 3: {
print "3 \ n";
break;
}
case 4:
case 5:
{
print "4 or 5 \ n"; {
break;
}
default: {
print "Other \ n";
}
}
case Statement
The case
statement is a statement that can be used in a switch block to specify conditions. For more information on case statements, see the "switch Statement" description.
default Statement
The default
statement is a statement that can be used in the switch block to specify the default condition. For more information on the default Statement, see the "switch Statement" description.
while Statement
The while
statement is a statement for repeating.
while (CONDITION) {
}
"Expressions" can be described in the condition Expression. "Bool Type Conversion" is executed for condition Expression, and if the value is not 0, Block is executed. Exit the otherwise Block.
Examples of While Statement:
An example of a while Statement.
my $i = 0;
while ($i <5) {
print "$i \ n";
$i++;
}
Inside the while block, you can leave the while block by using "last Statement".
while (1) {
last;
}
Inside a while block, you can use "next Statement" to move to the condition immediately before the next condition Expression.
my $i = 0;
while ($i <5) {
if ($i == 3) {
$i++;
next;
}
print "$i \ n";
$i++;
}
The while Statement is internally enclosed by an invisible "Simple Block".
{
while (CONDITION) {
$i++;
}
# After expansion
my $num = 5;
{
while (my $num = 3) {
$i++;
}
}
for Statement
The for
Statement is a statement for repeating.
for (INIT_STATEMENT; CONDITION; INCREMENT_STATEMENT) {
}
"Expressions" can be described in the initialization Expression. Generally, write Expression such as initialization of loop variable. Initialization Expression can be omitted.
Condition Expression, "Expressions" can be described. "Bool Type Conversion" is executed for condition Expression, and if the value is not 0, Block is executed. Exit the otherwise block.
"Expressions" can be described in INCREMENT_STATEMENT. Generally, Expression of Increment of loop variable is described. INCREMENT_STATEMENT can be omitted.
for Statement has the same meaning as the following while Statement. INCREMENT_STATEMENT is executed at the end of Block. Initialization Expression is enclosed in "Simple Block".
{
INIT_STATEMENT;
while (CONDITION) {
INCREMENT_STATEMENT;
}
}
Exampels fo for statements:
# for statements
for (my $i = 0; $i <5; $i++) {
print "$i \ n";
}
Inside the for Block, you can exit the for Block using "last Statement".
for (INIT_STATEMENT; CONDITION; INCREMENT_STATEMENT) {
}
Inside the for Block, you can use "next Statement" to move immediately before the next INCREMENT_STATEMENT to be executed.
for (my $i = 0; $i <5; $i++) {
if ($i == 3) {
next;
}
}
return Statement
The return
statement is a statement to get out of the method. The object assigned to the mortal variable is automatically released.
return;
If there is a Return Value, "Expressions" can be specified.
return EXPRESSION;
If the Return Value Type in "Method Definition" is "void Type", Expression Must not exist, otherwise a compilation error will occur.
"Method Definition", if the Return Value Type is other than "void Type", Expression Must match the type of, otherwise a compilation error will occur.
next Statement
The next
statement is a statement to move to the beginning of the next loop block.
next;
See also "while Statement", "for Statement".
last Statement
The last
statement" is a statement to move to the outside of the loop block.
last;
See also "while Statement", "for Statement".
break Statement
The break
statement is a statement to move to the outside of the switch block.
break;
See also "switch Statement".
warn Statement
The warn
statement is a statement to print a warning string to the standard error.
warn OPERNAD;
The operand must be "String Type".
If the end character of the string is \n
, warn
statement prints the string itself.
If not, the current file name and current line number are added to the end of the string.
If the value of the operand is an undef, print "Warning: something's wrong".
The buffer of the standard error is flushed after the printing.
die Statement
The die
statement is a statement to throw an exception.
die OPERAND;
The operand must be the string type. If not a compilation error will occur.
You can specify the error message to the operand.
# Throw an exception
die "Error";
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 code 255
.
The stack traces constain the class names, the method names, the file names and the line numbers.
Error
from TestCase::Minimal->sum2 at SPVM/TestCase/Minimal.spvm line 1640
from TestCase->main at SPVM/TestCase.spvm line 1198
The exception can be catched using an eval block.
Examples:
# Catch the exception
eval {
# Throw an exception
die "Error";
};
# Check the exception
if ($@) {
# ...
}
print Statement
The print
statement is a statement to print a string to the standard output.
print OPERAND;
The oeprand must be a string type.
If the value of the operand is an undef, print nothing.
make_read_only Statement
The make_read_only
statement is a statement to make the string read-only.
make_read_only OPERAND;
The oeprand must be a string type.
Read-only strings can't 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 Statement
The weaken
statement is a statement to create a weak reference.
weaken OBJECT->{FIELD_NAME};
The type of the object must be the class type, otherwise a compilation error will occur.
If the field name is not found, a compilation error will occur.
The type of the field targetted by the weaken
statement is not an object type, a compilation error will occur.
See "Weak Reference" to know the behavior of the weaken
statement.
Examples:
# weaken
weaken $object->{point};
unweaken Statement
The unweaken
statement is a statement to unweakens a weak reference.
unweaken OBJECT->{FIELD_NAME};
The type of the object must be the class type, otherwise a compilation error will occur.
If the field name is not found, a compilation error will occur.
The type of the field targetted by the unweaken
statement is not an object type, a compilation error will occur.
See "Weak Reference" to know the behavior of the unweaken
statement.
Examples:
# unweaken
unweaken $object->{point};
Types
The Summary of Types
SPVM is a static type language. All data has a static type.
"Local Variable Declaration", "Field Definition", "Class Variable Definition", and Arguments and Return Value of "Method Definition" must specify Type.
In "Local Variable Declaration", "Type Inference" can be used.
Type Initial Value
Local Variable Initial Value are described in "Class Variable Initial Value".
A list of Type Initial Value. All Bit columns in the data are set to 0.
Type Name | Initial Value |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0 |
float | 0 |
double | 0 |
Object Type | undef |
Multi-Numeric Types | All Field is 0 |
Numeric Types
Numeric Types are "Integral Types" and "Floating Point Types".
Numeric Types Order
"Numeric Types" has the type order. The order is "byte", "short", "int", "long", "float", "double" from the smallest.
Integral Types
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 |
See "Arithmetic Operators" for integer calculation.
Note that SPVM has only singed integral types, and doesn't have unsigned integral types.
byte Type
byte
type is a "Integral Types" that represents a signed 8-bit integer. This is the same type as int8_t
type of C language.
short Type
short
type is a "Integral Types" that represents a signed 16-bit integer. This is the same type as int16_t
type of C language.
int Type
int
type is is a "Integral Types" that represents signed 32-bit integer. This is same as int32_t
type of C language.
long Type
long
type is a "Integral Types" that represents a signed 64-bit integer. This is the same type as int64_t
type of C language.
Floating Point Types
Floating Point Types 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 |
See "Arithmetic Operators" for floating-point calculation.
float Type
float
type is a "Floating Point Types" that represents a single precision(32bit) floating point. This is the same type as float
type of C language.
double Type
double
type is a "Floating Point Types" that represents a double precision(64bit) floating point. This is the same type as double
type of C language.
Class Type
The class type is the type that can create the object using a new operator.
new ClassType;
Pointer Type
The pointer type is the type that has a class descriptor pointer_t
.
# Pointer Type
class Foo: pointer_t {
}
A pointer type is a class type.
Basic Object Types
Basic object types are the class type, the callback type, the array type, the string type, and the any object type.
Object Types
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 Types
A numeric object type is the object type that is corresponding to the numeric type.
The list of numeric object types:
Numeric Object Types | Corresponding Numeric Types |
---|---|
Byte | byte |
Short | short |
Int | int |
Long | long |
Float | float |
Double | double |
The document of numeric object types:
See also "Boxing Type Conversion" and "Unboxing Type Conversion".
Undefined Type
The undefined type is the type of undef value.
Callback Type
The callback type is a type that is defined using a class
keyword and a class descriptor callback_t
.
class Comparator: callback_t {
method : int ($x1 : object, $x2 : object);
}
See also "Callback".
Note that callback types are not class types although they are defined by class
keyword.
Interface Type
The interface type is a type that is defined using a class
keyword and a class descriptor interface_t
.
class Asset: interface_t {
method add_chunk : void ($chunk : string);
method contains : int ($substring : string);
method size : int ();
method is_file : int();
}
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 Types" 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 "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 Types
Array Types represents multiple continuous data areas. "Basic Type" can be an Array.
int[]
double[]
Point[]
object[]
string []
Array has dimensions and can express up to 255 dimensions.
# Two dimensions
int[] []
# Three-dimensional
int[] [] []
Array Types is "Object Types".
Use new Operator to create an Array. In the following example, "int Type" Array with 3 elements is created.
my $nums = new int [3];
You also use new Operator when creating a Multi-Dimensional Array.The following example creates an Array of int[] Type with 3 elements.
my $nums = new int[] [3];
Numeric Array Types
Numeric Array Types means "Numeric Types" with the element "Array Types" It is.
Numeric Array Types list
- byte[]
- short[]
- int[]
- long[]
- float[]
- double[]
Data represented by Numeric Array Types must have elements whose size is "Numeric Types", and must be consecutive by the number of Array Length.
All elements of Numeric Array Types are initialized by "Type 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 Types
Object array types are "Array Types" 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 Types
String array types are "Array Types" that the type of the element is the string type.
Examples:
# String array types
my $strings : string[];
Class Array Types
Class array types are "Array Types" that the type of the element is the class type.
Examples:
# Class array types
my $points : Point[];
Interface Array Types
Interface array types are "Array Types" that the type of the element is the interface type.
Examples:
# Interface array types
my $stringables : Stringable[];
Callback Array Types
Callback array types are "Array Types" that the type of the element is the callback type.
Examples:
# Callback array types
my $stringers : Stringer[];
Multi-Dimensional Array Type
The multi-dimensional array type is the array type that the type of the element is an array type.
Examples:
# Callback array types
my $stringers : Stringer[];
Multi-Numeric Array Types
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];
If a invalid type is assigned, a compilation error will occur.
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.
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 Types
Multi-Numeric Types are a type that can represent continuous numerical values.
Multi-Numeric Types can be defined by specifying "mulnum_t" Descriptor in "Class Definition".
class Point_3i : mulnum_t {
has x : int;
has y : int;
has z : int;
}
See "Values " for a detailed explanation of Multi-Numeric Types.
Reference Type
Reference Type is a Type that can store the address of a variable. Add "*" after "Numeric Types" or "Multi-Numeric Types" You can define it.
my $num : int;
my $num_ref : int* = \$num;
my $point : Point_3i;
my $point_ref : Point_3i* = \$point;
Only the address of the Local Variable acquired by "Reference Operator" can be assigned to the value of Reference Type.
If only Local Variable Declaration of Reference Type is performed, a compilation error will occur
Reference Type can be used as Type of "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 will occur
Reference Type can be used as Type of argument in "Method Definition".
Reference Type cannot be used as Return Value Type in "Method Definition".
Reference Type cannot be used as the type of Field in "Class Definition".
Reference Type cannot be used as the type of Class Variable in "Class Definition".
If the Reference Type is used at an Invalid location, a compilation error will occur
See "Reference" for a detailed explanation of Reference.
Reference Types
Reference Types are "Numeric Reference Type" and "Multi-Numeric Reference Type".
Numeric Reference Type
Numeric Reference Type means "Numeric Types" for "Reference Type". Says.
Multi-Numeric Reference Type
Multi-Numeric Reference Type means "Reference Type" for "Multi-Numeric Types" variables. > Means.
Type Inference
Omitting "Types" when "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;
Type Qualifiers
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 Assignability
Explains the type assignability at compile time.
The assignability is false, a compilation error will occur.
Type Assignability to Numeric
Explains the type assignability of to-Numeric.
Type Assignability from Numeric to Numeric
If the nemric type order of the left operand is greater than or equal to the nemric type order of the right operand, the assignability is true.
If the nemric type order of the left operand is greater than the nemric type order of the right operand, the unary numeric widening type conversion is performed.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | byte | byte | None |
True | short | short | None |
True | int | int | None |
True | long | long | None |
True | float | float | None |
True | double | double | None |
True | short | byte | Unary Numeric Widening Type Conversion |
True | int | byte | Unary Numeric Widening Type Conversion |
True | long | byte | Unary Numeric Widening Type Conversion |
True | float | byte | Unary Numeric Widening Type Conversion |
True | double | byte | Unary Numeric Widening Type Conversion |
True | int | short | Unary Numeric Widening Type Conversion |
True | long | short | Unary Numeric Widening Type Conversion |
True | float | short | Unary Numeric Widening Type Conversion |
True | double | short | Unary Numeric Widening Type Conversion |
True | long | int | Unary Numeric Widening Type Conversion |
True | float | int | Unary Numeric Widening Type Conversion |
True | double | int | Unary Numeric Widening Type Conversion |
True | float | long | Unary Numeric Widening Type Conversion |
True | double | long | Unary Numeric Widening Type Conversion |
True | double | float | Unary Numeric Widening Type 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 the left operand is lower than the nemric type order of the right operand, the assignment is conditional valid.
The condition is that the right operand is a interger literal and the value is between the max and minimal value of the type of the left operand.
If the condition is ture, the numeric narrowing type conversion is performed.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
Conditinal True | byte | short | Numeric Narrowing Type Conversion |
Conditinal True | byte | int | Numeric Narrowing Type Conversion |
Conditinal True | byte | long | Numeric Narrowing Type Conversion |
False | byte | float | None |
False | byte | double | None |
Conditinal True | short | int | Numeric Narrowing Type Conversion |
Conditinal True | short | long | Numeric Narrowing Type Conversion |
False | short | float | None |
False | short | double | None |
Conditinal True | int | long | Numeric Narrowing Type Conversion |
False | int | float | None |
False | int | double | None |
False | long | float | None |
False | long | double | None |
False | float | double | None |
Examples:
# int to byte
my $num : byte = 127;
Type Assignability from NumericObject to Numeric
If the type of the left operand is a numeric type corresponding to the numeric object type of the right operand and the type of the right operand is a numeric object type, the assignability is true.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | byte | Byte | Unboxing Type Conversion |
True | short | Short | Unboxing Type Conversion |
True | int | Int | Unboxing Type Conversion |
True | long | Long | Unboxing Type Conversion |
True | float | Float | Unboxing Type Conversion |
True | double | Double | Unboxing Type Conversion |
Examples:
my $int : int = Int->new(3);
my $double : double = Double->new(3.5);
Type Assignability from Any Object to Numeric
If the type of the left operand is a numeric type and the type of the right operand is a any object type object
, the assignability is true.
The unboxing type conversion corresponding to the numeric type is performed.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | NUMERIC_X | object | Unboxing Type Conversion |
Examples:
my $int : int = (object)Int->new(3);
my $double : double = (object)Double->new(3.5);
Type Assignability from Others to Numeric
If the type of the left operand is a numeric type and the type of the right operand is other than the types described above, the assignability is false.
Type Assignability to Multi-Numeric
If the type of the left operand is a multi-numeric type and the type of the right operand is the same type of the left operand, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | MULNUM_X | MULNUM_X | None |
False | MULNUM_X | OTHER | None |
Examples:
my $z1 : Complex_2d;
my $z2 : Complex_2d = $z1;
Type Assignability to Referenece
If the type of the left operand is a reference type and the type of the right operand is the same type of the left operand, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | REF_X | REF_X | None |
False | REF_X | OTHER | None |
Type Assignability to String
If the type of the left operand is the string type without the mutable type qualifier and the type of the right operand is the string type, the assignability is true.
If the type of the left operand is the string type with the mutable type qualifier and the type of the right operand is the string type with the mutable type qualifier, the assignability is true.
If the type of the left operand is the string type with the mutable type qualifier and the type of the right operand is the string type without the mutable type qualifier, the assignability is false.
If the type of the left operand is the string type and the type of the right operand is a numeric type or the undef type, the assignability is true.
If the type of the right operand is a numeric type, the Numeric-to-String type conversion is performed.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | string | string | None |
True | string | mutable string | None |
True | mutable string | mutable string | None |
False | mutable string | string | None |
True | string | string | None |
True | string | NUMERIC_X | Numeric-to-String type conversion |
True | string | undef | None |
False | string | OTHER | None |
Examples:
my $string : string = "abc";
my $num_string : string = 3;
my $string : string = undef;
Type Assignability to NumericObject
If the type of the left operand is a numeric object type and the type of the right operand is the same type of the left operand, a numeric type that is corresponding to the numeric object type, or the undef type, the assignability is true.
If not, the assignability is false.
If the type of the right operand is a numeric type, the boxing type conversion is performed.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | NUMERIC_OBJECT_X | NUMERIC_OBJECT_X | None |
True | NUMERIC_OBJECT_X | NUMERIC_X | Boxing type conversion |
True | NUMERIC_OBJECT | undef | None |
False | NUMERIC_OBJECT | OTHER | None |
Examples:
my $num_object : Int = Int->new(3);
my $num_object : Int = 3;
my $num_object : Int = undef;
Type Assignability to Class
If the type of the left operand is a class type and the type of the right operand is the same type, or the undef type, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | CLASS_X | CLASS_X | None |
True | CLASS | undef | None |
False | CLASS | OTHER | None |
Examples:
my $point : Point = Point->new;
my $point : Point = undef;
Type Assignability to Interface
If the type of the left operand is an interface type and the type of the right operand is the same type, or the undef type, the assignability is true.
If the type of the left operand is an interface type and the type of the right operand is a class type and the class has the same interface of the left operand, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | INTERFACE_X | INTERFACE_X | None |
Conditinal True | INTERFACE_X | CLASS_Y | None |
True | INTERFACE | undef | None |
False | INTERFACE | OTHER | None |
Examples:
# Point has Stringable interface
my $stringable : Stringable = Point->new_xy(1, 2);
my $stringable : Stringable = undef;
Type Assignability to Callback
If the type of the left operand is a callback type and the type of the right operand is the same type, or the undef type, the assignability is true.
If the type of the left operand is a callback type and the type of the right operand is a class type and the class has the same callback method defined in the callback type definition of the left operand, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | CALLBACK_X | CALLBACK_X | None |
Conditinal True | CALLBACK_X | CLASS_Y | None |
True | CALLBACK | undef | None |
False | CALLBACK | OTHER | None |
Examples:
# Create a callback and the callback is assigned to a callback type
my $comparator : Comparator = method : int ($x1 : object, $x2 : object) {
my $point1 = (Point)$x1;
my $point2 = (Point)$x2;
return $point1->x <=> $point2->x;
};
my $comparator : Comparator = undef;
Type Assignability to Any Object
If the type of the left operand is the any object type and the type of the right operand is an object type, a numeric type or the undef type, the assignability is true.
If not, the assignability is false.
If the type of the right operand is a numeric type, the boxing type conversion is performed.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | object | OBJECT_X | None |
True | object | NUMERIC_X | Boxing type conversion |
True | object | undef | None |
False | object | OTHER | None |
Examples:
my $object : object = Point->new;
my $num_object : object = 3;
my $object : object = undef;
Type Assignability to Undefined
If the type of the left operand is the undefined type, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
False | Undefined Type | OTHER | None |
Examples:
# The assignability is false
undef = Point->new;
Type Assignability to Numeric Array
If the type of the left operand is a numeric array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | byte[] | byte[] | None |
True | short[] | short[] | None |
True | int[] | int[] | None |
True | long[] | long[] | None |
True | float[] | float[] | None |
True | double[] | double[] | None |
True | NUMERIC[] | undef | None |
False | NUMERIC[] | OTHER | None |
Examples:
my $nums : int[] = new int[3];
my $nums : int[] = undef;
Type Assignability to Multi-Numeric Array
If the type of the left operand is a multi-numeric array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | MULNUM_X[] | MULNUM_X[] | None |
True | MULNUM_X[] | undef | None |
False | MULNUM_X[] | OTHER | None |
Examples:
my $nums : Complex_2d[] = new Complex_2d[3];
my $nums : Complex_2d[] = undef;
Type Assignability to String Array
If the type of the left operand is a string array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | string[] | string[] | None |
True | string[] | undef | None |
False | string[] | OTHER | None |
Examples:
my $strings : string[] = ["abc", "def"];
my $strings : string[] = undef;
Type Assignability to Class Array
If the type of the left operand is a class array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | CLASS_X[] | CLASS_X[] | None |
True | CLASS_X[] | undef | None |
False | CLASS_X[] | OTHER | None |
Examples:
my $points : Point[] = new Point[3];
my $points : Point[] = undef;
Type Assignability to Interface Array
If the type of the left operand is an interface array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.
If the type of the left operand is an interface array type and the type of the right operand is a class array type and its basic type can assign to the basic type of the left operand, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | INTERFACE_X[] | INTERFACE_X[] | None |
True | INTERFACE_X[] | undef | None |
Conditional True | INTERFACE_X[] | CLASS_Y[] | None |
False | INTERFACE_X[] | OTHER | None |
Examples:
my $stringables : Stringable[] = new Stringable[3];
my $stringables : Stringable[] = new Point[3];
my $stringables : Stringable[] = undef;
Type Assignability to Callback Array
If the type of the left operand is an Callback array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.
If the type of the left operand is an Callback array type and the type of the right operand is a class array type and its basic type can assign to the basic type of the left operand, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | Callback_X[] | Callback_X[] | None |
True | Callback_X[] | undef | None |
Conditional True | Callback_X[] | CLASS_Y[] | None |
False | Callback_X[] | OTHER | None |
Examples:
my $stringers : Stringer[] = new Stringer[3];
{
my $cb = method : string ($object : object) {
my $point = (Point)$object;
return $point->to_string;
};
my $stringers : Stringer[] = [$cb];
}
my $stringers : Stringer[] = undef;
Type Assignability to Any Object Array
If the type of the left operand is the any object array type object[]
and the type of the right operand is an object array type or the undef type, the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | object[] | OBJECT_X[] | None |
True | object[] | undef | None |
False | object[] | OTHER | None |
Examples:
my $any_object0 : object[];
my $any_object : object[] = $any_object0;
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;
Type Assignability to Multi-Dimensional Array
If the type of the left operand is a multi-dimensional array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.
If the basic type of the type of the left operand is an interface type and the basic type of the type of the right operand is a class type and the dimension of the type of the right operand is same as the dimension of the type left oerand and the basic type of the type of the right operand has the interface of the basic type of the type of the left operand , the assignability is true.
If the basic type of the type of the left operand is an callback type and the basic type of the type of the right operand is a class type and the dimension of the type of the right operand is same as the dimension of the type left oerand and the basic type of the type of the right operand has the callback of the basic type of the type of the left operand , the assignability is true.
If not, the assignability is false.
Assignable | To | From | Implicite Type Conversion |
---|---|---|---|
True | MULDIM_X | MULDIM_X | None |
True | object[] | undef | None |
Conditional True | INTERFACE_MULDIM_X[] | CLASS_MULDIM_Y[] | None |
Conditional True | CALLBACK_MULDIM_X[] | CLASS_MULDIM_Y[] | None |
False | object[] | OTHER | None |
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:
# Explicte long to int type conversion
my $num = (int)123L;
# Explicte byte[] to string type conversion
my $num = (string)new byte[3];
# Explicte string to byte[] type conversion
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 "Type Assignability" if you know when implicite type conversion is performed.
Examples:
# Implicite int to double type conversion
my $num : double = 5;
# Implicte double to Double type conversion
my $num_object : Double = 5.1;
# Implicte Double to double type conversion
my $num : double = Double->new(5.1);
# Implicte int to string type conversion
my $string : string = 4;
Numeric Type Conversion
Numeric Type Conversion is the conversion from "Numeric Types" to "Numeric Types".
Numeric Type Conversion performs exactly the same processing as Numeric Type Conversion in the corresponding C language. For example, Type Conversion from int to long in SPVM is the same as the type conversion from int32_t Type to int64_t Type in C language.
# SPVM conversion
my $src : int = 5;
my $dist = (long)$src;
# Correspondence in C language
int32_t src = 5;
int64_t dist = (int64_t)src;
SPVM has two Numeric Types Convertions.
There are some rules for automatic type conversion of Numeric Types.
- L
- L
Numeric types have an order.
See also L.Unary Numeric Widening Type Conversion
Unary Numeric Widening Type Conversion means that "Expressions" is "byte Type" or short Type. In this case, perform "Numeric Widening Type Conversion" to "int Type" I say that.
Unary Numeric Widening Type Conversion is performed in the following cases.
- Array Index
- Dimension when creating Array
- Unary Plus Operator operands
- Unary Minus Operator operands
- Left and the right operands of Shift Operator "<<" ">>" ">>>"
Binary Numeric Widening Type Conversion
Binary Numeric Widening Type Conversion is performed to the left operand and the right operand in Binary Operator that takes Numeric Types on the Left and Right sides. "Numeric Widening Type Conversion".
The following rules apply.
1. When one Expression is "double Type", the other Type is "double Type" Is converted to>.
2. If one Expression is "float Type", the other Type is "float Type" Is converted to>.
3. When one Expression is "long Type", the other Type is "long Type" Is converted to>.
4, otherwise, it will be converted to "int Type".
Binary Numeric Widening Type Conversion is performed in the following cases.
Numeric Narrowing Type Conversion
Numeric Narrowing Type Conversion is a conversion rule applied when converting from a large type to a small type in "Numeric Types".
Numeric Widening Type Conversion
Numeric Widening Type Conversion is a conversion rule applied when converting from a small type to a large type in "Numeric Types".
Numeric-to-String Type Conversion
The numeric-to-String type conversion is a type conversion from a numeric type to the string type.
# Numeric-to-String type 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[] Type Conversion
The String-to-byte[] type conversion is a "Type Conversion" from "String Type" to "byte[] Type".
# String-to-byte[] Type 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 Type Conversion
The byte[]-to-String type conversion is a "Type Conversion" from "byte[] type" to "String Type".
# byte[]-to-String type 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 Type Conversion
Boxing Type Conversion is the operation to convert the value of Numeric Types to Numeric Object Type.
Unboxing Type Conversion
Unboxing Type Conversion is an operation to convert the value of Numeric Object Type to the corresponding value of Numeric Types.
Bool Type Conversion
The bool type conversion is a type conversion that is performed in operands of conditional branches.
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
The type of the operand of the bool type conversion must be a numeric type or an object type or the undef type, otherwise a compilation error will occur.
The return type of the bool type conversion is the int type.
If the operand is the undef value, 0
is returned.
If the operand is true(the TRUE
method of Bool), 1
is returned.
If the operand is false(the FALSE
method of Bool), 0
is returned.
If the type of the operand is a numeric type, the unary numeric widening type conversion is performed.
And the following operation is performed.
!!OPERAND
If the type of the operand is an object type except for the Bool type, and if the object is not undef value, 1
is returned. If the object is undef value, 0
is returned.
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
}
if (undef) {
# not ok
}
Type Comment
The type comment syntax is supported. The type comment can be written after of
keyword.
TYPE of TYPE
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) { ... }
If the type specified as the type comment is not found, a compilation error will occur.
Type comments have no meanings at runtime.
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 "Setting Class Variable" to get Exception Variable Value.
See "Setting Exception Variable" to set Exception Variable Value.
Garbage Collection
The object is released from memory when the reference count reaches 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 released before 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 Reference Count Type. In the GC of Reference Count Type, the object is automatically released when the reference count becomes 0, but when the circular reference occurs, the reference count does not become 0 and the object is automatically released. 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 released 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 a Reference Count GC.
In such a case, it is possible to release correctly by setting one Field to Weak Reference using "weaken Statement".
{
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 a Reference Count of 2 and $bar has a 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 released even if the scope ends.
When a weaken statement is executed, $foo has a Reference Count of 2 and $bar has a Reference Count of 1.
When the Scope ends, the reference count of $bar is decremented by 1
and becomes 0, so it is released 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 released "weaken Statement", and it can be confirmed whether Field is Weak Reference the isweak operator.
SEE ALSO
Examples
You can see more examples in the following test codes.