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 occurs.

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 occurs.

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 occurs.

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 occurs.

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 occurs.

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.

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
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".

POD Examples:

=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 occurs.

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 occurs.

"_" 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", <a href = "#language-type-convertion-numeric-narrowing">Numeric Narrowing Type Conversion</a> 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", <a href = "#language-type-convertion-numeric-narrowing">Numeric Narrowing Type Conversion</a> is performed and the value converted to "short Type" value. If it exceeds the range, a compilation error will occur.

Integer Literal Example:

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

Hexadecimal Representation of Integer Literal Example:

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

Octal Representation of Integer Literal Example:

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".

Binary Representation of Integer Literal Example:

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 occurs.

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 occurs.

Floating Point Literal Example:

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".

Charater Literal Example:

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 the Bool module.

true

Examples of true:

# true
my $is_valid = true;

false

false is the alias for The FALSE method of the Bool module.

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$"

Syntax Parsing

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

The Definition of Syntax Parsing

Show the definition of syntax parsing that is written by yacc/bison. The definition of the precidence of operators is contained in this difinition.

%token <opval> CLASS HAS METHOD OUR ENUM MY USE AS REQUIRE 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
%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 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 is_read_only
%type <opval> type qualified_type basic_type array_type array_type_with_length ref_type  qualified_type_or_void
%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

init_block
  : INIT block

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

require
  : REQUIRE basic_type
  | REQUIRE basic_type AS basic_type';'

allow
  : ALLOW basic_type ';'

implement
  : IMPLEMENT basic_type ';'

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

has
  : HAS field_name ':' opt_descriptors qualified_type ';'

method
  : opt_descriptors METHOD method_name ':' qualified_type_or_void '(' opt_args opt_vaarg')' block
  | opt_descriptors METHOD method_name ':' qualified_type_or_void '(' opt_args opt_vaarg')' ';'
  | opt_descriptors METHOD ':' qualified_type_or_void '(' opt_args opt_vaarg')' block
  | opt_descriptors METHOD ':' qualified_type_or_void '(' opt_args opt_vaarg ')' ';'

anon_method
  : opt_descriptors METHOD ':' qualified_type_or_void '(' opt_args opt_vaarg')' block
  | '[' args ']' opt_descriptors METHOD ':' qualified_type_or_void '(' opt_args opt_vaarg')' block

opt_args
  : /* Empty */
  | args

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

arg
  : var ':' qualified_type

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
  | basic_type ARROW method_name '(' opt_expressions  ')'
  | basic_type 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
  | 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 ']'

qualified_type_or_void
  : qualified_type
  | VOID

field_name
  : NAME

method_name
  : NAME

The following is a correspondence table between tokens in yacc/bison and keywords and operators in SPVM.

ALLOWallow
ARROW->
ASas
ASSIGN=
BIT_AND&
BIT_NOT~
BIT_OR|
BIT_XOR^
BREAKbreak
BYTEbyte
CASEcase
CLASSclass
CLASS_VAR_NAMEA class variable name
CONSTANTLiteral
CONVERT(TypeName)
COPYcopy
CURRENT_CLASS&
CURRENT_CLASS_NAME__CLASS__
DEC--
DEFAULTdefault
DEREF$
DESCRIPTORThe name of a descriptor
DIEdie
DIVIDE/
DIVIDE_UNSIGNED_INTdivui
DIVIDE_UNSIGNED_LONGdivul
DOT3...
DOUBLEdouble
DUMPdump
ELSEelse
ELSIFelsif
END_OF_FILEThe end of the file
ENUMenum
EVALeval
EXCEPTION_VAR$@
FATCAMMA=>
FLOATfloat
FORfor
HAShas
HAS_IMPLEMENThas_implement
IFif
IMPLEMENTimplement
INC++
INITINIT
INTint
ISAisa
ISWEAKisweak
IS_READ_ONLYis_read_only
LASTlast
LENGTHlength
LOGICAL_AND&&
LOGICAL_NOT!
LOGICAL_OR||
LONGlong
MAKE_READ_ONLYmake_read_only
METHODmethod
MINUS-
MUTABLEmutable
MYmy
NAMEname
NEWnew
NEW_STRING_LENnew_string_len
NEXTnext
NUMEQ==
NUMERIC_CMP<=>
NUMGE>=
NUMGT>
NUMLE<=
NUMLT<
NUMNE!=
OBJECTobject
OURour
PLUS+
PRINTprint
REF\
REFCNTrefcnt
REFOPref
REMAINDER%
REMAINDER_UNSIGNED_INTremui
REMAINDER_UNSIGNED_LONGremul
REQUIRErequire
RETURNreturn
ROro
RWrw
SCALARscalar
SELFself
SHIFT<< >> >>>
SHORTshort
SPECIAL_ASSIGN+= -= *= /= &= |= ^= %= <<= >>= >>>= .=
SRING_CMPcmp
STREQeq
STRGEge
STRGTgt
STRINGstring
STRLEle
STRLTlt
STRNEne
SWITCHswitch
UNDEFundef
UNLESSunless
UNWEAKENunweaken
USEuse
VARvar
VOIDvoid
WARNwarn
WEAKENweaken
WHILEwhile
WOwo

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 occurs.

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 occurs.

# 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 occurs.

If more than one of "callback_t", "mulnum_t", "pointer_t" are specified, a compilation error occurs.

Destructor

If the class is "Class Type", the class can define the destructor.

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 occurs.

A destructor must be a instance method that don't have the arguments, otherwise a compilation error occurs.

method DESTROY : void () {

}

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";
  }
}

Callback

Callback is a class that is designed to receive a callback method.

A callback type is a "Class Type" with "Class Descriptors" "callback_t".

class Comparator: callback_t {
  method : int ($x1 : object, $x2 : object);
}

A callback type must have only one "Method Definition". The method must be "Instance Method".

Method names of the callback type must be anonymouse.

"Field Definition" and "Class Variable Definition" can't be defined.

A private class descriptor is specifed.

If the object has the same method declaration of the callback type, it can be assinged to the callback type.

# the definiton of a callback type
class Comparator: callback_t {
  method : int ($x1 : object, $x2 : object);
}

# The definition of a class
class SomeComparator {
  static method new: int () {
    return new SomeComparator;
  }

  method : int ($x1 : object, $x2 : object) {

  }
}

# The object can be assign to the callback type
my $comparator: Comparator = SomeComparator->new;

If the object is created by the syntax of "Create Callback" and the object has the same method declaration of the callback type, it can be assinged to the callback type.

# The definition of a callback type
class Comparator: callback_t {
  method : int ($x1 : object, $x2 : object);
}

# Create a callback and it is assigned to a callback type
my $comparator : Comparator = method : int ($x1 : object, $x2 : object) {
  
}

Interface

Interface is a type that is designed for class abstructions.

Interface Definision

A interface type is defined using 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 ();
}

