The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

Name

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

Description

This document describes classes.

Class

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

This section describes class syntax.

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

Class Definition

The class keyword defines a class type.

  class CLASS_NAME {
  
  }

A class type is also simply called a class.

An object can be created from a class using the new operator.

Compilation Errors:

The class name CLASS_NAME must be a class name, otherwise a compilation error occurs.

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

Examples:

  # Examepls of class definitions
  class Point {
  
  }

Class Attributes

One or more class attributes can be written after :.

  class CLASS_NAME : CLASS_ATTRIBUTE1 CLASS_ATTRIBUTE2 CLASS_ATTRIBUTEn {
  
  }

The List of Class Attributes:

Class Attributes Descriptions
public This class is public. All classes are able to create an object of this class using the new operator.
private This class is private. Classes other than this class are not able to create an object of this class using the new operator. This is default.
protected This class is protected. Only this class and its child classes are able to create an object of this class using the new operator.
interface_t This class is an interface type. The class definition with this attribute is interpreted as an interface definiton.
mulnum_t This class is a multi-numeric type. The class definition with this attribute is interpreted as an multi-numeric type definiton.
pointer The class is a pointer class.
precompile The precompile method attribute of all methods other than a INIT block, methods generated by enumuration values, and methods that does not have their method block is specified.

Compilation Errors:

Only one of private, protected or public must be specified, otherwise a compilation error occurs.

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

Examples:

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

Pointer Class

The pointer class is a class with the pointer class attribute .

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

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 :: are replaced to / and .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.

Version Statement

The version statement declares the version of a class.

  version VERSION_STRING;

This statement declares the version of a class given the version string VERSION_STRING.

Compilation Errors:

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

VERSION_STRING must be a version string, otherwise a compilation error occurs.

Examples:

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

Version String

The version string is the string that represents the version of a class.

A version string must be written by the following rules.

The type of a version string is the string type.

It consists of 0-9, ..

The count of . is less than or equal to 1.

It begins with 0-9.

It ends with 0-9.

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

It is able to be parsed by the 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"

Version Number

A version number is a floating point number created from a version string using the strtod function in the C language.

Examples:

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

use Statement

The use statemenet loads a class.

  use BASIC_TYPE;
  use BASIC_TYPE as CLASS_NAME;

This statement searches for the type BASIC_TYPE in class search directories from the beginning, and if found, loads the type.

BASIC_TYPE is a class type, an interface type, or a multi-numeric type.

See the require statement about how to load a type without causing a compile error when loading fails,

The follwoing use statement with as

  use BASIC_TYPE as CLASS_NAME;

is expanded to the following code using the alias statement.

  use BASIC_TYPE;
  alias BASIC_TYPE as CLASS_NAME

Compilation Errors:

BASIC_TYPE must be a class name, otherwise a compilation error occurs.

CLASS_NAME must be a class name, otherwise a compilation error occurs.

If BASIC_TYPE does not found, a compilation error occurs.

Examples:

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

Class Search Directories

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

These are set outside the program.

Directories set by the -I option of the spvm command and the spvmcc command are added to class search directories.

And directories with /SPVM added to the end of each value of Perl's @INC are added to the end of the class search directories.

Default Loaded Classes

The following classes are loaded by default.

alias Statement

The alias statemenet creates an alias name for a type.

  alias BASIC_TYPE as CLASS_NAME;

This statemenet creates an alias name CLASS_NAME for a type BASIC_TYPE.

BASIC_TYPE is a class type, an interface type, or a multi-numeric type.

Compilation Errors:

BASIC_TYPE must be a class name, otherwise a compilation error occurs.

CLASS_NAME must be a class name, otherwise a compilation error occurs.

Examples:

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

allow Statement

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

  allow BASIC_TYPE;

By default, objects of private classes cannot be created by the the 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 BASIC_TYPE private accesses to the current class.

BASIC_TYPE is loaded by the use statement.

Examples:

  # Allowing private access
  class MyClass {
    allow SomeClass;
  }

Inheritance

A class inherits a class using the extends keyword.

  class CLASS_NAME extends PARENT_CLASS_NAME {
    
  }

The class CLASS_NAME that inherits the parent class PARENT_CLASS_NAME is defined.

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

