=head1 Name

SPVM::Document::Language::Class - Classes in the SPVM Language

=head1 Description

This document describes classes.

=head1 Class

The SPVM language is an object-oriented programing language and has class syntax.

This section describes class syntax.

See L<SPVM::Document::Language::SyntaxParsing> about the grammer of the SPVM language.

=head2 Class Definition

The C<class> keyword defines a L<class type|SPVM::Document::Language::Types/"Class Types">.
  
  class CLASS_NAME {
  
  }
  
  class CLASS_NAME;
  
  class CLASS_NAME : ATTRIBUTES {
  
  }
  
  class CLASS_NAME : ATTRIBUTES;

I<CLASS_NAME> is a L<class name|SPVM::Document::Language::Tokenization/"Class Name">.

I<ATTRIBUTES> is one of
  
  ATTRIBUTES ATTRIBUTE
  ATTRIBUTE

I<ATTRIBUTE> is a L<class attributre|"Class Attributes">.

A class type is also simply called a class.

The L<new operator|/"new Operator"> creates an object from a class.

Compilation Errors:

I<CLASS_NAME> must be a L<class name|SPVM::Document::Language::Tokenization/"Class Name">. Otherwise, a compilation error occurs.

If more than one class is defined in a L<class file|/"Class File">, a compilation error occurs.

Examples:

  # Examepls of class definitions
  class Point {
  
  }

=head2 Class Attributes

The List of Class Attributes:

=begin html

<table>
  <tr>
    <th>
      Class Attributes
   </th>
    <th>
      Descriptions
   </th>
  </tr>
  <tr>
    <td>
      <b>public</b>
    </td>
    <td>
      This class is public. All classes are able to create an object of this class using the <a href="https://metacpan.org/pod/SPVM::Document::Language::Operators#new-Operator">new operator</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>private</b>
    </td>
    <td>
      This class is private. Classes other than this class are not able to create an object of this class using the <a href="https://metacpan.org/pod/SPVM::Document::Language::Operators#new-Operator">new operator</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>protected</b>
    </td>
    <td>
      This class is protected. Only this class and its child classes are able to create an object of this class using the <a href="https://metacpan.org/pod/SPVM::Document::Language::Operators#new-Operator">new operator</a>. This is default.
    </td>
  </tr>
  <tr>
    <td>
      <b>interface_t</b>
    </td>
    <td>
      This class is an <a href="https://metacpan.org/pod/SPVM::Document::Language::Types#Interface-Types">interface type</a>. The class definition with this attribute is interpreted as an <a href="#Interface-Definition">interface definiton</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>mulnum_t</b>
    </td>
    <td>
      This class is a <a href="https://metacpan.org/pod/SPVM::Document::Language::Types#Multi-Numeric-Types">multi-numeric type</a>. The class definition with this attribute is interpreted as an <a href="#Multi-Numeric-Type-Definition">multi-numeric type definiton</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>pointer</b>
    </td>
    <td>
      The class is a <a href="#Pointer-Class">pointer class</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>precompile</b>
    </td>
    <td>
      The <code>precompile</code> method attribute of all methods other than <code>INIT</code> method, methods generated by enumuration values, and methods that does not have their method block is specified.
    </td>
  </tr>
</table>

=end html

Compilation Errors:

Only one of C<private>, C<protected> or C<public> must be specified. Otherwise, a compilation error occurs.

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

Examples:

  # Examples of class attributes
  class Point : public {
  
  }
  
  class Point : public pointer {
  
  }

=head3 Pointer Class

The pointer class is a class with the C<pointer> L<class attribute|/"Class Attributes"> .

  class CLASS_NAME : pointer {
  
  }

An object of a pointer class has the pointer to a native address that is normally a pointer to a C language struct, or a C++ language struct or class.

Examples:

  # Examples of the pointer attribute
  class Foo : pointer {
  
  }

=head2 Class File

A class file is a file where a class is defined.

The name of a class file is the same as a class name, but all C<::> are replaced to C</> and C<.spvm> is added at the end of it.
  
  # Foo
  Foo.spvm
  
  # Foo::Bar
  Foo/Bar.spvm
  
  # Foo::Bar::Baz
  Foo/Bar/Baz.spvm

Compilation Errors:

A class definition must be written in its corresponding class file. Otherwise, a compilation error occurs.

=head2 version Statement

The C<version> statement declares the version of a class.

  version VERSION_STRING;

This statement declares the version of a class given L<version string|/"Version String"> I<VERSION_STRING>.

Compilation Errors:

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

I<VERSION_STRING> must be a L<version string|/"Version String">. Otherwise, a compilation error occurs.

Examples:
  
  class MyClass {
    version "1.001";
  }
  
  class MyClass {
    version "10.001003";
  }

=head3 Version String

The version string is the string that represents L<version|/"version Statement"> of a class.

A version string must be written by the following rules.

The type of a version string is string type.

It consists of C<0-9>, C<.>. 

The count of C<.> is less than or equal to 1.

It begins with C<0-9>.

It ends with C<0-9>.

The count of C<0-9> after C<.> is divisible by 3.

It is able to be parsed by the C<strtod> function in the C language.

Complication Errors:

If a version string is not valid, a compilation error occurs.

Examples:
  
  # Examples of version strings
  "1.001"
  "10.001003"
  "1"
  "10000"

=head3 Version Number

A version number is a floating point number created from a L<version string|/"Version String"> using the C<strtod> function in the C language.

Examples:

  # Examples of version numbers
  
  # "1.001"
  1.001
  
  # "10.001003"
  10.001003

=head2 version_from Statement

The C<version_from> statement allows you to make the version of the current class dependent on another class.

  version_from CLASS_NAME;

I<CLASS_NAME> is a L<class name|SPVM::Document::Language::Tokenization/"Class Name">.

It means the version of the current class is considered to be the same as the version of the class specified by I<CLASS_NAME>.

The class specified by I<CLASS_NAME> is loaded by L<use statement|/"use Statement">.

Compilation Errors:

If version_from has already been declared, a compilation error occurs.

Examples:
  
  class MyClass::Foo {
    version_from MyClass;
  }
  
  class MyClass {
    version "1.001";
  }

=head2 use Statement

The C<use> statemenet loads a class.

  use BASIC_TYPE;
  use BASIC_TYPE as CLASS_NAME;

This statement searches for the type I<BASIC_TYPE> in L<class search directories|/"Class Search Directories"> from the beginning, and if found, loads the type.

I<BASIC_TYPE> is a L<class type|SPVM::Document::Language::Types/"Class Types">, an L<interface type|SPVM::Document::Language::Types/"Interface Types">, or a L<multi-numeric type|SPVM::Document::Language::Types/"Multi-Numeric Types">.

See L<require statement|SPVM::Document::Language::Statements/"require Statement"> about how to load a type without causing a compile error when loading fails,

The follwoing C<use> statement with C<as>

  use BASIC_TYPE as CLASS_NAME;

is expanded to the following code using L<alias|/"alias Statement"> statement.

  use BASIC_TYPE;
  alias BASIC_TYPE as CLASS_NAME

Compilation Errors:

I<BASIC_TYPE> must be a L<class name|SPVM::Document::Language::Tokenization/"Class Name">. Otherwise, a compilation error occurs.

I<CLASS_NAME> must be a L<class name|SPVM::Document::Language::Tokenization/"Class Name">. Otherwise, a compilation error occurs.

If I<BASIC_TYPE> does not found, a compilation error occurs.

Examples:

  # Examples of use statement
  class MyClass {
    use Foo;
  }
  
  class MyClass {
    use Sys::Socket::Constant as SOCKET;
  }

=head2 Class Search Directories

Class search directories are directories in which classes are searched for.

These are set outside the program.

Directories set by C<-I> option of L<spvm> command and L<spvmcc> command are added to class search directories.

And directories with C</SPVM> added to the end of each value of Perl's L<@INC|https://perldoc.perl.org/perlvar#@INC> are added to the end of the class search directories.

=head3 Default Loaded Classes

The following classes are loaded by default. 

=over 2

=item * L<Byte|SPVM::Byte>

=item * L<Short|SPVM::Short>

=item * L<Int|SPVM::Int>

=item * L<Long|SPVM::Long>

=item * L<Float|SPVM::Float>

=item * L<Double|SPVM::Double>

=item * L<Bool|SPVM::Bool>

=item * L<Error|SPVM::Error>

=item * L<Error::System|SPVM::Error::System>

=item * L<Error::NotSupported|SPVM::Error::NotSupported>

=item * L<Error::Compile|SPVM::Error::Compile>

=item * L<CommandInfo|SPVM::CommandInfo>

=item * L<Address|SPVM::Address>