The object that the class has the interface can be assign to the interface type.

class Asset::Memory {
  implement Asset;
}

class Asset::File {
  implement Asset;
}

my $asset : Asset = Asset::Memory->new;

my $asset : Asset = Asset::File->new;

implement Statement

The class have a interface specified by a implement statement is expected to implement the all methods of the interface class.

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 (){
    # ...
  }
}

implement statements can be defined in the class that is class types.

Not that implement statement doesn't force the implementation of all methods of the interface class.

The class does not necessarily have all the methods declared in the interface.

class Asset::File {
  implement Asset;

  method add_chunk : void ($chunk : string){
    # ...
  }
  method contains : int ($substring : string){
    # ...
  }
  
  # OK although size and is_file method is not defined
}

The existence of a the method implementation can be checked by the has_implement operator.

Allow Class Access

By default, private Methods, Fields, and Class Variables cannot be accessed from outside the Class.

Also, Private Class cannot "Create Object" from outside of Class.

If the class allow other class, the other class can access private Methods, Fields, and Class Variables, and can "Create Object" 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 Create Object of Foo.

Specifying the module of allow also loads the module by "use" at the same time.

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 Module

Use use keyword to load a Module.

use Foo;
use Foo::Bar;

Modules are loaded at compile-time.

If the Module does not exist, a compilation error will occur.

use Keyword must be defined directly under "Class Definition".

class Foo {
  use Foo;
}

Class Alias

Define class aliases using as syntax with use

use 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);

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 occurs and it is assumed that there is no if block

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

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

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

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 occurs.

If more than one Class Variable with the same name is defined, a compilation error occurs.

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 occurs.

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

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 type of return value 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.

Class Variable Definition Example:

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 "Get Class Variable" for how to get the value of Class Variable.

See "Set 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 occurs.

If more than one field names Variable with the same name is defined, a compilation error occurs.

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 occurs.

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

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 type of return value 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.

Field Definition Example:

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

Field Access is an operation to access Field to get or set a value.

EXPRESSION->{FIELD_NAME}

Field Access has three different meanings.

1. Class Based Object Field Access

Class Based Object Field Access is Field Access from object which is create by "new" keyword.

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

See "Get Field" to get field of Class Based Object.

See "Set Field" to set field of Class Based Object.

2. Multi Numeric Field Access

Multi Numeric Field Access is Field Access from the value of "Multi Numeric Types". The value of "Multi Numeric Types" is allocated Callstack of Method.

my $z : Complex_2d;
$z->{x} = 1;
$z->{y} = 3;

See "Get Multi Numeric Field Value" to get field of the value of "Multi Numeric Types".

See "Set Multi Numeric Field Value" to set field of the value of "Multi Numeric Types".

3. Dereference Multi Numeric Field

Dereference Multi Numeric Field is Field access from Reference of the value of "Multi Numeric Types".

my $z : Complex_2d;
my $z_ref = \$z;
$z_ref->{x} = 1;
$z_ref->{y} = 3;

See "Get Multi Numeric Field Value via Dereference" to get Multi Numeric Field via Dereference.

See "Set Multi Numeric Field Value via Dereference" to set Multi Numeric Field via Dereference.

Method

Method Definition

"sub" Keyword defines Method.

static method METHOD_NAME : RETURN_VALUE_TYPE_NAME () {

}
static method METHOD_NAME : RETURN_VALUE_TYPE_NAME (ARGUMENT_NAME1 : ARGUMENT_TYPE_NAME1, ARGUMENT_NAME2 : ARGUMENT_TYPE_NAME2, ARGUMENT_NAMEN : ARGUMENT_TYPE_NAMEN) {

}

Method must be defined directly under "Class Definition".

Method name must be follow the rule of "Method Names".

Method names are allowed as same as "Keyword".

Type of Return Value must be "void Type", "Numeric Types", or "Object Types", otherwise a compilation error occurs.

Argument name must be follow the rule of "Local Variable Names".

Minimal Argument Count is 0. Max Argument Count is 255.

Type of Argument must be "Numeric Types", "Object Types", or "Reference Type", otherwise a compilation error occurs.

The defined Method can be called. See "Method Call" about calling Method, .

"Method Block" can have zero or more Statements.

Method Definition can have "Method Descriptor".

DESCRIPTOR1 DESCRIPTOR2 DESCRIPTORN static method METHOD_NAME : RETURN_VALUE_TYPE_NAME () {

}
DESCRIPTOR1 DESCRIPTOR2 DESCRIPTORN static method METHOD_NAME : RETURN_VALUE_TYPE_NAME (ARGUMENT_NAME1 : ARGUMENT_TYPE_NAME1, ARGUMENT_NAME2 : ARGUMENT_TYPE_NAME2, ARGUMENT_NAMEN : ARGUMENT_TYPE_NAMEN) {

}

If "..." follows Type of Argument, the Argument becomes Variable Length Argument. Only the last Argument can be Variable Length Argument.

The Type must be "Array Type".

static method METHOD_NAME : RETURN_VALUE_TYPE_NAME (ARGUMENT_NAME1 : ARGUMENT_TYPE_NAME1, ARGUMENT_NAME2 : ARGUMENT_TYPE_NAME2...) {

}

Variable Length Argument can recieve multi values.

# Variable Length Argument Definition
static method sprintf : string ($format : string, $values : object[]...) {

}

# Call Variable Length Argument Method with multi values.
sprintf("Value %d %f", 1, 2.0);

Variable Length Argument can recieve Array.

# Call Variable Length Argument Method with Array.
sprintf("Value  %d %f", [(object)1, 2.0]);

If you want to treat the value of Array as an individual element of the variable length argument, cast it to Type other than Array Type.

sprintf("aaa %p", (object)[(object)1, 2.0]);

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.

my $asset = Asset->new;
$asset->add_chumk("foo");

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.

my $total = Foo->sum(1, 2);

Method Descriptor

List of Method Descriptor.

Descriptor Description
native This Method is L<"Native Method">.

Native Method

Native Method is Method that call function written in Native Language(C, C++, etc).

See <a href="/native-api.html">SPVM Native AP/a Native Method.

Precompiled Method

If the Class has "precompile" descriptor, the methods of the class become Precompiled Method.

Precompiled Method is translated into C source code and converted into machine code.

The precompiled methods are C code, so you can get performance of C language.

Precompiled Method needs Build Directory described in <a href="/native-api.html">SPVM Native AP/a

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; }

Method

Method is Method that has "self Type" as its first argument.

method METHOD_NAME : TYPE  (ARGUMENT2 : TYPE2, ARGUMENT3 : TYPE3, ARGUMENTN : TYPEn) {

}

"self Type" must be first argument.

Method can be called from the object created by "new". See "Method Call" for Method Call.

$self is called Invocant.

Signature