The interface statements of the parent class PARENT_CLASS_NAME are added to the end of the interface statements of the class CLASS_NAME.

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

Compilation Errors:

The parent class PARENT_CLASS_NAME must be a class type, otherwise a compilation error occurs.

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

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

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

The class CLASS_NAME interpreted by an interface must satisfy the interface requirement to the parent class 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;
    }
  }

Interface

This section describes interfaces.

Interface Definition

A class definition with the interface_t class attribute defines an interface type.

  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 interface methods.

Compilation Errors:

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

An interface cannnot have class variable definitions. 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);
  }

interface Statement

The interface statement checks if the current class satisfies the interface requirement to an interface.

  interface BASIC_TYPE;

Compilation Errors:

The interface type BASIC_TYPE must be an interface type, ohterwise a compilation error occurs.

The current class must satisfy the interface requirement to the interface type BASIC_TYPE, ohterwise a compilation error occurs.

Examples:

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

Anon Class

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

  class {
  
  }

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

An anon class is also defined by the anon method.

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

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

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

Examples:

  # Anon class
  class {
    static method sum : int ($num1 : int, $num2 : int) {
      return $num1 + $num2;
    }
  }
  
  # Anon method
  class Foo::Bar {
    method sum : void () {
      my $anon_method = method : string () {
        
      }
   }
  }
  
  # The name of the anon class
  Foo::Bar::anon::3::23;

Outmost Class

An outmost class is the outmost defined class.

The outmost class is Foo::Bar in the following example.

  class Foo::Bar {
    static method baz : void () {
      my $outmost_class_name = __PACKAGE__;
      
      my $cb = method : void () {
        my $outmost_class_name = __PACKAGE__;
      };
    }
  }

Multi-Numeric Type Definition

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

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

The type of a field must be a numeric type.

The types of all fields must be the same types.

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

Multi-Numeric Type Suffix

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

  _[FieldsLength][TypeSuffix]

The List of the Multi-Numeric Type Suffix:

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

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

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

Enumeration

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

Enumeration Definition

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

  # Enumeration Definition
  enum {
    FLAG1,
    FLAG2,
    FLAG3
  }

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

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

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

The type of an enumeration value is the int type.

, after the last enumeration value can be allowed.

  enum {
    FLAG1,
    FLAG2,
    FLAG3,
  }

An enumeration value can be set by = explicitly.

  enum {
    FLAG1,
    FLAG2 = 4,
    FLAG3,
  }

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

An enumeration value is got by the class method call.

  Foo->FLAG1

Compilation Errors:

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

Examples:

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

Enumeration Attributes

Attributes can be specified to an enumeration definition.

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

The List of Enumeration Attributes:

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

Compilation Errors:

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

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;

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

Class variable attributes can be specified.

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

Compilation Errors:

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

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