=item * L<Error::Compile|SPVM::Error::Compile>

=item * L<SPVM|SPVM::SPVM>

=item * L<Error::MethodCallNotPermitted|SPVM::Error::MethodCallNotPermitted>

=item * L<Stringable|SPVM::Stringable>

=item * L<Countable|SPVM::Countable>

=item * L<CallerInfo|SPVM::CallerInfo>

=item * L<Cloneable|SPVM::Cloneable>

=back

=head2 alias Statement

The C<alias> statemenet creates an class alias name for a type.
  
  alias BASIC_TYPE as CLASS_NAME;

This statemenet creates an class alias name I<CLASS_NAME> for a type I<BASIC_TYPE>.

I<BASIC_TYPE> is a L<class type|SPVM::Document::Language::Types/"Class Types">, an L<interface type|SPVM::Document::Language::Types/"Interface Types">, or a L<multi-numeric type|SPVM::Document::Language::Types/"Multi-Numeric Types">.

Compilation Errors:

I<BASIC_TYPE> must be a L<class name|SPVM::Document::Language::Tokenization/"Class Name">. Otherwise, a compilation error occurs.

I<CLASS_NAME> must be a L<class name|SPVM::Document::Language::Tokenization/"Class Name">. Otherwise, a compilation error occurs.

Examples:

  class MyClass {
    use Sys::Socket::Constant;
    alias Sys::Socket::Constant as SOCKET;
    
    SOCKET->AF_INET;
  }

=head2 allow Statement

The C<allow> statemenet allows a type private accesses to the current class.

  allow BASIC_TYPE;

By default, objects of private classes cannot be created by L<new operator|/"new Operator"> from other classes.

And private methods, private fields, and private class variables cannot be accessed from other classes.

This statement allows the type I<BASIC_TYPE> private accesses to the current class.

I<BASIC_TYPE> is loaded by L<use statement|/"use Statement">.

Examples:

  # Allowing private access
  class MyClass {
    allow SomeClass;
  }

=head2 Inheritance

A class inherits a class using the C<extends> keyword.

  class CLASS_NAME extends PARENT_CLASS_NAME {
    
  }

The class I<CLASS_NAME> that inherits the parent class I<PARENT_CLASS_NAME> is defined.

The field definitions of the parent class I<PARENT_CLASS_NAME> are added to the end of the field definitions of the class I<CLASS_NAME> to the end of its fields.

The L<interface statements|/"interface Statement"> of the parent class I<PARENT_CLASS_NAME> are added to the end of L<interface statements|/"interface Statement"> of the class I<CLASS_NAME>.

The instance of the class I<CLASS_NAME> can calls instance methods of the parent class I<PARENT_CLASS_NAME> and its super classes.

Compilation Errors:

The parent class I<PARENT_CLASS_NAME> must be a L<class type|SPVM::Document::Language::Types/"Class Types">. Otherwise, a compilation error occurs.

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

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

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

The class I<CLASS_NAME> interpreted by an interface must satisfy L<interface requirement|SPVM::Document::Language::Types/"Interface Requirement"> to the parent class I<PARENT_CLASS_NAME>. Otherwise, a compilation error occurs.

Examples:

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

=head2 Interface

This section describes interfaces.

=head3 Interface Definition

A L<class definition|/"Class Definition"> with the C<interface_t> L<class attribute|/"Class Attributes"> defines an L<interface type|SPVM::Document::Language::Types/"Interface Types">.

  class CLASS_NAME : interface_t {
    
  }

An interface type is also simply called an interface.

Objects cannot be created from interface types.

Normally, an interface has L<interface methods|/"Interface Method">.

Compilation Errors:

An interface cannnot have L<field definitions|/"Field Definition">. If so, a compilation error occurs.

An interface cannnot have L<class variable definitions|/"Class Variable Definition">. If so, a compilation error occurs.

Examples:

  # Examples of interface definitions
  class TestCase::Pointable : interface_t {
    interface Stringable;
    
    method x : int ();
    method y : int();
    method to_string : string ();
  }
  
  class Stringable: interface_t {
    method to_string : string ();
    method call_to_string : string () {
      return "foo " . $self->to_string;
    }
  }

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

=head3 interface Statement

The C<interface> statement checks if the current class satisfies L<interface requirement|SPVM::Document::Language::Types/"Interface Requirement"> to an interface.

  interface BASIC_TYPE;

I<BASIC_TYPE> is loaded by L<use statement|/"use Statement">.

Compilation Errors:

The interface type I<BASIC_TYPE> must be an L<interface type|SPVM::Document::Language::Types/"Interface Types">, ohterwise a compilation error occurs.

The current class must satisfy L<interface requirement|SPVM::Document::Language::Types/"Interface Requirement"> to the interface type I<BASIC_TYPE>, ohterwise a compilation error occurs.

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

=head2 Anon Class

An anon class is a class without specifying its class name.

=head3 Anon Class Definition

An anon class is defined by the following syntax.

  class {
  
  }

An anon class cannot be defined in a L<class file|Class File>. It is able to be defined in a source code compiled by L<compile_anon_class|SPVM::Document::NativeAPI::Compiler/"compile_anon_class"> compiler native API.

An anon class has its L<class name|SPVM::Document::Language::Tokenization/"Class Name">, such as C<eval::anon_class::0>, C<eval::anon_class::1>, C<eval::anon_class::2>.

  eval::anon_class::123

L<Examples:>
  
  # Examples of the anon class definition
  class {
    static method sum : int ($num1 : int, $num2 : int) {
      return $num1 + $num2;
    }
  }

=head2 Anon Method Class

An anon method class is a class defined by an L<anon method operator|SPVM::Document::Language::Operators/"Anon Method Operator">.

=head3 Anon Method Class Definition

The anon method class definition has the following syntax.

  ANON_METHOD_CLASS_FIELD_DEFINITION METHOD_DEFINITION

I<ANON_METHOD_CLASS_FIELD_DEFINITION> is an L<anon method class field definition|/"Anon Method Class Field Definition">.

I<METHOD_DEFINITION> is a L<method definition|/"Method Definition">.

The anon method class definition defines a class to which this method belongs.

The name of this class is a string that joins L<outmost class|/"Outmost Class">, a string C<"anon_method">, the line number and the position of columns where an anon method class definition is written with C<::>.

  MyClass::anon_method::3::23

An anon method class has the same access control as its outmost class.

An anon method class has the same alias names as its outmost class.

Compilation Errors:

The method name of I<METHOD_DEFINITION> must be an empty string. Otherwise, a compilation error occurs.

The method must be an instance method. Otherwise, a compilation error occurs.

Examples:
  
  # Examples of the anon method definition
  class Foo::Bar {
    method my_method : void () {
      my $comparator = (Comparator)method : int ($x1 : object, $x2 : object) {
        my $point1 = (Point)$x1;
        my $point2 = (Point)$x2;
        
        return $point1->x <=> $point2->x;
      };
    }
  }

=head4 Anon Method Class Field Definition

An anon method class field definition defines fields of an L<anon class|/"Anon Class">, which is a part of L<anon method class definition|Anon Method Class Definition>.
  
  [ANON_METHOD_CLASS_FIELD_DEFINITION_ITEM1, ANON_METHOD_CLASS_FIELD_DEFINITION_ITEM, ANON_METHOD_CLASS_FIELD_DEFINITION_ITEMn]

I<ANON_METHOD_CLASS_FIELD_DEFINITION_ITEM> are one of
  
  has FIELD_NAME : TYPE
  has FIELD_NAME : TYPE = OPERAND
  VAR : TYPE
  VAR : TYPE = OPERAND
  
  has FIELD_NAME : ATTRIBUTE1 ATTRIBUTE2 ATTRIBUTEn TYPE
  has FIELD_NAME : ATTRIBUTE1 ATTRIBUTE2 ATTRIBUTEn TYPE = OPERAND
  VAR : ATTRIBUTE1 ATTRIBUTE2 ATTRIBUTEn TYPE
  VAR : ATTRIBUTE1 ATTRIBUTE2 ATTRIBUTEn TYPE = OPERAND

I<FIELD_NAME> is a L<field name|SPVM::Document::Language::Tokenization/"Field Name">.

I<TYPE> is a L<type|SPVM::Document::Language::Types/"Types">.

I<OPERAND> is an L<operator|SPVM::Document::Language::Operators/"Operators">.

C<VAR : TYPE = OPERAND> is expaneded to C<has FIELD_NAME : TYPE = OPERAND>. I<FIELD_NAME> is the same as the name of I<VAR>, but C<$> is removed. I<VAR> is declared at the top of this anon method and set to the value of its corresponding field.

