=head1 NAME

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

=head1 SPVM Language Specification

SPVM is designed to help Perl week points. Perl week points is:

=over 2

=item * Perl numeric and array operation is slow because Perl can't have Static Type.

=item * Perl can't calcurate number correctly, for exampele, float operation, bit operation of integral type, etc.

=item * Perl can't bind C/C++ library easily becuase Perl don't have type semaintics.

=back

SPVM provide Fast and Correct Numeric and Array operation, and C/C++ binding become much easy.

SPVM Module is used from Perl directory. SPVM is not single language. You can call SPVM subroutine easily from Perl .

If you use SPVM, you can create module which need numeric and array operation.

For example:

AI, Machine Learning, Deep Learning, Statistics, IoT, Image Recognition, Voice Recognition, 
Signal Processing.

SPVM have Numeric Type, Array Type, Package Type. Numeric Type is byte, short, int, long, float, double.
You can calcurate number by these types. Array Type is Contiguous Area of numeric type. Package Type have, for example, x, y field.

SPVM have Type Inference, GC, Memory Safety, Destructor, Package Template. GC is Reference Count GC. Template Package is like C++ Class Template.

=head1 Syntax

=head2 Package Definition

Package Definition is the following.

  package PackageName {
    
  }

C<PackageName> is package name.

Package name is consist of Upper Case and Lower Case and Number and C<::>.
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 C<_>.
Under Score is used for C<Package Template>.

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

Package Definition must be just under file itself.

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

=head2 Field Definition

Field Definition is the following.

  has field_name : type_name;

C<filed_name> is field name. 
Field name is consist of Upper Case and Lower Case and Number and Under Score C<_>.
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

C<type_name> is a type. Type is explained in L</"Type"> section.

Field Definition must be just under Package Definition.

  # Legal
  package PackageName {
    has field_name : type_name;
  }

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

=head3 Accessor Decralation

Accessor is a subroutine to get and set field.

B<Set Accessor Definition:>

  set x, y;

This is same as the following Subroutine Definition if x and y is int field of Point package.

  sub set_x : void ($self : Point, $value : int) { $self->{x} = $value }
  sub set_y : void ($self : Point, $value : int) { $self->{y} = $value }
  
If field is not exsit or same name subroutine is defined, Accessor Definition is compile error.

B<Get Accessor Definition:>

  get x, y;

This is same as the following Subroutine Definition if x and y is int field of Point package.

  sub get_x : int ($self : Point) { return $self->{x} }
  sub get_y : int ($self : Point) { return $self->{y} }

If field is not exsit or same name subroutine is defined, Accessor Definition is compile error.

=head2 Subroutine Decralation

Subroutine Definition is the following.

  descripter_names sub sub_name : type_name (arg_name : type_name, ...) {
    
  }

C<sub_name> is subroutine name. 
Subroutine name is consist of Upper Case and Lower Case and Number and Under Score C<_>.
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

C<arg_name> is Argument Name. This is Variable name. Variable name is explained in L</"Variable Declaration"> section,

C<type_name> is a Type. Type is explained L</"Type"> section.

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

C<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 L</"Native Subroutine">.

C<return_type_name> is a Type or C<void>. C<void> mean the subroutine don't have return value.
Type is explained L</"Type"> section.

Subroutine Definition must be just under Package Definition.

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

=head2 Variable Declaration

Variable Declaration is the following.

  my var_name : type_name;

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

  # Legal
  $foo
  $FOO
  $foo2
  $foo_bar

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

C<type_name> is a <Type>. Type is explained at L</"Type"> section.

You can Initialize the variable as same time as Variable Declaration.

  my $num : int = 3;

B<Variable Declaration Example:>
  
  # Numeric Type
  my $value : byte;
  my $value : short;
  my $value : int;
  my $value : long;
  my $value : float;
  my $value : double;
  
  # Array Type
  my $values : byte[];
  my $values : short[];
  my $values : int[];
  my $values : long[];
  my $values : float[];
  my $values : double[];
  my $values : PackageName[];

  # Multiple Dimension Array Type
  my $values : byte[][];
  my $values : short[][];
  my $values : int[][];
  my $values : long[][];
  my $values : float[][];
  my $values : double[][];
  my $values : PackageName[][];

  # Package Type
  my $obj : PackageName;

=head2 Type Inference

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

  my $num = 2;
  my $obj = new Foo;
  my $values = new int[3];