Signature is a string that follow the following rule sequence of Method Retrun Value and arguments arranged according to the following rules. Arguments do not need to exist. There cannot be spaces between them.

1. RETURN_VALUE_TYPE

2. (

3. ARGUMENT_TYPE1,ARGUMENT_TYPE2,ARGUMENT_TYPE3

4. )

It the method is a instance method, the part of signature of the first argument is "self".

Signature Example:

# Method Definition
static method foo : int ($num1 : double, $num2 : long[])

# Signature
int(double,long[])

# Method Definition
static method foo : void ()

# Signature
void()


# Method Definition
method foo : int ($num1 : double, $num2 : long[])

# Signature
int(self,double,long[])

Signature is not used in SPVM programs. Signature is used when calling the SPVM Method from <a href="/native-api.html">SPVM Native AP/a.

Method Callstack

Method Callstack is memory area allocated in each method call.

Method Callstack save the folloing information.

1. Memroy area for "Local Variable"

2. The places of Mortal Local Variable

Enumeration

Enumeration Definition

Enumeration Definition is a syntax to define multiple "Constant Methods" easily.

# Enumeration Definition
enum {
  FLAG1,
  FLAG2,
  FLAG3
}

Enumeration must be defined directly under "Class Definition".

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

The first value starts with "0". The value is incremented by "1". In this example, "FLAG1" is "0", "FALG2" is "1", and "FLAG3" is "2".

"," can be added after the last element of Enumeration.

enum {
  FLAG1,
  FLAG2,
  FLAG3,
}

Enumeration is an alias for "Constant Method" that the return type is "int Type". It is equivalent to the following Method Definition:

static method FLAG1 : int () { return 0; }
static method FLAG2 : int () { return 1; }
static method FLAG3 : int () { return 2; }

The value of "int Type" can be set in the enum element.

enum {
  FLAG1,
  FLAG2 = 4,
  FLAG3,
}

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

If Enum Definition is invalid, a compilation error occurs.

Enumeration Descriptor

Descriptor can be specified for Enumeration.

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

List of Enumeration Descriptor

Descriptor Description
public This Enumeration is public. This Enumeration can be accessed from other Class. This is default setting.
private This Enumeration is private. This Enumeration can not be accessed from other Class.

If both "public" and "private" Descriptors are specified, a compilation error occurs.

Enumeration Call

Enumeration is an alias for "Constant Method", so it can be called in exactly the same way as Method call.

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

In special case, Enumeration Call can be used in "case Statement" of "switch 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 "Get Local Variable" to get Local Variable value.

"Set 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

# Get the length of the string
my $message = "Hello"+
my $length = legnth $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) {
  
}

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"]

Array

Array Summary

Array is a data structure for continuous multiple values.

There are the following types of Array.

  • Numeric Types Array
  • Object Type Array
  • Multi Numeric Types Array

Numeric Types Array is an array that element type is "Numeric Types".

Numeric Types Array is an array that element type is "Object Types".

Numeric Types Array is an array that element type is "Multi Numeric Types".

Create Array

See "Create 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 "Get Array Element" to get the element value of Array.

See "Set 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 Type" .

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 on "Method Callstack". 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 "Get Multi Numeric Field Value" to get Multi Numeric Types Field Value.

See "Set Multi Numeric Field Value" to set Multi Numeric Types Field Value.

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 Type".

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 "Get Array Element" to get Array Element Value.

See "Set 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 Mutil Numeric Types Reference to get the pointed value
my $point2 = $$point_ref;

# Dereference Mutil 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 Value can be done by Arrow Operator.

# If the target of Reference Type is Multi Numeric Types, get Multi Numeric Types Field Value
my $x = $point_ref->{x};

# If the Target of Reference Type is Multi Numeric Types, set Multi Numeric Types Field Value
$point_ref->{x} = 1;

Expressions

Expressions are a syntax part that can be evaluated as a value.

These are "Operators", "Undefined Value", "Literals", "Get Local Variable", "Set Local Variable", "Get Class Variable", "Get Class Variable", "Set Class Variable", "Get Exception Variable", "Set Exception Variable", "Get Field", "Set Field", "Get Array Element", "Set Array Element" and "Method Call".

Get Local Variable

Get Local Variable is a Expression to get "Local Variable" Value.

$var

Set Local Variable

Set Local Variable Expression is a Expression to set "Local Variable" Value using "Assignment Operator".

$var = RIGHT_OPERAND

The Assignment must satisfy "Type Compatibility".

Set Local Variable Expression returns the value after setting.

If the right operand is "Object Types", 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 that object is decremented by 1.

See "Scope" to know Garbage Collection of Local Variable.

Get Class Variable

Get Class Variable Expression is a Expression to get "Class Variable" Value.

$CLASS_NAME::CLASS_VARIABLE_NAME

"CLASS_NAME::" can be omitted when the Class Variable belongs to own "Class".

$CLASS_VARIABLE_NAME

If you try to get the value of a Class Variable that is not defined, a compilation error occurs.

If you try to access a private Class Variable from outside the Class, a compilation error occurs.

Get Class Variable Example:

class Foo {
  our $VAR : int;

  static method bar : int () {
    my $var1 = $Foo::VAR;
    my $var2 = $VAR;
  }
}

Set Class Variable

Set Class Variable Expression is a Expression to set "Class Variable" Value using "Assignment Operator". .

$CLASS_NAME::CLASS_VARIABLE_NAME = RIGHT_OPERAND

"CLASS_NAME::" can be omitted when the Class Variable belongs to own "Class".

$CLASS_VARIABLE_NAME = RIGHT_OPERAND

If the assignment does not satisfy "Type Compatibility", a compilation error occurs.

Set Class Variable Expression returns the value after setting.

If you try to get the value of a Class Variable that is not defined, a compilation error occurs.

If you try to access a private Class Variable from outside the Class, a compilation error 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 Class Variable before the assignment, the Reference Count of that object is decremented by 1.

Set Class Variable Example:

class Foo {
  our $VAR : int;

  static method bar : int () {
    $Foo::VAR = 1;
    $VAR = 3;
  }
}

Get Exception Variable

Set Class Variable Expression is a Expression to get the value of "Exception Variable".

$@

Set Class Variable Expression returns the value of "string Type".

Set Class Variable Example:

eval {
  foo();
};

if (my $message = $@) {

}

Set Exception Variable

Set Exception Variable Expression is a Expression to set the value of "Exception Variable" using "Assignment Operator".

$@ = RIGHT_OPERAND

the right operand must be "string Type".

Returns the value of Exception Variable after setting. This is "string Type".

The Reference Count of the right operand is incremented by 1.

If an object has already been assigned to Exception Variable before the assignment, the Reference Count of that object is decremented by 1.

Set Exception Variable Example:

$@ = "Error";

Get Field

Get Field Expression is a Expression to get "Field" Value.

INVOCANT_EXPRESSION->{FIELD_NAME}