C<VAR : TYPE> is the same as above, but expaneded to C<has FIELD_NAME : TYPE = VAR>.

I<ATTRIBUTE> is a L<field attribute|/"Field Attributes">.

Compilation Errors:

Compilation errors caused by L<Field Definition|/"Field Definition"> could occur.

Examples:
  
  # Examples of the anon method class field definition
  class Foo::Bar {
    method my_method : void () {
      my $foo = 1;
      my $bar = 5L;
      
      my $comparator = (Comparator)[has foo : int = $foo, has bar : long = $bar] method : int ($x1 : object, $x2 : object) {
        my $foo = $self->{foo};
        my $bar = $self->{bar};
        
        say "$foo";
        say "$bar";
      };
    }
  }
  
  # More simple
  class Foo::Bar {
    method my_method : void () {
      my $foo = 1;
      my $bar = 5L;
      
      my $comparator = (Comparator)[$foo : int, $bar : long] method : int ($x1 : object, $x2 : object) {
        say "$foo";
        say "$bar";
      };
    }
  }

  # Change variable names
  class Foo::Bar {
    method my_method : void () {
      my $foo = 1;
      my $bar = 5L;
      
      my $comparator = (Comparator)[$foo_x : int = $foo, $bar_x : long = $bar] method : int ($x1 : object, $x2 : object) {
        say "$foo_x";
        say "$bar_x";
      };
    }
  }

=head2 Outmost Class

An outmost class is the outmost defined class. This is the same as the class defined by L<class definition|/"Class Definition">.

  class OutmostClass {
    
  }

Examples:
  
  # Examples of the outmost class
  class MyClass {
    static method my_method : void () {
      
      # The __PACKAGE__ operator returns the outmost class "MyClass".
      my $outmost_class_name = __PACKAGE__;
      
      # Anon method
      my $cb = method : void () {
        
        # The __PACKAGE__ operator returns the outmost class "MyClass".
        my $outmost_class_name = __PACKAGE__;
      };
    }
  }

=head2 Multi-Numeric Type Definition

A L<multi-numeric type|SPVM::Document::Language::Types/"Multi-Numeric Types"> is defined by L<class definition|/"Class Definition"> with the C<mulnum_t> L<class attribute|/"Class Attributes">.

  class CLASS_NAME : mulnum_t {
    
    has FIELD_NAME1 : NUMERIC_TYPE;
    has FIELD_NAME2 : NUMERIC_TYPE;
    has FIELD_NAMEn : NUMERIC_TYPE;
  }

A multi-numeric field must have at least one fields. The type of a field must be a numeric type. The types of all fields must be same.

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

I<CLASS_NAME> must ends with a L<multi-numeric type suffix|/"Multi-Numeric Type Suffix"> corresponding to the type of fields. 

I<FIELD_LENGTH> of L<multi-numeric type suffix|/"Multi-Numeric Type Suffix"> must be the same as the length of fields.

I<TYPE_SUFFIX> of L<multi-numeric type suffix|/"Multi-Numeric Type Suffix"> must correspond to the type of fields.

A multi-numeric type cannnot have instance methods.

A multi-numeric type cannnot have class variables.

Compilation Errors:

If the difinition of multi-numeric type is invalid, a compilation error occurs.

Examples:
  
  # Examples of the multi-numeric type definition
  class Complex_2f : mulnum_t {
    re : float;
    im : float;
  }
  
  class Complex_2d : mulnum_t {
    re : double;
    im : double;
  }
  
  class Quaternion_4f : mulnum_t {
    re : float;
    i : float;
    j : float;
    k : float;
  }
  
  class Quaternion_4d : mulnum_t {
    re : double;
    i : double;
    j : double;
    k : double;
  }

=head3 Multi-Numeric Type Suffix

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

  _(non-spaces)FIELD_LENGTH(non-spaces)TYPE_SUFFIX

I<FIELD_LENGTH> is the length of fields.

I<TYPE_SUFFIX> is a type suffix.

The List of Type Suffixes:

=begin html

<table>
  <tr>
    <th>
      Numeric Types
   </th>
    <th>
     Type Suffixes
   </th>
  </tr>
  <tr>
    <td>
      <b>byte</b>
    </td>
    <td>
      b
    </td>
  </tr>
  <tr>
    <td>
      <b>short</b>
    </td>
    <td>
      s
    </td>
  </tr>
  <tr>
    <td>
      <b>int</b>
    </td>
    <td>
      i
    </td>
  </tr>
  <tr>
    <td>
      <b>long</b>
    </td>
    <td>
      l
    </td>
  </tr>
  <tr>
    <td>
      <b>float</b>
    </td>
    <td>
      f
    </td>
  </tr>
  <tr>
    <td>
      <b>double</b>
    </td>
    <td>
      d
    </td>
  </tr>
</table>

=end html

Examples:
  
  # Examples of the multi-numeric type suffix
  _2f;
  _2d;
  _4f;
  _4d;

=head1 Enumeration

Enumeration is a syntax that defines 32-bit integers that belongs to a L<class|/"Class">.

=head2 Enumeration Definition

The C<enum> keyword defines an enumeration.

  enum {
    ITEM1,
    ITEM2,
    ITEMn
  }

C<,> after the last enumeration item is allowed.

  enum {
    ITEM1,
    ITEM2,
    ITEM3,
  }

I<ITEM> is one of

  NAME
  NAME = VALUE

I<NAME> is a L<method name|SPVM::Document::Language::Tokenization/"Method Name">.

I<VALUE> is an L<integer literal|SPVM::Document::Language::Tokenization/"Integer Literals"> within int type. I<VALUE> is converted the value of int type.

If I<VALUE> of I<ITEM1> is omitted, it is set to 0.

If I<VALUE> of I<ITEMn> is ommited, it is set to the value of the previous item plus 1.

The return type of the method is int type.

Every enumeration item is converted to a L<method definition|/"Method Definition"> that defines a class method that returns the value of the enumeration item.

  # Definition of an enumeration
  class MyClass {
    enum {
      NAME = 5,
    }
  }
  
  # This are replaced with a definition of a class method
  class MyClass {
    static method NAME : int () { return 5; }
  }

See also L</"Inline Expansion of Method Call to Get an Enuemration Value">.

Compilation Errors:

I<NAME> must be a L<method name|SPVM::Document::Language::Tokenization/"Method Name">. Otherwise, a compilation error occurs.

I<VALUE> must be an L<integer literal|/"Integer Literal"> within int type. Otherwise, a compilation error occurs.

Examples:
  
  # Examples of enumerations
  class MyClass {
    enum {
      FLAG1,
      FLAG2,
      FLAG3,
    }
    
    static method main : void () {
      my $flag1 = MyClass->FLAG1;
    }
  }
  
  class MyClass {
    enum {
      FLAG1,
      FLAG2 = 2,
      FLAG3,
    }
  }

=head2 Enumeration Attributes

The List of Enumeration Attributes:

=begin html

<table>
  <tr>
    <th>
      Attributes
   </th>
    <th>
      Descriptions
   </th>
  </tr>
  <tr>
    <td>
      <b>public</b>
    </td>
    <td>
      This enumeration is public. All classes can access all items of this enumeration. This is default.
    </td>
  </tr>
  <tr>
    <td>
      <b>private</b>
    </td>
    <td>
      This enumeration is private. All classes ohter than this class cannnot access all items of this enumeration.
    </td>
  </tr>
  <tr>
    <td>
      <b>protected</b>
    </td>
    <td>
      This enumeration is protected. All classes ohter than this class and its child classes cannot access all items of this enumeration.
    </td>
  </tr>
</table>

=end html

Compilation Errors:

One of C<private>, C<protected> and C<public> must be specified. Otherwise, a compilation error occurs.

=head1 Class Variable

A class variable is a global variable that belongs to a L<class|/"Class">.

=head2 Class Variable Definition

C<our> keyword defines a class variable.

  our CLASS_VARIABLE_NAME : OPT_ATTRIBUTES TYPE;

I<CLASS_VARIABLE_NAME> is a L<class variable name|SPVM::Document::Language::Tokenization/"Class Variable Name"> that does not contains C<::>.

I<TYPE> is a L<type|SPVM::Document::Language::Types/"Types">.

I<OPT_ATTRIBUTES> is one of

  EMPTY
  ATTRIBUTES

I<EMPTY> means nothing exists.

I<ATTRIBUTES> is one of
  
  ATTRIBUTES ATTRIBUTE
  ATTRIBUTE

I<ATTRIBUTE> is a L<class variable attribute|/"Class Variable Attributes">.

Each class variable is initialized by its L<type initial value|SPVM::Document::Language::Types/"Type Initial Value">.