Above is same as the following.

  my $num : int = 2;
  my $obj : Foo = new Foo;
  my $values : int[3] = new int[3];

=head2 Number Literal

=head3 Integer Literal

Integer Literal is composed of 

   [+|-][0x][0123456789abcdefABCDEF]...[y|s|L|f|d]

For example:

  123
  -123
  0xff
  0xFF
  123L
  123d

Default Number Literal Type is C<int>.
  
  # Type is int
  123

You can use hex number literal by start C<0x>.

C<a>, C<b>, C<c>, C<d>, C<e>, C<f>, C<A>, C<B>, C<C>, C<D>, C<E>, C<F> is used as hex number.

  0xAF
  0xaf

You can use octal number literal by start C<0>.

  0x177
  0x777

You can use binary number literal by start C<0b>.

  0b101
  0b001

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

  123_456
  0xAB_CD

You can use type specifier to specify integer leteral type.

=over 2

=item * y

  # Byte
  123y

=item * s
  
  # Short
  123s

=item * L
  
  # Long
  123L

=item * f
  
  # Float
  123f

=item * d

  # Double
  123d

=back

=head3 Floating Point Literal

If you use C<.> in number literal, the number is floating point literal. Default type of floating point value is C<double>.

  1.23
  -1.23

You can use C<E> or C<e> to specify exponential notation.

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

You can use type specifier to specify integer leteral type.

=over 2

=item * f
  
  # Float
  1.23f

=item * d

  # Double
  1.23d

=back

If you know more Type, see L</"Type"> section.

=head2 String Literal

String Literal is the following.

  "abc"

Type of String literal is C<byte[]>.

  my $string : byte[] = "abc";

Note that String Literal is Not Shared. New Byte Array is created and String literal is Copied to the byte array. 

=head3 Escape Sequences

A character preceded by a backslash (\) is an escape sequence and has special meaning to the compiler. The following table shows the SPVM escape sequences:

  [Escape Sequences]    [Escape Sequence	Description]
  \t                    Insert a tab in the text at this point.
  \b                    Insert a backspace in the text at this point.
  \n                   	Insert a newline in the text at this point.
  \r                    Insert a carriage return in the text at this point.
  \f                    Insert a formfeed in the text at this point.
  \'                    Insert a single quote character in the text at this point.
  \"                    Insert a double quote character in the text at this point.
  \\                    Insert a backslash character in the text at this point.

=head2 Undefined Literal

Undefined Literal is:

  undef

=head2 Type

The SPVM programming language is a statically typed language, which means that every variable and every expression has a type that is known at compile time.

The SPVM programming language is also a strongly typed language, because types limit the values that a variable can hold or that an expression can produce, limit the operations supported on those values, and determine the meaning of the operations. Strong static typing helps detect errors at compile time.

The types of the SPVM programming language are divided into two categories: numeric types and reference types. The numeric types are the numeric types. The numeric types are the integral types byte, short, int, long, and the floating-point types float and double. The reference types are package types, and array types. There is also a special undef type. An object is a dynamically created instance of a package type or a dynamically created array. The values of a reference type are references to objects. String literals are represented by array of byte.

=head3 Numeric Type

Numeric types are C<byte>, C<short>, C<int>, C<long>, C<float>, C<double>.
  
  [Type]  [Type Description]   [Type Bit Size]
  byte    Integral type        8-bit
  short   Integral type        16-bit
  int     Integral type        32-bit
  long    Integral type        64-bit
  float   floating-point type  32-bit
  double  floating-point type  64-bit

Numeric values do not share state with other numeric values.

The numeric types are the integral types and the floating-point types.

The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit
signed two's-complement integers.

The floating-point types are float, whose values include the 32-bit IEEE 754 floating-point numbers, and double,
whose values include the 64-bit IEEE 754 floating-point numbers.

B<The values of the integral types are integers in the following ranges:>

For byte, from -128 to 127, inclusive

For short, from -32768 to 32767, inclusive

For int, from -2147483648 to 2147483647, inclusive

For long, from -9223372036854775808 to 9223372036854775807, inclusive

B<Varialbe Definition>

Varialbe Definition with Type is the following.

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

If you know more Variable Declaration, see L</"Variable Declaration"> section.

=head3 Array Type

Array Type describe multiple values.

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

Array Type is a Object Type. You can create Array by C<new> keyword.

  my $values : int[] = new int[3];

If you know more Array Creating, see L</"New Array"> section.

=head3 Multiple Dimention Array Type

