The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

SPVM::Document::Spec - SPVM Language Specification(BETA before 1.0)

SPVM Language Specification

Package Declaration

Package declaration is the following.

  package PackageName {
    
  }

PackageName is package name.

Package name is consist of Upper Case and Lower Case and Number and ::. Package name must start with Upper Case. Package name which start with Lower Case is forbidden. Package name which start with Lower Case is resolved for core.

Note that package name can't contain Under Score _. Under Score is used for Package Template.

  # Legal
  Foo
  Foo2
  Foo::Bar
  Foo::Bar::Baz
  Foo::bar
  
  # Illegal
  foo
  foo::Bar
  2Foo
  Foo_Bar

Package Declaration must be just under file itself.

  # Legal
  package PackageName {
    
  }
  
  # Illegal
  sub foo() : int {
    package PackageName {
      
    }
  }

Field Declaration

Field declaration is the following.

  has field_name : type_name;

filed_name is field name. Field name is consist of Upper Case and Lower Case and Number and Under Score _. Field name must not start with Number. Under score must not continue more than one.

  # Legal
  foo
  foo_bar
  foo2
  foo_bar2
  FOO
  
  # Illegal
  2foo
  foo__bar

type_name is a type. Type is explained in "Type" section.

Field Declaration must be just under Package Declaration.

  # Legal
  package PackageName {
    has field_name : type_name;
  }

  # Illeagal
  has field_name : type_name;
  sub foo() : int {
    has field_name : type_name
  }

Subroutine Decralation

Subroutine declaration is the following.

  sub sub_name(arg_name : type_name, ...) : descripter_name return_type_name {
    
  }

sub_name is subroutine name. Subroutine name is consist of Upper Case and Lower Case and Number and Under Score _. Subroutine name must not start with Number. Under score must not continue more than one.

  # Legal
  foo
  foo_bar
  foo2
  foo_bar2
  FOO
  
  # Illegal
  2foo
  foo__bar

arg_name is Argument Name. This is Variable name. Variable name is explained in "Variable Declaration" section,

type_name is a Type. Type is explained "Type" section.

arg_name : type_name can be repeated with ,. If argument is none, that is ok. Max arguments count is 255.

descripter_name is a Descripter. If descripter is none, that is ok. Available descripters are following. Currently only one descripter is available.

  [Name]     [Description]
  native     the subroutine is native

Native subroutine is explained in "Native Subroutine".

return_type_name is a Type or void. void mean the subroutine don't have return value. Type is explained "Type" section.

Subroutine Declaration must be just under Package Declaration.

  # Legal
  package PackageName {
    sub foo($nums : int[]) : int {
    
    }
  }
  
  # Illeagal
  sub foo() : double {
    sub var() : void {
      
    }
  }

Variable Declaration

Variable Declaration is the following.

  my var_name : type_name;

var_name is Variable Name. Variable Name first character is $. Rest characters is consist of Upper case, Lower case, Number and Under score _.

  # Legal
  $foo
  $FOO
  $foo2
  $foo_bar

If Variable Declaration is done, you can use variable after the declaration.

type_name is a <Type>. Type is explained "Type" section.

Number literal

Default number literal type is int.

  123

You can use hex number literal by start 0x. A, B, C, D, E, F must be upper case.

  0xAF

If you use . in number literal, the number is floating point literal.

  1.23

You can use E or e to specify exponential notation.

  1.23E+12
  1.23E-12
  1.23e+12
  1.23e-12

You can use under line _ in number literal. Under line is meanless, only for visuality.

  123_456
  0xAB_CD

You can use specifier to specify number leteral type

  • b

      # Byte
      123b
  • s

      # Short
      123s
  • L

      # Long
      123L
  • f

      # Float
      123f
  • d

      # Double
      123d

Type

Numeric type

Numeric types are byte, short, int, long, float, double.

  byte    signed integer          1byte
  short   signed integer          2byte
  int     signed integer          4byte
  long    signed integer          8byte
  float   floating-point number   4byte
  double  floating-point number   8byte

Declaration

  my $value : byte;
  my $value : short;
  my $value : int;
  my $value : long;
  my $value : float;
  my $value : double;

String type

String type is string.

This is same as byte[] at internal data structure.

Declaration

  my $string : string;

Reference type

Reference types are `array` and `object`.

Object type

    PackageName

