++ed by:
POTATOGIM FAYLAND ILUX SKOLYCHEV BRTASTIC
10 non-PAUSE users
Author image Yuki Kimoto

Name

SPVM::Document::LanguageSpecification - SPVM Language Specification

Description

SPVM::Document::LanguageSpecification defines SPVM language specification.

Tokenization

The tokenizing the source codes of SPVM language is explained.

Character Set

The source codes of SPVM language are expected to be written by the UTF-8 charcter set.

Line Terminators

The line terminators are LF, CR, and CRLF of ASCII.

When a line terminator appears, the current line number is incremented by 1. The line terminator is converted to LF of ASCII.

Space Character

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

Word Character

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

Symbol Name

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

A symbol name can't contains __, and can't begin with a number 0-9.

A symbol name can't begin with ::, and can't end with ::.

A symbol name can't contains ::::, and can't begin with a number 0-9.

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

Class Name

A class name is a symbol name.

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

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

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

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

If class names are invalid, a compilation error will occur.

Examples:

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

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

Method Name

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

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

If method names are invalid, a compilation error will occur.

Examples:

  # Valid method names
  FOO
  FOO_BAR3
  foo
  foo_bar
  _foo
  _foo_bar_

  # Invalid method names
  foo__bar
  3foo

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

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

Field Name

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

If field names are invalid, a compilation error will occur.

Examples:

  # Field names
  FOO
  FOO_BAR3
  foo
  foo_bar
  _foo
  _foo_bar_

  # Invalid field names
  foo__bar
  3foo
  Foo::Bar

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

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

Variable Name

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

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

Examples:

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

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

Class Variable Name

A class variable name is a variable name.

If class variable names are invalid, a compilation error will occur.