Multiple Dimention Array Type is a Array Type.
  
B<Two Dimension Array Type>

  byte[][];
  short[][];
  int[][];
  long[][];
  float[][];
  double[][];
  PackageName[][];
  
B<Three Dimension Array Type>

  byte[][][];
  short[][][];
  int[][][];
  long[][][];
  float[][][];
  double[][][];
  PackageName[][][];
  
Max Dimension is C<255>.

You can create Multiple Dimension Array by C<new> keyword.

  my $values : int[][] = new int[][3];

This mean that Multiple Dimension Array is created, the multiple dimension array have 3 C<int[]> type array.
The elements is initialized by C<undef>.

If you know Multiple Dimension Array Creating, see L</"New Multiple Dimention Array">.

=head3 Package Type

If Package is defined, Package name is used as Type.

  PackageName

If you know more Package Definition, see L</"Package Definition"> section.

You can create Object by C<new> subroutine. This is Default Constructor.

  my $obj : PackageName = PackageName::new();

=head2 New Array

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

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

=head2 Array Initialization

Array Initialization Syntax:

  my $values = new int[] {1, 2, 3};
  my $points = new Point[] {Point::new(), Point::new(), Point::new()};

=head2 Array Manipulation

=head3 Get Array Length

You can use the three ways to get Array Length.

  @$values;
  @{$values};
  len $values;

=head3 Get and Set Array Element

Get Array Element:

  # Get
  $values->[0];

Set Array Element:

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

=head2 Object Manipulation

=head3 Field Access

Get field:

  # Get field
  $object->{foo};

Set field:

  # Set field;
  $object->{foo} = 5;

Field value is private. You can only use Field Access from self package.

If you want to get and set field value from other package, you must define Accessor.

see L</"Accessor Definition">.

=head2 Condition branch

  if (1) {

  }
  elsif (2) {

  }
  else {

  }

=head2 Loop Syntax

=head3 for statement

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

=head3 while statement

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

=head2 Comment

Comment:

  # Comment

=head2 POD

Pod syntax:

  =pod
    AAAA
    BBBB
  =cut

=head2 __END__

Script Ending:

  __END__

=head2 Exception

=head3 Throw Exception

Throw Exception:

  croak "Error";

=head3 Catch Exception

Catch Exception:

  eval {
    croak "Error";
  };

=head3 Exception Message

  $@;

=head3 Exception Detail

B<Call subroutine>

1. If exception don't occur in the subroutine and subroutine return back, undef is assigned to $@.

2. If exception occur in the subroutine and subroutine return back, error message which has String type is assigned to $@.

B<In called subroutnie>

1. At start of subroutine, $@ is initialized to undef.

2. At start of eval block, $@ is initialized to undef.

2. If croak is used, Error message is assigned to $@.

3. If croak is surrounded by eval block, the process jump to the end of eval block.

4. If croak is not surrounded by eval block, the process return from the subroutine. Return value is each type of default value(0 or undef).

=head2 Constructor

=head3 new operator

Constructor is C<new> operator.

  new Point;

C<new> operator is private. C<new> operator is only used in same package.

=head3 Default Constructor

If C<new> subroutine is not defined, Default Constructor is defined automatically.

  sub new () { return new Point }

This is used from other package.

  my $point = Point::new();

=head2 Destructor

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

=head2 Enumeration

Enumeration.

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

=head2 Weak Reference

=head3 weaken operator

Using Weak Reference, recursive reference is resolved.

  my $foo = Foo::new();
  my $bar = Bar::new();
  
  # Recursive reference
  $foo->set_bar($foo);
  $bar->set_foo($bar);
  
  # Weak reference
  $foo->weaken_bar;

Foo package;

  package Foo {
    has bar;
    
    set bar;
    
    sub wekan_bar : void () {
      weaken $foo->{bar};
    }
  }


=head2 Extension native function

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

=head2 Operators

=head3 Assign Operator

  =

B<Special Assign Operator>

  +=
  -=
  *=
  /=
  &=
  |=
  ^=
  %=
  <<=
  >>=
  >>>=

=head2 Basic Operator

  +
  -
  *
  /
  %

=head3 Comparison Operator

  ==
  !=
  >
  <
  <=
  >=

=head3 Logical Operator

  &&
  ||
  !

=head3 Bit Operator

  <<
  >>
  >>>
  &
  |
  ^
  ~

=head3 Increment/Decrement Operator

  ++
  --