Invocant Expression is "Class Type". If Expression is "Multi Numeric Types" Value, The Field Access is "Get Multi Numeric Field Value". If Expression is "Multi Numeric Reference Type" Value, The Field Access is, otherwise a compilation error occurs.

If the field names does not found in the <a href="#language-class">Class">, a compilation error occurs

Get Field Expression returns the value of the Field stored in the object.

Retrun Type is The "Types" of the Field.

Get Field Example:

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

Set Field

Set Field Expression is a Expression to set "Field" Value.

INVOCANT_EXPRESSION->{FIELD_NAME} = RIGHT_OPERAND

Invocant Expression is "Class Type". If Invocant Expression is "Multi Numeric Types", the Field Access is ,"Set Multi Numeric Field Value". If Invocant Expression is "Multi Numeric Reference Type", the Field Access is "Set Multi Numeric Field Value via Dereference", otherwise a compilation error occurs.

If the assignment does not satisfy "Type Compatibility" of the type of Field, a compilation error occurs.

If the field names does not found in the "Class", a compilation error occurs.

Set Field Expression returns the value of Field after setting.

Return Value Type is the type of Field.

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.

Set Field Example:

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

Get Multi Numeric Field Value

Get Multi Numeric Field Value Expression is a Expression to get Field Value of "Multi Numeric Value".

INVOCANT_EXPRESSION->{FIELD_NAME}

Invocant Expression is "Multi Numeric Types". If Invocant Expression is "Class Type", the Field Access is ". If Invocant Expression <a href="#language-type-ref-multi-numeric"is Multi Numeric Reference Type">, the Field Access is "Get Multi Numeric Field Value via Dereference", otherwise a compilation error occurs.

If the field names does not found in the "Class", a compilation error occurs

Get Multi Numeric Field Value Expression returns the field value in the Multi Numeric Value.

Retrun Type is The "Types" of the Field.

Get Multi Numeric Field Value Example:

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

Set Multi Numeric Field Value

Set Multi Numeric Field Value Expression is a Expression to set Field Value of "Multi Numeric Value" using "Assignment Operator".

INVOCANT_EXPRESSION->{FIELD_NAME} = RIGHT_OPERAND

<

Invocant Expression is "Multi Numeric Types". If Invocant Expression is "Class Type", the Field Access is "Set Field". Invocant Expression is "Multi Numeric Reference Type", "Set Multi Numeric Field Value via Dereference", otherwise a compilation error occurs.

If the field names does not found in the "Class", a compilation error occurs.

Set Multi Numeric Field Value Expression returns the value of Field after setting.

The Assignment must satisfy "Type Compatibility".

Return Value Type is the type of Field.

Set Multi Numeric Field Value Example:

my $z : Complex_2d;
$z->{x} = 2.5;

Get Multi Numeric Field Value via Dereference

Get Multi Numeric Field Value via Dereference Expression is a Expression to get Field Value of "Multi Numeric Value" via "Dereference".

INVOCANT_EXPRESSION->{FIELD_NAME}

Invocant Expression is "Multi Numeric Reference Type". If Invocant Expression is "Class Type", the Field Access is , "Get Field". If Invocant Expression is "Multi Numeric Types", the Field Access is "Get Multi Numeric Field Value", otherwise a compilation error occurs.

If the field names does not found in the "Class", a compilation error occurs

Get Multi Numeric Field Value via Dereference Expression returns the field value in the Multi Numeric Value.

Retrun Type is The "Types" of the Field.

Get Multi Numeric Field Value via Dereference Example:

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

Set Multi Numeric Field Value via Dereference

Set Multi Numeric Field Value Expression via Dereference is a Expression to set Field Value of "Multi Numeric Value" via "Dereference" using "Assignment Operator".

INVOCANT_EXPRESSION->{FIELD_NAME} = RIGHT_OPERAND

Invocant Expression is "Multi Numeric Reference Type". If Invocant Expression is "Class Type", "Set Field". If Invocant Expression is "Multi Numeric Types", "Set Multi Numeric Field Value", otherwise a compilation error occurs.

If the field names does not found in the "Class", a compilation error occurs

Set Multi Numeric Field Value via Dereference Expression returns the value of Field after setting.

The Assignment must satisfy "Type Compatibility".

Return Value Type is the type of Field.

Set Multi Numeric Field Value via Dereference Example:

my $z : Complex_2d;
my $z_ref = \$z;
$z_ref->{x} = 2.5;

Get Array Element

Get Array Element Expression is a Expression to get a Element Value of "Array".

ARRAY_EXPRESSION->[INDEX_EXPRESSION]

Array Expression must be "Array Type".

Index Expression must be "int Type" or the type that become "int Type" by "Unary Numeric Widening Type Conversion".

Get 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.

Get Array Element Example:

my $nums = new int[3];
my $num = $nums->[1];

my $points = new Point[3];
my $point = $points->[1];

my $objects : oarray = $points;
my $object = (Point)$objects->[1];

Set Array Element

Set Array Element Expression is a Expression to set a Element Value of a Array using "Assignment Operator".

ARRAY_EXPRESSION->[INDEX_EXPRESSION] = RIGHT_OPERAND

Array Expression must be "Array Type".

Index Expression must be "int Type" or the type that become "int Type" by "Unary Numeric Widening Type Conversion".

The Assignment must satisfy "Type Compatibility".

Set 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.

Set Array Element Example:

my $nums = new int[3];
$nums->[1] = 3;

my $points = new Point[3];
$points->[1] = Point->new(1, 2);

my $objects : oarray = $points;
$objects->[2] = Point->new(3, 5);

Create Object

Create Object Expression is a Expression to create Object using new operator.

my $object = new CLASS_NAME;

"Class" that is specified by "Class Names" must be "Class Type".

Fields of the Object are initialized by "Type Initial Value".

Created Object Reference count is 0 at first. If the Object is assigned to some Variable by "Assignment Operator", The Reference Count is incremented by 1. If implicite assignment is not done, Temporary Variable is created, the object is assigned to the Temporary Variable.

Create Object Example:

my $object = new Foo;

Create Object has the following information.

  • Reference Count
  • Back references of L<"Weaken Reference">
  • Basic Type ID
  • Type Dimension(Always 0)

Create Array

Create Array Expression is a Expression to create Array with new Keyword.

new Type[ELEMENTS_COUNT_EXPRESSION]

Type must be "Numeric Types", "Object Types", "Multi Numeric Types".

Elements Count Expression must be "int Type" or the type that become "int Type" by "Unary Numeric Widening Type Conversion".

If Index Expression is lower than 0, a Runtime Exception occurs.

Created Array Length is the value of Elements Count Expression.

All Array Element is initialized by "Type Initial Value".

All Element is gurantied to be continued on Memory.

Array is "Array Type". This is also "Object Types".

Create Array Example:

my $nums = new int[3];
my $objects = new Foo[3];
my $objects = new object[3];
my $values = new Complex_2d[3]

Created Array has the following information.

  • Reference Count
  • Basic Type ID
  • Type Dimension(the value is 1)
  • Array Length

Multi-Dimention Array is created by the following syntax.

# 2 Dimention Array (3 elements of int[] Type)
my $nums = new int[][3];

# 3 Dimention Array (3 elements of int[][] Type)
my $nums = new int[][][3];

The max of Dimention of Multi-Dimention Array is 255.

Array Initialization

SPVM has a syntax for Array Initialization to simplify Create 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 Type. If no element is specified, it will be an Array Type of "Any Object Type".

If Expression2 or later does not satisfy "Type Compatibility", 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 Call

Methods defined by "Method Definition" can be called from program. There are three types of method calls. Class Method Call and Instance Method Call.

Defined method can be called by Class Method Call except a case that the first argument is "self Type".

ClassName->MethodName(ARGS1, ARGS2, ARGS3, ..., ARGSn);

The arguments max count is 255.

If the number of arguments does not match the number of arguments defined in the method Definition, a compilation error occurs The Type of each argument and the type of the argument defined in Method Definition and <a href = "#language-type-compatible">Type Compatibility</a>, a compilation error occurs.

Class Method Call Example

my $ret = Foo->bar(1, 2, 3);

Current Class

& before method name means the current class. You can call method using "&" keyword instead of the current class name.

Current Class Example

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;
  }
  
}

Instance Method Call

Instance Method Call is a method to call Method which is "Method". In "Method Definition", the first argument is "self Type" If the argument of> is specified, it becomes Method.

Instance Method Call can be done with the following syntax using the object created by "Create Object".

OBJECT_EXPRESSION->METHOD_NAME(ARGS1, ARGS2, ARGS3, ..., ARGSn);

Instance Method Call takes arguments. If the number of arguments does not match the number of arguments defined in the method Definition, a compilation error occurs The Type of each argument and the type of the argument defined in Method Definition and <a href = "#language-type-compatible">Type Compatibility</a>, a compilation error occurs

Instance Method Call returns Return Value if Return Value is other than "void Type".

Instance Method Call is "Expressions".

Instance Method Call Example

my $point = new Point;
$point->set_x(3);

Since the object created by "Create Callback" is a normal object, you can call Method.

OBJECT_EXPRESSION->(ARGS1, ARGS2, ARGS3, ..., ARGSn);

Example that calls Method from the object created with Create Callback

An Example that calls a Method from the object created by Create Callback.

my $cb_obj = method : int ($num1 : int, $num2 : int) {
  return $num1 + $num2;
};

my $ret = $cb_obj->(1, 2);

Get 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 occurs.

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 occurs.

The Type of Expression must match the type of the variable when dereferenced, otherwise a compilation error occurs.

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;

Get Current Class Names

Get Current class names is a Expression to get the current class name by __CLASS__ "Keyword".

__CLASS__

Get Current class names Example:

class Foo::Bar {
  static method baz : void () {
    # Foo::Bar
    my $class_name == __CLASS__;
  }
}

Get Current File Name

Get Current File Name is a 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.

Get Current File Name Example:

# 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__;
  }
}

Get Current Line Number

Get Current Line Number is a Expression to get the current line number of the current file by __LINE__ "Keyword".

__LINE__

Get Current Line Number Example:

class Foo::Bar {
  static method baz : void () {
    # 4
    my $line = __LINE__;
  }
}

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 occurs.

"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 occurs.

"Unary Numeric Widening Type Conversion" applys to the operand.

the unary minus operator performs the following operation of C language.

-x

Return type of a 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 calcurate 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 occurs.

"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 calcurate 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 occurs.

"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 calcurate 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 occurs.

"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 occurs.

"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 occurs.

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 occurs.

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 calcurate 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 occurs.

"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 calcurate 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 occurs.

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 calcurate 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 occurs.

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 Operator

Increment Operator is an Operator that adds 1 to the value. the meaning of Increment Operator is different depending on whether the Increment Operator is placed Pre or Post.

# Pre Increment Operator
++LEXICAL_VARIABLE
++CLASS_VARIABLE
++FIELD_ACCESS
++ARRAY_ACCESS
++DEREFERENCE

# Post Increment Operator
LEXICAL_VARIABLE++
CLASS_VARIABLE++
FIELD_ACCESS++
ARRAY_ACCESS++
DEREFERENCE++

The operand of Increment Operator must "Local Variable", "Class Variable", <a href = "#language-field-access">Field Access</a>, "Array Access", "Dereference", otherwise a compilation error occurs.

The Type of operand of Increment Operator must be "Numeric Types", otherwise a compilation error will occur.

Pre Increment Operator

Pre Increment Operator adds 1 to the operand and returns the value after increment.

Pre Increment Operator is equivalent to the following Expression. After 1 is added to the operand, "Type Cast" is performed with the operand Type and the value is assinged to original operand.

(OPERAND_OPERAND = (TYPE)(OPERAND_OPERAND + 1))

For example, Pre Increment of "byte Type" value is equivalent to the following Expression:

($num = (byte)($num + 1))

Post Increment Operator

Post Increment Operator add 1 to the operand and returns the value before Increment.

Post Increment Operator is equivalent to the following Expression using "Sequential Operator". The value of operand is saved in a temporary variable, 1 is added to the operand, "Type Cast" is performed with the operand Type, and the value is assinged to original operand. Then the temporary variable is returned.

(my TMP_VARIABLE = OPERAND_OPERAND, OPERAND_OPERAND = (TYPE)(OPERAND_OPERAND + 1), TMP_VARIABLE)

For example, Post Increment of "byte Type" value is equivalent to the following Expression.

(my $tmp = $num, $num = (byte)($num + 1), $tmp)

Decrement Operator

Decrement Operator is an Operator that subtracts 1 to the value. the meaning of Decrement Operator is different depending on whether the Decrement Operator is placed Pre or Post.

# Pre Decrement Operator
--LEXICAL_VARIABLE
--CLASS_VARIABLE
--FIELD_ACCESS
--ARRAY_ACCESS
--DEREFERENCE

# Post Decrement Operator
LEXICAL_VARIABLE--
CLASS_VARIABLE--
FIELD_ACCESS--
ARRAY_ACCESS--
DEREFERENCE--

The operand of Decrement Operator must "Local Variable", "Class Variable", <a href = "#language-field-access">Field Access</a>, "Array Access", "Dereference", otherwise a compilation error occurs.

The Type of operand of Decrement Operator must be "Numeric Types", otherwise a compilation error will occur.

Pre Decrement Operator

Pre Decrement Operator subtracts 1 to the operand and returns the value after decrement.

Pre Decrement Operator is equivalent to the following Expression. After 1 is subtracted to the operand, "Type Cast" is performed with the operand Type and the value is assinged to original operand.