Examples:

  # Class variable names
  $NAME
  $MY_NAME
  ${NAME}
  $FOO::NAME
  $FOO::BAR::NAME
  ${FOO::NAME_BRACE}
  $FOO::name
  
  # Invalid class variable names
  $::NAME
  $NAME::
  $FOO::::NAME
  $MY__NAME
  $3FOO
  ${NAME

Local Variable Name

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

Examples:

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

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

Keyword

The list of keywords:

  alias
  allow
  as
  break
  byte
  case
  cmp
  class
  class_id
  copy
  default
  die
  divui
  divul
  double
  dump
  elsif
  else
  enum
  eq
  error
  error_code
  eval
  extends
  for
  float
  false
  gt
  ge
  has
  has_impl
  if
  isa
  isweak
  is_read_only
  interface
  int
  interface_t
  last
  length
  lt
  le
  long
  make_read_only
  my
  mulnum_t
  method
  mutable
  native
  ne
  next
  new
  new_string_len
  of
  our
  object
  print
  private
  public
  precompile
  pointer_t
  ref
  refcnt
  remui
  remul
  return
  require
  required
  rw
  ro
  set_error_code
  static
  switch
  string
  short
  scalar
  true
  undef
  unless
  unweaken
  use
  void
  warn
  while
  weaken
  wo
  INIT
  __END__
  __CLASS__
  __FILE__
  __LINE__

Operator for Tokenization

The list of the operators for tokenization:

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

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

Comment

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

  # Comment

Comments have no meaning in source codes.

POD

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

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

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

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

  =pod
  
  =head1
  
  =item * foo
  

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

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

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

  =cut
  

Examples:

  =pod
  
  Multi-Line
  Comment
  
  =cut
  
  =head1
  
  Multi-Line
  Comment
  
  =cut
  

POD has no meaning in source codes.

Literal

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

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

Numeric Literal

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

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

Integer Literal

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

Integer Literal Decimal Notation

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

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

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

The suffix L or l can be at the end.

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

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

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

Examples:

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

Integer Literal Hexadecimal Notation

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

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

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

The suffix L or l can be at the end.

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

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

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

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

  uint32_t value_uint32_t;
  int32_t value_int32_t = (int32_t)value_uint32_t;

And if - exists, the following conversion is performed.

  value_int32_t = -value_int32_t;

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

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

  uint64_t value_uint64_t;
  value_int64_t = (int64_t)value_uint64_t;

And if - exists, the following conversion is performed.

  value_int64_t = -value_int64_t;

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

Examples:

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

Integer Literal Octal Notation

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

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

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

The suffix L or l can be at the end.

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

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

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

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

  uint32_t value_uint32_t;
  int32_t value_int32_t = (int32_t)value_uint32_t;

And if - exists, the following conversion is performed.

  value_int32_t = -value_int32_t;

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

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

  uint64_t value_uint64_t;
  value_int64_t = (int64_t)value_uint64_t;

And if - exists, the following conversion is performed.

  value_int64_t = -value_int64_t;

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

Examples:

  0755
  -0644
  0666L
  0655_755

Integer Literal Binary Notation

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

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

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

The suffix L or l can be at the end.

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

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

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

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

  uint32_t value_uint32_t;
  int32_t value_int32_t = (int32_t)value_uint32_t;

And if - exists, the following conversion is performed.

  value_int32_t = -value_int32_t;

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

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

  uint64_t value_uint64_t;
  value_int64_t = (int64_t)value_uint64_t;

And if - exists, the following conversion is performed.

  value_int64_t = -value_int64_t;

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

Examples:

  0b0101
  -0b1010
  0b110000L
  0b10101010_10101010

Floating Point Literal

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

Floating Point Literal Decimal Notation

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

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

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

And can be followed by a floating point part.

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

And can be followed by an exponent part.

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

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

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

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

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

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

Examples:

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

Floating Point Literal Hexadecimal Notation

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

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

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

And can be followed by a floating point part.

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

And can be followed by an exponent part.

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

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

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

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

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

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

Examples:

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

Charater Literal

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

A character literal represents an ASCII character.

A character literal begins with '.

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

And ends with '.

The return type is the byte type.

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

Charater Literal Escape Characters

The list of character literal escape characters.

Character literal escape characters ASCII characters
\0 0x00 NUL
\a 0x07 BEL
\t 0x09 HT
\n 0x0a LF
\f 0x0c FF
\r 0x0d CR
\" 0x22 "
\' 0x27 '
\\ 0x5c \
Hexadecimal escape character An ASCII character

Examples:

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

String Literal

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

The return type is a string type.

A character literal begins with ".

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

And ends with ".

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

Examples:

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

String Literal Escape Characters

String literal escape characters Descriptions
\0 ASCII 0x00 NUL
\a ASCII 0x07 BEL
\t ASCII 0x09 HT
\n ASCII 0x0a LF
\f ASCII 0x0c FF
\r ASCII 0x0d CR
\" ASCII 0x22 "
\' ASCII 0x27 '
\\ ASCII 0x5c \
\$ ASCII 0x44 $
Hexadecimal escape character An ASCII character
Unicode escape character An UTF-8 character
Raw escape character The value of raw escape character

Unicode Escape Character

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

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

The Unicode escape character begins with N{U+.

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

And ends with }.

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

Examples:

  # あいう
  "\N{U+3042}\N{U+3044}\N{U+3046}"
  
  # くぎが
  "\N{U+304F}\N{U+304E}\N{U+304c}"

Raw Escape Character

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

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

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

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

The list of raw escape characters.

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

Hexadecimal Escape Character

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

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

The hexadecimal escape character begins with \x.

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

The hexadecimal numbers can be sorrounded by { and }.

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

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

Bool Literal

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

true

true is the alias for the TRUE method of Bool.

  true

Examples:

  # true
  my $is_valid = true;

false

false is the alias for FALSE method of Bool.

  false

Examples:

  # false
  my $is_valid = false;

Variable Expansion

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

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

The above codes are convarted to the following codes.

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

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

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

The end $ is not interpreted as a variable expansion.

  "AAA$"

Fat Comma

The fat comma => is a separator.

  =>

The fat comma is an alias for Comma ,.

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

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

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

  ["foo_bar2" => "Mark"]

Syntax Parsing

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

Syntax Parsing Definition

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

  %token <opval> CLASS HAS METHOD OUR ENUM MY USE AS REQUIRE ALIAS ALLOW CURRENT_CLASS MUTABLE
  %token <opval> DESCRIPTOR MAKE_READ_ONLY INTERFACE ERROR_CODE ERROR
  %token <opval> IF UNLESS ELSIF ELSE FOR WHILE LAST NEXT SWITCH CASE DEFAULT BREAK EVAL
  %token <opval> SYMBOL_NAME VAR_NAME CONSTANT EXCEPTION_VAR
  %token <opval> UNDEF VOID BYTE SHORT INT LONG FLOAT DOUBLE STRING OBJECT TRUE FALSE END_OF_FILE
  %token <opval> DOT3 FATCAMMA RW RO WO INIT NEW OF CLASS_ID EXTENDS SUPER
  %token <opval> RETURN WEAKEN DIE WARN PRINT CURRENT_CLASS_NAME UNWEAKEN '[' '{' '('
  %type <opval> grammar
  %type <opval> opt_classes classes class class_block
  %type <opval> opt_declarations declarations declaration
  %type <opval> enumeration enumeration_block opt_enumeration_values enumeration_values enumeration_value
  %type <opval> method anon_method opt_args args arg has use require alias our
  %type <opval> opt_descriptors descriptors
  %type <opval> opt_statements statements statement if_statement else_statement
  %type <opval> for_statement while_statement
  %type <opval> switch_statement case_statement case_statements opt_case_statements default_statement
  %type <opval> block eval_block init_block switch_block if_require_statement
  %type <opval> unary_operator binary_operator comparison_operator isa
  %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_impl
  %type <opval> new array_init die opt_extends
  %type <opval> var_decl var interface
  %type <opval> operator opt_operators operators opt_operator logical_operator
  %type <opval> field_name method_name class_name class_alias_name is_read_only
  %type <opval> type qualified_type basic_type array_type
  %type <opval> array_type_with_length ref_type  return_type type_comment opt_type_comment
  %right <opval> ASSIGN SPECIAL_ASSIGN
  %left <opval> LOGICAL_OR
  %left <opval> LOGICAL_AND
  %left <opval> BIT_OR BIT_XOR
  %left <opval> BIT_AND
  %nonassoc <opval> NUMEQ NUMNE STREQ STRNE
  %nonassoc <opval> NUMGT NUMGE NUMLT NUMLE STRGT STRGE STRLT STRLE ISA NUMERIC_CMP STRING_CMP
  %left <opval> SHIFT
  %left <opval> '+' '-' '.'
  %left <opval> '*' DIVIDE DIVIDE_UNSIGNED_INT DIVIDE_UNSIGNED_LONG REMAINDER  REMAINDER_UNSIGNED_INT REMAINDER_UNSIGNED_LONG
  %right <opval> LOGICAL_NOT BIT_NOT '@' CREATE_REF DEREF PLUS MINUS CONVERT SCALAR STRING_LENGTH ISWEAK REFCNT REFOP DUMP NEW_STRING_LEN IS_READ_ONLY COPY HAS_IMPL SET_ERROR_CODE
  %nonassoc <opval> INC DEC
  %left <opval> ARROW

  grammar
    : opt_classes

  opt_classes
    : /* Empty */
    | classes

  classes
    : classes class
    | class

  class
    : CLASS basic_type opt_extends class_block END_OF_FILE
    | CLASS basic_type opt_extends ':' opt_descriptors class_block END_OF_FILE
    | CLASS basic_type opt_extends ';' END_OF_FILE
    | CLASS basic_type opt_extends ':' opt_descriptors ';' END_OF_FILE

  opt_extends
    : /* Empty */
    | EXTENDS class_name

  class_block
    : '{' opt_declarations '}'

  opt_declarations
    : /* Empty */
    | declarations

  declarations
    : declarations declaration
    | declaration

  declaration
    : has
    | method
    | enumeration
    | our
    | use
    | allow
    | interface
    | init_block
    | alias

  init_block
    : INIT block

  use
    : USE class_name ';'
    | USE class_name AS class_alias_name ';'

  require
    : REQUIRE class_name

  alias
    : ALIAS class_name AS class_alias_name ';'

  allow
    : ALLOW class_name ';'

  interface
    : INTERFACE class_name ';'

  enumeration
    : opt_descriptors ENUM enumeration_block

  enumeration_block
    : '{' opt_enumeration_values '}'

  opt_enumeration_values
    : /* Empty */
    | enumeration_values

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

  enumeration_value
    : method_name
    | method_name ASSIGN CONSTANT

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

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

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

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

  opt_args
    : /* Empty */
    | args

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

  arg
    : var ':' qualified_type opt_type_comment

  opt_vaarg
    : /* Empty */
    | DOT3

  opt_descriptors
    : /* Empty */
    | descriptors

  descriptors
    : descriptors DESCRIPTOR
    | DESCRIPTOR

  opt_statements
    : /* Empty */
    | statements

  statements
    : statements statement
    | statement

  statement
    : if_statement
    | for_statement
    | while_statement
    | block
    | switch_statement
    | case_statement
    | default_statement
    | eval_block
    | if_require_statement
    | operator ';'
    | LAST ';'
    | NEXT ';'
    | BREAK ';'
    | RETURN ';'
    | RETURN operator ';'
    | die
    | WARN operator ';'
    | PRINT operator ';'
    | weaken_field ';'
    | unweaken_field ';'
    | ';'
    | MAKE_READ_ONLY operator ';'

  die
    : DIE operator ';'
    | DIE ';'

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

  while_statement
    : WHILE '(' operator ')' block

  switch_statement
    : SWITCH '(' operator ')' switch_block

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

  opt_case_statements
    : /* Empty */
    | case_statements

  case_statements
    : case_statements case_statement
    | case_statement

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

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

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

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

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

  block
    : '{' opt_statements '}'

  eval_block
    : EVAL block ';'

  opt_operators
    : /* Empty */
    | operators

  opt_operator
    : /* Empty */
    | operator

  operator
    : var
    | EXCEPTION_VAR
    | CONSTANT
    | UNDEF
    | call_spvm_method
    | field_access
    | array_access
    | convert
    | new
    | array_init
    | array_length
    | var_decl
    | unary_operator
    | binary_operator
    | assign
    | inc
    | dec
    | '(' operators ')'
    | CURRENT_CLASS_NAME
    | isweak_field
    | comparison_operator
    | isa
    | TRUE
    | FALSE
    | is_read_only
    | has_impl
    | logical_operator
    | CLASS_ID class_name
    | ERROR_CODE
    | SET_ERROR_CODE operator
    | ERROR

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

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

  is_read_only
    : IS_READ_ONLY operator

  inc
    : INC operator
    | operator INC

  dec
    : DEC operator
    | operator DEC

  binary_operator
    : operator '+' operator
    | operator '-' operator
    | operator '*' operator
    | operator DIVIDE operator
    | operator DIVIDE_UNSIGNED_INT operator
    | operator DIVIDE_UNSIGNED_LONG operator
    | operator REMAINDER operator
    | operator REMAINDER_UNSIGNED_INT operator
    | operator REMAINDER_UNSIGNED_LONG operator
    | operator BIT_XOR operator
    | operator BIT_AND operator
    | operator BIT_OR operator
    | operator SHIFT operator
    | operator '.' operator

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

  isa
    : operator ISA type

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

  assign
    : operator ASSIGN operator
    | operator SPECIAL_ASSIGN operator

  new
    : NEW basic_type
    | NEW array_type_with_length
    | anon_method

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

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

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

  call_spvm_method
    : CURRENT_CLASS SYMBOL_NAME '(' opt_operators  ')'
    | CURRENT_CLASS SYMBOL_NAME
    | class_name ARROW method_name '(' opt_operators  ')'
    | class_name ARROW method_name
    | operator ARROW method_name '(' opt_operators ')'
    | operator ARROW method_name
    | operator ARROW '(' opt_operators ')'

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

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

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

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

  has_impl
    : HAS_IMPL var ARROW method_name
    | HAS_IMPL var

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

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

  var
    : VAR_NAME

  qualified_type
    : type
    | MUTABLE type {

  type
    : basic_type
    | array_type
    | ref_type

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

  ref_type
    : basic_type '*'

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

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

  return_type
    : qualified_type opt_type_comment
    | VOID

  opt_type_comment
    : /* Empty */
    | type_comment

  type_comment
    : OF type

  field_name
    : SYMBOL_NAME

  method_name
    : SYMBOL_NAME

  class_name
    : SYMBOL_NAME

  class_alias_name
    : SYMBOL_NAME

Syntax Parsing Token

The list of syntax parsing tokens:

TokensKeywords or operators
ALIASalias
ALLOWallow
ARROW->
ASas
ASSIGN=
BIT_AND&
BIT_NOT~
BIT_OR|
BIT_XOR^
BREAKbreak
BYTEbyte
CASEcase
CLASSclass
CLASS_IDclass_id
VAR_NAMEA 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
ERRORerror
ERROR_CODEerror_code
EXTENDSextends
SET_ERROR_CODEset_error_code
EVALeval
EXCEPTION_VAR$@
FATCAMMA=>
FLOATfloat
FORfor
HAShas
HAS_IMPLhas_impl
IFif
INTERFACEinterface
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
SYMBOL_NAMEA symbol name
NEWnew
NEW_STRING_LENnew_string_len
OFof
NEXTnext
NUMEQ==
NUMERIC_CMP<=>
NUMGE>=
NUMGT>
NUMLE<=
NUMLT<
NUMNE!=
OBJECTobject
OURour
PLUS+
PRINTprint
REF\
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

Operator Precidence

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

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

  %right <opval> ASSIGN SPECIAL_ASSIGN
  %left <opval> LOGICAL_OR
  %left <opval> LOGICAL_AND
  %left <opval> BIT_OR BIT_XOR
  %left <opval> BIT_AND
  %nonassoc <opval> NUMEQ NUMNE STREQ STRNE
  %nonassoc <opval> NUMGT NUMGE NUMLT NUMLE STRGT STRGE STRLT STRLE ISA NUMERIC_CMP STRING_CMP
  %left <opval> SHIFT
  %left <opval> '+' '-' '.'
  %left <opval> '*' DIVIDE DIVIDE_UNSIGNED_INT DIVIDE_UNSIGNED_LONG REMAINDER  REMAINDER_UNSIGNED_INT REMAINDER_UNSIGNED_LONG
  %right <opval> LOGICAL_NOT BIT_NOT '@' CREATE_REF DEREF PLUS MINUS CONVERT SCALAR STRING_LENGTH ISWEAK REFCNT REFOP DUMP NEW_STRING_LEN IS_READ_ONLY COPY HAS_IMPL SET_ERROR_CODE
  %nonassoc <opval> INC DEC
  %left <opval> ARROW

See also syntax parsing token to know real operators.

The operator precidence can be increased using ().

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

Class

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

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

Class Definition

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

  # Class definition
  class CLASS_NAME {
  
  }

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

Examples:

  # Class definition
  class Point {
  
  }

Class descriptors can be written after :.

  class CLASS_NAME : CLASS_DESCRIPTOR {
  
  }
  
  class CLASS_NAME : CLASS_DESCRIPTOR1 CLASS_DESCRIPTOR2 CLASS_DESCRIPTOR3 {
  
  }

Examples:

  # Class descriptors
  class Point : public {
  
  }

  class Point : public pointer_t {
  
  }

In a class block, loading modules, class variables, fields, enumerations, methods, allow statements, interface guarantees and a INIT block can be defined.

  class Foo {
    
    # allow statements
    allow Bar;
    
    # INIT block
    INIT {
      # ...
    }
    
    # Loading modules
    use Point;
    
    # Interface guarantees
    interface Stringable;
    
    # Class variables
    our $VAR : int;
    
    # Fields
    has var : int;
    
    # Enumerations
    enum {
      CONST_VAL1,
      CONST_VAL2,
    }
    
    # Methods
    method foo : int ($num : int) {
      # ...
    }
  }

If more than one class is defined in a module file, a compilation error will occur.

Class Descriptor

The list of class descriptors.

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

If both public and private are specifed, a compilation error will occur.

If more than one of interface_t, mulnum_t, and pointer_t are specified, a compilation error will occur.

Destructor

A class can have the destructor.

  method DESTROY : void () {
  
  }

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

The name of the destructor must be DESTROY.

A destructor can't have its arguments.

The retrun type must be void type.

A destructor must be an instance method.

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

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

Examples:

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

Allowing Private Access

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

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

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

  allow CLASS_NAME;

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

The module that is the operand of the allow syntax is loaded by the same way as the use syntax.

Examples:

  # Allowing private access
  class Foo {
    allow Bar;
  }

Interface Guarantee

The interface syntax guarantees that the class has the required method defined in the interface.

  interface INTERFACE_NAME;

The interface syntax must be defined directory under the class definition.

If the required method of the interface is not defined in the current class, a compilation error will occur.

The current class is expected to have all methods defined in the interface.

Examples:

  # Interface guarantee
  class Foo {
    interface Stringable;
    interface Cloneable;
  }

Anon Class

The anon class is the class that is defined by the anon method syntax.

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

Examples:

    123456789...
  1:class Foo::Bar {
  2:  method sum : void () {
  3:    my $anon_method = method : string () {
  4:      
  5:    }
  6:: }
  7:}
  
  # The name of the anon class
  Foo::Bar::anon::3::23;

Inheritance

A class inherits a class using the extends keyword.

  class CLASS_NAME extends PARENT_CLASS_NAME {
    
  }

The parant class must be a class type. Otherwise a compilation error will occur.

The parant class must be a non-pointer type. Otherwise a compilation error will occur.

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

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

The field that name is the same as the field of the super class can't be defined. Otherwise a compilation error will occur.

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

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

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

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

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

Examples:

  class Point3D extends Point {
    
    has z : rw int;

    static method new : Point3D () {
      return new Point3D;
    }
    
    static method new_xyz : Point3D ($x : int, $y : int, $z : int) {
      my $self = Point3D->new;
      
      $self->set_x($x);
      $self->set_y($y);
      $self->set_z($z);
      
      return $self;
    }

    method clear : void () {
      $self->SUPER::clear;
      $self->{z} = 0;
    }
    
    method to_string : string () {
      my $x = $self->x;
      my $y = $self->y;
      my $z = $self->z;
      
      my $string = "($x,$y,$z)";
      
      return $string;
    }
    
    method cloneable_clone : object () {
      my $self_clone = Point3D->new_xyz($self->x, $self->y, $self->z);
      
      return $self_clone;
    }
  }

Interface

Explains interfaces.

Interface Definition

A interface is defined using a class definition with a "Class Descriptor" in class descriptor interface_t.

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

A interface can have multiple method declarations. The methods can't have the method blocks.

A interface must have only one required method. The required method is the method that has the method descriptor required.

The type of the interface is the "Interface Type".

The class that has interface Guarantees must have the required method that is declared in the interface. Otherwise a compilation error will occur.

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

A interface can't have filed definitions.

A interface can't have class variable definitions.

A interface can have interface Guarantees.

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

If the interface definition is invalid, a compilation error will occur.

new operator can't create the objects from interfaces.

Module

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

Loading Module

The use syntax loads a Module.

  # Load a module
  use Foo;

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

Modules are loaded at compile-time.

use syntax must be defined directly under the class definition.

  class Foo {
    use Foo;
  }

Class Alias

alias syntax create an alias name for a class name.

  # Create alias
  alias Foo::Bar as FB;

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

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

alias syntax must be defined directly under the class definition.

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

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

  use Foo::Bar as FB;

Automatically Loaded Module

The followings are Automatically Loaded Modules. They can be used without "Loading Module".

  • Byte
  • Short
  • Int
  • Long
  • Float
  • Double

Load Module Selective

In SPVM, there is an if require Statement that loads a Module only if it exists in the module path, and if it does not exist, the block does not exist.

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

  if (require Foo) {
  
  }

if require Statement can be followed by else Statement.

  if (require Foo) {
  
  }
  else {
  
  }

Note that elsif Statement cannot be followed.

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

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

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

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

Default Loaded Modules

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

Class Variable

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

Class Variable Definition

our keyword defines a class variable.

  our CLASS_VARIABLE_NAME : TYPE;

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

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

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

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

Class variable descriptors can be specified.

  our CLASS_VARIABLE_NAME : DESCRIPTOR TYPE;
  our CLASS_VARIABLE_NAME : DESCRIPTOR1 DESCRIPTOR2 DESCRIPTOR3 TYPE;

Examples:

  class Foo {
    our $NUM1 : byte;
    our $NUM2 : short;
    our $NUM3 : int;
    our $NUM4 : long;
    our $NUM5 : float;
    our $NUM6 : double;
  
    our $NUM_PUBLIC : public int;
    our $NUM_RO : ro int;
    our $NUM_WO : wo int;
    our $NUM_RW : rw int;
  }

Class Variable Descriptor

The list of class variable descriptors.

Descriptors Descriptions
public The class variable is public. The class variable can be accessed from other classes.
private The class variable is private. The class variable can't be accessed from other classes. This is default setting.
ro The class variable has its getting method.
wo The class variable has its setting method.
rw The class variable has its getting method and setting method.

If both public and private descriptors are specified, a compilation error will occur.

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

Class Variable Method

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

Class Variable Getting Method

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

It has no arguments and the return type is the same as the type of the class variable.

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

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

Inline expantion to the getting class variable is performed to each class variable getting method.

Examples:

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

Class Variable Setting Method

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

It has an argument that type is the same as the type of the class variable. The return type is the "void Type" in void type.

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

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

Inline expantion to the setting class variable is performed to each class variable setting method.

Examples:

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

Class Variable Initial Value

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

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

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

Class Variable Access

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

See the getting class varialbe and the setting class varialbe.

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 the class definition.

Field Definition must be specify "Type". The Type must be a numeric type or an object type.

Field names must follows the rule specified in "Field Name".

Field Type must be a numeric type or an object type, otherwise a compilation error will occur.

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

Field Descriptor can be specified together in Field Definition.

  has FIELD_NAME : DESCRIPTOR TYPE_NAME;
  has FIELD_NAME : DESCRIPTOR1 DESCRIPTOR2 DESCRIPTORN TYPE_NAME;

Field Descriptor

The list of field descriptors.

Descriptors Descriptions
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 its getting method. The getting method name is the same as the field name. For example, If the field names is foo, The getting method name is C.
wo This field has its setting method. The setting method name is the same as field names adding set_ to top. For example, If the field names is foo, The setting method name is set_foo.
rw This field has its getting method and its setting method.

If both public and private Descriptors are specified, a compilation error will occur.

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

A field getting method is an instance method. It has no arguments. The return type of a field getting method is the same as its field type.

A field setting method is an instance method. It has an argument. The type of the argument is the same as the field type. The return type is the "void Type" in void type.

Inline expansion to the field access is performed to field getting and setting methods. The performance penalty using field methods is nothing.

Examples:

  class Foo {
    has num1 : byte;
    has num2 : short;
    has num3 : int;
    has num4 : long;
    has num5 : float;
    has num6 : double;
  
    has num_public : public int;
    has num_ro : ro int;
    has num_wo : wo int;
    has num_rw : rw int;
  }

Field Access

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

  INVOCANT->{FIELD_NAME}

The field access has three different syntax.

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

If the field name does not found, a compilation error will occur

Field Access of the class

The field access of the class.

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

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

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

Field Access of the Multi-Numeric Type

The field access of the multi-numeric type.

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

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

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

Field Access of the Multi-Numeric Reference via Derefernce

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

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

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

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

Method

a.

Method Definition

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

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

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

Methods must be defined directly under the class definition.

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

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

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

The types of the arguments must be a numeric type, "Multi-Numeric Type", an object type, or "Reference Type", otherwise a compilation error will occur.

The type of the return value must be the "void Type" in void type, a numeric type, "Multi-Numeric Type" or an object type, otherwise a compilation error will occur.

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

A method can have method descriptors.

  DESCRIPTORS static method METHOD_NAME : RETURN_VALUE_TYPE (ARG_NAME1 : ARG_TYPE1, ARG_NAME2 : ARG_TYPE2, ...) {
  
  }

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

Variable Length Arguments

... after the type of the argument indicates the argument is a variable length argument. Only the last argument can become a variable length argument.

  static method METHOD_NAME : RETURN_VALUE_TYPE (ARG_NAME1 : ARG_TYPE1, ARG_NAME2 : ARG_TYPE2...) {
  
  }

The type of the variable length argument must be "Array Type".

A variable length argument can recieve multiple values.

  # Definition of variable length argument 
  static method sprintf : string ($format : string, $values : object[]...) {
  
  }
  
  # Pass multiple values to the a variable length argument
  sprintf("Value %d %f", 1, 2.0);

A variable length argument can recieve an array.

  # Pass array to a variable lenght argument
  sprintf("Value  %d %f", [(object)1, 2.0]);

If you want to treat the value as an individual element, cast it to type other than "Array Type"..

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

Class Method

A class method is defined with the static keyword.

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

A class method can be called from the class name.

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

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

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

Instance Method

An instance method is defined without the static keyword.

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

An instance method can be called from the object.

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

Method Descriptors

Method descriptors are descriptors used in a method definition.

Descriptors Descriptions
public This method is public. This method can be accessed from other classes. This is default setting.
private This method is private. This method can not be accessed from other classes.
precompile This method is a precompile method.
native This method is a native method.
required This method is required.
If C and C descriptors can't used together. C and C descriptors can't be used together. C can be only used in a method of a L. If the specifed descriptor is not found or the way to specify is invalid, a compilation error will occur. B # private method private method : int sum ($num1 : int, $num2 : int) { return $num1 + $num2; } # precompile method precompile method : int sum ($num1 : int, $num2 : int) { return $num1 + $num2; } # native method native method : int sum ($num1 : int, $num2 : int);

Native Method

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

A native method is defined by the native method descriptor.

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

A native method doesn't have its method block.

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

Precompiled Method

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

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

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

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

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

Constant Method

Constant Method is a Method that the return type is a numeric type and returns Constant Value.

  static method foo : int () { return 5; }
  static method foo : long () { return 5L; }
  static method foo : float () { return 5.0f; }
  static method foo : double () { return 5.0; }

Inline Expansion optimization is performed to Constant Method.

Note that SPVM does not perform constant convolution optimization, so if a constant is calculated, it will not performe Inline Expansion.

  # This is not Constant Method.  Inline Expansion is not performed
  static method foo : int () { return 5 + 3; }

Signature

A signature is a string that represents the return type and the types of the arguments of a method.

  RETURN_TYPE(ARG_TYPE1,ARG_TYPE2,ARG_TYPEn)

It the method is an instance method, the type representation of the first argument is self.

Examples:

  # Method Definition
  static method foo : int ($num1 : double, $num2 : long[])
  
  # The signature
  int(double,long[])
  
  # Method Definition
  static method foo : void ()
  
  # The signature
  void()
  
  # Method Definition
  method foo : int ($num1 : double, $num2 : long[])
  
  # Signature
  int(self,double,long[])

Signatures are used by native APIs.

Enumeration

The enumeration defines constant values.

Enumeration Definition

The enum keyword defines an enumeration. An enumeration defines constant values.

  # Enumeration Definition
  enum {
    FLAG1,
    FLAG2,
    FLAG3
  }

An enumeration must be defined directly under the class definition.

The first value of an enumeration begins with 0. The next value is incremented by 1, and this is continued in the same way. In this example, FLAG1 is 0, FALG2 is 1, and FLAG3 is 2.

The type of a value of an enumeration is the int type.

, after the last value can be allowed.

  enum {
    FLAG1,
    FLAG2,
    FLAG3,
  }

A value of an enumeration is implemented as a constant method.

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

The value can be set explicitly.

  enum {
    FLAG1,
    FLAG2 = 4,
    FLAG3,
  }

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

If an enumeration definition is invalid, a compilation error will occur.

Examples:

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

Enumeration Descriptors

Descriptors can be specified to an enumeration definition.

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

The list of enumeration descriptors:

Descriptors Descriptions
public This enumeration is public. Each value of this enumeration can be accessed from other classes. This is default setting.
private This enumeration is private. Each value of this enumeration can not be accessed from other classes.

If both public and private descriptors are specified, a compilation error will occur.

Enumeration Call

The value of enumeration called as a class method call.

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

In special cases, a value of an enumeration can be used as the operand of a case statement.

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

Local Variable

Local Variable Declaration

Local Variable is a variable that is declared in "Scope Block". Local Variable has "Scope". This is the 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 Name".

"Type" must be specified. Type must be a numeric type, an object type, "Multi-Numeric Type", 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 "Type" 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 the "Initial Value" in initial value.

Local Variable Access

Local Variable Access is an operation to access Local Variable to get or set the value.

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

"Setting Local Variable" to get Local Variable value.

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

Scope

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

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

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

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

See also garbage collection.

Block

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

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

Examples:

  # Blocks
  {
    1;
  }
  
  if (true) {
    
  }
  
  while (true) {
    
  }
  
  enum {
    ONE,
    TWO,
  }
  
  class Foo {
    
  }

Class Block

A class block is a block.

  # Class block
  class Point {
  
  }

Enumeration Block

A enumeration block is a block.

  # Enumeration block
  enum {
    ONE,
    TWO,
  }

Scope Block

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

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

Simple Block

A simple block is a scope block.

  # Simple block
  {
    1;
  }

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

Method Block

A method block is a scope block.

  # Method block
  static method foo : int () {
  
  }

eval Block

a eval block is a scope block.

  # eval block
  eval {
  
  };

if Block

A if block is a scope block.

  # if block
  if (CONDITION) {
  
  }

elsif Block

A elsif block is a scope block.

  # elsif block
  elsif (CONDITION) {
  
  }

else Block

A else block is a scope block.

  # else block
  else {
  
  }

for Block

A for block is a scope block.

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

while Block

A while block is a scope block.

  # while block
  while (CONDITION) {
  
  }

switch Block

A switch block is a scope block.

  # switch block
  switch (CONDITION) {
  
  }

INIT Block

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

  INIT {
  
  }

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

  class Foo {
    INIT {
  
    }
  }

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

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

The return statement cannot be written in INIT block.

Each class can have its INIT block.

The execution order of INIT blocks is not guaranteed.

Examples:

  class Foo {
    use Point;
    
    our $NUM : int;
    our $POINT : Point;
    
    # INIT block
    INIT {
      $NUM = 3;
      $POINT = Point->new;
    }
  }

String

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

  # Create a string using a string literal
  my $string = "Hello";
  
  # Create a string using a string creation operator
  my $string = new_string_len 3;
  
  # Create a string using a type conversion to the string type
  my $bytes = [(byte)93, 94, 95];
  my $string = (string)$bytes;

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

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

By default, each character can't be set.

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

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

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

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

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

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

Undefined Value

An undefined value is represented by undef.

  undef

An undefined value can be assigned to an object type.

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

  (void*)NULL

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

The type of undef is undefined type

Examples:

  # Undefine values
  my $string : string = undef;
  
  if (undef) {
    
  }
  
  my $message = "Hello";
  if ($message == undef) {
    
  }

Array

The array is the data structure for multiple values.

There are the following types of array.

  • Numeric Array
  • Object Array
  • Multi-Numeric Array

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

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

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

See "Creating Array" to create Array.

Array Access

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

  ARRAY->[INDEX]

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

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

Multi-Numeric Value

Multi-Numeric Type 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 Type are defined by specifying mulnum_t "Class Descriptor" in the class definition.

  # Three consecutive 32bit signed integers
  class Complex_2d : 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 Type must end with _, Number of the fields, "Multi-Numeric Type Suffix".

The suffix must correspond to a numeric type.

All Fields must be the same a numeric type.

The maximum number of the fields is 255.

Multi-Numeric Type can be used as "Type" of "Local Variable Declaration".

Multi-Numeric Type can be used as an argument "Type" in the method definition .

Multi-Numeric Type can be used as "Type" of Return Value in the method definition.

Multi-Numeric Type can be used as "Basic Type" of "Array Type" .

  my $points = new Complex_2d[5];

Reference can be created for Multi-Numeric Type value.

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

undef cannot be assigned to Multi-Numeric Type value.

See "Multi-Numeric Type Field Access" to get and set the value of field of Multi-Numeric Type Value.

Multi-Numeric Type Suffix

List of Multi-Numeric Type Suffix.

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

Multi-Numeric Type Usage

To use Multi-Numeric Type, load a Module using "use Statement".

  use Complex_2d;
  use Complex_2d;

Next is "Local Variable Declaration". Local Variable Declaration create continuous area for fields of Multi-Numeric Type Value. All fields of of Multi-Numeric Type Value are initialized by the "Initial Value" in initial value.

  my $z : Complex_2d;
  my $z : Complex_2d;

Note that Multi-Numeric Type value are not object, so cannot create a Object by "new" syntax.

Multi-Numeric Type Field Access

Multi-Numeric Type Field Access is an operation to access Multi-Numeric Type Field to get or set a value.

  MULTI_NUMERIC_TYPE_VALUE->{FIELD_NAME}

See "Getting Multi-Numeric Field" to get Multi-Numeric Type Field.

See "Setting Multi-Numeric Field" to set Multi-Numeric Type Field.

Multi-Numeric Array

"Multi-Numeric Value" can be an element of "Array".

  my $points = new Complex_2d[5];
  
  my $zs = new Complex_2d[5];

Multi-Numeric Array has continuous Multi-Numeric Values.

The Element Type is "Multi-Numeric Type", not an object type.

For example, Complex_2d[5] is continuous 15 (= 3 * 5) count the int type Value.

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

See "Setting Array Element" to get Array Element Value.

Reference

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

Creating Reference

The reference operator creates the reference of a local variable.

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

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

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

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

  # Method Definition
  static method sum : void ($result_ref : int*, $num1 : int, $num2 : int) {
    $$result_ref = $num1 + $num2;
  }
  
  # Method Call
  my $num1 = 1;
  my $num2 = 2;
  my $result_ref = \$result;
  sum($result_ref, $num1, $num2);

Dereference

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

A dereference operator perform a dereference.

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

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

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

Type

SPVM language has data types.

See Data type - Wikipedia about data types.

Initial Value

Local Variable Initial Value are described in "Class Variable Initial Value".

A list of 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 Type All Field is 0

Numeric Type

Numeric Type are "Integral Type" and "Floating Point Type".

Numeric Type Order

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

Integral Type

Integral types are the following four types.

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

See also arithmetic operators to calculate integer values.

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

byte Type

byte type is a "Integral Type" 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 Type" 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 Type" that represents signed 32-bit integer. This is the same as int32_t type of C language.

long Type

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

Floating Point Type

Floating Point Type are the following two.

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

See also arithmetic operators to calculate floating-point values.

float Type

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

double Type

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

Class Type

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

  new ClassType;

Pointer Type

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

  # Pointer Type
  class Foo: pointer_t {
  
  }

A pointer type is a class type.

Basic Object Type

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

Object Type

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

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

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

Numeric Object Type

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

The list of numeric object types:

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

The document of numeric object types:

See also "Boxing Type Conversion" and "Unboxing Type Conversion".

Undefined Type

The undefined type is the type of undef value.

Interface Type

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

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

See also "Interface".

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

Any Object Type

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

  my $object: object;

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

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

void Type

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

  void

Basic Type

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

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

Array Type

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 an object type.

Use new Operator to create an Array. In the following example, the int type Array with 3 elements is created.

my $nums = new int [3];

You also use new Operator when creating a Multi-Dimensional Array.The following example creates an Array of int[] Type with 3 elements.

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

Numeric Array Type

Numeric Array Type means a numeric type 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 a numeric type, and must be consecutive by the number of Array Length.

All elements of Numeric Array Type are initialized by the "Initial Value" in initial value when the creating array is performed.

byte[] Type

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

  byte[]

Object Array Type

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

Examples:

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

String Array Type

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

Examples:

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

Class Array Type

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

Examples:

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

Interface Array Type

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

Examples:

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

Multi-Dimensional Array Type

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

Examples:

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

Multi-Numeric Array Type

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

  • Complex_2d[]
  • Complex_2f[]

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

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

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

  my $complex_nums = new Complex_2d[10];

Any Object Array Type

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

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

If a invalid type is assigned, a compilation error will occur.

Any Object Array Type is an array type.

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

  my $array : object[] = new Int[3];
  
  # Getting the length of the element of Any Object Array Type
  my $length = @$array;

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

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

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

String Type

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

  string

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

  mutable string

Examples:

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

Multi-Numeric Type

Multi-Numeric Type are a type that can represent continuous numerical values.

Multi-Numeric Type can be defined by specifying mulnum_t Descriptor in the the class definition.

  class Complex_2d : mulnum_t {
    has x : int;
    has y : int;
    has z : int;
  }

See "Values ​​" for a detailed explanation of Multi-Numeric Type.

Reference Type

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

  my $num : int;
  my $num_ref : int* = \$num;
  
  my $z : Complex_2d;
  my $z_ref : Complex_2d* = \$z;

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

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

Reference Type can be used as Type of "Local Variable Declaration". The address of the Local Variable must be stored by the Reference Operator. In case of only Local Variable Declaration, a compilation error will occur

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

Reference Type cannot be used as Return Value Type in the method definition.

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

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

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

See "Reference" for a detailed explanation of Reference.

Reference Type

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

Numeric Reference Type

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

Multi-Numeric Reference Type

Multi-Numeric Reference Type means "Reference Type" for "Multi-Numeric Type" variables. > Means.

Type Qualifier

Type qualifiers qualify the type.

  QUALIFIER TYPE

mutable Type Qualifier

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

  my $string : mutable string;

Examples:

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

Type Inference

Omitting "Type" 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;

Assignability

The assignability at compile-time is explained.

The assignability is false, a compilation error will occur.

Assignability to Numeric

Explains the assignability to the numeric types.

Assignability from Numeric to Numeric

If the nemric type order of the left operand is greater than or equal to the nemric type order of the right operand, the assignability is true.

If the nemric type order of the left operand is greater than the nemric type order of the right operand, the numeric widening type conversion is performed.

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

Examples:

  # int to int
  my $num : int = 3;
  
  # byte to int
  my $num : int = (byte)5;
  
  # double to double
  my $num : double = 4.5;
  
  # float to double
  my $num : double = 4.5f;

If the nemric type order of the left operand is less than the nemric type order of the right operand, the assignability is conditional true.

The condition is that the right operand is a interger literal and the value is between the max and minimal value of the type of the left operand.

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

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

Examples:

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

Assignability from NumericObject to Numeric

If the type of the left operand is a numeric type corresponding to the numeric object type of the right operand and the type of the right operand is a numeric object type, the assignability is true.

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

Examples:

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

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

Assignability from Any Object to Numeric

If the type of the left operand is a numeric type and the type of the right operand is a any object type object, the assignability is true.

The unboxing type conversion corresponding to the numeric type is performed.

AssignabilityToFromImplicite Type Conversion
TrueNUMERIC_XobjectUnboxing Type Conversion

Examples:

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

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

Assignability from Others to Numeric

If the type of the left operand is a numeric type and the type of the right operand is other than the types described above, the assignability is false.

Assignability to Multi-Numeric

If the type of the left operand is a multi-numeric type and the type of the right operand is the same type of the left operand, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueMULNUM_XMULNUM_XNone
FalseMULNUM_XOTHERNone

Examples:

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

Assignability to Referenece

If the type of the left operand is a reference type and the type of the right operand is the same type of the left operand, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueREF_XREF_XNone
FalseREF_XOTHERNone

Examples:

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

Assignability to String

If the type of the left operand is the string type without the mutable type qualifier and the type of the right operand is the string type, the assignability is true.

If the type of the left operand is the string type with the mutable type qualifier and the type of the right operand is the string type with the mutable type qualifier, the assignability is true.

If the type of the left operand is the string type with the mutable type qualifier and the type of the right operand is the string type without the mutable type qualifier, the assignability is false.

If the type of the left operand is the string type and the type of the right operand is a numeric type or the undef type, the assignability is true.

If the type of the right operand is a numeric type, the Numeric-to-String type conversion is performed.

AssignabilityToFromImplicite Type Conversion
TruestringstringNone
Truestringmutable stringNone
Truemutable stringmutable stringNone
Falsemutable stringstringNone
TruestringstringNone
TruestringNUMERIC_XNumeric-to-String type conversion
TruestringundefNone
FalsestringOTHERNone

Examples:

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

Assignability to NumericObject

If the type of the left operand is a numeric object type and the type of the right operand is the same type of the left operand, a numeric type that is corresponding to the numeric object type, or the undef type, the assignability is true.

Otherwise, the assignability is false.

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

AssignabilityToFromImplicite Type Conversion
TrueNUMERIC_OBJECT_XNUMERIC_OBJECT_XNone
TrueNUMERIC_OBJECT_XNUMERIC_XBoxing type conversion
TrueNUMERIC_OBJECTundefNone
FalseNUMERIC_OBJECTOTHERNone

Examples:

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

Assignability to Class

If the type of the left operand is a class type and the type of the right operand is the same type, or the undef type, the assignability is true.

If the type of the left operand is a super class of the type of the right operand, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueCLASS_XCLASS_XNone
TrueCLASSundefNone
TrueSUPER_CLASS_XCLASS_YNone
FalseCLASSOTHERNone

Examples:

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

Assignability to Interface

If the type of the left operand is an interface type and the type of the right operand is the same type, or the undef type, the assignability is true.

If the type of the left operand is an interface type and the type of the right operand is a class type and the class has the same interface of the left operand, the assignability is true.

Otherwise, the assignability is false.

AssignabilityToFromImplicite Type Conversion
TrueINTERFACE_XINTERFACE_XNone
TrueINTERFACE_XINTERFACE_HAVING_YNone
TrueINTERFACEundefNone
FalseINTERFACEOTHERNone

Examples:

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

Assignability to Any Object

If the type of the left operand is the any object type and the type of the right operand is an object type, a numeric type or the undef type, the assignability is true.

Otherwise, the assignability is false.

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

AssignabilityToFromImplicite Type Conversion
TrueobjectOBJECT_YNone
TrueobjectNUMERIC_XBoxing type conversion
TrueobjectundefNone
FalseobjectOTHERNone

Examples:

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

Assignability to Undefined

If the type of the left operand is the undefined type, the assignability is false.

AssignabilityToFromImplicite Type Conversion
FalseUndefined TypeOTHERNone

Examples:

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

Assignability to Numeric Array

If the type of the left operand is a numeric array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.

Otherwise, the assignability is false.

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

Examples:

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

Assignability to Multi-Numeric Array

If the type of the left operand is a multi-numeric array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.

Otherwise, the assignability is false.

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

Examples:

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

Assignability to String Array

If the type of the left operand is a string array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.

Otherwise, the assignability is false.

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

Examples:

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

Assignability to Class Array

If the type of the left operand is a class array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.

If the basic type of the left operand is an super class of the type of the right operand, the assignability is true.

Otherwise, the assignability is false.

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

Examples:

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

Assignability to Interface Array

If the type of the left operand is an interface array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.

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

Otherwise, the assignability is false.

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

Examples:

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

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

Assignability to Any Object Array

If the type of the left operand is the any object array type object[] and the type of the right operand is an object array type or the undef type, the assignability is true.

Otherwise, the assignability is false.

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

Examples:

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

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

  my $any_object : object[] = undef;

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

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

Assignability to Multi-Dimensional Array

If the type of the left operand is a multi-dimensional array type and the type of the right operand is the same type of the left operand or the undef type, the assignability is true.

If the type dimesion of the left operand is equal to the type dimension of the right operand, and the basic type of the left operand is a super class of the basic type of the right operand, the assignability is true.

If the type dimesion of the left operand is equal to the type dimension of the right operand, and the basic type of the right operand has the basic type of the left operand, the assignability is true.

Otherwise, the assignability is false.

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

Examples:

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

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

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

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

Castability

The castability at compile-time is explained.

The castability is false, a compilation error will occur.

Castability to Numeric

The castability to the numeric types is explained.

Castability from Numeric to Numeric

If the type of the left operand is a numeric type and the type of the right operand is a numeric type, the castability is true.

If the nemric type order of the left operand is greater than the nemric type order of the right operand, the numeric widening type conversion is performed.

If the nemric type order of the left operand is less than the nemric type order of the right operand, the numeric narrowing type conversion is performed.

If the nemric type order of the left operand is equal to the nemric type order of the right operand, copying is performed.

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

Examples:

  # int to int
  my $num = (int)3;
  
  # byte to int
  my $num_byte : byte = 5;
  my $num = (int)5;
  
  # double to double
  my $num = (double)4.5;
  
  # float to double
  my $num = (double)4.5f;
  
  # int to byte
  my $num = (byte)127;

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

Castability from NumericObject to Numeric

If the type of the left operand is a numeric type corresponding to the numeric object type of the right operand and the type of the right operand is a numeric object type, the castability is true.

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

Examples:

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

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

Castability from Any Object to Numeric

If the type of the left operand is a numeric type and the type of the right operand is a any object type object, the castability is true.

The unboxing type conversion corresponding to the numeric type is performed.

CastabilityToFromConversion or Type Checking
TrueNUMERIC_XobjectUnboxing Type Conversion

Examples:

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

Castability from Others to Numeric

If the type of the left operand is a numeric type and the type of the right operand is other than the types described above, the castability is false.

Castability to Multi-Numeric

If the type of the left operand is a multi-numeric type and the type of the right operand is the same type of the left operand, the castability is true.

Otherwise, the castability is false.

CastabilityToFromConversion or Type Checking
TrueMULNUM_XMULNUM_XNone
FalseMULNUM_XOTHERNone

Examples:

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

Castability to Referenece

If the type of the left operand is a reference type and the type of the right operand is the same type of the left operand, the castability is true.

Otherwise, the castability is false.

CastabilityToFromConversion or Type Checking
TrueREF_XREF_XNone
FalseREF_XOTHERNone

Examples:

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

Castability to String

If the type of the left operand is the string type and the type of the right operand is the string type, the castability is true.

If the type of the left operand is the string type with the mutable type qualifier and the type of the right operand is the string type without the mutable type qualifier, the runtime type checking is performed.

If the type of the right operand is a numeric type, the Numeric-to-String type conversion is performed.

If the type of the left operand is the string type and the type of the right operand is a numeric type, the undef type, or the any object type object, the castability is true.

If the type of the right operand is a numeric type, the Numeric-to-String type conversion is performed.

If the type of the left operand is the string type and the type of the right operand is the any object type object, the castability is true and the runtime type checking is performed.

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

Examples:

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

Castability to NumericObject

If the type of the left operand is a numeric object type and the types of the right operands are the following cases:

If the type of the right operand is the same type of the left operand, a numeric type that is corresponding to the numeric object type, the any object type object, or the undef type, the castability is true.

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

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

If the type of the left operand is the type of the right operand is the any object type object, the runtime type checking is performed.

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

Examples:

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

Castability to Class

If the type of the left operand is a class type and the types of the right operands are the following cases:

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

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

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

Otherwise, the castability is false.

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

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

Examples:

  my $point : Point = Point->new;
  
  my $stringable : Stringable;
  my $point = (Point)$stringable;

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

  my $point = (Point)undef;

Castability to Interface

If the type of the left operand is an interface type, and the types of the right operands are the following cases:

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

If the type of the right operand is a class type and the class has the interface of the left operand, the castability is true.

Otherwise, the castability is false.

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

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

Examples:

  my $stringable1 : Stringable;
  my $stringable2 = (Stringable)$stringable1;
  
  my $cloneable : Cloneable;
  my $stringable = (Stringable)$cloneable;
  
  my $stringable  = (Stringable)Point->new_xy(1, 2);

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

Castability to Any Object

If the type of the left operand is the any object type and the types of the right operands are the following cases:

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

Otherwise, the castability is false.

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

CastabilityToFromConversion or Type Checking
TrueobjectOBJECT_YNone
TrueobjectNUMERIC_XBoxing type conversion
TrueobjectundefNone
FalseobjectOTHERNone

Examples:

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

Castability to Numeric Array

If the type of the left operand is the byte[] type and the type of the right operand is the string type, the castability is true.

If the type of the left operand is a numeric array type and the types of the right operands are the following cases:

If the type of the right operand is the same type of the left operand, the any object type obejct or the undef type, the castability is true.

Otherwise, the castability is false.

If the type of the left operand is the byte[] type and the type of the right operand is the string type, "String-to-byte[] Type Conversion" is performed.

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

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

Examples:

  my $bytes = (byte[])"abc";
  
  my $nums = (int[])new int[3];
  
  my $object : object = new int[3];
  my $nums = (int[])$object;
  
  my $nums = (int[])undef;

Castability to Multi-Numeric Array

If the type of the left operand is a multi-numeric array type and the types of the right operands are the following cases:

If the type of the right operand is the same type of the left operand, the any object type obejct or the undef type, the castability is true.

Otherwise, the castability is false.

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

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

Examples:

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

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

  my $nums = (Complex_2d[])undef;

Castability to String Array

If the type of the left operand is a string array type and the types of the right operands are the following cases:

If the type of the right operand is the same type of the left operand, the any object type obejct, the any object array type obejct[] or the undef type, the castability is true.

Otherwise, the castability is false.

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

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

Examples:

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

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

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

  my $strings  = (string[])undef;

Castability to Class Array

If the type of the left operand is a class array type and the types of the right operands are the following cases:

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

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

If the type of the right operand is the same type of the left operand, the any object type obejct, the any object array type obejct[] or the undef type, the castability is true.

Otherwise, the castability is false.

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

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

Examples:

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

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

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

  my $points = (Point[])undef;

Castability to Interface Array

If the type of the left operand is an interface array type and the types of the right operands are the following cases:

If the type of the right operand is a class array type and its basic type has the interface of the basic type of the left operand, the castability is true.

If the type of the right operand is the same type of the left operand, the castability is true.

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

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

Otherwise, the castability is false.

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

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

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

Examples:

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

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

Castability to Any Object Array

If the type of the left operand is the any object array type object[] and the types of the right operands are the following cases:

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

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

Otherwise, the castability is false.

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

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

Examples:

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

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

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

  my $any_object = (object[])undef;

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

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

Castability to Multi-Dimensional Array

If the type of the left operand is a multi-dimensional array type and and the types of the right operands are the following cases:

If the type of the right operand is the same type of the left operand or the undef type, the castability is true.

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

If the type dimesion of the left operand is equal to the type dimension of the right operand, and the basic type of the left operand is a super class of the basic type of the right operand, the castability is true.

If the type dimesion of the left operand is equal to the type dimension of the right operand, and the basic type of the right operand is a super class of the basic type of the left operand, the castability is true.

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

Otherwise, the castability is false.

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

Examples:

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

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

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

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

Type Conversion

Type conversion is explained.

Explicite Type Conversion

The explicite type conversion is the type conversion performed by a type cast expicitely.

Examples:

  # Explicte long to int type conversion
  my $num = (int)123L;

  # Explicte byte[] to string type conversion
  my $num = (string)new byte[3];

  # Explicte string to byte[] type conversion
  my $num = (byte[])"Hello";

Implicite Type Conversion

The implicite type conversion is the type conversion performed implicitly when a value is assigned using assignment operator, pass an argument to a method using a method call, or set a return value using the return statement.

See "Assignability" if you know when implicite type conversion is performed.

Examples:

  # Implicite int to double type conversion
  my $num : double = 5;
  
  # Implicte double to Double type conversion
  my $num_object : Double = 5.1;
  
  # Implicte Double to double type conversion
  my $num : double = Double->new(5.1);
  
  # Implicte int to string type conversion
  my $string : string = 4;

Numeric Widening Type Conversion

The numeric widening type conversion is a conversion from a small-order numeric type to a large-order numeric type.

See also numeric types order abount the order of numeric type.

The return value of a converion are same as the return value of the type cast of C language.

  (TYPE)OPERAND

byte to short:

  int8_t from = VALUE;
  int16_t to = (int16_t)from;

byte to int:

  int8_t from = VALUE;
  int32_t to = (int32_t)from;

byte to long:

  int8_t from = VALUE;
  int64_t to = (int64_t)from;

byte to float:

  int8_t from = VALUE;
  float to = (float)from;

byte to double:

  int8_t from = VALUE;
  double to = (double)from;

short to int:

  int16_t from = VALUE;
  int32_t to = (int32_t)from;

short to long:

  int16_t from = VALUE;
  int64_t to = (int64_t)from;

short to float:

  int16_t from = VALUE;
  float to = (float)from;

short to double:

  int16_t from = VALUE;
  double to = (double)from;

int to long:

  int32_t from = VALUE;
  int64_t to = (int64_t)from;

int to float:

  int32_t from = VALUE;
  float to = (float)from;

int to double:

  int32_t from = VALUE;
  double to = (double)from;

long to float:

  int64_t from = VALUE;
  float to = (float)from;

long to double:

  int64_t from = VALUE;
  double to = (double)from;

The numeric widening type conversion is performed in some of the type casts, the index of the array access, the length of the creating array, the operand of the unary plus operator, the operand of the unary minus operator, and the left and right operands of the shift operators.

Numeric Narrowing Type Conversion

The numeric narrowing type conversion is a conversion from a large-order numeric type to a small-order numeric type.

See also numeric types order abount the order of numeric type.

The return value of a converion are same as the return value of the type cast of C language.

  (TYPE)OPERAND

b<double to float:>

  double from = value;
  float to = (float)from;

b<double to long:>

  double from = value;
  int64_t to = (int64_t)from;

b<double to int:>

  double from = value;
  int32_t to = (int32_t)from;

b<double to short:>

  double from = value;
  int16_t to = (int16_t)from;

b<double to byte:>

  double from = value;
  int8_t to = (int8_t)from;

b<float to long:>

  float from = value;
  int64_t to = (int64_t)from;

b<float to int:>

  float from = value;
  int32_t to = (int32_t)from;

b<float to short:>

  float from = value;
  int16_t to = (int16_t)from;

b<float to byte:>

  float from = value;
  int8_t to = (int8_t)from;

b<long to int:>

  int64_t from = value;
  int32_t to = (int32_)from;

b<long to short:>

  int64_t from = value;
  int16_t to = (int16_t)from;

b<long to byte:>

  int64_t from = value;
  int8_t to = (int8_t)from;

b<int to short:>

  int32_t from = value;
  int16_t to = (int16_t)from;

b<int to byte:>

  int32_t from = value;
  int16_t to = (int16_t)from;

b<short to byte:>

  int16_t from = value;
  int8_t to = (int8_t)from;

The numeric narrowing type conversion is performed in some of the type casts.

Binary Numeric Type Conversion

Binary Numeric Type Conversion is performed to the left operand and the right operand in Binary Operator that takes Numeric Type 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 the int type.

Binary Numeric Type Conversion is performed in the following cases.

Numeric-to-String Type Conversion

The numeric-to-String type conversion is a type conversion from a numeric type to the string type.

  # Numeric-to-String type conversion
  my $byte = (byte)1;
  my $short = (short)2;
  my $int = 3;
  my $long = 4L;
  my $float = 2.5f;
  my $double = 3.3;
  
  # The string is 1.
  my $string_byte = (string)$byte;
  
  # The string is 2.
  my $string_short = (string)$short;

  # The string is 3.
  my $string_int = (string)$int;

  # The string is 4.
  my $string_long = (string)$long;
  
  # The string is "2.5"
  my $string_float = (string)$float;
  
  # The string is "3.3"
  my $string_double = (string)$double;

String-to-byte[] Type Conversion

The String-to-byte[] type conversion is a "Type Conversion" from "String Type" to "byte[] Type".

  # String-to-byte[] Type Conversion
  my $string : string = "Hello";
  my $bytes : byte[] = (byte[])$string;

A new byte[] object is created and all characters in the string are copied to the elements of byte[] object.

byte[]-to-String Type Conversion

The byte[]-to-String type conversion is a "Type Conversion" from "byte[] type" to "String Type".

  # byte[]-to-String type conversion
  my $bytes : byte[] = new byte[3];
  $bytes->[0] = 'a';
  $bytes->[1] = 'b';
  $bytes->[2] = 'c';
  my $string : string = (string)$bytes;

A new string is created and all elements in the byte[] object are copied to the characters of the string.

Boxing Type Conversion

Boxing Type Conversion is the operation to convert the value of Numeric Type 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 Type.

Conditional Type Conversion

The conditional type conversion is a type conversion that is performed to the conditional operand.

The type of the operand of the conditional type conversion must be one of a numeric type, an object type or the undef type. Otherwise a compilation error will occur.

The conditional type conversion returns the following value corresponding to the type of the condional operand.

If the type is the int type, return the value.

If the type is the undef, return 0.

If the type is the value returned by the TRUE method of Bool, return 1.

If the type is the value returned by the FALSE method of Bool, return 0.

If the type is a numeric type except for int type, the numeric widening type conversion is performed.

And the following operation in C language is performed to the operand .

  !!OPERAND

Examples:

  if (1) {
    # ok
  }
  
  if (0) {
    # not ok
  }
  
  if (1.5) {
    # ok
  }
  
  if (0.0) {
    # not ok
  }
  
  if (true) {
    # ok
  }
  
  if (Bool->TRUE) {
    # ok
  }
  
  if (false) {
    # not ok
  }
  
  if (Bool->FALSE) {
    # not ok
  }
  
  my $object = SPVM::Int->new(1);
  
  if ($object) {
    # ok
  }
  
  $object = undef;
  if ($object) {
    # not ok
  }
  
  if (undef) {
    # not ok
  }

Conditional Operand

List of conditional operands:

The operand of the if statement:

  if (CONDITION) {
  
  }

The operand of the unless statement:

  unless (CONDITION) {
  
  }

The second operand of the for statement:

  for (INITIALIZEATION;CONDITION;NEXT_VALUE;) {
  
  }

The operand of the while statement:

  while (CONDITION) {
  
  }

The left and right operand of the logical AND operator:

  CONDITION && CONDITION

The left and right operand of the logical OR operator:

  CONDITION || CONDITION

The operand of the logical NOT operator:

  !CONDITION

Runtime Type Checking

The runtime type cheking is the type cheking that is performed at runtime.

The type cast operators that operand is an object type performe the runtime type checking by the rule of the "Runtime Assignability" in runtime assignability.

Runtime Assignability

The runtime assignability is the assignability at runtime.

The isa operator checks the "Runtime Assignability" in runtime assignability

The runtime assignability is false, an exception will be thrown.

If the type of the distribution is an object type and the type of the source is undef, the runtime assignability is true.

If the type of the distribution is the same as the type of the source, the runtime assignability is true.

If the type of the distribution is the any object type object and the type of the source is an object type, the runtime assignability is true.

If the type of the distribution is the any object array type object[] and the type of the source is an object array type, the runtime assignability is true.

If the type of distribution is an class type, an class array type, an class multi-dimensional array type and the dimention of the type of the distribution is the same as the dimention of the type of the source and the basic type of distribution is a super class of the basic type of the source, the runtime assignability is true.

If the type of distribution is an interface type, an interface array type, an interface multi-dimensional array type and the dimention of the type of the distribution is the same as the dimention of the type of the source and the basic type of distribution has the interface of the basic type of the source, the runtime assignability is true.

Runtime AssignabilityToFrom
TrueOBJECT_Xundef
TrueOBJECT_XOBJECT_X
TrueobjectOBJECT_Y
Trueobject[]OBJECT_ARRAY_Y
TrueSUPER_CLASS_XCLASS_Y
TrueSUPER_CLASS_X[]CLASS_Y[]
TrueSUPER_CLASS_X[][]...CLASS_Y[][]...
TrueINTERFACE_XINTERFACE_HAVING_Y
TrueINTERFACE_X[]INTERFACE_HAVING_Y[]
TrueINTERFACE_X[][]...INTERFACE_HAVING_Y[][]...
FalseOBJECT_XOTHER

Type Comment

The type comment syntax is supported. The type comment can be written after of keyword.

  TYPE of TYPE

The type comment can be used the type of the field decralation, the class variable definition, the local variable declaration, and the return value and the types of arguments of the method definition.

  has points : List of Point;
  
  our $POINTS : List of Point;
  
  my $points : List of Point;
  
  static method foo : List of Point ($arg : List of Point) { ... }

If the type specified as the type comment is not found, a compilation error will occur.

Type comments have no meanings at runtime.

Statement

Statements are syntax or operations that are written direct under a scope block.

empty Statement

An empty statement is a statement that do nothing and ends with just ;.

  ;

Operation Statement

The operation statement is the statement to execute an operation.

A operation statement is composed of an operator and ;.

  OPERATOR;

Examples:

  1;
  $var;
  1 + 2;
  foo();
  my $num = 1 + 2;

if Statement

The if statement is a statement for conditional branch.

  if (CONDITION) {
  
  }

The condition the conditional 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 the conditional type conversion is executed, and a corresponding Block is executed if the value is non-zero.

  if (CONDITION) {
  
  }
  elsif(CONDITION) {
  
  }

You can use else statement to describe what happens if or if the elsif Statement does not meet the criteria. If the if statement and elsif statement condition determination are all false, the statement inside the elseBlock is executed. Elsif Statement does not have to be.

  if (CONDITION) {
  
  }
  elsif (CONDITION) {
  
  }
  else {
  
  }

Examples:

  # An example of if Statement.
  my $flag = 1;
  
  if ($flag == 1) {
    print "One\n";
  }
  elsif ($flag == 2) {
    print "Tow\n";
  }
  else {
    print "Other";
  }

The if Statement is internally surrounded by an invisible Simple Block.

  {
    if (CONDITION) {
  
    }
  }

elsif is internally expanded into if Statement and else Statement.

  #Before deployment
  if (CONDITION1) {
  
  }
  elsif (CONDITION2) {
  
  }
  else {
  
  }
  
  #After deployment
  if (CONDITION1) {
  }
  else {
    if (CONDITION2) {
  
    }
    else {
  
    }
  }

When a variable is declared in the conditional part of if Statement, it must be surrounded by invisible "Simple Block". Be aware that elsif is internally expanded into if Statement and else Statement.

  #Before deployment
  my $num = 1;
  if (my $num = 2) {
  
  }
  elsif (my $num = 3) {
  
  }
  else {
  
  }
  
  #After deployment
  my $num = 1;
  {
    if (my $num = 2) {
  
    }
    else {
      {
        if (my $num = 3) {
          
        }
        else {
          
        }
      }
    }
  }

unless Statement

The unless statement is a statement for conditional branches.

  unless (CONDITION) {
    
  }

This is the same as the following if Statement.

  if (!CONDITION) {
    
  }

switch Statement

The switch statement is a statement for conditional branch.

  switch (CONDITION) {
    case CASE_VALUE1: {
      # ...
    }
    case CASE_VALUE2: {
      # ...
    }
    case CASE_VALUE3: {
      # ...
    }
    default: {
      # ...
    }
  }

The condition must be an integral type that numeric order is less than or equal to the int type. Otherwise a compilation occur will occur.

The numeric widening type conversion to the int type is performed to the value of the condition.

The value of the case statement must be one of a character literal, an integer literal or an enumeration call.

If the value is a character literal, the value is converted to the int type at compile-time.

The values of the case statements can't be duplicated. If they are duplicated, a compilation error will occur.

If the value of the condition matches a value of a case statement, the program jumps to the block of the case statement.

If it doesn't match and the default statement exists, the program jumps to the block of the default statement.

If it doesn't match and the default statement doesn't exists, the program jumps to the end of the switch block.

The case statements and the default statement can be ommited.

The break statement jumps to the end of the switch block.

  switch (CONDITION) {
    case CASE_VALUE1: {
      break;
    }
    case CASE_VALUE2: {
      break;
    }
    case CASE_VALUE3: {
      break;
    }
    default: {
      
    }
  }

If the last statment of the case block is not the break statement, a break statement is added to the end of the case block.

Multiple case values are specified at once.

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

Examples:

  # switch statement
  my $code = 2;
  my $flag = 1;
  switch ($code) {
    case 1: {
      print "1\n";
    }
    case 2: {
      print "2\n";
    }
    case 3: {
      if ($flag) {
        break;
      }
      print "3\n";
    }
    case 4:
    case 5:
    {
      print "4 or 5\n";
    }
    default: {
      print "Other\n";
    }
  }
  
  # switch statement using enumeration
  class Foo {
    enum {
      ID1,
      ID2,
      ID3,
    }
    
    static method main : int () {
      my $value = 1;
      switch ($value) {
        case Foo->ID1: {
          print "1\n";
        }
        case Foo->ID2: {
          print "2\n";
        }
        case Foo->ID3: {
          if ($flag) {
            break;
          }
          print "3\n";
        }
        default: {
          print "Other\n";
        }
      }
    }
  }

case Statement

The case statement is the statement that specifies a case value and a branch of a switch statement.

default Statement

The default statement is a statement that specifies a default branch of a switch statement.

break Statement

The break statement is a statement to jump to the end of the switch block of the switch statement.

  break;

while Statement

The while statement is a statement for repeating.

  while (CONDITION) {
  
  }

"Expressions" can be described in the condition Expression. The conditional type conversion is executed for condition Expression, and if the value is not 0, Block is executed. Exit the otherwise Block.

Examples:

An example of a while Statement.

  my $i = 0;
  while ($i <5) {
  
    print "$i\n";
  
    $i++;
  }

Inside the while block, you can leave the while block by using "last Statement".

  while (1) {
    last;
  }

Inside a while block, you can use "next Statement" to move to the condition immediately before the next condition Expression.

  my $i = 0;
  while ($i <5) {
  
    if ($i == 3) {
      $i++;
      next;
    }
  
    print "$i\n";
    $i++;
  }

The while Statement is internally enclosed by an invisible "Simple Block".

  {
    while (CONDITION) {
    $i++;
  }
  
  # After expansion
  my $num = 5;
  {
    while (my $num = 3) {
  
      $i++;
    }
  }

for Statement

The for Statement is a statement for repeating.

  for (INIT_STATEMENT; CONDITION; INCREMENT_STATEMENT) {
  
  }

"Expressions" can be described in the initialization Expression. Generally, write Expression such as initialization of loop variable. Initialization Expression can be omitted.

Condition Expression, "Expressions" can be described. The conditional 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 destroyed.

  return;

If there is a Return Value, "Expressions" can be specified.

  return EXPRESSION;

If the Return Value Type in the method definition is the "void Type" in void type, Expression Must not exist, otherwise a compilation error will occur.

the method definition, if the The return type is other than the "void Type" in void type, Expression Must match the type of, otherwise a compilation error will occur.

next Statement

The next statement is a statement to move to the beginning of the next loop block.

  next;

See also "while Statement", "for Statement".

last Statement

The last statement" is a statement to move to the outside of the loop block.

  last;

See also "while Statement", "for Statement".

warn Statement

The warn statement is a statement to print a warning string to the standard error.

  warn OPERNAD;

The operand must be "String Type".

If the end character of the string is \n, warn statement prints the string itself.

If not, the current file name and current line number are added to the end of the string.

If the value of the operand is an undef, print "Warning: something's wrong".

The buffer of the standard error is flushed after the printing.

die Statement

The die statement is a statement to throw an exception.

  die OPERAND;

The operand must be the string type. If not a compilation error will occur.

You can specify the error message to the operand.

  # Throw an exception
  die "Error";

The error message is set to the exception variable $@.

If an exception is thrown, the program prints the error message to the standard error with the stack traces and finishes with error code 255.

The stack traces constain the class names, the method names, the file names and the line numbers.

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

The exception can be catched using an eval block.

Examples:

  # Catch the exception
  eval {
    # Throw an exception
    die "Error";
  };
  
  # Check the exception
  if ($@) {
    # ...
  }

The print statement is a statement to print a string to the standard output.

  print OPERAND;

The oeprand must be a string type.

If the value of the operand is an undef, print nothing.

make_read_only Statement

The make_read_only statement is a statement to make the string read-only.

  make_read_only OPERAND;

The oeprand must be a string type.

Read-only strings can't be cast to string type qualified by mutable.

  # A string
  my $string = new_string_len 3;
  
  # Make the string read-only
  make_read_only $string;
  
  # The conversion to the string type qualified by mutable throw an exception.
  my $string_mut = (mutable string)$string;

weaken Statement

The weaken statement is a statement to create a weak reference.

  weaken OBJECT->{FIELD_NAME};

The type of the object must be the class type, otherwise a compilation error will occur.

If the field name is not found, a compilation error will occur.

The type of the field targetted by the weaken statement is not an object type, a compilation error will occur.

See "Weak Reference" to know the behavior of the weaken statement.

Examples:

  # weaken
  weaken $object->{point};

unweaken Statement

The unweaken statement is a statement to unweakens a weak reference.

  unweaken OBJECT->{FIELD_NAME};

The type of the object must be the class type, otherwise a compilation error will occur.

If the field name is not found, a compilation error will occur.

The type of the field targetted by the unweaken statement is not an object type, a compilation error will occur.

See "Weak Reference" to know the behavior of the unweaken statement.

Examples:

  # unweaken
  unweaken $object->{point};

Operator

An operator performs an operation.

Operators are "Unary Operator" in unary operators, binary operators, increment operators, decrement operators, comparison operators, logical operators, and assignment operators.

Unary Operator

The unary operator is the operator that has an operand.

  UNARY_OPERATOR OPERAND

Unary operators are the unary plus operator, the unary minus operator, the bit NOT operator, the array length operator, the string creating operator, and the string length operator.

Binary Operator

The binary operator is the operator that has the left operand and the right operand.

  LEFT_OPERAND BINARY_OPERATOR RIGHT_OPERAND

Binary operators are the "Addition Operator" in addition operator, the subtraction operator, the multiplication operator, the division operator, the remainder operator, the bit AND operator, the bit OR operator, the "Shift Operator" in shift operators, and the 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.

Exampless:

  # 3 is assigned to $foo
  my $foo = (1, 2, 3);
  
  # $x is 3, $ret is 5
  my $x = 1;
  my $y = 2;
  my $ret = ($x += 2, $x + $y);

Arithmetic Operator

Arithmetic operators are the "Operator" in operators to perform arithmetic operations.

Arithmetic operators are the additional operator, the subtraction operator, the multiplication operator, the division, the division unsigned int operator, the division unsigned long operator, the reminder operator, the remainder unsigned int operator, the remainder unsigned long operator, the "Unary Plus Operator" in unary plus operator, the umary minus operator, the increment operators, and the decrement operators.

Unary Plus Operator

The unary plus operator + is an unary operator to return the value of the operand.

  +OPERAND

The operand must be an operator that type is a numeric type, otherwise a compilation error will occur.

"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 "Numeric Widening Type Conversion" is performed.

Examples:

  # 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 operator that type is a numeric type, otherwise a compilation error will occur.

"Numeric Widening Type Conversion" applys to the operand.

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

  -x

Return type of an unary minus operator is the type that "Numeric Widening Type Conversion" is performed.

Examples:

  # A unary minus operator
  my $num = -10;

Addition Operator

The addition operator + is a binary operator to calculate the result of the addition of two numbers.

  LEFT_OPERAND + RIGHT_OPERAND

The left operand and the right operand must be a numeric type, otherwise a compilation error will occur.

"Binary Numeric 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 Type Conversion" is performed.

Subtraction Operator

The subtraction operator - is a binary operator to calculate the result of the subtraction of two numbers.

  LEFT_OPERAND - RIGHT_OPERAND

The left operand and the right operand must be a numeric type, otherwise a compilation error will occur.

"Binary Numeric 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 Type Conversion" is performed.

Multiplication Operator

The multiplication operator is a binary operator to calculate the result of multiplication of two numbers.

  LEFT_OPERAND * RIGHT_OPERAND

The left operand and the right operand must be a numeric type, otherwise a compilation error will occur.

"Binary Numeric 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 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 a numeric type, otherwise a compilation error will occur.

"Binary Numeric 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 Type Conversion" is performed.

If the two operands are integral types and the value of the right operand is 0, an exception is thrown.

Division Unsigned Int Operator

The division unsigned int operator divui is a binary operator to culcurate the unsigned int division of two numbers.

  LEFT_OPERAND divui RIGHT_OPERAND

The left operand and the right operand must be an int type, otherwise a compilation error will occur.

The division unsigned int operator performs the operation that exactly same as the following operation in C language.

  (uint32_t)x / (uint32_t)y;

The return type of the division operator is the int type.

If the value of the right operand is 0, an exception is thrown.

Division Unsigned Long Operator

The division unsigned long operator divul is a binary operator to culcurate the unsigned long division of two numbers.

  LEFT_OPERAND divul RIGHT_OPERAND

The left operand and the right operand must be an long type, otherwise a compilation error will occur.

The division unsigned long operator performs the operation that exactly same as the following operation in C language.

  (uint64_t)x / (uint64_t)y;

The return type of the division operator is the long type.

If the value of the right operand is 0, an exception is thrown.

Remainder Operator

The remainder operator % is a binary operator to calculate a remainder of two numbers.

  LEFT_OPERAND % RIGHT_OPERAND

The left operand and the right operand must be an integral type, otherwise a compilation error will occur.

"Binary Numeric 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 Type Conversion" is performed.

If the right operand is 0, the remainder operator throw an exception.

Remainder Unsigned Int Operator

The remainder unsigned int operator remui is a binary operator to calculate a unsigned int remainder of two numbers.

  LEFT_OPERAND remui RIGHT_OPERAND

The left operand and the right operand must be a int type, otherwise a compilation error will occur.

The remainder unsigned int operator performs the operation that exactly same as the following operation in C language.

  (uint32_t)x % (uint32_t)y;

The return type of the remainder unsigned int operator is the int type.

If the value of the right operand is 0, an exception is thrown .

Remainder Unsigned Long Operator

The remainder unsigned long operator remul is a binary operator to calculate a unsigned long remainder of two numbers.

  LEFT_OPERAND remul RIGHT_OPERAND

The left operand and the right operand must be a long type, otherwise a compilation error will occur.

The remainder unsigned long operator performs the operation that exactly same as the following operation in C language.

  (ulong64_t)x % (ulong64_t)y;

The return type of the remainder unsigned long operator is the long type.

If the value of the right operand is 0, an exception is thrown .

Increment Operator

Increment operators are the pre-increment operator and post-increment operator.

Pre-Increment Operator

The pre-increment operator adds 1 to the value of the operand and returns the value after the incrementation.

  # Pre-increment operator
  ++OPERAND

The type of the operand must be a local variable, a class variable, a field access</a>, an array access, a dereference, otherwise a compilation error will occur.

The pre-increment operator performs the same operation as the following.

  (OPERAND = (TYPE_OF_OPERAND)(OPERAND + 1))

For example, if the type of the operand is the byte type, the following operation is performed.

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

Examples:

  # Pre-increment of a local variable
  ++$num;
  
  # Pre-increment of a class variable
  ++$NUM;
  
  # Pre-increment of an element of an array
  ++$point->{x};
  
  # Pre-increment of a field
  ++$nums->[0];
  
  # Pre-increment of a dereferenced value
  ++$$num_ref;

Post-Increment Operator

The post-increment operator adds 1 to the value of the operand and returns the value before the incrementation.

  # Post-increment operator
  OPERAND++

The type of the operand must be a local variable, a class variable, a field access</a>, an array access, a dereference, otherwise a compilation error will occur.

The post-increment operator performs the same operation as the following.

  (my TMP_VARIABLE = OPERAND, OPERAND = (TYPE_OF_OPERAND)(OPERAND + 1), TMP_VARIABLE)

For example, if the type of the operand is the byte type, the following operation is performed.

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

Examples:

  # Post-increment of a local variable
  $num++;
  
  # Post-increment of a class variable
  $NUM++;
  
  # Post-increment of an element of an array
  $point->{x}++;
  
  # Post-increment of a field
  $nums->[0]++;
  
  # Post-increment of a dereferenced value
  $$num_ref++;

Decrement Operator

Decrement operators are the pre-decrement operator and post-decrement operator.

Pre-Decrement Operator

The pre-decrement operator subtracts 1 to the value of the operand and returns the value after the decrementation.

  # Pre-decrement operator
  --OPERAND

The type of the operand must be a local variable, a class variable, a field access</a>, an array access, a dereference, otherwise a compilation error will occur.

The pre-decrement operator performs the same operation as the following.

  (OPERAND = (TYPE_OF_OPERAND)(OPERAND - 1))

For example, if the type of the operand is the byte type, the following operation is performed.

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

Examples:

  # Pre-decrement of a local variable
  --$num;
  
  # Pre-decrement of a class variable
  --$NUM;
  
  # Pre-decrement of an element of an array
  --$point->{x};
  
  # Pre-decrement of a field
  --$nums->[0];
  
  # Pre-decrement of a dereferenced value
  --$$num_ref;

Post-Decrement Operator

The post-decrement operator subtracts 1 to the value of the operand and returns the value before the decrementation.

  # Post-decrement operator
  OPERAND--

The type of the operand must be a local variable, a class variable, a field access</a>, an array access, a dereference, otherwise a compilation error will occur.

The post-decrement operator performs the same operation as the following.

  (my TMP_VARIABLE = OPERAND, OPERAND = (TYPE_OF_OPERAND)(OPERAND - 1), TMP_VARIABLE)

For example, if the type of the operand is the byte type, the following operation is performed.

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

Examples:

  # Post-decrement of a local variable
  $num--;
  
  # Post-decrement of a class variable
  $NUM--;
  
  # Post-decrement of an element of an array
  $point->{x}--;
  
  # Post-decrement of a field
  $nums->[0]--;
  
  # Post-decrement of a dereferenced value
  $$num_ref--;

Bit Operator

Bit operators are operators to perform bit operations.

Bit operators are the bit AND operator, the bit OR operator, or the bit NOT operator.

Bit AND Operator

The bit AND operator & is an operator to performe a bit AND operation.

  LEFT_OPERAND & RIGHT_OPERAND

The left operand and the right operand must be an "Integral Type" in integral type, otherwise a compilation error will occur.

A binary numeric widening type conversion is performed.

The return value is the same as the follwoing operation of C language.

  x & y;

The return type is the type after the binary numeric widening type conversion is performed.

Examples:

  # The bit AND operator
  my $num1 = 0xff;
  my $num2 = 0x12;
  my $result = $num1 & $num2;
  

Bit OR Operator

The bit OR operator | is an operator to performe a bit OR operation.

  LEFT_OPERAND | RIGHT_OPERAND

The left operand and the right operand must be an "Integral Type" in integral type, otherwise a compilation error will occur.

A binary numeric widening type conversion is performed.

The return value is the same as the follwoing operation of C language.

  x | y;

The return type is the type after the binary numeric widening type conversion is performed.

Examples:

  # The bit OR operator
  my $num1 = 0xff;
  my $num2 = 0x12;
  my $result = $num1 | $num2;

Bit NOT Operator

The bit NOT operator ~ is an unary operator to perform the bit NOT operation.

  ~OPERAND

The type of the operand must is an integral type, otherwise a compilation error will occur.

The numeric widening type conversion is performed.

The return value is the same as the follwoing operation of C language.

  ~x

The return type is the type that the numeric widening type conversion is performed.

Examples:

  # The bit NOT operator
  my $num = ~0xFF0A;

Shift Operator

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

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

The right operand must be "Integral Type" except for the long type, otherwise a compilation error will occur.

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

The return type is the 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 Type", otherwise a compilation error will occur.

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

The right operand must be "Integral Type" except for the long type, otherwise a compilation error will occur.

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

The return type is the 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 Type", otherwise a compilation error will occur.

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

The right operand must be "Integral Type" except for the long type, otherwise a compilation error will occur.

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

The return type is the 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

The comparison operator is the operator to compare the left operand and the right operand.

  LEFT_OPERAND COMPARISON_OPERATOR RIGHT_OPERAND

Comparison operators are the numeric comparison operators, the string comparison operators, and the isa operator.

Numeric Comparison Operator

The 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

The list of numeric comparison operators.

Operator Allowing Type Description
LEFT_OPERAND == RIGHT_OPERAND The left operand and the right operand are numeric types, The left operand and the right operand are Object Type (including Undefined Value) The left operand and the right operand are equal
LEFT_OPERAND != RIGHT_OPERAND The left operand and the right operand are numeric types, The left operand and the right operand are Object Type (including Undefined Value) The left operand and the right operand are not equal
LEFT_OPERAND > RIGHT_OPERAND The left operand and the right operand are numeric types The left operand is greater than the right operand
LEFT_OPERAND >= RIGHT_OPERAND The left operand and the right operand are numeric types The left operand is greater than or equal to the right operand
LEFT_OPERAND < RIGHT_OPERAND The left operand and the right operand are numeric types The left operand is less than the right operand
LEFT_OPERAND <= RIGHT_OPERAND The left operand and the right operand are numeric types The left operand is less than or equal to the right operand
LEFT_OPERAND <=> RIGHT_OPERAND The left operand and the right operand are numeric types If the left operand is greater than the right operand, return 1. If the left operand is less than Right value_op, return -1. If the left operand is equals to Right value_op, return 0.

The types of the left operand and the right operand must be comparable types. Otherwise a compilation error will occur.

In Numeric Type Comparison, "Binary Numeric 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 Type Comparison, Object Type Comparison
  (int32_t)(x == y);
  (int32_t)(x != y);
  
  # Numeric Type 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 Type Operation(==, !=, >, >=, <, <=), the int type Operation, "long Type" Operation, "float Type" Operation, "double Type" Operation is defined.

And Object Type Operation(==, !=) is defined.

The return type of the Numeric Comparison Operator is the int type.

String Comparison Operator

The string comparison operator is a comparison operator to compare tow strings.

  LEFT_OPERAND STRING_COMPARISON_OPERATOR RIGHT_OPERAND

The type of the left operand and the right operand must be the string type or byte[] type.

The return type is the int type. If the condition is satisfied, return 1, otherwise 0.

The list of string comparison operators.

Operators Descriptions
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 value_op, return 1. If the left operand is less than the right operand, return -1. If the left operand is equal to the right operand, return 0.

isa Operator

The isa operator is a comparison operator to check whether the left operand can be assigned to the right type.

  LEFT_OPERAND isa RIGHT_TYPE

The return type is int type.

If the right type is a numeric type, "Multi-Numeric Type", "Any Object Type", "Reference Type", it checks the assignability at compile-time.

If the assignability is true, it is replaced with 1. Otherwise it is replaced with 0.

If the right type is other type, it checks the runtime assignability at runtime. If the runtime assignability is true, it returns 1. Otherwise return 0.

Examples:

  if ($object isa Point) {
    
  }
  
  if ($object isa Point3D) {
    
  }
  
  if ($object isa Stringable) {
    
  }
  
  if ($value isa int) {
    
  }
  

ref Operator

The ref operator is an operator to get the type name of the object.

  ref OPERAND

If the operand is defined, it returns the type name of the object. If not, return undef.

The return type is the string type.

If the operand is not an object type, a compilation error will occur.

Examples:

  # "Point"
  my $poitn = Point->new;
  my $type_name = ref $point;

dump Operator

The dump operator is an operator to get the string representation of the object.

  dump OPERAND

It returns the the string representation of the object.

The return type is the string type.

If the operand is not an object type, a compilation error will occur.

The string representation may be changed from SPVM version to version. Please don't use dump operator for the purpose of the data serialization.

Logical Operator

The logical operators are the operators to perform logical operations.

The logical operators are the logical AND operator, the logical OR operator, and the logical NOT operator.

Logical AND Operator

The logical AND operator && is a logical operator to perform a logical AND operation.

  LEFT_OPERAND && RIGHT_OPERAND
  

The left operand and the right operand must be an operator.

The return type of the logical AND operator is the int type.

Thg logical AND operator performs the conditional type conversion to the left operand. If the evaluated value is 0, return 0. Otherwise proceed to the evaluation of the right operand.

It performs the conditional type conversion to the right operand. If the evaluated value is 0, return 0. Otherwise return the evaluated value.

Logical OR Operator

The logical OR operator || is a logical operator to performe a logical OR operation.

  LEFT_OPERAND || RIGHT_OPERAND

The return type of the logical OR operator is the int type.

Thg logical OR operator performs the conditional type conversion to the left operand. If the evaluated value is not 0, return the evaluated value. Otherwise proceed to the evaluation of the right operand.

It performs the conditional type conversion to the right operand. If the evaluated value is not 0, return the evaluated value. Otherwise return 0.

Logical NOT Operator

The logical NOT operator ! is a logical operator to performe a logical NOT operation.

  !OPERAND

The return type of the logical NOT operator is the int type.

Thg logical NOT operator performs the conditional type conversion to the operand. If the evaluated value is 0, returns 1. Otherwise return 0.

String Concatenation Operator

String concatenation operator . is a binary operator to concat two strings.

  LEFT_OPERAND . RIGHT_OPERAND

The left operand and the right operand must be a string type, "byte[] Type", or numeric type, otherwise a compilation error will occur.

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

The return type is a string type.

A string concatenation operator returns the result to concat two operands.

If both the left operand and the right operand are a string literal, the two string literals are concatenated at compile-time.

If the left operand or the right operand is undef, an exception occurs.

Examples:

  my $str = "abc" . "def";
  my $str = "def" . 34;
  my $str = 123 . 456;

Assignment Operator

The assignment operator = is a binary operator to assign a value.

  LEFT_OPERAND = RIGHTH_OPERAND

The assignment operator has different meanings depending on the left operand and the right operand.

Local Variable Assignment

See "Getting Local Variable" and "Setting Local Variable".

Class Variable Assignment

See the getting class varialbe and the setting class varialbe.

Array Element Assignment

See "Getting Array Element" and "Setting Array Element".

Field Assignment

See "Getting Field" and "Setting Field".

Special Assignment Operator

A special assignment operator is the alias for the combination of an operator and "Assignment Operator" =.

  LEFT_OPERAND OPERATOR= RIGHTH_OPERAND

Above is the alias for the following code.

  LEFT_OPERAND = (TYPE_OF_LEFT_OPERAND)(LEFT_OPERAND OPERATOR RIGHTH_OPERAND)

For example, See a byte case.

  # Addition assignment operator
  $x += 1;
  
  # Above is the same as the following code.
  $x = (byte)($x + 1)

The following operators are used as the operators of the special assignment operators.

Addition assignment operator +=
Subtraction assignment operator -=
Multiplication assignment operator *=
Division assignment operator /=
Remainder assignment operator %=
Bit AND assignment operator &=
Bit OR assignment operator |=
Left shift assignment operator <<=
Arithmetic right shift assignment operator >>=
Logical right shift assignment operator >>>=
Concatenation assignment operator .=

Examples:

  # Special assignment operators
  $x += 1;
  $x -= 1;
  $x *= 1;
  $x /= 1;
  $x &= 1;
  $x |= 1;
  $x ^= 1;
  $x %= 1;
  $x <<= 1;
  $x >>= 1;
  $x >>>= 1;
  $x .= "abc";

Array Length Operator

The array length operator is an 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 will occur.

The array length operator returns a the int type value that is the length of the "Array".

Array Length Operator returns "Expressions"

Examples:

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

  # Getting the length of the array with a scalar operator. This is exactly same as the avobe
  my $nums = new byte[10];
  my $length = scalar @$nums;
  

Note that SPVM does not have the context different from Perl, and array length operators always return the length of the array.

String Creating 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 operator that type is a "Integral Type" except for a long type, otherwise a compilation error will occur.

The string creation operator returns the string that is created with the lenght.

The return type is a string type.

Examples:

  # 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 operator that type is a object type, otherwise a compilation error will occur.

If the type of operand is none of a string type, a numeric type, a multi-numeric type, An exception is thorwn.

The copy operator returns the copied object.

The return type is the same as the type of operand.

Read-only flag of the string is dropped.

Examples:

  # New a string with the length
  my $message = copy "abc";

is_read_only Operator

The is_read_only is an unary operator to check if the string is read-only.

  is_read_only OPERAND

The operand must be a string type, otherwise a compilation error will occur.

If the string is read-only, the is_read_only operator returns 1, otherwise returns 0.

The return type is an int type.

Examples:

  # New a string with the length
  my $message = "Hello";
  my $is_read_only = is_read_only $message;

String Length Operator

The string length operator length is an unary operator to get the length of the string.

  length OPERAND

The returned length is the byte size. Note that the length is not the count of UTF-8 characters.

The type of the operand must be the string type. Otherwise a compilation error will occur.

The return type is the int type.

Examples:

  # Getting the string length. The length is 5.
  my $message = "Hello";
  my $length = length $message;
  
  # Getting the string length of UTF-8. The length is 9.
  my $message = "あいう";
  my $length = length $message;

scalar Operator

The scalar operator is an Operator that returns the value of the operand.

  scalar OPERAND

The operand must be an "Array Length Operator", otherwise a compilation error will occur.

Examples:

  # Getting the array length 
  my $nums = new int[3];
  foo(scalar @$nums);

  # This is exactlly same as the above.
  my $nums = new int[3];
  foo(@$nums);

Note that the sclara operator exists only to reduce the confusion.

isweak Operator

The isweak operator checks whether the field is weak reference

  isweak OBJECT->{FIELD_NAME};

The type of the object must be the class type, otherwise a compilation error will occur.

If the field name is not found, a compilation error will occur.

The type of the field targetted by the isweak operator is not an object type, a compilation error will occur.

If the field is weaken, the isweak operator returns 1, otherwise returns 0.

The return type of the isweak operator is the int type.

See "Weak Reference" to know the behavior of the isweak operator.

Examples:

  # isweak
  my $isweak = isweak $object->{point};

has_impl Operator

The has_impl operator checks the existence of the method implementation.

  has_impl OPERAND->METHOD_NAME

  has_impl OPERAND

The operand must the object that has a class type or an interface type, otherwise a compilation error will occur.

If the class or the interface doesn't have the method declaration, a compilation error will occur.

The method name must be a method name, otherwise a compilation error will occur.

If method name is not specified, the method name become "".

The return type is int type.

If the class or the interface has the method implementation, returns 1, otherwise returns 0.

Examples:

  my $stringable = (Stringable)Point->new_xy(1, 2);
  
  if (has_impl $stringable->to_string) {
    # ...
  }

Type Cast

The type cast is the operator to perform an explicite type conversion.

  # Type Cast
  (TYPE)OPERAND
  
  # Postfix Type Cast
  OPERAND->(TYPE)

If the type cast doesn't have the castability, a compilation error will occur.

A type cast performs a type conversion, merely copying, or copying with a runtime type checking.

The behavior of type casts are explains in Castability.

Examples:

  # Explicte long to int type conversion
  my $num = (int)123L;

  # Explicte byte[] to string type conversion
  my $num = (string)new byte[3];

  # Explicte string to byte[] type conversion
  my $num = (byte[])"Hello";

  # Postfix type cast
  my $point = Point->new;
  my $stringable = $point->(Stringable);

Getting Local Variable

The getting local variable is an operator to get the value of the local variable.

  $var

The return value is the value of the local variable.

The return type is the type of the local variable.

Setting Local Variable

The setting local variable is an operator to set the value of "Local Variable" using the assignment operator.

  $var = VALUE

The assignment of the value must satisfy the assignability, otherwise a compilation error will occur.

The return value is the value after the assignment.

If the type of the assigned value is an object type, the reference count of the object is incremented by 1.

If an object has already been assigned to $var before the assignment, the reference count of the object is decremented by 1.

See the scope to know the garbage collection of local variables.

Getting Class Variable

The getting class variable is an operator to get the value of the class variable.

  $CLASS_NAME::CLASS_VARIABLE_NAME

CLASS_NAME:: can be omitted if the class variable belongs to the current class.

  $CLASS_VARIABLE_NAME

If the class variable does not found, a compilation error will occur.

If the class variable is private and it is accessed outside of the class, a compilation error will occur.

Examples:

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

Setting Class Variable

Setting Class Variable Expression is an operator to set "Class Variable" Value using the assignment operator.

  $CLASS_NAME::CLASS_VARIABLE_NAME = VALUE

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

  $CLASS_VARIABLE_NAME = VALUE

If the assignment does not satisfy the assignability, a compilation error will occur.

The return value is the value after the setting.

The return type is the type of the class variable.

If the class variable does not found, a compilation error will occur.

If the class variable is private and it is accessed outside of the class, a compilation error will occur.

If the type of the assigned value is an object type, the reference count of the object is incremented by 1.

If an object has already been assigned to $CLASS_VARIABLE_NAME before the assignment, the reference count of the object is decremented by 1.

Examples:

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

Getting Exception Variable

The setting exception variable is an operator to get the value of the exception variable.

  $@

The return value is the value of exception variable.

The return type is the string type.

Examples:

  # Getting the exception variable
  my $message = $@;

Setting Exception Variable

The setting exception variable is an operator to set the value of "Exception Variable" using the assignment operator.

  $@ = VALUE

The type of the assigned value must be "String Type".

The return value is the value after the setting.

The return type is the string type.

The reference count of the assigned value is incremented by 1.

If an string has already been assigned to the exception variable before the assignment, the reference count of the string is decremented by 1.

Examples:

  $@ = "Error";

Getting Field

The getting field is an operator to get the field of the object. This is one syntax of the field access.

  INVOCANT->{FIELD_NAME}

The type of invocant is a class type.

The retrun type is the type of the Field.

Examples:

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

Setting Field

The setting field is an operator to set the field of the object. This is one syntax of the field access.

  INVOCANT->{FIELD_NAME} = VALUE

The type of invocant is a class type.

If the assignment does not satisfy the assignability, a compilation error will occur.

The return value is the value after the setting.

The return type is the field type.

If the type of assigned value is a basic object type, Reference Count of the object is incremented by 1.

If an object has already been assigned to Field before the assignment, the reference count of that object is decremented by 1.

Examples:

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

Getting Multi-Numeric Field

Getting Multi-Numeric Field Expression is an operator to get Field of "Multi-Numeric Value". This is one syntax of the field access.

  INVOCANT->{FIELD_NAME}

Invocant Expression is "Multi-Numeric Type".

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

Getting Multi-Numeric Field Expression returns the field value in the Multi-Numeric Value.

Retrun Type is The "Type" of the Field.

Examples:

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

Setting Multi-Numeric Field

Setting Multi-Numeric Field Expression is an operator to set Field of "Multi-Numeric Value" using "Assignment Operator". This is one syntax of the field access.

  INVOCANT->{FIELD_NAME} = RIGHT_OPERAND

Invocant Expression is "Multi-Numeric Type".

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

Setting Multi-Numeric Field Expression returns the value of the field after setting.

The assignment must satisfy the assignability.

The return type is the field type.

Examples:

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

Getting Array Element

Getting Array Element Expression is an operator to get a Element Value of "Array".

  ARRAY->[INDEX]

Array Expression must be "Array Type".

the index must be the int type or the type that become the int type by "Numeric Widening Type Conversion".

Getting Array Element Expression returns the Element Value of the Index.

If the array is undef, a Runtime Exception occurs.

If the index is less than 0 or more than the max index of the Array, a Runtime Exception occurs.

Examples:

  my $nums = new int[3];
  my $num = $nums->[1];
  
  my $points = new Point[3];
  my $point = $points->[1];
  
  my $objects : object[] = $points;
  my $object = (Point)$objects->[1];

Setting Array Element

Setting Array Element Expression is an operator to set a Element Value of a Array using "Assignment Operator".

  ARRAY->[INDEX] = RIGHT_OPERAND

The array must be "Array Type".

The index must be the int type or the type that become the int type by "Numeric Widening Type Conversion".

The assignment must satisfy the assignability.

Setting Array Element Expression returns the value of the element after setting.

If the array is undef, a Runtime Exception occurs.

If the index is less than 0 or more than the max index of the Array, a Runtime Exception occurs.

If the right operand is an object type, Reference Count of the object is incremented by 1.

If an object has already been assigned to Field before the assignment, the reference count of that object is decremented by 1.

Examples:

  my $nums = new int[3];
  $nums->[1] = 3;
  
  my $points = new Point[3];
  $points->[1] = Point->new(1, 2);
  
  my $objects : object[] = $points;
  $objects->[2] = Point->new(3, 5);

new Operator

The new operator is an operator to create an object or an array.

Creating Object

The creating object is an operator to create an object using the new keyword.

  new CLASS_NAME;

The class name must be the name of the class defined by the class definition.

The fields of the created object are initialized by the rule of initial value.

The reference count of the created object is 0. If the object is assigned to a local variable, a class variable, or a field by "Assignment Operator", the reference count is incremented by 1.

Examples:

  my $object = new Foo;

Creating Array

The creating array is an operator to create an array using the new keyword.

  new BasicType[LENGTH]

The type must be a basic type.

The type of length must be the int type or the type that become int type after the numeric widening type conversion.

If the length is less than 0, an exception is thrown.

All elements of the array are initialized by the rule of initial value.

The type of created array is the array type.

Examples:

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

Multi Dimensional Array

Multi dimensional arrays can be created.

  new BasicType[][LENGTH]
  new BasicType[][]...[LENGTH]

Examples:

  # 2 dimentional int array
  my $nums = new int[][3];
  
  # 3 dimentional int array
  my $nums = new int[][][3];

The max dimention is 255.

Array Initialization

The array initialization is an operator to create an array and initialize the array easily.

  []
  [ELEMENT1, ELEMENT2, ELEMENT3]

The array initialization create an array that has the length of the elements.

And the array is initialized by the elements.

And the created array is returned.

The type of the created array is the type that 1 dimension is added to the type of the first element.

If no element is specified, the type of the create array becomes any object type.

Examples:

  # int array
  my $nums = [1, 2, 3];
  
  # double array
  my $nums = [1.5, 2.6, 3.7];
  
  # string array
  my $strings = ["foo", "bar", "baz"];

The first example is the same as the following codes.

  # int array
  my $nums = new int[3];
  $nums->[0] = 1;
  $nums->[1] = 2;
  $nums->[2] = 3;

The array initialization has another syntax using {}.

  {}
  {ELEMENT1, ELEMENT2, ELEMENT3, ELEMENT4}

This is the same as above array init syntax, but the type of the created array is always "Any Object Array Type" object[].

And if the length of the elements is odd number, a compilation error will occur.

Examples:

  # Key values empty
  my $key_values = {};
  
  # Key values
  my $key_values = {foo => 1, bar => "Hello"};

Method Call

Method calls are "Class Method Call" and "Instance Method Call".

Class Method Call

A method defined as the class method can be called using the class method call.

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

If the number of arguments does not correct, a compilation error will occur.

If the types of arguments have no type compatible, a compilation error will occur.

Examples:

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

Instance Method Call

A method defined as the instance method can be called using the instance method call.

  Object->MethodName(ARGS1, ARGS2, ...);

If the number of arguments does not correct, a compilation error will occur.

If the types of arguments have no type compatible, a compilation error will occur.

Examples:

  $object->bar(5, 3. 6);

SUPER:: qualifier call the method of the super class.

  $object->SUPER::bar(5, 3. 6);

A instance method can be called statically by specifing the calss name.

  $point3d->Point::clear;

Current Class

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

Examples:

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

Reference Operator

The reference operator \ is the operator to create a reference.

  \ OPERAND

The operand must be a local variable that type is a numeric type or a multi-numeric type. Otherwise a compilation error will occur.

The return type is the reference type of the operand.

Examples:

  # Create the reference of a numeric type
  my $num : int;
  my $num_ref : int* = \$num;
  
  # Create the reference of a multi-numeric type
  my $z : Complex_2d;
  my $z_ref : Complex_2d* = \$z;

Dereference Operator

The dereference operators are the operatoers to perform a deference.

Getting value by Dereference

Obtaining a value by Dereference is an operation to obtain the actual value from Reference. It was designed to realize the C joint operator *.

  $ VARIABLE

The variable Type must be Reference Type, otherwise a compilation error will occur.

The value obtained by Dereference returns "Expressions".

    B<Example of getting value by Dereference>

  my $num : int;
  my $num_ref : int* = \$num;
  my $num_deref : int = $$num_ref;
  
  my $z : Complex_2d;
  my $z_ref : Complex_2d* = \$z;
  my $z_deref : Complex_2d = $$z_ref;

Setting the value with Dereference

Setting a value with Dereference is an operation to set the actual value from Reference. It was designed to realize the C joint operator *.

  $ VARIABLE = OPERAND

The variable Type must be Reference Type, otherwise a compilation error will occur.

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

Setting a value with Dereference returns the set value. This is "Expressions".

    B<Example of setting values ​​with Dereference>

  my $num : int;
  my $num_ref : int* = \$num;
  $$num_ref = 1;
  
  my $z : Complex_2d;
  my $z_ref : Complex_2d* = \$z;
  
  my $z2 : Complex_2d;
  
  $$z_ref = $z2;

Getting Multi-Numeric Field via Dereference

Getting Multi-Numeric Field via Dereference Expression is an operator to get Field of "Multi-Numeric Value" via "Dereference". This is one syntax of the field access

  INVOCANT->{FIELD_NAME}

Invocant Expression is "Multi-Numeric Reference Type".

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

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

Retrun Type is The "Type" of the Field.

Examples:

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

Setting Multi-Numeric Field via Dereference

Setting Multi-Numeric Field Expression via Dereference is an operator to set Field of "Multi-Numeric Value" via "Dereference" using "Assignment Operator". This is one syntax of the field access.

  INVOCANT->{FIELD_NAME} = RIGHT_OPERAND

Invocant Expression is "Multi-Numeric Reference Type".

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

Setting Multi-Numeric Field via Dereference Expression returns the value of the field after setting.

The assignment must satisfy the assignability.

The return type is the field type.

Examples:

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

Getting Current Class Name

The getting current class name __CLASS__ is an operator to get the current class name.

  __CLASS__

Examples:

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

Getting Current File Name

The getting current file name __FILE__ is an operator to get the current file name.

  __FILE__

Current File Name means the relative path from the base path of the module file. For example, if the Module Loaded Path is "/mypath" and the Module name is "Foo::Bar", the absolute path is "/mypath/SPVM/Foo/Bar.spvm" and the relative path is "SPVM/Foo/Bar.spvm". "SPVM/Foo/Bar.spvm" is Current File Name.

Examples:

  # SPVM/Foo/Bar.spvm
  class Foo::Bar {
    static method baz : void () {
      # Get the current file name - SPVM/Foo/Bar.spvm
      my $file_name == __FILE__;
    }
  }
  class Foo::Bar2 {
    static method baz : void () {
      # Get the current file name - SPVM/Foo/Bar.spvm
      my $file_name == __FILE__;
    }
  }

Getting Current Line Number

The getting current line number __LINE__ is an operator to get the current line number of the current file.

  __LINE__

Examples:

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

Anon Method

The anon method is an operator to define an anon calss and define an instance method that has 0-length name and create the object by the new operator.

  method : TYPE_NAME  (ARGS1 : TYPE1, ARGS2 : TYPE2, ...) {
  
  }

Examples:

  # Anon method
  class Foo::Bar {
    method some_method : void () {
      my $comparator = (Comparator)method : int ($x1 : object, $x2 : object) {
        my $point1 = (Point)$x1;
        my $point2 = (Point)$x2;
        
        return $point1->x <=> $point2->x;
      };
    }
  }

See also Comparator.

The above example is the same as the following codes.

  class Foo::Bar {
    method some_method : void () {
      my $comparator = (Comparator)new Foo::Bar::anon::3::31;
    }
  }

  class Foo::Bar::anon::3::31 : public {
    method : int ($x1 : object, $x2 : object) {
      my $point1 = (Point)$x1;
      my $point2 = (Point)$x2;
      
      return $point1->x <=> $point2->x;
    }
  }

Capture

The capture is a syntax to pass local variables to an anon method.

  # Capture
  [VAR_NAME1 : Type1, VAR_NAME2 : Type2] method METHOD_NAME : int ($x1 : object, $x2 : object) {
  
  };

Examples:

  class Foo::Bar {
    method some_method : void () {
      my $foo = 1;
      my $bar = 5L;
      my $comparator = (Comparator)[$foo : int, $bar : long] method : int ($x1 : object, $x2 : object) {
        print "$foo\n";
        print "$bar\n";
      };
    }
  }

A capture is actually implemented as a field.

The above example is the same as the following codes.

  class Foo::Bar {
    method some_method : void () {
      my $foo = 1;
      my $bar = 5L;
      
      my $anon = new Foo::Bar::anon::5::61;
      $anon->{foo} = $foo;
      $anon->{bar} = $bar;
      my $comparator = (Comparator)$anon;
    }
  }

  class Foo::Bar::anon::5::61 : public {
    has foo : public int;
    has bar : public long;
    
    method : int ($x1 : object, $x2 : object) {
      print "$self->{foo}\n";
      print "$self->{bar}\n";
    }
  }

class_id Operator

The class_id operator is an operator to get the class id from a class name.

  class_id CLASS_NAME

The class name must be an existing class. Otherwise a compilation error occur.

The return value is the class id.

The return type is the int type.

error_code

The error_code is an operator to get the value of the error code.

  error_code

set_error_code

The set_error_code operator is an operator to set the value of the error code.

  set_error_code OPERAND

The type of the operand must be the int type.

error

The error operatoer is an operator to get the current error code.

  error

This value is set to 0 at the beginning of the eval block.

If A exception is catched, the current error code is set to the value of error_code.

Exception

Explains exceptions.

Throwing Exception

You can throw an exception using the die statement.

  die OPERAND;

Examples:

  # Throw an exception
  die "Error";

Exception Catching

You can catch an exception using an eval block.

  eval {
    die "Error";
  };

The undef is set to the exception variable $@ at the top of the eval block.

The error message is set to the exception variable $@ when the exception is thrown.

Examples:

  # Catch the exception
  eval {
    # Throw an exception
    die "Error";
  };
  
  # Check the error message
  if ($@) {
    # ...
  }

Exception Variable

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

  $@

See the setting class varialbe to get Exception Variable Value.

See "Setting Exception Variable" to set Exception Variable Value.

Garbage Collection

The object is destroyed when the reference count becomes 0.

If the object is an Array that has Object Type values ​​as elements, the reference count of all Array elements that are not Undefined Value is decremented by 1 before Garbage Collection

When an object is a class type and has a field of Object Type, the reference count of the objects owned by all Fields of Object Type that are not Undefined Value is decremented by 1 before Garbage Collection. If Weak Reference is set to the object saved in Field, Weak Reference is destroyed before Reference Count is decremented by 1.

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

The above process is done recursively.

Weak Reference

Weak Reference is a reference that does not increase the reference count. Weak Reference can be used to solve the problem of circular references.

SPVM has GC of Reference Count Type. In the GC of Reference Count Type, the object is automatically destroyed when the reference count becomes 0, but when the circular reference occurs, the reference count does not become 0 and the object is automatically destroyed. not.

This is an Example when the Field of the object is circularly referenced.

  {
    my $foo = new Foo;
    my $bar = new Bar;
  
    $foo->{bar} = $bar;
    $bar->{foo} = $foo;
  }

In this case, both objects are not destroyed when the Scope ends. This is because a circular reference has occurred and the reference count does not become 0.

Weak Reference is a function to correctly destroy objects when a circular reference occurs in a programming language that has a Reference Count GC.

In such a case, it is possible to release correctly by setting one Field to Weak Reference using "weaken Statement".

  {
    my $foo = new Foo;
    my $bar = new Bar;
  
    $foo->{bar} = $bar;
    $bar->{foo} = $foo;
  
    weaken $foo->{bar};
  }

Before the weaken statement is executed, $foo has a Reference Count of 2 and $bar has a Reference Count of 2.

If there is no weaken statement, the reference count of $foo and the reference count of $bar will not be 0 and will not be destroyed 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 destroyed correctly.

Even if there are 3 circular references, you can release them correctly by setting Weak Reference in 1 Field.

  {
    my $foo = new Foo;
    my $bar = new Bar;
    my $baz = new Baz;
  
    $foo->{bar} = $bar;
    $bar->{baz} = $baz;
    $baz->{foo} = $foo;
  
    weaken $foo->{bar};
  }

As a syntax related to Weak Reference, Weak Reference can be destroyed "weaken Statement", and it can be confirmed whether Field is Weak Reference the isweak operator.

See Also

Examples

You can see more examples in the following test codes.

Examples of SPVM