The value of a class variable is got by the operation of L<getting a class variable|SPVM::Document::Language::Operators/"Class Variable Get Operation">.

The value of a class variable is set by the operation of L<setting a class variable|SPVM::Document::Language::Operators/"Class Variable Set Operation">.

Compilation Errors:

I<CLASS_VARIABLE_NAME> must a L<class variable name|SPVM::Document::Language::Tokenization/"Class Variable Name"> that does not contains C<::>. Otherwise, a compilation error occurs.

I<TYPE> must be a L<numeric type|SPVM::Document::Language::Types/"Numeric Types"> or an L<object type|SPVM::Document::Language::Types/"Object Types">.

I<ATTRIBUTE> must be a L<class variable attribute|/"Class Variable Attributes">. Otherwise, a compilation error occurs.

If two or more class variables that has a same name are defined, a compilation error occurs.

Examples:

  class MyClass {
    our $NUM_BYTE : byte;
    our $NUM_SHORT : short;
    our $NUM_INT : int;
    our $NUM_LONG : long;
    our $NUM_FLOAT : float;
    our $NUM_DOUBLE : double;
    our $POINT : Point;
    
    our $NUM_PUBLIC : public int;
    our $NUM_RO : ro int;
    our $NUM_RW : rw int;
  }

=head2 Class Variable Attributes

The List of Class Variable Attributes:

=begin html

<table>
  <tr>
    <th>
      Class Variable Attributes
   </th>
    <th>
      Descriptions
   </th>
  </tr>
  <tr>
    <td>
      <b>public</b>
    </td>
    <td>
      This class variable is public. All classes can access this class variable.
    </td>
  </tr>
  <tr>
    <td>
      <b>private</b>
    </td>
    <td>
      This class variable is private. All classes ohter than this class cannnot access this class variable.
    </td>
  </tr>
  <tr>
    <td>
      <b>protected</b>
    </td>
    <td>
      This class variable is protected. All classes ohter than this class and its child classes cannot access this class variable. This is default.
    </td>
  </tr>
  <tr>
    <td>
      <b>ro</b>
    </td>
    <td>
      This class variable defines a <a href="#Class-Variable-Getter-Method">getter method</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>wo</b>
    </td>
    <td>
      This class variable defineds a <a href="#Class-Variable-Setter-Method">setter method</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>rw</b>
    </td>
    <td>
      This class variable defines a <a href="#Class-Variable-Getter-Method">getter method</a> and a <a href="#Class-Variable-Setter-Method">setter method</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>cache</b>
    </td>
    <td>
      This class variable is used for cache in runtime.
    </td>
  </tr>
  <tr>
    <td>
      <b>virtual</b>
    </td>
    <td>
      The class variable is not defined, but you can defined accessors.
    </td>
  </tr>
</table>

=end html

Compilation Errors:

One of C<private>, C<protected> and C<public> must be specified. Otherwise, a compilation error occurs.

One of C<ro>, C<wo>, and C<rw> must be specified. Otherwise, a compilation error occurs.

=head3 Class Variable Getter Method

A class variable getter method is a method to perform the operation of L<getting a class variable|SPVM::Document::Language::Operators/"Class Variable Get Operation">.

This method is a class method that has no arguments.

If the type of the class variable is byte type or short type, the return type is int type. Otherwise, it is the same type as the class variable.

The method name is the same as the class variable name, but C<$> is removed. For example, if the class variable name is C<$FOO>, the method name is C<FOO>.

Examples:

  # Examples of class variable getter methods
  class MyClass {
    our $VALUE : ro int;
    
    static method main : void {
      my $num = Foo->VALUE;
    }
  }

A user defined class variable getter can be defined with C<get> keyword.

  class MyClass {
    our $VALUE : ro int
      get {
        return $VALUE;
      }
    ;
  }

User defined getter and setter can be defined at once.

  class MyClass {
    our $VALUE : rw int
      get {
        return $VALUE;
      }
      set {
        $VALUE = $_;
      }
    ;
  }

=head3 Class Variable Setter Method

A class variable setter method is a method to perform the operation of L<setting a class variable|SPVM::Document::Language::Operators/"Class Variable Set Operation">.

This method is a class method that has an argument.

If the type of the class variable is byte type or short type, the argument type is int type. Otherwise, it is the same type as the class variable.

The return type is void type.

The method name is the same as the class variable name, but C<$> is removed and C<SET_> is added to the beginning of it. For example, if the class variable name is C<$FOO>, the method name is C<SET_FOO>.

Examples:

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

A user defined class variable setter can be defined with C<set> keyword. The passed value is assigned to C<$_>.

  class MyClass {
    our $VALUE : wo int
      set {
        $VALUE = $_;
      }
    ;
  }

The argument can be replaced.

  class MyClass {
    our $VALUE : wo int
      set ($VAL : object) {
        $VALUE = (int)$VAL;
      }
    ;
  }

=head1 Field

A field is a data member of a L<class|/"Class">.

=head2 Field Definition

The C<has> keyword defines a field.
  
  has FIELD_NAME : OPT_ATTRIBUTES TYPE;

I<FIELD_NAME> is a L<field name|SPVM::Document::Language::Tokenization/"Field Name">.

I<TYPE> is a L<type|SPVM::Document::Language::Types/"Types">.

I<OPT_ATTRIBUTES> is one of

  EMPTY
  ATTRIBUTES

I<EMPTY> means nothing exists.

I<ATTRIBUTES> is one of
  
  ATTRIBUTES ATTRIBUTE
  ATTRIBUTE

I<ATTRIBUTE> is a L<field attribute|/"Field Attributes">.

Each field of an object is initialized by its L<type initial value|SPVM::Document::Language::Types/"Type Initial Value"> when the object is created.

The value of a field is got by the operation of L<getting a field|SPVM::Document::Language::Operators/"Field Get Operation">.

The value of a field is set by the operation of L<setting a field|SPVM::Document::Language::Operators/"Field Set Operation">.

Compilation Errors:

I<FIELD_NAME> must a L<field name|SPVM::Document::Language::Tokenization/"Field Name">. Otherwise, a compilation error occurs.

I<TYPE> must be a L<numeric type|SPVM::Document::Language::Types/"Numeric Types"> or an L<object type|SPVM::Document::Language::Types/"Object Types">.

I<ATTRIBUTE > must be a L<field attribute|/"Field Attributes">. Otherwise, a compilation error occurs.

If two or more fields that has a same name are defined, a compilation error occurs.

If the field is already defined with a different type in the super class, a compilation error occurs.

Examples:

  class MyClass {
    has num_byte : byte;
    has num_short : short;
    has num_int : int;
    has num_long : long;
    has num_float : float;
    has num_double : double;
    
    has num_public : public int;
    has num_ro : ro int;
    has num_rw : rw int;
  }

=head2 Field Attributes

The List of Field Attributes:

=begin html

<table>
  <tr>
    <th>
      Field Attributes
   </th>
    <th>
      Descriptions
   </th>
  </tr>
  <tr>
    <td>
      <b>public</b>
    </td>
    <td>
      This field is public. All classes can access this field.
    </td>
  </tr>
  <tr>
    <td>
      <b>private</b>
    </td>
    <td>
      This field is private. All classes ohter than this class cannnot access this field.
    </td>
  </tr>
  <tr>
    <td>
      <b>protected</b>
    </td>
    <td>
      This field is protected. All classes ohter than this class and its child classes cannot access this field. This is default.
    </td>
  </tr>
  <tr>
    <td>
      <b>ro</b>
    </td>
    <td>
      This field defines a <a href="#Field-Getter-Method">getter method</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>wo</b>
    </td>
    <td>
      This field defineds a <a href="#Field-Setter-Method">setter method</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>rw</b>
    </td>
    <td>
      This field defines a <a href="#Field-Getter-Method">getter method</a> and a <a href="#Field-Setter-Method">setter method</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>virtual</b>
    </td>
    <td>
      The field is not defined, but you can defined accessors.
    </td>
  </tr>
</table>

=end html

Compilation Errors:

One of C<private>, C<protected> and C<public> must be specified. Otherwise, a compilation error occurs.

One of C<ro>, C<wo>, and C<rw> must be specified. Otherwise, a compilation error occurs.

=head3 Field Getter Method

A field getter method is a method to perform the operation of L<getting a field|SPVM::Document::Language::Operators/"Field Get Operation">.

This method is an instance method that has no arguments.

If the type of the field is byte type or short type, the return type is int type. Otherwise, it is the same type as the field.

The method name is the same as the field name. For example, if the field name is C<foo>, the method name is C<foo>.

Examples:

  # Examples of field getter methods
  class MyClass {
    has value : ro int;
    
    static method new {
      return new Foo;
    }
    
    static method main : void {
      my $foo = Foo->new;
      
      my $value = $foo->value;
    }
  }