(OPERAND_OPERAND = (TYPE)(OPERAND_OPERAND - 1))

For example, Pre Decrement of "byte Type" value is equivalent to the following Expression:

($num = (byte)($num - 1))

Post Decrement Operator

Post Decrement Operator subtract 1 to the operand and returns the value before Decrement.

Post Decrement Operator is equivalent to the following Expression using "Sequential Operator". The value of operand is saved in a temporary variable, 1 is subtracted to the operand, "Type Cast" is performed with the operand Type, and the value is assinged to original operand. Then the temporary variable is returned.

(my TMP_VARIABLE = OPERAND_OPERAND, OPERAND_OPERAND = (TYPE)(OPERAND_OPERAND - 1), TMP_VARIABLE)

For example, Post Decrement of "byte Type" value is equivalent to the following Expression.

(my $tmp = $num, $num = (byte)($num - 1), $tmp)

Bit Operator

Bit Operator is an Operator that performs Bit operation. "Bit AND Operator", <a href = "#language-operator-bit-or">Bit OR Operator</a>, "Bit NOT Operator".

Bit AND Operator

Bit AND is "Binary Operators" represented by "&".

LEFT_OPERAND & RIGHT_OPERAND

The left operand and the right operand must be "Integral Types", otherwise a compilation error occurs.

"Binary Numeric Widening Type Conversion" is performed on The left operand and the right operand.

the operation result of Bit AND Operator performs the operation that exactly same as the following operation in C language

x & y;

The Type of Return Value of Bit AND Operator is the type after "Binary Numeric Widening Type" is performed.

Bit OR Operator

Bit OR is "Binary Operators" represented by "|".

LEFT_OPERAND | RIGHT_OPERAND

The left operand and the right operand must be "Integral Types", otherwise a compilation error occurs.

"Binary Numeric Widening Type Conversion" is performed on The left operand and the right operand.

the operation result of Bit OR Operator performs the operation that exactly same as the following operation in C language.

x | y;

The Type of Return Value of Bit OR Operator is the type that is "Binary Numeric Widening Type Converted".

Bit NOT Operator

The bit NOT operator ~ is a unary operator to get the value of bit-not operation.

~OPERAND

The operand must be an expression that type is an integral type, otherwise a compilation error occurs.

"Unary Numeric Widening Type Conversion" is performed to the operand.

The bit NOT operator performs the operation that exactly same as the following operation in C language.

~x

The type of return value is the type that "Unary Numeric Widening Type Conversion" is performed.

Examples of bit NOT operators:

# Bit NOT operations
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 occurs.

"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 occurs.

"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 occurs.

"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 occurs.

"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 occurs.

"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 occurs.

"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 Comparable 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 occurs.

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 Type of Return Value 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 Type of Return Value 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 occurs.

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 occurs.

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 occurs.

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

The type of return value 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""Type Compatibility"を満たさない場合は,a compilation error occurs

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)

Special Assignment Operator Example

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 occurs

Reference Operator returns expression. The type returned is "Reference Type".

  B<Reference Operator Example>

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 Type", otherwise a compilation error occurs.

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:

# Get the length of the array.
my $nums = new byte[10];
my $length = @$nums;

# Get 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 occurs.

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 occurs.

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 occurs.

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 occurs.

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:

# Get the string length. The result is 5
my $message = "Hello";
my $length = length $message;

# Get 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 occurs.

Examples of scalar operators:

# Get 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

isweak Operator is an Operator that checks whether Field is</a>"Weaken Reference."

isweak VARIABLE->{FIELD_NAME};

The Type of object Expression must be "Class Type". otherwise a compilation error occurs.

Field names must be a existed field names, otherwise a compilation error occurs.

The Type of the value stored in field must be <a href="#language-type-object">Object Type">, otherwise a compilation error occurs.

If the value stored in field at Run Time is</a> "Undefined Value, it returns false. This is <a href="#language-expression"Expression">

isweak Operator returns "Expressions"

Operator Precidence can be a top priority by using "()".

#  a * b is the first
a * b + c

# b + c is the first
a * (b + c)

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 a interface type, otherwise a compilation error occurs.

The method name must be a method name, otherwise a compilation error occurs.

The return type is int type.

If the class of the object has the method implementation, returns 1, otherwise returns 0.

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 (CONDITON) {

}
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 {
        
      }
    }
  }
}

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 occurs

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.

While Statement Example

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++;
}

# 展開後
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 occurs.

"Method Definition", if the Return Value Type is other than "void Type", Expression Must match the type of, otherwise a compilation error occurs.

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 a string type, otherwise a compilation error occurs.

The exception thrown by die statement can be cached by an eval block and can be checked by the exception variable $@.

Examples of die statements:

# Catch the exception
eval {
  # Throw a exception
  die "Error";
}

# Check the exception
if ($@) {
  # ...
}

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

A weaken Statement is a Statement that sets "Weaken Reference" for the Field.

weaken VARIABLE->{FIELD_NAME};

The Type of the object Expression must be "Class Type", otherwise a compilation error occurs.

Field names must be an existing field names, otherwise a compilation error occurs.

The Type of the value saved in Field must be "Object Types", otherwise a compilation error occurs.

If the value stored in the Field at execution time is "Undefined Value", the weak Statement does nothing.

If the value stored in the Field at runtime is not "Undefined Value", then the following is done:

1. Decrement the Reference Count of the object stored in Field by 1.

2. Set the Weaken Reference flag in Field.

3. Add Field to the back reference of the object saved in Field.

Note that the Weaken Reference flag is set on the Field itself, not on the object stored in the Field.

If the Reference Count of the object saved in Field becomes 0, the Weaken Reference is not created and the object saved in Field is released.

Back Reference is the data of the object saved in Field, and is added to know the Field with the Weaken Reference flag set. There may be more than one.

# There are multiple back references
my $foo = new Foo;
my $bar = new Bar;
my $baz = new Baz;

$foo->{bar} = $bar;
$foo->{baz} = $baz;

$bar->{foo} = $foo;
$baz->{foo} = $foo;

weaken $bar->{foo};
weaken $baz->{foo};

In the above example, "$bar->{foo}" and "$baz->{foo}" have the Weaken Reference flag set. The object represented by $foo has the back References "$bar->{foo}" and "$baz->{foo}".

The information of the back Reference is necessary because when the "Garbage Collection" is performed, it is necessary to assign the Undefined Value to the Field pointed to by the back Reference.

unweaken Statement

unweaken Statement is a Statement that cancels "Weaken Reference" for Field.

unweaken VARIABLE->{FIELD_NAME};

The Type of the object Expression must be "Class Type", otherwise a compilation error occurs.

Field names must be an existing Field names, otherwise a compilation error occurs.

The Type of the value saved in Field must be "Object Types", otherwise a compilation error occurs.

If the value stored in the Field at execution time is "Undefined Value", the unweaken Statement does nothing.