Examples:

  class MyClass {
    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 Attributes

The List of Class Variable Attributes:

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

Compilation Errors:

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

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

Class Variable Getter Method

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

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

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

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

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

Examples:

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

Class Variable Setter Method

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

The return type is the void type.

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

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

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

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

Examples:

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

Field

Fields are the data that an object has.

Field Definition

The has keyword defines a field.

  # The field definition
  has FIELD_NAME : OPT_ATTRIBUTES TYPE;
  
  # An examples
  has name : string;
  has age : protected int;
  has max : protected rw int

Field attributes can be specified.

Compilation Errors:

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

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

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

Examples:

  class MyClass {
    has name : string;
  }

Field Attributes

The List of Field Attributes:

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

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

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

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

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

Compilation Errors:

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

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

Examples:

  class MyClass {
    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 Getter Method

A field getter method is a method to perform the operation of the getting a field.

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

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

It is defined by the ro or rw field attributes.

It is a method that name is the same as the field name.

Examples:

  # Field getter method
  class MyClass {
    has num : ro int;
    
    static method new {
      return new Foo;
    }
    
    static method main : void {
      my $foo = Foo->new;
      
      my $num = $foo->num;
    }
  }

Field Setter Method

A field setter method is a method to perform the operation of the setting a field.

The return type is the void type.

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

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

It is defined by the wo or rw field attributes.

It is a method that name is the same as the field name, but prepend set_ to it. For example, if the field name is foo, its setter method name is set_foo.

Examples:

  # Field setter method
  class MyClass {
    has num : wo int;
    
    static method new {
      return new Foo;
    }
    
    static method main : void {
      my $foo = Foo->new;
      
      $foo->set_num(3);
    }
  }

Method

Method Definition

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

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

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

Method names must be follow the rule of method name.

The argument names must be follow the rule of local variable name.

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

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

A method can have method attributes.

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

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

Compilation Errors:

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

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

Optional Arguments

The optional argument is the syntax to specify optional arguments.

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

Examples:

  static method substr ($string : string, $offset : int, $length : int = -1) {
    # ...
  }
  
  my $string = "abc";
  my $offset = 1;
  my $substr = &substr($string, $offset);
  
  # This is the same as the following code
  my $string = "abc";
  my $offset = 1;
  my $length = -1;
  my $substr = &substr($string, $offset, $length);
  

Class Method

A class method is defined with the static keyword.

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

A class method can be called from the class name.

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

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

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

Instance Method

An instance method is defined without the static keyword.

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

An instance method can be called from the object.

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

Interface Method

Instance methods defined in interface types are called interface methods.

Normally, an instance method does not have its method block.

  method my_method : int ();

But, an interface method can have its method block.

  method my_method : int () {
    
  }

An interface method can have the required method attribute that indicates classes that implement this interface must implement this method.

  required method my_method : int ();

Method Attributes

Method attributes are attributes used in a method definition.

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

INIT Block

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

  INIT {
    
  }

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

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

The return statement cannot be written in INIT block.

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

An INIT block is editted.

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

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

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

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

An INIT block is automatically called only once.

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

Examples:

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

Destructor

A class can have a destructor.

  method DESTROY : void () {
  
  }

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

The name of the destructor must be DESTROY.

A destructor cannnot have its arguments.

The retrun type must be void type.

A destructor must be an instance method.

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

Compilation Errors:

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

Examples:

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

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

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 the interface requirement to the parent method.

Compilation Errors:

The overridding method in the child class must satisfy the interface requirement to the parent method, otherwise a compilation error occurs.

Anon Method

The anon method operator defines an anon calss that has an anon instance method.

And this operator creates an object which type is the anon class by the "new Operator" in new operator, and returns it.

  # Anon method
  method : TYPE  (VAR1 : TYPE1, VAR2 : TYPE2, ...) {
  
  }

The way to define the method is the same as the method definition.

Examples:

  # Anon method
  class Foo::Bar {
    method some_method : void () {
      my $comparator = (Comparator)method : int ($x1 : object, $x2 : object) {
        my $point1 = (Point)$x1;
        my $point2 = (Point)$x2;
        
        return $point1->x <=> $point2->x;
      };
    }
  }

See also Comparator.

The above example is the same as the following codes.

  # Foo/Bar.spvm
  class Foo::Bar {
    method some_method : void () {
      my $comparator = (Comparator)new Foo::Bar::anon::3::31;
    }
  }
  
  # Foo/Bar/anon/3/31.spvm
  class Foo::Bar::anon::3::31 : public {
    method : int ($x1 : object, $x2 : object) {
      my $point1 = (Point)$x1;
      my $point2 = (Point)$x2;
      
      return $point1->x <=> $point2->x;
    }
  }

Anon Method Field Definition

The anon method field definition is the syntax to define the field of the anon class of the anon method.

  # Anon method field definitions
  [has FIELD_NAME : TYPE1, has FIELD_NAME : TYPE2, ...] ANON_METHOD_DEFINITION
  
  # Anon method field definitions with field default values
  [has FIELD_NAME : TYPE1 = OPERAND1, has FIELD_NAME : TYPE2 = OPERAND2, ...] ANON_METHOD_DEFINITION
  
  [VAR1 : TYPE1, VAR2 : TYPE2, ...] ANON_METHOD_DEFINITION
  

Examples:

  class Foo::Bar {
    method some_method : void () {
      my $foo = 1;
      my $bar = 5L;
      
      my $comparator = (Comparator)[has foo : int = $foo, has bar : long = $bar] method : int ($x1 : object, $x2 : object) {
        my $foo = $self->{foo};
        my $bar = $self->{bar};
        
        print "$foo\n";
        print "$bar\n";
      };
    }
  }

Same as avobe but more simple:

  class Foo::Bar {
    method some_method : void () {
      my $foo = 1;
      my $bar = 5L;
      
      my $comparator = (Comparator)[$foo : int, $bar : long] method : int ($x1 : object, $x2 : object) {
        print "$foo\n";
        print "$bar\n";
      };
    }
  }

The above example is the same as the following codes.

  # Foo/Bar.spvm
  class Foo::Bar {
    method some_method : void () {
      # Externally defined local variables
      my $foo = 1;
      my $bar = 5L;
      
      my $anon = new Foo::Bar::anon::5::61;
      $anon->{foo} = $foo;
      $anon->{bar} = $bar;
      
      my $comparator = (Comparator)$anon;
    }
  }
  
  # Foo/Bar/anon/5/61.spvm
  class Foo::Bar::anon::5::61 : public {
    has foo : public int;
    has bar : public long;
    
    method : int ($x1 : object, $x2 : object) {
      my $foo = $self->{foo};
      my $bar = $self->{bar};
      
      print "$foo\n";
      print "$bar\n";
    }
  }

Native Method

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

A native method is defined by the native method attribute.

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

A native method doesn't have its method block.

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

Precompilation Method

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

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

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

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

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

Bootstrap Method

A bootstrap method is the methods where the program start.

  void main : void () {
    
  }

The method name is main.

The return type is the void type.

It has no arguments.

Method Implementation

Normally a method has a method block. Statements can be written in a method block.

  # Method implementation
  static method foo : int ($num1 : int, $num2 : int) {
    
    my $total = $num1 + $num2;
    
    return $total;
  }

Local Variable

A local variable is a variable that has a scope.

Local Variable Declaration

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

The local variable is declared using my "Keyword".

  my LOCAL_VARIABLE_NAME : TYPE;

The local variable name must be follow the rule of local variable name.

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

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

The local variable is initialized by type initial value.

  # Initialized by 0
  my $num : int;
  
  # Initialized by 0
  my $num : double;
  
  # Initialized by undef
  my $point : Point;
  
  # x is initialized by 0. y is initialized by 0.
  my $z : Complex_2d;

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

  # Initialized by 1
  my $num : int = 1;
  
  # Initialized by 2.5
  my $num : double = 2.5;
  
  # Initialized by Point object
  my $point : Point = new Point;

The type can be omitted using the type inference,

  # Type inference - int
  my $num = 1;
  
  # Type inference - double
  my $num = 1.0;

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

  my $ppp = my $bar = 4;
  
  if (my $bar = 1) {
  
  }
  
  while (my $bar = 1) {
  
  }

See the scope about the scope of the local variable.

Type Inference

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

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

Block

A block is the part enclosed by { and }.

Class Block

A class block is a block used in a class definition.

  # Class block
  class Point {
  
  }

Enumeration Block

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

  # Enumeration block
  enum {
    ONE,
    TWO,
  }

Scope Block

The scope block has its scope. Zero or more statements are written in a scope block.

Simple Block

The simple block is a scope block.

  # Simple block
  {
    1;
  }

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

Method Block

The method block is a scope block.

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

The block of INIT method is a method block.

  INIT {
    
  }

eval Block

The eval block is a scope block.

  # eval block
  eval {
  
  }

if Block

The if block is a scope block.

  # if block
  if (CONDITION) {
  
  }

elsif Block

The elsif block is a scope block.

  # elsif block
  elsif (CONDITION) {
  
  }

else Block

The else block is a scope block.

  # else block
  else {
  
  }

for Block

The for block is a scope block.

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

while Block

The while block is a scope block.

  # while block
  while (CONDITION) {
  
  }

switch Block

The switch block is a scope block.

  # switch block
  switch (CONDITION) {
  
  }

case Block

The case block is a scope block.

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

default Block

The default block is a scope block.

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

Type Comment

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

  TYPE of TYPE
  TYPE of TYPE1|TYPE2
  TYPE of TYPE1|TYPE2|TYPE3

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

  has points : List of Point;
  
  our $POINTS : List of Point;
  
  my $points : List of Point;
  
  static method foo : List of Point ($arg : List of Point) { ... }
  
  my $replace : object of string|Regex::Replacer;

Type comments have no meanings at runtime.

Compilation Errors:

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

See Also

Copyright & License

Copyright (c) 2023 Yuki Kimoto

MIT License