A user defined field getter can be defined with C<get> keyword.

  class MyClass {
    has value : ro int
      get {
        return $self->{value};
      }
    ;
  }

User defined getter and setter can be defined at once.

  class MyClass {
    has value : rw int
      get {
        return $self->{value};
      }
      set {
        $self->{value} = $_;
      }
    ;
  }

=head3 Field Setter Method

A field setter method is a method to perform the operation of L<setting a field|SPVM::Document::Language::Operators/"Field Set Operation">.

This method is an instance method that has an argument.

If the type of the field is byte type or short type, the argument type is int type. Otherwise, it is the same type as the field.

The return type is void type.

The method name is the same as the field name, but C<set_> is added to the beginning of it. For example, if the field name is C<foo>, the method name is C<set_foo>.

Examples:

  # Examples of field setter methods
  class MyClass {
    has value : wo int;
    
    static method new {
      return new Foo;
    }
    
    static method main : void {
      my $foo = Foo->new;
      
      $foo->set_value(3);
    }
  }

A user defined field setter can be defined with C<set> keyword. The passed value is assigned to C<$_>.

  class MyClass {
    has value : wo int
      set {
        $self->{value} = $_;
      }
    ;
  }

The argument can be replaced.

  class MyClass {
    has value : wo int
      set ($value : object) {
        $self->{value} = (int)$value;
      }
    ;
  }

The return type can be replaced.

  class MyClass {
    has value : wo int
      set : MyClass ($value : object) {
        $self->{value} = (int)$value;
        return $self;
      }
    ;
  }

If there is no method block and a return type is specified, the default setter returns the invocant.

  class MyClass {
    has value : wo int
      set : MyClass
    ;
  }

=head2 Field Existence

An object has field existence flags.

When a new object is created, these flags are zero.

When one of field set operations is performed, this flag is set to 1.
  
  # The field existence flag for "value" field is set to 1.
  $object->{value} = 1;

You can check if a field exists using L<exists operator|SPVM::Document::Language::Operators/"exists Operator">.

  my $exists = exists $object->{value};

You can delete a field using L<delete operator|SPVM::Document::Language::Operators/"delete Operator">.

  delete $object->{value};

The field existence flag is set to 0, and the value of the field is set to 0 in the case of numeric types or undef in the case of object types.

=head1 Method

=head2 Method Definition

The C<method> keyword defines a method.

  OPT_ATTRIBUTES method METHOD_NAME : RETURN_TYPE (OPT_ARG_ITEMS) { }
  OPT_ATTRIBUTES method METHOD_NAME : RETURN_TYPE (OPT_ARG_ITEMS);

I<OPT_ATTRIBUTES> is one of

  EMPTY
  ATTRIBUTES

I<EMPTY> means nothing exists.

I<ATTRIBUTES> is one of
  
  ATTRIBUTES ATTRIBUTE
  ATTRIBUTE

I<ATTRIBUTE> is a L<method attribute|/"Method Attributes">.

I<METHOD_NAME> is a L<method name|SPVM::Document::Language::Tokenization/"Method Name">.

I<RETURN_TYPE> is a L<type|SPVM::Document::Language::Types/"Types">.

I<OPT_ARG_ITEMS> is one of

  EMPTY
  ARG_ITEMS

I<EMPTY> means nothing exists.

I<ARG_ITEMS> is one of
  
  ARG_ITEMS , ARG_ITEM
  ARG_ITEM

I<ARG_ITEM> is one of

  ARG_NAME : ARG_TYPE
  ARG_NAME : ARG_TYPE = VALUE

I<ARG_NAME> is a L<local variable name|SPVM::Document::Language::Tokenization/"Local Variable Name">.

The local variable specified I<ARG_NAME> is declared at the beginning of L<method implementation|/"Method Implementation">.

I<ARG_TYPE> is a L<type|SPVM::Document::Language::Types/"Types">.

I<VALUE> is a L<literal|SPVM::Document::Language::Tokenization/"Literals"> or C<undef>. 

A method with the C<static> L<method attribute|/"Method Attributes"> is a L<class method|/"Class Method">.

A method without the C<static> L<method attribute|/"Method Attributes"> is an L<instance method|/"Instance Method">.

An argument with I<VALUE> is an optional arguments. If a method call dose not give a value to an optional argument, I<VALUE> is given to the argument.

A interface method defined in an L<interface|/"Interface"> is an L<interface method|/"Interface Method">.

A method with the C<native> L<method attribute|/"Method Attributes"> is a L<native method|/"Native Method">.

Compilation Errors:

The count of I<ARGS> must be less than or equal to 255. Otherwise, a compilation error occurs.

I<ARG_TYPE> must be a L<numeric type|SPVM::Document::Language::Types/"Numeric Types">, a L<multi-numeric type|SPVM::Document::Language::Types/"Multi-Numeric Types">, an L<object type|SPVM::Document::Language::Types/"Object Types">, or a L<reference type|SPVM::Document::Language::Types/"Reference Types">. Otherwise, a compilation error occurs.

I<RETURN_TYPE> must be void type, a L<numeric type|SPVM::Document::Language::Types/"Numeric Types">, a L<multi-numeric type|SPVM::Document::Language::Types/"Multi-Numeric Types"> or an L<object type|SPVM::Document::Language::Types/"Object Types">. Otherwise, a compilation error occurs.

Methods other than interface methods and native methods must have a method block. Otherwise, a compilation error occurs.

I<VALUE> must satisfy L<assignment requirement|SPVM::Document::Language::Types/"Assignment Requirement"> to I<ARG_TYPE>. Otherwise, a compilation error occurs.

I<METHOD_NAME> must not be "INIT". Otherwise, a compilation error occurs.

A non-optional argument must not be placed after an optional argument. Otherwise, a compilation error occurs.

Examples:
  
  class MyClass {
    # Class method
    static method substr : string ($string : string, $offset : int, $length : int = -1) {
      # ...
    }
    
    # Instance method
    method clear : void () {
      
    }
  }

=head2 Method Attributes

The List of Method Attributes:

=begin html

<table>
  <tr>
    <th>
      Method Attributes
   </th>
    <th>
      Descriptions
   </th>
  </tr>
  <tr>
    <td>
      <b>public</b>
    </td>
    <td>
      This method is public. All classes can call this method. This is default.
    </td>
  </tr>
  <tr>
    <td>
      <b>private</b>
    </td>
    <td>
      This method is private. All classes ohter than this class cannnot call this method.
    </td>
  </tr>
  <tr>
    <td>
      <b>protected</b>
    </td>
    <td>
      This method is protected. All classes ohter than this class and its child classes cannot call this method.
    </td>
  </tr>
  <tr>
    <td>
      <b>precompile</b>
    </td>
    <td>
      This method is a <a href="#Precompilation-Method">precompilation method</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>native</b>
    </td>
    <td>
      This method is a <a href="#Native-Method">native method</a>.
    </td>
  </tr>
  <tr>
    <td>
      <b>required</b>
    </td>
    <td>
      A method that implements this interface method must be defined.
    </td>
  </tr>
</table>

=end html

Compilation Errors:

One of C<private>, C<protected> and C<public> must be specified. Otherwise, a compilation error occurs.

C<required> must be specified to an interface method. Otherwise, a compilation error occurs.

Examples:
  
  # private method
  private method : int sum ($num1 : int, $num2 : int) {
    return $num1 + $num2;
  }
  
  # precompile method
  precompile method : int sum ($num1 : int, $num2 : int) {
    return $num1 + $num2;
  }
  
  # native method
  native method : int sum ($num1 : int, $num2 : int);

=head2 Class Method

A method defined with the C<static> L<method attribute|/"Method Attributes"> is a class method.

A class method can be called by a L<class method call|SPVM::Document::Language::Operators/"Class Method Call">.

=head2 Instance Method

A method defined without the C<static> L<method attribute|/"Method Attributes"> is an instance method.

An instance method can be called by an L<instance method call|SPVM::Document::Language::Operators/"Instance Method Call">.

=head2 Interface Method

An instance method defined in an L<interface|/"Interface"> is an interface method.

Normally, an interface method does not have a method block.

  method my_method : int ();

But, an interface method can have a method block.

  method my_method : int () {
    
  }

An interface method can have the C<required> L<method attribute|/"Method Attributes"> that indicates classes must define a method with the same name that implements this interface method.

  required method my_method : int ();

=head2 INIT Block

An C<INIT> block is a special scope block to initialize class variables or perform setup tasks.

  our $FOO : int;
  
  INIT {
    $FOO = 1;
  }