Declaration

    my $object : PackageName;

Array type

  byte[]   byte array
  short[]  short array
  int[]    int array array
  long[]   long array
  float[]  float array
  doube[]  double array
  PackageName[] object array

Declaration

  my $values : byte[];
  my $values : short[];
  my $values : int[];
  my $values : long[];
  my $values : float[];
  my $values : double[];
  my $values : PackageName[];

Multiple array type

  my $values : byte[][];
  my $values : short[][];
  my $values : int[][];
  my $values : long[][];
  my $values : float[][];
  my $values : double[][];
  my $values : PackageName[][];

  my $values : byte[][][];
  my $values : short[][][];
  my $values : int[][][];
  my $values : long[][][];
  my $values : float[][][];
  my $values : double[][][];
  my $values : PackageName[][][];

Type inference

If the type of right value is known, the type of left value is automatically decided.

  # Type of $value2 is byte.
  my $value1 : byte;
  my $value2 = $value1;

  # Type of $values2 is int[]
  my $values1 = new int[3];
  my $values2 = $values1;

  # Type of $object2 is PackageName
  my $object1 = new PackageName
  my $object2 = $object1;

Array

Create array

Array is created by new. Elements values is not initialized.

  my $nums = new byte[3];
  my $nums = new short[3];
  my $nums = new int[3];
  my $nums = new long[3];
  my $nums = new float[3];
  my $nums = new double[3];

Get array length

  my $len = @$nums;
  my $len = @{$nums};
  my $len = len $nums;

Get and set array element

  # Get
  my $num = $nums->[0];

  # Set
  $nums->[0] = 5;

Condition branch

  if (1) {

  }
  elsif (2) {

  }
  else {

  }

Loop

for

  my $nums = new int[10];
  for (my $i = 0; $i < @$nums; $i++) {
    $nums->[$i] = 0;
  }

while

  my $nums = new int[10];
  my $i = 0;
  while ($i < @$nums) {
    $nums->[$i] = 0;
  }

Constant

Constant type

Type of constant default integral value is `int`.

  # int type
  1;
  3;

Type of constant default floating-point value is `double`.

  # double
  1.2
  5.3

Type of constant is specified by type specifier.

  # long
  3L

  # float
  3.2f

  # double
  3.2d

POD

  =pod
    AAAA
  =cut

__END__

  __END__

Exception

Exception occur

  die "Error";

Catch exception

  eval {
    die "Error";
  };

Exception message

  $@;

Name

Package name

Package name is a combination of alphabets, numbers, and `::`. Numbers should not appear as the first character. `_` can't be used in class name.

  # OK
  Foo
  Foo::Bar
  Foo1::Bar1

  # Not OK
  1Foo
  Foo::2Bar
  Foo_Bar;

Subroutine name

Subroutine name is a combination of alphabets, numbers, and `_` separators. Continual `_`(For example `__`) can't be used in subroutine name.

  # OK
  foo
  foo1
  foo_bar

  # Not OK
  1foo
  foo__bar

Field name

Field name is a combination of alphabets, numbers, and `_` separators. Continual `_`(For example `__`) can't be used in field name.

  # OK
  foo
  foo1
  foo_bar

  # Not OK
  1foo
  foo__bar

Absolute name

Absolute name is combination of package name and subroutine name, or package name and field name.

  PackageName1::foo
  PackageName1::PackageName2::foo_bar

Weak reference

Using weak reference, recursive reference is resolved.

  my $foo = new Foo;
  my $bar = new Bar;
  
  # Recursive reference
  $foo->{bar} = $foo;
  $bar->{foo} = $foo;
  
  # Weak reference
  weaken $foo->{bar};

Destructor

Destructor.

  package Foo {
  
    sub DESTROY($self : Foo) : void {
      
    }
  }

enumeration

Enumeration.

  package Foo {
    enum {
      ONE,
      TWO,
      THREE
    }
    
    enum {
      FORE = 4,
      FIVE,
    }
  }

Extension native function

  package TestCase::Extension {
    sub sum($num1 : int, $num2 : int) : native int;
  }

  __NATIVE__

  #include <spvm_api.h>

  int32_t SPVM__TestCase__Extension__sum(SPVM_API* api, SPVM_API_VALUE* args) {

    int32_t total = args[0].int_value + args[1].int_value;
    
    return total;
  }