If the value stored in the Field at runtime is not "Undefined Value", then the following is done:

1. Increase the Reference Count of the object stored in the Field by 1.

2. Clear the Weaken Reference flag of Field.

3. Delete the Field from the back reference of the object stored in the Field.

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".

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. Class types are the class that doesn't have class descriptors mulnum_t, interface_t, and callback_t, and the class that has a pointer_t class descriptor.

# Class types
class Foo {

}

class Foo: pointer_t {

}

Pointer Type

The pointer type is the type that has a pointer_t class descriptor.

# Pointer Type
class Foo: pointer_t {

}

A pointer type is a class type

Object Types

Object types are "Class Type", "Callback Type", "Array Type", "string Type", "Any Object Type".

The value of a object type can be assigned to a any object type.

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

Numeric Object Type

Numeric Object Type are the following six.

Type Description
Byte Numeric Object Type with L<"byte Type"> data
Short Numeric Object Type with L<"short Type"> data
Int Numeric Object Type with L<"int Type"> data
Long Numeric Object Type with L<"long Type"> data
Float Numeric Object Type with L<"float Type"> data
Double Numeric Object Type with L<"double Type"> data

For the conversion between "Numeric Types" and Numeric Object Type, see "Type Conversions".

Undefined Type

The undefined type is the type of undef.

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];

self Type

self Type represents the Class Type to which it belongs, and indicates that the argument is Invocant.

self

It can only be used as the type of the first argument in "Method Definition".

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

A Type that does not have dimensions is called a Basic Type. "Numeric Types", "Class Type", <a href = "#language-type- any-object ">Any Object Type">, "string Type" is a Basic Type.

Array Type

Array Type 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 Type 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 multidimensional Array.The following example creates an Array of int[] Type with 3 elements.

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

Numeric Array Type

Numeric Array Type means "Numeric Types" with the element "Array Type" It is.

Numeric Array Type list

  • byte[]
  • short[]
  • int[]
  • long[]
  • float[]
  • double[]

Data represented by Numeric Array Type must have elements whose size is "Numeric Types", and must be consecutive by the number of Array Length.

All elements of Numeric Array Type are initialized by "Type Initial Value" when Create Array is performed.

byte[] Type

In SPVM, the "byte[] Type" is a special Type in that it is "string Type".

byte[]

"string Type" is treated as "string Type" at compile time, but at runtime It will be "byte[] Type".

Object Array Type

Object Array Type is "Array Type" that has the value of "Object Types" as an element. It is.

Object Array TypeのExample

  • Foo[]
  • Foo[][]
  • Comparable[]
  • object[]

The data represented by Object Array Type must have elements of size of "Object Types" and consecutive by the number of Array Length.

All elements of Object Array Type are initialized by "Type Initial Value" when Create Array is performed.

Multi Numeric Array Type

Multi Numeric Array Type means "Array Type that has the value of <a href="#language-type-multi-numeric"Multi Numeric Types"> as an element.</a>.

Multi Numeric Array Type Example

  • Complex_2d[]
  • Complex_2f[]

Data represented by Multi Numeric Array Type must have elements whose size is "Multi Numeric Types" and must be contiguous with the number of Array Length ..

All elements of Multi Numeric Array Type are initialized by "Type Initial Value" when Create Array is performed.

Any Object Array Type

Any Object Array Type is an arbitrary "Object Types" expressed as an oarray as an element. A Type that can be assigned the value of array ">Array Type</a>. Any Array Type can be cast to void * Type and passed to the first argument of the C language qsort function, but Any Object Array Type is not designed to realize the function corresponding to this. It was

my $array : oarray = new Point[3];
my $array : oarray = new object[3];

If a value with a Type other than Object Type is assigned, a compilation error occurs

Note that "oarrayType" is a different Type than "object[] Type". While oarrayType is a Type that can be methodstituted with an arbitrary Array Type value that has an Object Type value as an element, "object[] Type" is a Type that represents an "Array that has an objectType value as an element". Therefore, the value of arbitrary Array Type cannot be assigned.

Any Object Array Type is "Array Type". "Array Length Operator" to get length, "Set Array Element", "Get Array Element".

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

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

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

# Setting the value of the element of Any Object Array Type
$array->[0] = Int->new(5);

When setting the value of the element of Any Object Array Type, a check is made at runtime whether the type of the element is smaller than the type Dimension of Array by 1. If the check fails, "Exception" will occur. Any Object Array Type guarantees runtime Type safety.

string Type

string type is a "Types" that represents a "String".

string

string type can be qualified "mutable Type Qualifier".

mutable string

Examples:

# string type
my $message : string;
my $message : mutable string;

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 occurs

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 occurs

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 occurs

See "Reference" for a detailed explanation of Reference.

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 Conversions

Type Cast

Type Cast is Type Conversion that is explicitly described.

# Type Cast
(TYPE)EXPRESSION

"int Type" value is converted to "long Type" Become.

my $num = (long)3;

ype Cast returns "Expressions".

If the source Type and the specified Type are the same, the value is simply copied.

my $num : int = (int)4;

List of Type Conversion in Type Cast

It is a list of Type Conversion in Type Cast. If a Type Cast not listed in this table is performed, a compilation error occurs.

The specified Type Source type Content of conversion
byte[] string The address value is copied.
string byte[] The address value is copied.
Numeric Types Numeric Types L<"Numeric Types Conversion"> is performed.
Numeric Object Type Numeric Types L<"Boxing Type Conversion"> 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.
Any Object Type Numeric Types L<"Boxing Type Conversion"> is performed.
Numeric Types Numeric Object Type L<"Unboxing Type Conversion"> 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<"Unboxing Type Conversion"> is performed.
string Type Numeric Types The number is converted to a string using the "%g" format of the C standard sprintf function.

Implicit Type Conversion

Implicit type conversion is automatic type conversion performed by SPVM. The following are the places where implicit Type Conversion may occur.

  • When assigning to a different Type
  • When passing to Method Arguments of different Type
  • When returning a Type different from Return Value

Implicit Type Conversion occurs when:

Implicit Widening Type Conversion

If both the source and destination Type are Numeric Types and the destination Type is greater than the source Type, "Numeric Widening Type Conversion" is done.

# Implicit Widening Type Conversion
my $num : long = 123;
my $num : double = 12.5f;

Implicit Narrowing Type Conversion

Both the source and destination Type are Numeric Types, and the destination Type is smaller than the source Type, and the source value can be expressed in the range of Integer Literal and destination Type value. "Numeric Narrowing Type Conversion" is performed.

# Implicit Narrowing Type Conversion
my $num : byte = 123;
my $num : short = 134;

Implicit Numeric Type to Any Object Conversion

If the source Type is Numeric Types and the destination Type is Any Object Type, "Boxing Type Conversion" to the corresponding Numeric Object Type Is done. In the following case, the converted Int Type object is assigned to the generic object.