Multiple C<INIT> blocks can be defined:

  INIT {
    # First setup
  }
  
  INIT {
    # Second setup
  }

All C<INIT> blocks in a class are merged into a single L<INIT method|/"INIT Method"> at compile time.

=head2 INIT Method

An C<INIT> method is a special method that is automatically generated by the compiler.

It consists of all L<INIT blocks|/"INIT Block"> in a class. If no C<INIT> block exists, an empty C<INIT> method is generated.

This method has no arguments and its return type is the C<void> type.

The C<INIT> methods of the parent class and classes loaded via L<use statements|/"use Statement"> are called at the beginning of the C<INIT> method of the current class.

Note that the execution order of C<INIT> methods among different classes is not generally guaranteed. However, the C<INIT> methods of L<Default Loaded Classes|/"Default Loaded Classes"> are guaranteed to be called before any user-defined C<INIT> methods.

This method is automatically called after all classes are loaded, and before the first method in the program is called. It can also be called manually.

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

=head2 END Block

An C<END> block is a special scope block to perform cleanup tasks.

  END {
    # Cleanup tasks
  }

Multiple C<END> blocks can be defined:

  END {
    # First cleanup
  }
  
  END {
    # Second cleanup
  }

All C<END> blocks in a class are merged into a single L<END method|/"END Method"> in reverse order (LIFO) at compile time.

=head2 END Method

An C<END> method is a special method that is automatically generated by the compiler.

It consists of all L<END blocks|/"END Block"> in a class. If no C<END> block exists, an empty C<END> method is generated.

This method has no arguments and its return type is the C<void> type.

Note that the execution order of C<END> methods among different classes is not generally guaranteed.

If an exception occurs in an C<END> method, it is converted to a warning message and printed to C<stderr>, and the program continues its termination process.

This method is automatically called when the program is about to terminate, just before class variables are destroyed. It can also be called manually.

=head2 Destructor

A destructor is a method called just before an object is destroyed.

  method DESTROY : void () {
  
  }

A destructor is an L<instance method|/"Instance Method">.

The name of a destructor is C<DESTROY>.

A destructor has no arguments.

The retrun type is void type.

An L<exception|SPVM::Document::Language::ExceptionHandling/"Exception Handling"> thrown in a destructor is converted to a warning message.

The warning message is printed to L<SPVM's standard error|SPVM::Document::Language::System/"Standard Streams">.

If the reference count of an object is 0, the destructor method in the class of the object is called.

In this time, the return value and an exception variable in the current L<runtime stack|SPVM::Document::NativeClass/"Runtime Stack"> is saved before the call to the destructor method, and restore it after the call.

So, the exception variable in the current runtime stack cannot be changed in a destructor.

See L<Garbage Collection|SPVM::Document::Language::GarbageCollection/"Garbage Collection"> about garbage collection.

If the current class does not have C<DESTROY> method and its super class have C<DESTROY> method, the C<DESTROY> in its super class is called just before an object is destroyed.

Compilation Errors:

A destructor must be an L<instance method|/"Instance Method">. Otherwise, a compilation error occurs.

The name of a destructor must be C<DESTROY>. Otherwise, a compilation error occurs.

If a destructor has arguments, a compilation error occurs.

The retrun type must be void type. Otherwise, a compilation error occurs.

If two or more destructors are defined, a compilation error occurs.

Examples:
  
  # Destructor
  class MyClass {
    method DESTROY : void () {
      say "DESTROY";
    }
  }

=head2 Method Override

An instance method in a parent class can be overridden by an instance method with the same name in a child class.

  class ChildClass extends ParentClass {
    # Method Override
    method clear : void () {
      # ...
    }
  }

  class ParentClass {
    
    method clear : void () {
      # ...
    }
  }

The overridding method in the child class must satisfy L<interface method requirement|SPVM::Document::Language::Types/"Interface Method Requirement"> to the parent method interpretted as an interface method.

Compilation Errors:

The overridding method in the child class must satisfy L<interface requirement|SPVM::Document::Language::Types/"Interface Requirement"> to the parent method. Otherwise, a compilation error occurs.

=head2 Native Method

A method with the C<native> L<method attribute|/"Method Attributes"> is a native method.

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

A native method has no L<method block|/"Method Block">.

The implementation of a native method is written by native languages such as the C language, C<C++>.

See L<SPVM::Document::NativeClass> about the way to write the implementation of a native method.

=head2 Precompilation Method

A method with the C<precompile> L<method attribute|/"Method Attributes"> is a precompilation method.

  precompile sum : int ($num1 : int, $num2 : int) {
  
  }

The source code of each precompilation method is converted to a C source code and it is compiled to the machine code.

And the machine codes of all precompilation methods in a class is linked to a dynamic link library such as C<MyClass.so> on Linux/Unix, C<MyClass.dll> on Windows, C<MyClass.dylib> on Mac.

The address of machine code of each precompilation method in the dynamic link library is bind to a precompilation method.

Precompilation methods need a L<build directory|SPVM::Document::EnvironmentVariables/"SPVM_BUILD_DIR"> such as C<~/.spvm_build> to compile and link them.

=head2 Bootstrap Method

A bootstrap method is a method where a program start.

  void main : void () {
    
  }

The method name is C<main>.

The return type is void type.

It has no arguments.

=head2 Method Implementation

Normally a method has a method block. L<Statements|SPVM::Document::Language::Statements/"Statements"> can be written in a method block.
  
  static method foo : int ($num1 : int, $num2 : int) {
    
    my $total = $num1 + $num2;
    
    return $total;
  }

SPVM operation codes are generated from a method implementation.

=head2 Arguments Signature

An arguments signature uniquely identifies the sequence of argument types without the type of invocant.

  TYPE1,TYPE2,TYPEn

The arguments signature of the following class method and instance method is C<string,mutable string,string[],Point[][],int*>.

  static method args_signature_class_method : void ($args1 : string, $args2 : mutable string, $args3 : string[], $args4 : Point[][], $args5 : int*) {
  
  }
  
  method args_signature_instance_method : void ($args1 : string, $args2 : mutable string, $args3 : string[], $args4 : Point[][], $args5 : int*) {
  
  }

=head2 Variable Length Arguments

The variable length arguments syntax C<object...> is a syntax suger to pass a C<object[]> object as an argument.

  static method varargs_method : string ($args : object...) {
    
  }

A C<object[]> object is created with the arguments. Each element is casted to any object type C<object>.

  &varags_method("abc", 1);

If no arguments are specified, zero-length C<object[]> object is passed.

  &varags_method();

If you want to pass an C<object[]> object as one argument, you can use the type cast to C<object...>.

  my $objects = [(object)"abc", 1];
  
  &varags_method((object...)$objects);

Compilation Errors:

The use of variable length arguments is restricted to object[] type. Otherwise a compilation error occurs.
  
The use of variable length arguments must be the last argument. Otherwise a compilation error occurs.

The use of variable length arguments cannot have a default value. If so, a compilation error occurs.

=head2 Generics

Generics are supported.

The type parameter is C<element>.

C<element> and C<element[]> are allowed as a type parameter based type.

  element
  element[]

A type parameter based type must be the return type of an instance method.

The return type is casted to the element type of a L<generic type|SPVM::Document::Language::Types/"Generic Type">.

Examples:

  class MyList {
    
    has array : object[];
    
    static method new : MyList ($objects : object[]) {
      
      my $self = new MyList;
      
      $self->{array} = $objects;
      
      return $self;
    }
    
    method get : element ($index : int) {
      
      return $self->{array}->[$index];
      
    }
    
    method get_array : element[] () {
      
      return $self->{array};
    }
  }
  
  # MyList of string is a generic type
  my $list = (MyList of string)MyList->new(["a", "b"]);
  
  # $elem is casted to string type
  my $elem = $list->get(0);
  
  # $array is casted to string[] type
  my $array = $list->get_array;

=head2 Union Mapping

If both the return type and an argument type of a method are L<union types|SPVM::Document::Language::Types/"Union Type">, the return type is automatically cast to the specific type corresponding to the index of the type of the passed argument at compile time.

  # Mapping definition:
  # Index 0: Int[]  -> int[]
  # Index 1: Long[] -> long[]
  static method union_mapping_method : int[]|long[] ($arg : Int[]|Long[]) {
    # ...
  }
  
  # The return type is automatically cast to int[]
  my $int_array = &union_mapping_method(Int->new_array([1, 2]));
  
  # The return type is automatically cast to long[]
  my $long_array = &union_mapping_method(Long->new_array([4L, 5L]));

This mapping is resolved based on the first argument that has a union type.

If the passed argument does not match any type in the argument's union type, or if no union type argument exists, no automatic casting is performed. In this case, the return type remains the defined union type (which is handled as the any object type C<object>).

=head1 Local Variable

A local variable is a variable that has a L<scope|SPVM::Document::Language::GarbageCollection/"Scope">.

=head2  Local Variable Declaration

A C<my> keyword declares a local variable.

  my LOCAL_VAR_NAME
  my LOCAL_VAR_NAME : TYPE
  my LOCAL_VAR_NAME = VALUE
  my LOCAL_VAR_NAME : TYPE = VALUE

I<LOCAL_VAR_NAME> is a L<local variable name|SPVM::Document::Language::Tokenization/"Local Variable Name">.

I<TYPE> is a L<type|SPVM::Document::Language::Types/"Types">.

If I<TYPE> is ommited, I<TYPE> is set to the type of I<VALUE>. This is called L<type inference|/"Type Inference">.

I<VALUE> is an L<operator|SPVM::Document::Language::Operators/"Operators">.

A local variable is declared in a L<scope block|/"Scope Block">.

A local variable declaration performs the operation of L<pushing a local variable on the mortal stack|SPVM::Document::Language::GarbageCollection/"Pushing a Local Variable on the Mortal Stack">.

A local variable declaration is a L<local variable access|SPVM::Document::Language::Operators/"Local Variable Access">.

Compilation Errors:

I<LOCAL_VAR_NAME> must be a L<local variable name|SPVM::Document::Language::Tokenization/"Local Variable Name">. Otherwise a compilation error occurs.

I<TYPE> must be a L<numeric type|SPVM::Document::Language::Types/"Numeric Types">, an L<object type|SPVM::Document::Language::Types/"Object Types">, L<multi-numeric type|SPVM::Document::Language::Types/"Multi-Numeric Types">, or a L<reference type|SPVM::Document::Language::Types/"Reference Types">. Otherwise a compilation error occurs.

If I<TYPE> is not resolved, a compilation error occurs.

Examples:

  # Examples of local variable declarations
  my $var : int;
  my $var : Point;
  my $var : Complex_2d;
  my $var : int*;
  
  my $num = 1;
  
  my $num = 1.0;
  
  my $ppp = my $bar = 4;
  
  if (my $bar = 1) {
  
  }
  
  while (my $bar = 1) {
  
  }

=head3 Type Inference

If the type of the local variable declaration is ommited, the type of the local variable is set to the right operand type of assignment operator. This is called type inference.

  # int
  my $num = 1;
  
  # double
  my $num = 1.0;
  
  # Foo
  my $foo = new Foo;

=head2 Local Temporary Variable

The declaration of a local variable C<$_> is treated as a declaration of a local templrary variable.

  my $_ : TYPE;

The internal variable name like C<$_.line_12_column_85>.

Local temporary variables can be declared repeatedly with different types in the same scope.

  my $_ = 1;
  
  my $_ = 2;
  
  my $_ = Point->new;

Examples:

  my $_ = 1;
  
  say $_;
  
  my $_ = 2;
  
  say $_;
  
  my $_ = Point->new;
  
  say $_->x;
  
  my $point = (my $_ = Point->new(1, 2), $_->clear, $_);

=head2 Monitor Variable

A monitor variable is a special local variable that is used for debugging or reflection.

The name of a monitor variable is C<$^MONITOR>.

Only one monitor variable can be declared in a class file.

A monitor variable must be declared as a local variable.

Example:

  my $var = new int[3];
  
  # $^MONITOR is declared as a local variable and assigned a value
  my $^MONITOR = $var;

A monitor variable is used by L<Native::BasicType#has_monitor_var|SPVM::Native::BasicType/"has_monitor_var"> and L<Native::BasicType#get_monitor_var_type|SPVM::Native::BasicType/"get_monitor_var_type"> in the native API.

Compilation Errors:

If more than one monitor variable is declared in a class file, a compilation error occurs.

=head1 Symbol Name Resolution

This section describes resolutions of symbol names, such as variable names, class names, field names, method names in the current L<method implementation|/"Method Implementation">.


=head2 Variable Name Resolution

A variable name resolves to a L<class variable access|SPVM::Document::Language::Operators/"Class Variable Access"> or a L<local variable access|SPVM::Document::Language::Operators/"Local Variable Access">.

If C<::> is contained in a variable name, a class variable definition as the same name as I<VAR_NAME> in I<CLASS_TYPE> is searched.

  CLASS_TYPE::VAR_NAME

If found, a variable name resloves to a L<class variable access|SPVM::Document::Language::Operators/"Class Variable Access">.

If C<::> is not contained in a variable name, a local variable declaration as the same name as I<VAR_NAME> is searched upwards from the posotion of I<VAR_NAME>.

  VAR_NAME

If found, a variable name resloves to a L<local variable access|SPVM::Document::Language::Operators/"Local Variable Access">.

If not found, a class variable definition as the same name as I<VAR_NAME> in L<outmost class|/"Outmost Class"> is searched.

If found, a variable name resloves to a L<class variable access|SPVM::Document::Language::Operators/"Class Variable Access">.

Compilation Errors:

I<VAR_NAME> must be a valid variable name. Otherwise, a compilation error occurs.

The class specified by I<CLASS_TYPE> must be loaded. Otherwise, a compilation error occurs.

The class variable relative name specified by I<VAR_NAME> must be defined in the class specified by I<VAR_NAME>. Otherwise, a compilation error occurs.

If it resolves to a class variable, L<outmost class|/"Outmost Class"> must has the access control to I<VAR_NAME> in the I<CLASS_TYPE>. Otherwise, a compilation error occurs.

=head2 Field Access Resolution

The following syntax resolves to a L<field access|SPVM::Document::Language::Operators/"Field Access">.

  INVOCANT->{FIELD_NAME}

The type of I<INVOCANT> is a L<class type|SPVM::Document::Language::Types/"Class Type">, a L<multi-numeric type|SPVM::Document::Language::Types/"Multi-Numeric Type">, or a L<multi-numeric reference type|SPVM::Document::Language::Types/"Multi-Numeric Reference Type">.

I<FIELD_NAME> is a L<field name|SPVM::Document::Language::Tokenization/"Field Name">.

A field specified by I<FIELD_NAME> is searched in the type of I<INVOCANT>.

If it is found and the type of I<INVOCANT> is a L<class type|SPVM::Document::Language::Types/"Class Type">, it resolves to a field access for class types.

If it is found and the type of I<INVOCANT> is a L<multi-numeric type|SPVM::Document::Language::Types/"Multi-Numeric Type">, it resolves to a field access for multi-numeric types.

If it is found and the type of I<INVOCANT> is a L<multi-numeric reference type|SPVM::Document::Language::Types/"Multi-Numeric Reference Type">, it resolves to a field access for multi-numeric reference types.

Compilation Errors:

I<INVOCANT> must be an object of a L<class type|SPVM::Document::Language::Types/"Class Type">, a multi-numeric number of a L<multi-numeric type|SPVM::Document::Language::Types/"Multi-Numeric Type">, a multi-numeric number referenced by a L<multi-numeric reference type|SPVM::Document::Language::Types/"Multi-Numeric Reference Type">. Otherwise, a compilation error occurs.

If the type of I<INVOCANT> is a class type, the field specified by I<FIELD_NAME> must be defined in the class, or its super classes. Otherwise, a compilation error occurs.

If the type of I<INVOCANT> is a multi-numeric type, the field specified by I<FIELD_NAME> must be defined in the multi-numeric type. Otherwise, a compilation error occurs.

If the type of I<INVOCANT> is a multi-numeric reference type, the field specified by I<FIELD_NAME> must be defined in the multi-numeric type referenced by the multi-numeric reference type. Otherwise, a compilation error occurs.

The L<outmost class|/"Outmost Class"> must has the access control to I<FIELD_NAME> in the type of I<INVOCANT>. Otherwise, a compilation error occurs.

=head2 Method Call Resolution

A L<method call|SPVM::Document::Language::Operators/"Method Call"> is an operation to call a method.

A method call resolves to one of the three types of method calls, a class method call, a static instance method call, and an instance method call.

=head3 Class Method Call Resolution

A class method call calls a class method.

  CLASS_TYPE->METHOD_NAME
  CLASS_TYPE->METHOD_NAME(OPT_ARGS)
  &METHOD_NAME
  &METHOD_NAME(OPT_ARGS)

I<CLASS_TYPE> is a L<class type|SPVM::Document::Language::Types/"Class Types"> or a class alias name created by an L<alias statement|/"alias Statement">.

C<&> is converted to L<outmost class|/"Outmost Class">. This becomes C<I<CLASS_TYPE-E<gt>>>.