# Implicit Boxing Type Conversion to objectType
my $num = 123;
my $object : object = $num;

Implicit Numeric Type to Numeric Object Type Conversion

When the source Type is Numeric Types and the destination Type is the corresponding Numeric Object Type, "Boxing Type Conversion" to the corresponding Numeric Object Type a> is done.

# Implicit Boxing Type Conversion to object Type
my $num = 123;
my $object : Int = $num;

When the source Type is Any Object Type and the destination Type is Numeric Types, "Unboxing Type Conversion" in the corresponding Numeric Types are displayed. Will be opened. In the following case, an attempt is made to convert the Int Type object to "int Type".

Implicit Numeric Object Type to Numeric Type Conversion

# Implicit Unboxing Type Conversion from objectType-
my $object : object;
my $num : int = $object;

If the source Type is Numeric Object Type and the destination Type is the corresponding Numeric Types, "Unboxing Type Conversion" in the corresponding Numeric Types Is done.

# Implicit Unboxing Type Conversion from Numeric Object Type
my $num_obj = Int->new(3);
my $num : int = $num_obj;

Implicit Numeric Type to string Type Conversion

If the source Type is Numeric Types and the destination Type is "string Type", <a href = "#language-type-convertion-numeric-to-string ">Numeric-to-string Type Conversion</a> is performed. In the following case, the numerical value "123" is converted to String "" 123 "" and assigned.

# Implicit Boxing Type Conversion to string Type
my $num = 123;
my $str : string = $num;

Numeric Types Conversion

Numeric Types Conversion is the conversion from "Numeric Types" to "Numeric Types".

Numeric Types Conversion performs exactly the same processing as Numeric Types 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<"Unary Numeric Widening Type Conversion">
  • L<"Binary Numeric Widening Type Conversion">

Numeric types have an order.

  • L<"Numeric Types Order">

Numeric Types Order

"Numeric Types" has the order of Type. The order of Type is "byte", "short", "int", "long", "float", "double" from the smallest.

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 numerci to string type conversion is a type conversion from a numeric type to a 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

string to byte[] type conversion is a "Type Conversions" 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

byte[] to string type conversion is a "Type Conversions" 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

Bool Type Conversion is a conversion applied in the conditional part of if Statement, etc. for True/False Value judgment.

Where Bool Type Conversion takes place

Inside the if statement braces

if (CONDITION) {

}

In unless statement brackets

unless (CONDITION) {

}

The second in the parentheses for

for (INITIALIZEATION;CONDITION;NEXT_VALUE;) {

}

in parentheses while

while (CONDITION) {

}

Left and Right of Logical AND Operator

CONDITION && CONDITION

Left and Right of Logical OR Operator

CONDITION || CONDITION

Right side of Logical NOT Operator

!CONDITION

Expression specified by Bool Type Conversion is "Numeric Types" or "Object Types" or It must be "Undefined Type", otherwise a compilation error occurs.

Return Value of Bool Type Conversion is Expression of "int Type".

If Expression is "Undefined Value", 0 is returned.

If Expression is Bool->FALSE, 0 is returned. This is special case of the object of Bool class. false keywords means Bool->FALSE.

If Expression is Bool->TRUE, 1 is returned. This is special case of the object of Bool class. true keywords means Bool->TRUE.

When Expression is "Numeric Types", "Unary Numeric Widening Type Conversion" is done.

If Expression is "int Type", that value is returned.

Expression is "long Type", "float Type", <a href = "#language- If it is type-double ">double Type</a>, Object Type, the operation that exactly same as the following operation in C language is performed and the result is returned.

!!x

If Expression is Object Type, 0 is returned if it is Undefined Value, 1 otherwise.

Bool Type Conversion Examples

if (1) {
  # run
}

if (0) {
  # not run
}

if (1.5) {
  # run
}

if (0.0) {
  # not run
}

if (true) {
  # run
}

if (Bool->TRUE) {
  # run
}

if (false) {
  # not run
}

if (Bool->FALSE) {
  # not run
}

my $object = SPVM::Int->new(1);

if ($object) {
  # run
}

if (undef) {
  # not run
}

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';

Exception

Exception overview

SPVM has a mechanism of Exception. Exception consists of raising "Exception" and catching the exception.

Throw Exception

Use "die Statement" to throw "Exception".

die EXPRESSION;

When the die statement is executed, the stack trace and the String specified by Expression are displayed, and the program ends. The stack trace includes class names, Method names, File Name and line number. File Name is a relative File Name from the path where Module is loaded.

Error
from TestCase::Minimal->sum2 at SPVM/TestCase/Minimal.spvm line 1640
from TestCase->main at SPVM/TestCase.spvm line 1198

Exception Catching

Exception catching is a function that can stop the program from ending and get an error message when "Exception" is thrown.

Exceptions are caught using eval Block Statement. Please note that the eval Block Statement requires a semicolon at the end.

eval {
  # Processing that may throw L<"Exception">
};

When "Exception" is caught by the eval Block, the program termination is stopped and "is added to <a href="#language-exception-var"Exception Variable">. The message specified in Exception is thrown</a> is methodstituted.

Exception Variable

Exception Variable is a global variable that is represented by "$@"

$@

See "Set Class Variable" to get Exception Variable Value.

See "Set 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 Weaken Reference is set to the object saved in Field, Weaken Reference is released before Reference Count is decremented by 1.

When the object has Back references of Weaken Reference, Undefined Value is assigned to all Fields registered as back References and all back References are deleted.

The above process is done recursively.

Create Callback

Create Callback is a Syntax that creates an object that conforms to Callback Type by using a special syntax for the purpose of Callback.

method : TYPE_NAME  (ARGS1 : TYPE1, ARGS2 : TYPE2, ARGSN : TYPEn) {

}

When Create Callback is performed, "Class Definition" is performed internally, an object based on that Class is generated, and <a href = " Returned as # language-expression ">Expression</a>. It is possible to assign to a variable like the following.

my $cb_obj = method : TYPE (ARGS1 : TYPE1, ARGS2 : TYPE2, ..., ARGSn : TYPEn) {

};

Method defined by Create Callback must be "Method". It must also be a Method with no name.

Create Callback Example

my $comparator = method : int ($x1 : object, $x2 : object) {

}

You can call Method because the object created by Create Callback is a normal object. For the call to Create Callback, see "Method Call".

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.

Weaken Reference

Weaken Reference is a reference that does not increase the Reference Count. Weaken 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.

Weaken 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 Weaken 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 Weaken 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 Weaken Reference, Weaken Reference can be released "weaken Statement", and it can be confirmed whether Field is Weaken Reference <a href = "#language- There is an operator-isweak ">isweak Operator</a>.

Default Loaded Modules

SPVM loads the following modules just after the program start. These modules are deeply relataed to SPVM language, such as type conversions.