I<METHOD_NAME> is a L<method name|SPVM::Document::Language::Tokenization/"Method Name">.

I<OPT_ARGS> is one of

  EMPTY
  ARGS

I<EMPTY> means nothing exists.

I<ARGS> is one of
  
  ARGS , ARG
  ARG

I<ARG> is an L<operator|SPVM::Document::Language::Operators/"Operators">.

If a method specified I<METHOD_NAME> is searched in I<CLASS_TYPE>.

If found, it resolves to a L<class method call|SPVM::Document::Language::Operators/"Class Method Call">.

The return type is the type of the found method.

Compilation Errors:

If the method is not found, a compilation error occurs.

If the found method is an instance method, a compilation error occurs.

If the type of I<ARG> does not satisfy L<assignment requirement|SPVM::Document::Language::Types/"Assignment Requirement">, a compilation error occurs.

If the length of I<ARGS> is too many, a compilation error occurs.

If the length of I<ARGS> is too few, a compilation error occurs.

The L<outmost class|/"Outmost Class"> must has the access control to the found method. Otherwise, a compilation error occurs.

Examples:

  # Examples of class method calls
  class MyClass {
    
    static method main : void () {
      my $ret = Fn->INT_MAX;
      
      my $ret = Fn->abs(-5);
      
      my $ret = &sum(1, 2);
    }
    
    static method sum : int ($num1 : int, $num2 : int) {
      return $num1 + $num2;
    }
  }

=head4 Inline Expansion of Method Call to Get an Enuemration Value

An inline expansion is performed on every class method call to get an enumeration value, and it is replaced with the return value.

Examples:

  class MyClass {
    enum {
      FLAG1 = 5;
    }
    
    method main : void () {
      
      # This is replaced with 5.
      MyClass->FLAG1;
    }
  }

=head3 Static Instance Method Call Resolution

A static instance method call calls an instance method specifying a class.

  INVOCANT->CLASS_TYPE::METHOD_NAME
  INVOCANT->CLASS_TYPE::METHOD_NAME(OPT_ARGS)

I<INVOCANT> is an object of a L<class type|SPVM::Document::Language::Types/"Class Types"> or an L<interface type|SPVM::Document::Language::Types/"Interface Types">.

I<CLASS_TYPE> is a L<class type|SPVM::Document::Language::Types/"Class Types">, an L<interface type|SPVM::Document::Language::Types/"Interface Types">, or C<SUPER>.

If C<SUPER> is specified, a method specified by I<METHOD_NAME> is searched in the super classes of the current class. If it is found and it is an instance method, C<SUPER> is replaced to the class of the found method. This becomes I<CLASS_TYPE>.

I<METHOD_NAME> is a L<method name|SPVM::Document::Language::Tokenization/"Method Name">.

I<OPT_ARGS> is one of

  EMPTY
  ARGS

I<EMPTY> means nothing exists.

I<ARGS> is one of
  
  ARGS , ARG
  ARG

I<ARG> is an L<operator|SPVM::Document::Language::Operators/"Operators">.

A method specified I<METHOD_NAME> is searched in I<CLASS_TYPE>.

If found, it resolves to a L<static instance method call|SPVM::Document::Language::Operators/"Static Instance Method Call">.

The return type is the type of the found method.

Compilation Errors:

I<CLASS_TYPE> must be a L<class type|SPVM::Document::Language::Types/"Class Types">, an L<interface type|SPVM::Document::Language::Types/"Interface Types">, or C<SUPER>. Ohterwise a compilation error occurs.

The type of I<INVOCANT> must satisfies L<assignment requirement|SPVM::Document::Language::Types/"Assignment Requirement"> to I<CLASS_TYPE>. Ohterwise a compilation error occurs.

If C<SUPER> is specified and the found method is a class method, a compilation error occurs.

If the method is not found, a compilation error occurs.

If the found method is a class method, a compilation error occurs.

If the type of I<ARG> does not satisfy L<assignment requirement|SPVM::Document::Language::Types/"Assignment Requirement">, a compilation error occurs.

If the length of I<ARGS> is too many, a compilation error occurs.

If the length of I<ARGS> is too few, a compilation error occurs.

The L<outmost class|/"Outmost Class"> must has the access control to the found method. Otherwise, a compilation error occurs.

Examples:
  
  # Examples of static instance method calls
  my $point3d = Point3D->new;
  
  $point3d->Point::clear;
  
  $point3d->SUPER::clear;
  
=head3 Instance Method Call Resolution

An instance method call calls an instance method.

  INVOCANT->METHOD_NAME
  INVOCANT->METHOD_NAME(OPT_ARGS)

I<INVOCANT> is an object of a L<class type|SPVM::Document::Language::Types/"Class Types"> or an L<interface type|SPVM::Document::Language::Types/"Interface Types">.

I<METHOD_NAME> is a L<method name|SPVM::Document::Language::Tokenization/"Method Name">.

I<OPT_ARGS> is one of

  EMPTY
  ARGS

I<EMPTY> means nothing exists.

I<ARGS> is one of
  
  ARGS , ARG
  ARG

I<ARG> is an L<operator|SPVM::Document::Language::Operators/"Operators">.

If the type of I<INVOCANT> is a L<class type|SPVM::Document::Language::Types/"Class Types">, a method specified I<METHOD_NAME> is searched in the class and its super classes.

If found, it resolves to an L<instance method call|SPVM::Document::Language::Operators/"Instance Method Call">.

If the type of I<INVOCANT> is an L<interface type|SPVM::Document::Language::Types/"Interface Types">, a method specified I<METHOD_NAME> is searched in the interface.

If found, it resolves to an L<instance method call|SPVM::Document::Language::Operators/"Instance Method Call">.

The return type is the type of the found method.

Compilation Errors:

The type of I<INVOCANT> must be a L<class type|SPVM::Document::Language::Types/"Class Types"> or an L<interface type|SPVM::Document::Language::Types/"Interface Types">.

If the method specified by I<METHOD_NAME> is not found, a compilation error occurs.

If the found method is a class method, a compilation error occurs.

If the type of I<ARG> does not satisfy L<assignment requirement|SPVM::Document::Language::Types/"Assignment Requirement">, a compilation error occurs.

If the length of I<ARGS> is too many, a compilation error occurs.

If the length of I<ARGS> is too few, a compilation error occurs.

The L<outmost class|/"Outmost Class"> must has the access control to the found method. Otherwise, a compilation error occurs.

Examples:
  
  # Examples of instance method calls
  
  my $point = Point->new;
  
  $point->clear;
  
  my $stringable = (Stringable)$point;
  
  my $string = $strinble->to_string;

=head1 Block

A block is the part enclosed by C<{> and C<}>.

=head2 Class Block

A class block is a block used in a class definition.
  
  class MyClass {
  
  }

=head2 Enumeration Block

An enumeration block is a block used in an enumeration definition.

  enum {
    ONE,
    TWO,
  }

=head2 Scope Block

A scope block is a block that has its L<scope|SPVM::Document::Language::GarbageCollection/"Scope">.

Zero or more L<statements|SPVM::Document::Language::Statements/"Statements"> are written in a scope block.

=head3 Simple Block

A simple block is a scope block.

  {
    1;
  }

A simple block must have at least one statements. Otherwise, it is intepreted as a L<key-value array initialization|SPVM::Document::Language::Operators/"Key-Value Array Initialization">.

=head3 Method Block

A method block is a scope block.

  static method foo : int () {
  
  }

=head3 INIT Block

An C<INIT> block is a scope block.

  INIT {
    
  }

=head3 eval Block

An C<eval> block is a scope block.

  eval {
  
  }

=head3 if Block

An C<if> block is a scope block.

  if (CONDITION) {
  
  }

=head3 elsif Block

An C<elsif> block is a scope block.

  elsif (CONDITION) {
  
  }

=head3 else Block

An C<else> block is a scope block.

  else {
  
  }

=head3 for Block

A C<for> block is a scope block.

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

=head3 while Block

A C<while> block is a scope block.

  while (CONDITION) {
  
  }

=head3 switch Block

A C<switch> block is a scope block.
  
  switch (CONDITION) {
  
  }

=head3 case Block

A C<case> block is a scope block.
  
  case CASE_VALUE1: {
    # ...
  }

=head3 default Block

A C<default> block is a scope block.
  
  default: {
    # ...
  }

=head1 See Also

=over 2

=item * L<SPVM::Document::Language::SyntaxParsing>

=item * L<SPVM::Document::Language::Operators>

=item * L<SPVM::Document::Language::Statements>

=item * L<SPVM::Document::Language>

=item * L<SPVM::Document>

=back

=head1 Copyright & License

Copyright (c) 2023 Yuki Kimoto

MIT License
