SPVM::Document::LanguageSpecification - SPVM Language Specification
SPVM Language Specification.
For example, if SPVM multiple Numeric Type
package Point_2i: mulnum_t {has x: int; has y: int;}
matches the Type declared in C99
int32_t var[2];
Foo Foo::Bar Foo::Bar::Baz3 Foo::bar Foo_Bar::Baz_Baz
foo _Foo Foo::::Bar Foo::Bar:: Foo__Bar Foo::bar
# Valid Method Name FOO FOO_BAR3 foo foo_bar _foo _foo_bar_ # Invalid Method Name foo__bar
# Valid Field Name FOO FOO_BAR3 foo foo_bar _foo _foo_bar_ # Invalid Field Name 3foo foo__bar
# Valid Package Variable Name $FOO::BAR $Foo::Bar3 $FOO $FOO_BAR $foo # Invalid Package Variable Name $FOO__BAR $3FOO
# Valid Lexical Variable Name $foo $foo_bar3 $_foo $FOO # Invalid Lexical Variable Name $foo__bar $3foo
allow byte INIT case die warn print default double elsif else enum eq eval for float gt ge has if callback_t isa int last break length lt le long my native ne next new our object package private public precompile pointer_t return require rw ro self switch sub string short scalar undef unless use void mulnum_t while weaken wo __END__ __PACKAGE__ __FILE__ __LINE__
( ) { } [ ] ; , ->=>
=>
# Comma ["a", "b", "c", "d"] # Use Fat Comma instead of Comma ["a" => "b", "c" => "d"]
# Identifiers placed on the Left of Fat Comma are treated as String Literal # a is "a", c is "c" [a => "b", c => "d"]
= > < ! ~ == <= >= != <=> && || ++ -- + - * / & | ^ % << >> >>> += -= *= /= &= |= ^= %= <<= >>= >>>= \ $ @ . .= cmp length isa ref
%token PACKAGE HAS SUB OUR ENUM MY SELF USE REQUIRE ALLOW %token DESCRIPTOR %token IF UNLESS ELSIF ELSE FOR WHILE LAST NEXT SWITCH CASE DEFAULT BREAK EVAL %token NAME VAR_NAME CONSTANT EXCEPTION_VAR %token UNDEF VOID BYTE SHORT INT LONG FLOAT DOUBLE STRING OBJECT %token DOT3 FATCAMMA RW RO WO INIT NEW %token RETURN WEAKEN DIE WARN CURRENT_PACKAGE UNWEAKEN '[' '{' '(' %type grammar %type opt_packages packages package package_block %type opt_declarations declarations declaration %type enumeration enumeration_block opt_enumeration_values enumeration_values enumeration_value %type sub cb_obj opt_args args arg invocant has use require our %type opt_descriptors descriptors sub_names opt_sub_names %type opt_statements statements statement if_statement else_statement %type for_statement while_statement switch_statement case_statement default_statement %type block eval_block begin_block switch_block if_require_statement %type unary_op binary_op comparison_op isa logical_op expression_or_logical_op %type call_sub opt_vaarg %type array_access field_access weaken_field unweaken_field isweak_field convert array_length %type assign inc dec allow %type new array_init %type my_var var %type expression opt_expressions expressions opt_expression case_statements %type field_name sub_name %type type basic_type array_type array_type_with_length ref_type type_or_void %right ASSIGN SPECIAL_ASSIGN %left LOGICAL_OR %left LOGICAL_AND %left BIT_OR BIT_XOR %left '&' %nonassoc NUMEQ NUMNE STREQ STRNE %nonassoc NUMGT NUMGE NUMLT NUMLE STRGT STRGE STRLT STRLE ISA NUMERIC_CMP STRING_CMP %left SHIFT %left '+' '-' '.' %left MULTIPLY DIVIDE REMAINDER %right LOGICAL_NOT BIT_NOT '@' REF DEREF PLUS MINUS CONVERT SCALAR STRING_LENGTH ISWEAK REFCNT REFOP DUMP %nonassoc INC DEC %left ARROW %% grammar : opt_packages opt_packages : /* Empty */ | packages packages : packages package | package package : PACKAGE basic_type package_block | PACKAGE basic_type ':' opt_descriptors package_block | PACKAGE basic_type ';' | PACKAGE basic_type ':' opt_descriptors ';' package_block : '{' opt_declarations '}' opt_declarations : /* Empty */ | declarations declarations : declarations declaration | declaration declaration : has | sub | enumeration | our ';' | use | allow | begin_block begin_block : INIT block use : USE basic_type ';' | USE basic_type '(' opt_sub_names ')' ';' require : REQUIRE basic_type allow : ALLOW basic_type ';' enumeration : opt_descriptors ENUM enumeration_block enumeration_block : '{' opt_enumeration_values '}' opt_enumeration_values : /* Empty */ | enumeration_values enumeration_values : enumeration_values ',' enumeration_value | enumeration_values ',' | enumeration_value enumeration_value : sub_name | sub_name ASSIGN CONSTANT our : OUR PACKAGE_VAR_NAME ':' opt_descriptors type has : HAS field_name ':' opt_descriptors type ';' sub : opt_descriptors SUB sub_name ':' type_or_void '(' opt_args opt_vaarg')' block | opt_descriptors SUB sub_name ':' type_or_void '(' opt_args opt_vaarg')' ';' cb_obj : opt_descriptors SUB ':' type_or_void '(' opt_args opt_vaarg')' block | '[' args ']' opt_descriptors SUB ':' type_or_void '(' opt_args opt_vaarg')' block opt_args : /* Empty */ | args | invocant | invocant ',' args args : args ',' arg | args ',' | arg arg : var ':' type opt_vaarg : /* Empty */ | DOT3 invocant : var ':' SELF opt_descriptors : /* Empty */ | descriptors descriptors : descriptors DESCRIPTOR | DESCRIPTOR opt_statements : /* Empty */ | statements statements : statements statement | statement statement : if_statement | for_statement | while_statement | block | switch_statement | case_statement | default_statement | eval_block | if_require_statement | expression ';' | LAST ';' | NEXT ';' | RETURN ';' | RETURN expression ';' | DIE ';' | DIE expression ';' | WARN ';' | WARN expression ';' | PRINT expression ';' | weaken_field ';' | unweaken_field ';' | ';' for_statement : FOR '(' opt_expression ';' expression_or_logical_op ';' opt_expression ')' block while_statement : WHILE '(' expression_or_logical_op ')' block switch_statement : SWITCH '(' expression ')' switch_block switch_block : '{' case_statements '}' | '{' case_statements default_statement '}' case_statements : case_statements case_statement | case_statement case_statement : CASE expression ':' block | CASE expression ':' default_statement : DEFAULT ':' block | DEFAULT ':' if_require_statement : IF '(' require ')' block | IF '(' require ')' block ELSE block if_statement : IF '(' expression_or_logical_op ')' block else_statement | UNLESS '(' expression_or_logical_op ')' block else_statement else_statement : /* NULL */ | ELSE block | ELSIF '(' expression_or_logical_op ')' block else_statement block : '{' opt_statements '}' eval_block : EVAL block ';' opt_expressions : /* Empty */ | expressions opt_expression : /* Empty */ | expression expression_or_logical_op : expression | logical_op expression : var | EXCEPTION_VAR | package_var_access | CONSTANT | UNDEF | call_sub | field_access | array_access | convert | new | array_init | array_length | my_var | binary_op | unary_op | assign | inc | dec | '(' expressions ')' | CURRENT_PACKAGE | isweak_field | comparison_op | isa expressions : expressions ',' expression | expressions ',' | expression unary_op : '+' expression %prec PLUS | '-' expression %prec MINUS | BIT_NOT expression | REFCNT var | REFOP expression | STRING_LENGTH expression | DUMP expression | DEREF var | REF var inc : INC expression | expression INC dec : DEC expression | expression DEC binary_op : expression '+' expression | expression '-' expression | expression MULTIPLY expression | expression DIVIDE expression | expression REMAINDER expression | expression BIT_XOR expression | expression '&' expression | expression BIT_OR expression | expression SHIFT expression | expression '.' expression comparison_op : expression NUMEQ expression | expression NUMNE expression | expression NUMGT expression | expression NUMGE expression | expression NUMLT expression | expression NUMLE expression | expression NUMERIC_CMP expression | expression STREQ expression | expression STRNE expression | expression STRGT expression | expression STRGE expression | expression STRLT expression | expression STRLE expression | expression STRING_CMP expression isa : expression ISA type logical_op : expression_or_logical_op LOGICAL_OR expression_or_logical_op | expression_or_logical_op LOGICAL_AND expression_or_logical_op | LOGICAL_NOT expression_or_logical_op | '(' logical_op ')' assign : expression ASSIGN expression | expression SPECIAL_ASSIGN expression new : NEW basic_type | NEW array_type_with_length | cb_obj array_init : '[' opt_expressions ']' | '{' expressions '}' | '{' '}' convert : '(' type ')' expression %prec CONVERT array_access : expression ARROW '[' expression ']' | array_access '[' expression ']' | field_access '[' expression ']' call_sub : NAME '(' opt_expressions ')' | basic_type ARROW sub_name '(' opt_expressions ')' | basic_type ARROW sub_name | expression ARROW sub_name '(' opt_expressions ')' | expression ARROW sub_name | expression ARROW '(' opt_expressions ')' field_access : expression ARROW '{' field_name '}' | field_access '{' field_name '}' | array_access '{' field_name '}' weaken_field : WEAKEN var ARROW '{' field_name '}' unweaken_field : UNWEAKEN var ARROW '{' field_name '}' isweak_field : ISWEAK var ARROW '{' field_name '}' array_length : '@' expression | '@' '{' expression '}' | SCALAR '@' expression | SCALAR '@' '{' expression '}' my_var : MY var ':' type | MY var var : VAR_NAME package_var_access : PACKAGE_VAR_NAME type : basic_type | array_type | ref_type basic_type : NAME | BYTE | SHORT | INT | LONG | FLOAT | DOUBLE | OBJECT | STRING ref_type : basic_type '&' array_type : basic_type '[' ']' | array_type '[' ']' array_type_with_length : basic_type '[' expression ']' | array_type '[' expression ']' type_or_void : type | VOID field_name : NAME sub_name : NAME opt_sub_names : /* Empty */ | sub_names sub_names : sub_names ',' sub_name | sub_names ',' | sub_name %%
# Comment
=pod Multi-Line Comment =cut =head1 Multi-Line Comment =cut
package PACAKGE_NAME { }
package PACAKGE_NAME : PACAKGE_DESCRIPTOR { } package PACAKGE_NAME : PACAKGE_DESCRIPTOR1 PACAKGE_DESCRIPTOR2 PACAKGE_DESCRIPTORN { }
# Package Name package Point { }
# Package Name and Package Descriptor package Point : public { }
package Foo { # use use Point; # Package Variable Definition our $VAR int; # Field Defintion has var : int; # Enumeration Definition enum { CONST_VAL1, CONST_VAL2, } # Method Definition sub foo : int ($num : int) { } }
sub DESTROY : void ($self : self) { }
package Foo { sub new : Foo { return new Foo; } sub DESTROY : void ($self : self) { print "DESTROY"; } }
allow PACKAGE_NAME;
package Foo { allow Bar; }
# lib/path/Foo/Bar.spvm package Foo::Bar { }
# lib/path/Foo/Bar.spvm package Foo::Bar { } package Foo::Bar::Baz { }
Foo.spvm Foo/Bar.spvm Foo/Bar/Baz.spvm
use Foo; use Foo::Bar;
package Foo { use Foo; }
if (require Foo) { }
if (require Foo) { } else { }
my $foo : object; if (require Foo) { $foo = new Foo; } else { warn "Warning: Can't load Foo"; }
use Foo(method1, method2);
our PACKAGE_VARIABLE_NAME : TYPE;
our PACKAGE_VARIABLE_NAME : DESCRIPTOR TYPE; our PACKAGE_VARIABLE_NAME : DESCRIPTOR1 DESCRIPTOR2 DESCRIPTORN TYPE;
package Foo { our $NUM1 : byte; our $NUM2 : short; our $NUM3 : int; our $NUM4 : long; our $NUM5 : float; our $NUM6 : double; our $NUM_PUBLIC : public int; our $NUM_RO : ro int; our $NUM_WO : wo int; our $NUM_RW : rw int; }
package Foo { our $VAR : int; INIT { $VAR = 3; } }
has FIELD_NAME : TYPE;
has FIELD_NAME : DESCRIPTOR TYPE_NAME; has FIELD_NAME : DESCRIPTOR1 DESCRIPTOR2 DESCRIPTORN TYPE_NAME;
package Foo { has num1 : byte; has num2 : short; has num3 : int; has num4 : long; has num5 : float; has num6 : double; has num_public : public int; has num_ro : ro int; has num_wo : wo int; has num_rw : rw int; }
EXPRESSION->{FIELD_NAME}
my $point = new Point; $point->{x} = 1;
my $z : SPVM::Complex_2d; $z->{x} = 1; $z->{y} = 3;
my $z : SPVM::Complex_2d; my $z_ref = \$z; $z_ref->{x} = 1; $z_ref->{y} = 3;
sub SUBROUTINE_NAME : RETURN_VALUE_TYPE_NAME () { } sub SUBROUTINE_NAME : RETURN_VALUE_TYPE_NAME (ARGUMENT_NAME1 : ARGUMENT_TYPE_NAME1, ARGUMENT_NAME2 : ARGUMENT_TYPE_NAME2, ARGUMENT_NAMEN : ARGUMENT_TYPE_NAMEN) { }
DESCRIPTOR1 DESCRIPTOR2 DESCRIPTORN sub SUBROUTINE_NAME : RETURN_VALUE_TYPE_NAME () { } DESCRIPTOR1 DESCRIPTOR2 DESCRIPTORN sub SUBROUTINE_NAME : RETURN_VALUE_TYPE_NAME (ARGUMENT_NAME1 : ARGUMENT_TYPE_NAME1, ARGUMENT_NAME2 : ARGUMENT_TYPE_NAME2, ARGUMENT_NAMEN : ARGUMENT_TYPE_NAMEN) { }
sub SUBROUTINE_NAME : RETURN_VALUE_TYPE_NAME (ARGUMENT_NAME1 : ARGUMENT_TYPE_NAME1, ARGUMENT_NAME2 : ARGUMENT_TYPE_NAME2...) { }
# Variable Length Argument Definition sub sprintf : string ($format : string, $values : object[]...) { } # Call Variable Length Argument Method with multi values. sprintf("Value %d %f", 1, 2.0);
# Call Variable Length Argument Method with Array. sprintf("Value %d %f", [(object)1, 2.0]);
sprintf("aaa %p", (object)[(object)1, 2.0]);
sub foo : int () { return 5; } sub foo : long () { return 5L; } sub foo : float () { return 5.0f; } sub foo : double () { return 5.0; }
# This is not Constant Method. Inline Expansion is not performed sub foo : int () { return 5 + 3; }
sub SUB_NAME : TYPE ($self : self, ARGUMENT2 : TYPE2, ARGUMENT3 : TYPE3, ARGUMENTN : TYPEn) { }
# Method Definition sub foo : int ($num1 : double, $num2 : long[]) # Signature int(double,long[]) # Method Definition sub foo : void () # Signature void()
Method Callstack save the folloing information.
1. Memroy area for Lexical Variable
2. The places of Mortal Lexical Variable
# Enumeration Definition enum { FLAG1, FLAG2, FLAG3 }
package Foo { enum { FLAG1, FLAG2, FLAG3 } }
enum { FLAG1, FLAG2, FLAG3, }
sub FLAG1 : int () { return 0; } sub FLAG2 : int () { return 1; } sub FLAG3 : int () { return 2; }
enum { FLAG1, FLAG2 = 4, FLAG3, }
private enum { FLAG1, FLAG2 = 4, FLAG3, }
my $flag1 = Foo->FLAG1; my $flag2 = Foo->FLAG2; my $flag3 = Foo->FLAG3;
In special case, Enumeration Call can be used in case Statement of switch Statement.
switch ($num) { case Foo->FLAG1: { break; } case Foo->FLAG2: { break: } case Foo->FLAG3: { break: } default: { } }
INIT { }
package Foo { INIT { } }
INIT { my $foo = 1 + 1; my $bar; }
package Foo { use Point; our $NUM : int; our $POINT : Point; INIT { $NUM = 3; $POINT = Point->new; } }
my LEXICAL_VARIABLE_NAME : TYPE;
# Lexical Variable Declaration Examples my $var : int; my $var : Point; my $var : SPVM::Complex_2d; my $var : int&;
# 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 : SPVM::Complex_2d;
# 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;
# int my $num = 1; # double my $num = 1.0;
my $ppp = my $bar = 4; if (my $bar = 1) { } while (my $bar = 1) { }
# Scope Block { # Start of Scope # ... # End of Scope }
{ # $num become Mortal Variable in run-time my $num = new Foo; }
# Block { }
# Simple Block { }
# Method Block sub foo : int () { }
# eval Block eval { }
# if Block if (EXPRESSION) { }
#elsif Block elsif (EXPRESSION) { }
# else Block else { }
# for Block for (my $i = 0; $i < 3; $i++) { }
# while Block while (EXPRESSION) { }
switch (EXPRESSION) { }
123 +123 -123 123L 123l 123_456_789 -123_456_789L
0x3b4f -0x3F1A 0xDeL 0xFFFFFFFF_FFFFFFFF
0755 -0644 0666L 0655_755
0b0101 -0b1010 0b110000L 0b10101010_10101010
# Floating Point Literal [Sign Part][Numeric Part][Exponent Part][Suffix Part]
# Exponent Part [Exponential Notation][Signed Decimal Integer]
1.32 -1.32 1.32f 1.32F 1.32e3 1.32e-3 1.32E+3 1.32E-3 0x3d3d.edp0 0x3d3d.edp3 0x3d3d.edP3 0x3d3d.edP-3f
# Charater Literal 'a' 'x' # Charater Literal using Escape Character '\a' '\b' '\t' '\n' '\f' '\r' '\"' '\'' '\\' '\x0D' '\x0A'
# String Literal "abc" "あいう" # Escape Character of String Literal "abc\tdef\n" "\x0D\x0A" "\N{U+3042}\N{U+3044}\N{U+3046}"
"AAA $foo BBB" "AAA $FOO BBB" "AAA $$foo BBB" "AAA $foo->{x} BBB" "AAA $foo->[3] BBB" "AAA $foo->{x}[3] BBB" "AAA $@ BBB"
"AAA" . $foo . "BBB" "AAA" . $FOO . "BBB" "AAA" . $$foo . "BBB" "AAA" . $foo->{x} . "BBB" "AAA" . $foo->[3] . "BBB" "AAA" . $foo->{x}[3] . "BBB" "AAA" . $@ . "BBB"
"AAA ${foo}_ccc BBB"
The above is expanded as the following.
"AAA " . ${foo} . "_ccc BBB"
"AAA$"
# String is Array of byte Type my $string : string = "Hello"; my $char0 = $string->[0]; my $char1 = $string->[1]; my $char2 = $string->[2]; # Compile Error because String Type is immutable. $string_const->[0] = 'd'; # Create new String using Type Convertion; my $bytes = new byte[3]; $bytes->[0] = 'a'; $bytes->[1] = 'b'; $bytes->[2] = 'c'; my $string = (string)$bytes;
undef
ARRAY->[INDEX]
# Three consecutive 32bit signed integers package Point_3i : mulnum_t { has x : int; has y : int; has z : int; } # Tow consecutive 64bit floating point numbers package Complex_2d : mulnum_t { x : double; y : double; }
my $points = new Point_3i[5];
my $point : Point_3i; my $point_ref = \$point;
use Point_3i; use Complex_2d;
my $point : Point_3i; my $z : Complex_2d;
MULTI_NUMERIC_TYPE_VALUE->{FIELD_NAME}
my $points = new Point_3i[5]; my $zs = new Complex_2d[5];
Array->[INDEX]
# Numeric Type Reference my $num : int; my $num_ref : int& = \$num; # Multi Numeric Type Reference my $point : Point_3d; my $point_ref : Point_3d& = \$point;
# Method Definition sub sum : void ($out_ref : int&, $in1 : int, $in2 : int) { $$out_ref = $in1 + $in2; } # Method Call my $num1 = 1; my $num2 = 2; my $out : int; my $out_ref = \$out; sum($out_ref, $num1, $num2);
# Dereference Numeric Type Reference to get the pointed value my $num2 = $$num_ref; # Dereference Numeric Type Reference to set the pointed value $$num_ref = 3; # Dereference Mutil Numeric Type Reference to get the pointed value my $point2 = $$point_ref; # Dereference Mutil Numeric Type Reference to set the pointed value $$point_ref = $point2;
# If the target of Reference Type is Multi Numeric Type, get Multi Numeric Type Field Value my $x = $point_ref->{x}; # If the Target of Reference Type is Multi Numeric Type, set Multi Numeric Type Field Value $point_ref->{x} = 1;
$var
$var = RIGHT_EXPRESSION
$PACKAGE_NAME::PACKAGE_VARIABLE_NAME
$PACKAGE_VARIABLE_NAME
package Foo { our $VAR : int; sub bar : int () { my $var1 = $Foo::VAR; my $var2 = $VAR; } }
$PACKAGE_NAME::PACKAGE_VARIABLE_NAME = RIGHT_EXPRESSION
$PACKAGE_VARIABLE_NAME = RIGHT_EXPRESSION
package Foo { our $VAR : int; sub bar : int () { $Foo::VAR = 1; $VAR = 3; } }
$@
eval { foo(); }; if (my $message = $@) { }
$@ = RIGHT_EXPRESSION
$@ = "Error";
INVOCANT_EXPRESSION->{FIELD_NAME}
my $point = Point->new; my $x = $point->{x};
INVOCANT_EXPRESSION->{FIELD_NAME} = RIGHT_EXPRESSION
my $point = Point->new; $point->{x} = 1;
Invocant Expression is Multi Numeric Type. If Invocant Expression is Class Type, the Field Access is . If Invocant Expression is Multi Numeric Reference Type, the Field Access is Get Multi Numeric Field Value via Dereference, otherwise Compile Error occurs. If the Field Name does not found in the Package, Compile Error occurs Get Multi Numeric Field Value Expression returns the field value in the Multi Numeric Value. Retrun Type is The Type of the Field. Get Multi Numeric Field Value Example:
my $z : SPVM::Complex_2d; my $re = $z->{x};
my $z : SPVM::Complex_2d; $z->{x} = 2.5;
my $z : SPVM::Complex_2d; my $z_ref = \$z; my $re = $z_ref->{x};
my $z : SPVM::Complex_2d; my $z_ref = \$z; $z_ref->{x} = 2.5;
ARRAY_EXPRESSION->[INDEX_EXPRESSION]
my $nums = new int[3]; my $num = $nums->[1]; my $points = new Point[3]; my $point = $points->[1]; my $objects : oarray = $points; my $object = (Point)$objects->[1];
ARRAY_EXPRESSION->[INDEX_EXPRESSION] = RIGHT_EXPRESSION
my $nums = new int[3]; $nums->[1] = 3; my $points = new Point[3]; $points->[1] = Point->new(1, 2); my $objects : oarray = $points; $objects->[2] = Point->new(3, 5);
my $object = new PACKAGE_NAME;
my $object = new Foo;
new Type[ELEMENTS_COUNT_EXPRESSION]
my $nums = new int[3]; my $objects = new Foo[3]; my $objects = new object[3]; my $values = new Complex_2d[3]
# 2 Dimention Array (3 elements of int[] Type) my $nums = new int[][3]; # 3 Dimention Array (3 elements of int[][] Type) my $nums = new int[][][3];
SPVM has a syntax for Array Initialization to simplify Create Array. Expression is not required.
[] [Expression1, Expression2, Expression3]
Array Initialization returns an Array that has the length of the number of elements of Expression.
The type of Array is the type of Expression1 converted to Array Type. If no element is specified, it will be an Array Type of Any Object Type.
If Expression2 or later does not satisfy Type Compatibility, a Compile Error will occur.
# int array my $nums = [1, 2, 3]; # double array my $nums = [1.5, 2.6, 3.7]; # string array my $strings = ["foo", "bar", "baz"];
{} {Expression1, Expression2, Expression3, Expression4}
# Key values empty my $key_values = {}; # Key values my $key_values = {foo => 1, bar => "Hello"};
PackageName->MethodName(ARGS1, ARGS2, ARGS3, ..., ARGSn);
my $ret = Foo->bar(1, 2, 3);
use Foo(MethodName);
MethodName(ARGS1, ARGS2, ARGS3, ..., ARGSn);
package Foo { use SPVM::Math(sin); sub test : void () { my $ret = sin(3.0); } }
Method Call is a method to call Method which is Method. In Method Definition, the first argument is self Type If the argument of> is specified, it becomes Method.
Method Call can be done with the following syntax using the object created by Create Object.
OBJECT_EXPRESSION->SUB_NAME(ARGS1, ARGS2, ARGS3, ..., ARGSn);
Method Call takes arguments. If the number of arguments does not match the number of arguments defined in the Method Definition, Compile Error occurs The Type of each argument and the type of the argument defined in Method Definition and Type Compatibility, Compile Error occurs
Method Call returns Return Value if Return Value is other than void Type.
Method Call is Expression.
Method Call Example
my $point = new Point; $point->set_x(3);
Since the object created by Create Callback Object is a normal object, you can call Method.
OBJECT_EXPRESSION->(ARGS1, ARGS2, ARGS3, ..., ARGSn);
Example that calls Method from the object created with Create Callback Object
An Example that calls a Method from the object created by Create Callback Object.
my $cb_obj = sub : int ($self: self, $num1 : int, $num2 : int) { return $num1 + $num2; }; my $ret = $cb_obj->(1, 2);
Obtaining a value by Dereference is an operation to obtain the actual value from Reference. It was designed to realize the C joint operator "*".
$VARIABLE
The variable Type must be Reference Type, otherwise Compile Error occurs.
The value obtained by Dereference returns Expression.
Example of getting value by Dereference
my $num : int; my $num_ref : int& = \$num; my $num_deref : int = $$num_ref; my $z : SPVM::Complex_2d; my $z_ref : SPVM::Complex_2d& = \$z; my $z_deref : SPVM::Complex_2d = $$z_ref;
Setting a value with Dereference is an operation to set the actual value from Reference. It was designed to realize the C joint operator "*".
$VARIABLE = Expression
The Type of Expression must match the Type of the variable when dereferenced, otherwise Compile Error occurs.
Setting a value with Dereference returns the set value. This is Expression.
Example of setting values with Dereference
my $num : int; my $num_ref : int& = \$num; $$num_ref = 1; my $z : SPVM::Complex_2d; my $z_ref : SPVM::Complex_2d& = \$z; my $z2 : SPVM::Complex_2d; $$z_ref = $z2;
__PACKAGE__
Get Current Package Name Example:
package Foo::Bar { sub baz : void () { # Foo::Bar my $package_name == __PACKAGE__; } }
__FILE__
# Foo/Bar.spvm package Foo::Bar { sub baz : void () { # Foo/Bar.spvm my $file_name == __FILE__; } } package Foo::Bar2 { sub baz : void () { # Foo/Bar.spvm my $file_name == __FILE__; } }
__LINE__
Get Current Line Number Example:
package Foo::Bar { sub baz : void () { # 4 my $line = __LINE__; } }
UNARY_OPERATOR EXPRESSION
LEFT_EXPRESSION BINARY_OPERATOR RIGHT_EXPRESSION
(EXPRESSION1, EXPRESSION2, EXPRESSION3)
# 3 is assigned to $foo my $foo = (1, 2, 3); # $x is 3, $ret is 5 my $x = 1; my $y = 2; my $ret = ($x += 2, $x + $y);
+Expression
my $num = +10;
-Expression
-x
my $num = -10;
LEFT_EXPRESSION + RIGHT_EXPRESSION
x + y;
LEFT_EXPRESSION - RIGHT_EXPRESSION
x - y;
LEFT_EXPRESSION * RIGHT_EXPRESSION
x * y;
LEFT_EXPRESSION / RIGHT_EXPRESSION
x / y;
LEFT_EXPRESSION % RIGHT_EXPRESSION
x % y;
Increment Operator is an Operator that adds 1 to the value. the meaning of Increment Operator is different depending on whether the Increment Operator is placed Pre or Post.
# Pre Increment Operator ++LEXICAL_VARIABLE ++PACKAGE_VARIABLE ++FIELD_ACCESS ++ARRAY_ACCESS ++DEREFERENCE # Post Increment Operator LEXICAL_VARIABLE++ PACKAGE_VARIABLE++ FIELD_ACCESS++ ARRAY_ACCESS++ DEREFERENCE++
The operand of Increment Operator must Lexical Variable, Package Variable, Field Access, Array Access, Dereference, otherwise Compile Error occurs.
The Type of operand of Increment Operator must be Numeric Type, otherwise Compile Error will occur.
Pre Increment Operator adds 1 to the operand and returns the value after increment.
Pre Increment Operator is equivalent to the following Expression. After 1 is added to the operand, Type Cast is performed with the operand Type and the value is assinged to original operand.
(OPERAND_EXPRESSION = (TYPE)(OPERAND_EXPRESSION + 1))
For example, Pre Increment of byte Type value is equivalent to the following Expression:
($num = (byte)($num + 1))
Post Increment Operator add 1 to the operand and returns the value before Increment.
Post Increment Operator is equivalent to the following Expression using Sequential Operator. The value of operand is saved in a temporary variable, 1 is added to the operand, Type Cast is performed with the operand Type, and the value is assinged to original operand. Then the temporary variable is returned.
(my TMP_VARIABLE = OPERAND_EXPRESSION, OPERAND_EXPRESSION = (TYPE)(OPERAND_EXPRESSION + 1), TMP_VARIABLE)
For example, Post Increment of byte Type value is equivalent to the following Expression.
(my $tmp = $num, $num = (byte)($num + 1), $tmp)
Decrement Operator is an Operator that subtracts 1 to the value. the meaning of Decrement Operator is different depending on whether the Decrement Operator is placed Pre or Post.
# Pre Decrement Operator --LEXICAL_VARIABLE --PACKAGE_VARIABLE --FIELD_ACCESS --ARRAY_ACCESS --DEREFERENCE # Post Decrement Operator LEXICAL_VARIABLE-- PACKAGE_VARIABLE-- FIELD_ACCESS-- ARRAY_ACCESS-- DEREFERENCE--
The operand of Decrement Operator must Lexical Variable, Package Variable, Field Access, Array Access, Dereference, otherwise Compile Error occurs.
The Type of operand of Decrement Operator must be Numeric Type, otherwise Compile Error will occur.
Pre Decrement Operator subtracts 1 to the operand and returns the value after decrement.
Pre Decrement Operator is equivalent to the following Expression. After 1 is subtracted to the operand, Type Cast is performed with the operand Type and the value is assinged to original operand.
(OPERAND_EXPRESSION = (TYPE)(OPERAND_EXPRESSION - 1))
For example, Pre Decrement of byte Type value is equivalent to the following Expression:
($num = (byte)($num - 1))
Post Decrement Operator subtract 1 to the operand and returns the value before Decrement.
Post Decrement Operator is equivalent to the following Expression using Sequential Operator. The value of operand is saved in a temporary variable, 1 is subtracted to the operand, Type Cast is performed with the operand Type, and the value is assinged to original operand. Then the temporary variable is returned.
(my TMP_VARIABLE = OPERAND_EXPRESSION, OPERAND_EXPRESSION = (TYPE)(OPERAND_EXPRESSION - 1), TMP_VARIABLE)
For example, Post Decrement of byte Type value is equivalent to the following Expression.
(my $tmp = $num, $num = (byte)($num - 1), $tmp)
Bit Operator is an Operator that performs Bit operation. Bit AND Operator, Bit OR Operator, Bit NOT Operator.
Bit AND is Binary Operator represented by "&".
LEFT_EXPRESSION & RIGHT_EXPRESSION
Left Expression and Right Expression must be Integral Type, otherwise Compile Error occurs.
Binary Numeric Widening Type Conversion is performed on Left Expression and Right Expression.
After that, the operation result of Bit AND Operator performs the operation that exactly matches the following operation in C99
x & y;
The Type of Return Value of Bit AND Operator is the type after Binary Numeric Widening Type is performed.
Bit AND Operator does not throw Exception.
Bit OR is Binary Operator represented by "|".
LEFT_EXPRESSION | RIGHT_EXPRESSION
After that, the operation result of Bit OR Operator performs the operation that exactly matches the following operation in C99.
x | y;
The Type of Return Value of Bit OR Operator is the type that is Binary Numeric Widening Type Converted.
Bit OR Operator does not throw Exception.
Bit NOT Operator is Unary Operator represented by "~".
~EXPRESSION
Expression must be Integral Type, otherwise Compile Error occurs.
Unary Numeric Widening Type Conversion is performed to Expression before Operation.
After that, the operation result of Bit NOT Operator performs the operation that exactly matches the following operation in C99.
~x
The Type of Return Value of Bit NOT Operator is the type after Unary Numeric Widening Type Conversion
Bit NOT Operator does not throw Exception.
Bit NOT Operator Example
my $num = ~0xFF0A;
Shift Operator is an operator that performs Bit shift. Left Shift Operator, Arithmetic Right Shift Operator, Logical Right Shift Operator.
The Left shift is Binary Operator represented by "<<".
LEFT_EXPRESSION << RIGHT_EXPRESSION
Left Expression must be Integral Type, otherwise Compile Error occurs.
Right Expression must be int Type, otherwise Compile Error occurs.
The calculation result of Left Shift Operator is the same as the following calculation in C99.
x << y;
Left Shift Operator does not throw Exception.
Arithmetic Right Shift Operator is Binary Operator represented by ">>".
LEFT_EXPRESSION >> RIGHT_EXPRESSION
First, for Left Expression, Unary Numeric Widening Type Conversion is performed.
The operation result of Arithmetic Right Shift Operator is the operation that exactly matches the following operation in C99.
x >> y;
Arithmetic Right Shift Operator does not throw Exception.
Logical Right Shift Operator is Binary Operator represented by ">>>".
LEFT_EXPRESSION >>> RIGHT_EXPRESSION
The calculation result of Logical Right Shift Operator is the same as the following calculation in C99.
(SIGNED_INTEGRAL_TYPE_CAST)((UNSINGED_INTEGRAL_TYPE_CAST)x >> y);
Logical Right Shift Operator does not throw Exception.
Comparison Operator is an Operator that is placed between Left Expression and Right Expression to compare the size, and return True/False Value.
LEFT_EXPRESSION COMPARISON_OPERATOR RIGHT_EXPRESSION
Comparison Operators are Numeric Comparison Operator, String Comparison Operator, and isa Operator.
Numeric Comparison Operator is a Comparison Operator that is placed between Left Expression and Right Expression to compare the size of number or check the equqlity of objects.
LEFT_EXPRESSION NUMERIC_COMPARISON_OPERATOR RIGHT_EXPRESSION
A list of Numeric Comparison Operators.
The Types of Left Expression and Right Expression Comparable Types, otherwise Compile Error occurs.
In Numeric Type Comparison, Binary Numeric Widening Type Conversion is performed for Left Expression and Right Expression.
After that, the Numeric Comparison Operation is performed that exactly matches the following operation in C99.
# Numeric Type Comparison, Object Type Comparison (int32_t)(x == y); (int32_t)(x != y); # Numeric Type Comparison (int32_t)(x > y); (int32_t)(x >= y); (int32_t)(x < y); (int32_t)(x <= y); (int32_t)(x > y ? 1 : x < y ? -1 : 0);
The Type of Return Value of the Numeric Comparison Operator is int Type.
Numeric Comparison Operator does not throw Exception.
String Comparison Operator is a Comparison Operator that is placed between Left Expression and Right Expression to compare String Size in dictionary order.
LEFT_EXPRESSION STRING_COMPARISON_OPERATOR RIGHT_EXPRESSION
Left Expression and Right Expression must be String Type.
A list of String Comparison Operators.
The Type of Return Value of the String Comparison Operator is int Type. If the condition is met, returns 1, otherwise 0.
isa Operator is a Comparison Operator to check whether Left Expression satisfies Right Type.
LEFT_EXPRESSION isa RIGHT_TYPE
isa Operator has three behaviors, depending on Right Type.
1. If Right Type is Numeric Type, Multi Numeric Type, Any Object Type, Reference Type, isa operator checks whether the Type of Left Expression is same as Right Type. This check is done at compile time and isa operator is replaced by int Type value. If their types is same, replaced by 1, otherwise by 0.
2. If the Right Type is Class Type, isa operator checks whether the Type of Left Expression is same as Right Type at Run Time. If their types are same, int Type 1 is return, otherwise 0. The Type of Left Expression must be Object Type, otherwise Compile Error occurs.
3. If the Right Type is Callback Type, isa Operator checks whether the Type of Left Expression satisfy the Callback Type at Run Time. If Left Expression satisfies the Callback Type, returns int Type 1, otherwise 0. The Type of Left Expression must be Object Type, otherwise Compile Error occurs.
ref EXPRESSION
dump EXPRESSION
Logical Operator is an Operator that performs logical operations,Logical AND OperatorLogical NOT Operator
Logical Operator returns Expression
Logical AND Operator is a Binary Operator
LEFT_EXPRESSION && RIGHT_EXPRESSION
Logical AND Operator のReturn ValueのTypeは,int Type.
Logical AND Operator behaves as follows:
1. Run the Bool Type Conversion to Left Expression.
2. If the value of Left Expression is non-zero, execute the and return that value.
3. If the value of Left Expression is 0, it returns that value.
Logical AND Operator returns Expression
Logical AND Operator does not throw Exception.
Logical OR Operator is a logical OR operation that is "Expression is an operand of Binary Operator
LEFT_EXPRESSION || RIGHT_EXPRESSION
Logical OR Operator behaves as follows:
Logical OR Operator のReturn ValueのTypeは,int Type.
2. If the value of Left Expression is 0, the and returns that value for Right Expression.
3. If the value of Left Expression is non-zero, it returns that value.
Logical OR Operator はExpressionを返します。
Logical OR Operator returns Expression
Logical NOT Operator is an operator to the Left of expression to perform logical NOT operations, returning Unary Operator For more information about Expression, see Expression.
!EXPRESSION
Logical NOT Operator のReturn ValueのTypeは,int Type.
Logical NOT Operator executes =$Bool Type Conversion for Expression, returns 1 if its value is 0, and 0 if it is not 0.
Logical NOT Operator returns Expression
Logical NOT Operator does not throw Exception.
String StringOn Operator is a Binary Operator.
LEFT_EXPRESSION . RIGHT_EXPRESSION
If the Left Expression or Right Expression wasNumeric Type==>stringtype convertion converts it to a String.
Both Left Expression and Right Expression must be String Type There is an otherwise Compile Error.
String Concatenation Operator concatenates the String represented by Left Expression and Right Expression and returns a new String.
String Concatenation Operator retruns Expression, The Type is String Type.
If both Left Expression and Right Expression were String Literal, a string Literal concatenated at compile time is generated. You can concatenate String Literal with string Concatenation Operator without being aware of the cost of performance.
If Left expression or Right Expression is Undefined Value Exception occurs at Run Time.
String Concatenation Operator Example
my $str = "abc" . "def"; my $str = "def" . 34; my $str = 123 . 456;
Assignment Operator is a Binary Operator for assignment, expressed in "=".
LEFT_EXPRESSION = RIGHTH_EXPRESSION
Assignment Operator has multiple meanings depending on the Right and Left sides. Please refer to each item.
In Assignment Operator, the Left Expression is evaluated after the Right Expression is evaluated. This is with the exception of expression being executed from Left to Right as a rule.
Special Assignment Operator is a and Assignment OperatorType Compatibilityを満たさない場合は,Compile Error occurs
List of Special Assignment Operators
The Special Assignment Operator is deployed as follows:
# Before unexpanding LEFT_EXPRESSION SPECIAL_ASSIGNMENT_OPERATOR RIGHT_EXPRESSION # After unwinding LEFT_EXPRESSION ASSIGNMENT_OPERATOR (LEFT EXPRESSION TYPE CAST)(LEFT_EXPRESSION SPECIFIC_OPERATOR RIGHT_EXPRESSION)
For example, for add assignment Operator, it is expanded as follows:
# Before unexpanding x is byte Type $x += 1; # After unwinding $x = (byte)($x + 1)
Special Assignment Operator Example
$x += 1; $x -= 1; $x *= 1; $x /= 1; $x &= 1; $x |= 1; $x ^= 1; $x %= 1; $x <<= 1; $x >>= 1; $x >>>= 1;
The Reference Operator is an Operator that retrieves the address of a variable for Numeric Type or Multi Numeric Type. Designed to achieve c address Operator "&".
\VARIABLE
If the variable is not numeric type or Multi Numeric Type, Compile Error occurs
Reference Operator returns expression. The type returned is Reference Type.
Reference Operator Example
my $num : int; my $num_ref : int& = \$num; my $z : SPVM::Complex_2d; my $z_ref : SPVM::Complex_2d& = \$z;
For a detailed description of Reference, see Reference.
Array Length Operator is a ArrayUnary Operator
@RIGHT EXPRESSION
Right Expression must be an Array Type, otherwise Compile Error occurs.
Array Length Operator returns array length for int Type value.
Array Length Operator returns Expression
Array Length Operator Example
my $nums = new byte[10]; my $length = @$nums;
Note that SPVM does not have the idea of a context in Perl, and array length operators always return Array Length.
String Length Operator is a String Unary Operator
length RIGHT_EXPRESSION
Right Expression must be String Type, otherwise Compile Error occurs.
The String Length Operator returns the length of the String as a int Type value. String Length The length of the String returned by the Operator is the length when viewed as a byte string.
String Length Operator returns the Expression
String Length Operator Example
String Length Operator Exampleです。
my $nums = "abcde"; my $length = length $nums;
Scalar Operator is an Operator that returns the given value itself without doing anything. It is provided only to clarify the meaning of Array Length Operator operator
scalar RIGHT_EXPRESSION
Right ExpressionはArray Length Operatorでなければなりません。 otherwise Compile Error occurs.
Scalar Operator returns Expression.
Scalar Operator Example
my $nums = new int[3]; foo(scalar @$nums);
isweak Operator is an Operator that checks whether Field isWeaken Reference.
isweak VARIABLE->{FIELD_NAME};
The Type of object Expression must beClass Type.< otherwise Compile Error occurs.
Field Name must be a existed Field Name, otherwise Compile Error occurs.
The Type of the value stored in field must be Object Type, otherwise Compile Error occurs.
If the value stored in field at Run Time is Undefined Value, it returns false. This is Expression
isweak Operator returns if Field is weaken reference, or 0. This is Expression
Operator Precidence is the following street. The lower you go, the higher your priority.
Operator Precidence can be a top priority by using "()".
# a * b is the first a * b + c # b + c is the first a * (b + c)
Statement can be written more than one in Scope Block for a single process. Expression is not evaluated as a value.
List of Statements
If Statement is a statement for conditional branching.
if (EXPRESSION) { }
Expression Bool Type Conversion is executed and Block is executed if the value is non-zero.
If you want to write more than one condition, you can continue with "elsif Statement". The condition determination is performed from above, and each Expression is Bool Type Conversion is executed, and a corresponding Block is executed if the value is non-zero.
if (EXPRESSION) { } elsif(EXPRESSION) { }
You can use "elseStatement" to describe what happens if or if the elsif Statement does not meet the criteria. If the if statement and elsif statement condition determination are all false, the statement inside the elseBlock is executed. Elsif Statement does not have to be.
if (EXPRESSION) { } elsif (EXPRESSION) { } else { }
if Statement Example
An example of if Statement.
my $flag = 1; if ($flag == 1) { print "One \ n"; } elsif ($flag == 2) { print "Tow \ n"; } else { print "Other"; }
The if Statement is internally surrounded by an invisible Simple Block.
{ if (EXPRESSION) { } }
elsif is internally expanded into if Statement and else Statement.
#Before deployment if (EXPRESSION1) { } elsif (EXPRESSION2) { } else { } #After deployment if (EXPRESSION1) { } else { if (EXPRESSION2) { } else { } }
When a variable is declared in the conditional part of if Statement, it must be surrounded by invisible Simple Block. Be aware that elsif is internally expanded into if Statement and else Statement.
#Before deployment my $num = 1; if (my $num = 2) { } elsif (my $num = 3) { } else { } #After deployment my $num = 1; { if (my $num = 2) { } else { { if (my $num = 3) { } else { } } } }
The switch statement is a statement for conditional branching with an integer of int Type as a condition. Faster than if Statement if the condition is an integer of int Type and there are many branches.
switch (CONDITION_EXPRESSION) { case constant 1: ( break; } case constant 2: { break; } case constant n: { break; } default: { } }
As the condition Expression, Expression can be specified. Bool Type Conversion is executed for the condition Expression.
The constants specified in case Statement are byte Type or int Type constants. must be. For a constant of byte Type, type conversion to int Type at compile time. Will be done. The value of enumType and Constant Method of int Type are constants of int Type. As it is expanded at the time of syntax analysis, it can be used.
The constants specified in the case statement must not overlap. If there are duplicates, Compile Error occurs
If the value specified in the condition Expression matches the value specified in the case statement, jump to the position of that case statement.
If there is no match and a default statement is specified, jump to the default statement position. If no default statement is specified, switch block will not be executed.
A switch statement requires at least one case statement, otherwise Compile Error will occur.
The default Statement is optional.
Only case statement and default statement can be described directly under switch block.
The case and default Blocks can be omitted.
switch (CONDITION_EXPRESSION) { case constant 1: case constant 2: { break; } default: }
If you use break Statement, you can exit from the switch block.
If a case Block exists, the last Statement must be a break Statement or a returnl Statement, otherwise Compile Error will occur.
Switch Statement Example
An example of a switch statement.
my $code = 2; switch ($code) { case 1: { print "1 \ n"; break; } case 2: { print "2 \ n"; break; } case 3: { print "3 \ n"; break; } case 4: case 5: { print "4 or 5 \ n"; { break; } default: { print "Other \ n"; } }
A case statement is a Statement that can be used in a switch block to specify conditions. For more information on case statements, see the switch Statement description.
The default Statement is a Statement that can be used in the switch block to specify the default condition. For more information on the default Statement, see the switch Statement description.
while Statement is a Statement for repeating.
while (CONDITION_EXPRESSION) { }
Expression can be described in the condition Expression. Bool Type Conversion is executed for condition Expression, and if the value is not 0, Block is executed. Exit the otherwise Block.
While Statement Example
An example of a while Statement.
my $i = 0; while ($i <5) { print "$i \ n"; $i++; }
Inside the while block, you can leave the while block by using last Statement.
while (1) { last; }
Inside a while block, you can use next Statement to move to the condition immediately before the next condition Expression.
my $i = 0; while ($i <5) { if ($i == 3) { $i++; next; } print "$i \ n"; $i++; }
The while Statement is internally enclosed by an invisible Simple Block.
{ while (CONDITION_EXPRESSION) { $i++; } # 展開後 my $num = 5; { while (my $num = 3) { $i++; } }
for Statement is a Statement for repeating.
for (INITIALIZATION_EXPRESSION; CONDITIONAL_EXPRESSION; INCREMENT_EXPRESSION) { }
Expression can be described in the initialization Expression. Generally, write Expression such as initialization of loop variable. Initialization Expression can be omitted.
Condition Expression, Expression can be described. Bool Type Conversion is executed for condition Expression, and if the value is not 0, Block is executed. Exit the otherwise block.
Expression can be described in INCREMENT_EXPRESSION. Generally, Expression of Increment of loop variable is described. INCREMENT_EXPRESSION can be omitted.
for Statement has the same meaning as the following while Statement. INCREMENT_EXPRESSION is executed at the end of Block. Initialization Expression is enclosed in Simple Block.
{ INITIALIZATION_EXPRESSION; while (CONDITION_EXPRESSION) { INCREMENT_EXPRESSION; } }
for Statement Example
An example of for Statement.
for (my $i = 0; $i <5; $i++) { print "$i \ n"; }
Inside the for Block, you can exit the for Block using last Statement.
Inside the for Block, you can use next Statement to move immediately before the next INCREMENT_EXPRESSION to be executed.
for (my $i = 0; $i <5; $i++) { if ($i == 3) { next; } }
Use the returnl Statement to get out of the Method. The object assigned to the mortal variable is automatically released.
return;
If there is a Return Value, Expression can be specified.
return EXPRESSION;
If the Return Value Type in Method Definition is void Type, Expression Must not exist, otherwise Compile Error occurs.
Method Definition, if the Return Value Type is other than void Type, Expression Must match the Type of, otherwise Compile Error occurs.
die Statement is a Statement for raising Exception.
die EXPRESSION;
Expression must be a String Type.
See Exception for a detailed explanation of the die statement.
A weaken Statement is a Statement that sets Weaken Reference for the Field.
weaken VARIABLE->{FIELD_NAME};
The Type of the object Expression must be Class Type, otherwise Compile Error occurs.
Field Name must be an existing Field Name, otherwise Compile Error occurs.
The Type of the value saved in Field must be Object Type, otherwise Compile Error occurs.
If the value stored in the Field at execution time is Undefined Value, the weak Statement does nothing.
If the value stored in the Field at runtime is not Undefined Value, then the following is done:
1. Decrement the Reference Count of the object stored in Field by 1.
2. Set the Weaken Reference flag in Field.
3. Add Field to the back reference of the object saved in Field.
Note that the Weaken Reference flag is set on the Field itself, not on the object stored in the Field.
If the Reference Count of the object saved in Field becomes 0, the Weaken Reference is not created and the object saved in Field is released.
Back Reference is the data of the object saved in Field, and is added to know the Field with the Weaken Reference flag set. There may be more than one.
# There are multiple back references my $foo = new Foo; my $bar = new Bar; my $baz = new Baz; $foo->{bar} = $bar; $foo->{baz} = $baz; $bar->{foo} = $foo; $baz->{foo} = $foo; weaken $bar->{foo}; weaken $baz->{foo};
In the above example, "$bar->{foo}" and "$baz->{foo}" have the Weaken Reference flag set. The object represented by $foo has the back References "$bar->{foo}" and "$baz->{foo}".
The information of the back Reference is necessary because when the Garbage Collection is performed, it is necessary to assign the Undefined Value to the Field pointed to by the back Reference.
unweaken Statement is a Statement that cancels Weaken Reference for Field.
unweaken VARIABLE->{FIELD_NAME};
If the value stored in the Field at execution time is Undefined Value, the unweaken Statement does nothing.
1. Increase the Reference Count of the object stored in the Field by 1.
2. Clear the Weaken Reference flag of Field.
3. Delete the Field from the back reference of the object stored in the Field.
"next Statement" is a Statement to move to the beginning of the next loop. in while Block, for Block You can use it.
next;
Please see the explanation of while Statement, for Statement for the actual operation. ..
"last Statement" is a Statement to break the loop. in while Block, for Block You can use it.
last;
"break Statement" is a Statement to escape the switch block. It can be used in switch Block.
See switch Statement for the actual operation.
break;
Use warnStatement to throw a warning.
warn Expression;
Expression must be String Type.
If the end is a line feed Character "\ n", the String specified in Expression is output to the standard error output.
If the end is not a line feed character, File Name and line number are added to the end, and standard error is output.
If the length of String specified in Expression is 0 or Undefined Value, the specified message behaves as "Warning: something's wrong".
The standard error output buffer is flushed.
Use print Statement to print a String to standard output.
print Expression;
If Expression is Undefined Value, do nothing.
The expression Statement is a Statement consisting of Expression and ";".
Expression;
An example of an expression statement.
1; $var; 1 + 2; foo (); my $num = 1 + 2;
An empty statement is a statement that ends with just ";".
;
Lexical Variable Declaration, Field Definition, Package Variable Definition, and Arguments and Return Value of Method Definition must specify Type.
Lexical Variable Initial Value,Package Variable Initial Value,Create ObjectにおけるFieldの初期値は,Type Initial Valueによって決まります。
A list of Type Initial Value. All Bit columns in the data are set to 0.
byte Type is Integral Type that represents a signed 8-bit integer. It is the same Type as int8_tType of C99.
byte Type is Integral Type that represents a signed 16-bit integer. It is the same Type as int16_tType of C99.
long Type is Integral Type that represents a signed 64-bit integer. It is the same Type as int64_tType of C99.
Floating Point Type It is the same Type as float Type of C99.
double Type represents a double precision floating point (64bit) Floating Point Type It is the same Type as double Type of C99.
Package Type is the Type defined by Package Definition.
package Foo { }
Package Type is Class Type Callback Type Multi Numeric Type.
# Class Type package Foo { } # Callback Type package Foo: callback_t { } # Multi Numeric Type package Foo: mulnum_t { }
Pointer Type is also Class Type, so Pointer Type will also be Package Type.
# Pointer Type package Foo: pointer_t { }
What is Object Type Class Type Callback Type Array Type String Type Any Object Type It is a combination of a>. "Multi Numeric Type" and "Reference Type" are not included.
The Object Type value can be assigned to "Any Object Type".
my $object: object = new Foo; my $object: object = new Foo []; my $object: object = "abc";
The size of Object Type must match the value of "sizeof (void *)" in C99.
Numeric Object Type are the following six.
Undefined Type is the Type that Undefined Value has. It cannot be used explicitly.
The only Undefined Type value is Undefined Value.
The value of Undefined Type can be assigned to Object Type.If you assign to another Type, Compile Error occurs
Class Type is the Type defined by Package Definition and is not "Multi Numeric Type" "Callback Type".
packag Foo { }
Class Type can create objects by new Operator.
my $foo = new Foo;
Class Type is a Object Type.
Class Type is a Package Type.
Pointer Type is the Class Type.
Pointer Type is the one that "pointer_t Descriptor" is specified in Package Definition.
package Foo: pointer_t { }
Pointer Type is a type of Class Type.
Pointer type data can store C language pointers.
Field cannot be defined for Pointer Type. If it is defined, Compile Error occurs
package SPVM::Comparator: callback_t { sub: int ($self: self, $x1: object, $x2: object); }
# Callback Type Definition package SPVM::Comparator: callback_t { sub: int ($self: self, $x1: object, $x2: object); } # Class Definition package SomeComparator { sub new: int () { return new SomeComparator; } sub: int ($self: self, $x1: object, $x2: object) { } } # The object can be assign to the variable of Callback Type my $comparator: SPVM::Comparator = SomeComparator->new;
Definition of #Callback Type package SPVM::Comparator: callback_t { sub: int ($self: self, $x1: object, $x2: object); } # The object which is created by Create Callback Object can be assign to the variable of Callback Type my $comparator : SPVM::Comparator = sub: int ($self: self, $x1: object, $x2: object) { }
Any Object Type is represented by "object". Designed to represent the "void *" Type in C.
my $object: object;
You can substitute the value of "Object Type" for Any Object Type.
my $object: object = new Foo; my $object: object = "abc"; my $object: object = new Foo [3];
self Type represents the Package Type to which it belongs, and indicates that the argument is Invocant.
self
It can only be used as the Type of the first argument in Method Definition.
void
A Type that does not have dimensions is called a Basic Type. Numeric Type, Package Type , Any Object Type, String Type is a Basic Type.
Array Type represents multiple continuous data areas. Basic Type can be an Array.
int[] double[] Point[] object[] string []
Array has dimensions and can express up to 255 dimensions.
# Two dimensions int[] [] # Three-dimensional int[] [] []
Array Type is Object Type.
Use new Operator to create an Array. In the following example, int Type Array with 3 elements is created.
my $nums = new int [3];
You also use new Operator when creating a multidimensional Array.The following example creates an Array of int[] Type with 3 elements.
my $nums = new int[] [3];
Numeric Array Type means Numeric Type with the element Array Type It is.
Numeric Array Type list
Data represented by Numeric Array Type must have elements whose size is Numeric Type, and must be consecutive by the number of Array Length.
All elements of Numeric Array Type are initialized by Type Initial Value when Create Array is performed.
In SPVM, the byte[] Type is a special Type in that it is String Type.
byte[]
String Type is treated as String Type at compile time, but at runtime It will be byte[] Type.
Object Array Type is Array Type that has the value of Object Type as an element. It is.
Object Array TypeのExample
The data represented by Object Array Type must have elements of size of Object Type and consecutive by the number of Array Length.
All elements of Object Array Type are initialized by Type Initial Value when Create Array is performed.
Multi Numeric Array Type means Array Type that has the value of Multi Numeric Type as an element..
Multi Numeric Array Type Example
Data represented by Multi Numeric Array Type must have elements whose size is Multi Numeric Type and must be contiguous with the number of Array Length ..
All elements of Multi Numeric Array Type are initialized by Type Initial Value when Create Array is performed.
Any Object Array Type is an arbitrary Object Type expressed as an oarray as an element. A Type that can be assigned the value of array ">Array Type. Any Array Type can be cast to void * Type and passed to the first argument of the C language qsort function, but Any Object Array Type is not designed to realize the function corresponding to this. It was
my $array : oarray = new Point[3]; my $array : oarray = new object[3];
If a value with a Type other than Object Type is assigned, Compile Error occurs
Note that "oarrayType" is a different Type than "object[] Type". While oarrayType is a Type that can be substituted with an arbitrary Array Type value that has an Object Type value as an element, "object[] Type" is a Type that represents an "Array that has an objectType value as an element". Therefore, the value of arbitrary Array Type cannot be assigned.
Any Object Array Type is Array Type. Array Length Operator to get length, Set Array Element You can use Value, Get Array Element Value.
my $array : oarray = new SPVM::Int[3]; # Get the length of the element of Any Object Array Type my $length = @$array; # Get the value of any object array type element my $num = (SPVM::Int)$array->[0]; # Setting the value of the element of Any Object Array Type $array->[0] = SPVM::Int->new(5);
When setting the value of the element of Any Object Array Type, a check is made at runtime whether the Type of the element is smaller than the Type Dimension of Array by 1. If the check fails, Exception will occur. Any Object Array Type guarantees runtime Type safety.
String Type is a Type that represents a String. Expressed by string. Designed to represent C "const char *".
my $str : string;
String Literal allows you to assign the generated String object.
my $str : string = "abc";
SPVM String is an Array of bytes whose elements cannot be changed. You can get the Character by accessing the Array.
# Acquisition of Character my $ch = $str->[1];
If you try to change the element, Compile Error occurs
# Compile Error when changing element $str->[1] = 'd';
String Type will be exactly the same as the Array of bytes Type after compilation. For example, the first expression is treated as the second expression.
# isa String Type if ($str isa string) { } # isa byte[] Type if ($str isa byte[]) { }
Note that SPVM Strings are immutable, but this is a compile-time check.
String Type can be cast to byte[] Type, and the String can be changed at runtime.
my $bytes = (byte[])$str; $bytes->[1] = 'd';
Treat String as if you can always change it.
String Type is a combination of String Type and byte[] Type. Say that.
When a String Type value is generated, it is guaranteed that the last one after the last memory area reserved for the value will be "\ 0". (For example, if it is "abc", "c" is followed by "\ 0".) From the SPVM language, this "\ 0" has no meaning, but when using the native API, String Type is It can be handled as a C language String.
Multi Numeric Type is a type that can represent continuous numerical values.
Multi Numeric Type can be defined by specifying "mulnum_t" Descriptor in Package Definition.
package Point_3i : mulnum_t { has x : int; has y : int; has z : int; }
See Values for a detailed explanation of Multi Numeric Type.
Reference Type is a Type that can store the address of a variable. Add "&" after Numeric Type or Multi Numeric Type You can define it.
my $num : int; my $num_ref : int& = \$num; my $point : Point_3i; my $point_ref : Point_3i& = \$point;
Only the address of the Lexical Variable acquired by Reference Operator can be assigned to the value of Reference Type.
If only Lexical Variable Declaration of Reference Type is performed, Compile Error occurs
Reference Type can be used as Type of Lexical Variable Declaration. The address of the Lexical Variable must be stored by the Reference Operator. In case of only Lexical Variable Declaration, Compile Error occurs
Reference Type can be used as Type of argument in Method Definition.
Reference Type cannot be used as Return Value Type in Method Definition.
Reference Type cannot be used as the Type of Field in Package Definition.
Reference Type cannot be used as the Type of Package Variable in Package Definition.
If the Reference Type is used at an Invalid location, Compile Error occurs
See Reference for a detailed explanation of Reference.
Numeric Reference Type means Numeric Type for Reference Type. Says.
Multi Numeric Reference Type means Reference Type for Multi Numeric Type variables. > Means.
Omitting Type when Lexical Variable Declaration by Type Inference can. Type Inference is always performed by the Type on the Right side of Assignment Operator.
# int my $num = 1; # double my $num = 1.0; # Foo my $foo = new Foo;
Type compatibility means that the value can be moved without performing Type Cast.
Types are compatible in the following cases.
When the source and destination types are the same
If the source and destination types are the same, there is Type Compatibility.
my $num1 : int; my $num2 : int; $num1 = $num2;
When the source Type is byte[] Type and the destination Type is String Type
If the source Type is byte[] Type and the destination Type is String Type, there is Type Compatibility.
my $bytes = new byte[3]; my $str : string; $str = $bytes;
When the source Type is Object Type and the destination Type is Any Object Type
my $foo : Foo = new Foo; my $object : object; $object = $foo;
When the source Type and destination Type are Any Object Type or Any Object Type Array and the source Type Dimension count is greater than or equal to the destination Type Dimension count
my $objects_dim2_src : object[]; my $objects_dim1_dist : object; $objects_dim1_dist = $objects_dim2_src;
Note that the general object Array and the Basic Type Array are not compatible.
# Compilation error my $objets : object[] = new int[3];
If the types are not compatible, implicit Type Conversion is tried. If the implicit Type Conversion fails, Compile Error occurs
Type Cast is Type Conversion that is explicitly described.
# Type Cast (TYPE)EXPRESSION
int Type value is converted to long Type Become.
my $num = (long)3;
ype Cast returns Expression.
If the source Type and the specified Type are the same, the value is simply copied.
my $num : int = (int)4;
List of Type Conversion in Type Cast
It is a list of Type Conversion in Type Cast. If a Type Cast not listed in this table is performed, Compile Error occurs.
Implicit type conversion is automatic type conversion performed by SPVM. The following are the places where implicit Type Conversion may occur.
Implicit Type Conversion occurs when:
If both the source and destination Type are Numeric Type and the destination Type is greater than the source Type, Numeric Widening Type Conversion is done.
# Implicit Widening Type Conversion my $num : long = 123; my $num : double = 12.5f;
Both the source and destination Type are Numeric Type, and the destination Type is smaller than the source Type, and the source value can be expressed in the range of Integer Literal and destination Type value. Numeric Narrowing Type Conversion is performed.
# Implicit Narrowing Type Conversion my $num : byte = 123; my $num : short = 134;
If the source Type is Numeric Type and the destination Type is Any Object Type, Boxing Type Conversion to the corresponding Numeric Object Type Is done. In the following case, the converted SPVM::Int Type object is assigned to the generic object.
# Implicit Boxing Type Conversion to objectType my $num = 123; my $object : object = $num;
When the source Type is Numeric Type and the destination Type is the corresponding Numeric Object Type, Boxing Type Conversion to the corresponding Numeric Object Type a> is done.
# Implicit Boxing Type Conversion to object Type my $num = 123; my $object : SPVM::Int = $num;
When the source Type is Any Object Type and the destination Type is Numeric Type, Unboxing Type Conversion in the corresponding Numeric Type is displayed. Will be opened. In the following case, an attempt is made to convert the SPVM::Int Type object to int Type.
# Implicit Unboxing Type Conversion from objectType- my $object : object; my $num : int = $object;
If the source Type is Numeric Object Type and the destination Type is the corresponding Numeric Type, Unboxing Type Conversion in the corresponding Numeric Type Is done.
# Implicit Unboxing Type Conversion from Numeric Object Type my $num_obj = SPVM::Int->new(3); my $num : int = $num_obj;
If the source Type is Numeric Type and the destination Type is String Type, Numeric-to-String Type Conversion is performed. In the following case, the numerical value "123" is converted to String "" 123 "" and assigned.
# mplicit Boxing Type Conversion to String Type my $num = 123; my $str : string = $num;
# SPVM conversion my $src : int = 5; my $dist = (long)$src; # Correspondence in C language int32_t src = 5; int64_t dist = (int64_t)src;
Numeric Type has the order of Type. The order of Type is "byte", "short", "int", "long", "float", "double" from the smallest.
Unary Numeric Widening Type Conversion means that Expression is byte Type or short Type. In this case, perform Numeric Widening Type Conversion to int Type I say that.
Unary Numeric Widening Type Conversion is performed in the following cases.
Binary Numeric Widening Type Conversion is applied to Left Expression and Right Expression in Binary Operator that takes Numeric Type on the Left and Right sides. Numeric Widening Type Conversion.
The following rules apply.
1. When one Expression is double Type, the other Type is double Type Is converted to>.
2. If one Expression is float Type, the other Type is float Type Is converted to>.
3. When one Expression is long Type, the other Type is long Type Is converted to>.
4, otherwise, it will be converted to int Type.
Binary Numeric Widening Type Conversion is performed in the following cases.
Numeric Narrowing Type Conversion is a conversion rule applied when converting from a large type to a small type in Numeric Type.
Numeric Widening Type Conversion is a conversion rule applied when converting from a small type to a large type in Numeric Type.
# String-to-byte[] Type Conversion my $string : string = "Hello"; my $bytes : byte[] = (byte[])$string;
# byte[]-to-String Type Conversion my $bytes : byte[] = new byte[3]; $bytes->[0] = 'a'; $bytes->[1] = 'b'; $bytes->[2] = 'c'; my $string : string = (string)$bytes;
Boxing Type Conversion is the operation to convert the value of Numeric Type to Numeric Object Type.
Unboxing Type Conversion is an operation to convert the value of Numeric Object Type to the corresponding value of Numeric Type.
Bool Type Conversion is a conversion applied in the conditional part of if Statement, etc. for True/False Value judgment.
Where Bool Type Conversion takes place
Inside the if statement braces
if (CONDITION) { }
In unless statement brackets
unless (CONDITION) { }
The second in the parentheses for
for (INITIALIZEATION;CONDITION;NEXT_VALUE;) { }
in parentheses while
while (CONDITION) { }
Left and Right of Logical AND Operator
CONDITION && CONDITION
Left and Right of Logical OR Operator
CONDITION || CONDITION
Right side of Logical NOT Operator
!CONDITION
Expression specified by Bool Type Conversion is Numeric Type or Object Type or It must be Undefined Type, otherwise Compile Error occurs.
Return Value of Bool Type Conversion is Expression of int Type.
If Expression is Undefined Value, 0 is returned.
When Expression is Numeric Type, Unary Numeric Widening Type Conversion is done.
If Expression is int Type, that value is returned.
Expression is long Type, float Type, double Type, Object Type, the operation that exactly matches the following operation in C99 is performed and the result is returned.
!!x
If Expression is Object Type, 0 is returned if it is Undefined Value, 1 otherwise.
SPVM has a mechanism of Exception. Exception consists of raising Exception and catching the exception.
Use die Statement to throw Exception.
When the die statement is executed, the stack trace and the String specified by Expression are displayed, and the program ends. The stack trace includes Package Name, Method Name, File Name and line number. File Name is a relative File Name from the path where Module is loaded.
Error from TestCase::Minimal->sum2 at TestCase/Minimal.spvm line 1640 from TestCase->main at TestCase.spvm line 1198
Exception catching is a function that can stop the program from ending and get an error message when Exception is thrown.
Exceptions are caught using eval Block Statement. Please note that the eval Block Statement requires a semicolon at the end.
eval { # Processing that may throw Exception };
When Exception is caught by the eval Block, the program termination is stopped and is added to Exception Variable. The message specified in Exception is thrown is substituted.
The object is released from memory when the Reference Count reaches 0.
If the object is an Array that has Object Type values as elements, the Reference Count of all Array elements that are not Undefined Value is decremented by 1 before Garbage Collection
When an object is a Class Type and has a Field of Object Type, the Reference Count of the objects owned by all Fields of Object Type that are not Undefined Value is decremented by 1 before Garbage Collection. If Weaken Reference is set to the object saved in Field, Weaken Reference is released before Reference Count is decremented by 1.
When the object has Back references of Weaken Reference, Undefined Value is assigned to all Fields registered as back References and all back References are deleted.
The above process is done recursively.
Callback Type in SPVM is a Package Type in which only one unnamed Method with no implementation is defined. If callback_tDescriptor is specified in Package Definition, it becomes Callback Type.
The purpose of Callback Type is to provide a Type that can be assigned to different objects when they have the same MethodDefinition. Consider that the function corresponding to the C function pointer is realized in SPVM.
package Foo1 { sub new : Foo1 () { new Foo1; } sub : int ($self : self, $num : int) { return 1 + $num; } } package Foo2 { sub new : Foo2 () { new Foo2; } sub : int ($self : self, $num : int) { return 2 + $num; } } package FooCallback : callback_t { sub : int ($self : self, $num : int); }
Foo1 and Foo2 have the same MethodDefinition "sub: int ($self: self, $num: int)". Now suppose you want to selectively call the Foo1 or Foo2 Method.
In this case, if you define a Callback TypeFooCallback with the same MethodDefinition, you can assign either object to this Type. Then you can call Method from this object.
my $foo1 = Foo1->new; my $foo2 = Foo2->new; my $foo : FooCallback; my $flag = 1; if ($flag) { $foo = $foo1; } else { $foo = $foo2; } my $ret = $foo->(5);
If $flag is 1, the anonymous Method of Foo1 is called, otherwise the anonymous Method of Foo2 is called.
For more information on Callback Type, see Callback Type.
Create Callback Object is a Syntax that creates an object that conforms to Callback Type by using a special syntax for the purpose of Callback.
sub : TYPE_NAME ($self : self, ARGS1 : TYPE1, ARGS2 : TYPE2, ARGSN : TYPEn) { }
When Create Callback Object is performed, Package Definition is performed internally, an object based on that Package is generated, and Expression. It is possible to assign to a variable like the following.
my $cb_obj = sub : TYPE ($self : self, ARGS1 : TYPE1, ARGS2 : TYPE2, ..., ARGSn : TYPEn) { };
Method defined by Create Callback Object must be Method. It must also be a Method with no name.
Create Callback Object Example
my $comparator = sub : int ($self : self, $x1 : object, $x2 : object) { }
You can call Method because the object created by Create Callback Object is a normal object. For the call to Create Callback Object, see Method Call.
In Create Callback Object, you can use the syntax called Capture to use the variables defined outside the Method defined by Create Callback Object inside the Method defined by Create Callback Object.
# Capture [VariableName1 : Type1, VariableName2 : Type2] sub Method Name : int ($self : self, $x1 : object, $x2 : object) { };
my $foo = 1; my $bar = 5L; my $comparator = [$foo : int, $bar : long] sub : int ($self : self, $x1 : object, $x2 : object) { print "$foo\n"; print "$bar\n"; }
The variable name used in Capture must be the one with "$" added at the beginning of Field Name.
The Capture is actually defined as a Field of Class. Capture is a field definition and value setting syntax sugar.
If Lexical Variable with the same name as the Capture variable exists in the Scope, access the Lexical Variable.
If there is a Package Variable with the same name as the Capture variable, access the Capture variable.
If you write Create Callback Object and Capture without using syntax sugar, it will be as follows.
package ComapartorImpl { has foo : int; has bar : long; sub : int ($self : self, $x1 : object, $x2 : object) { print $self->{foo} . "\n"; print $self->{bar} . "\n"; } }
my $foo = 1; my $bar = 5L; my $comparator = new ComparatorImpl; $comparator->{foo} = $foo; $comparator->{bar} = $bar;
Weaken Reference is a reference that does not increase the Reference Count. Weaken Reference can be used to solve the problem of circular references.
SPVM has GC of Reference Count Type. In the GC of Reference Count Type, the object is automatically released when the Reference Count becomes 0, but when the circular reference occurs, the Reference Count does not become 0 and the object is automatically released. not.
This is an Example when the Field of the object is circularly referenced.
{ my $foo = new Foo; my $bar = new Bar; $foo->{bar} = $bar; $bar->{foo} = $foo; }
In this case, both objects are not released when the Scope ends. This is because a circular reference has occurred and the Reference Count does not become 0.
Weaken Reference is a function to correctly destroy objects when a circular reference occurs in a programming language that has a Reference Count GC.
In such a case, it is possible to release correctly by setting one Field to Weaken Reference using weaken Statement.
{ my $foo = new Foo; my $bar = new Bar; $foo->{bar} = $bar; $bar->{foo} = $foo; weaken $foo->{bar}; }
Before the weaken statement is executed, $foo has a Reference Count of 2 and $bar has a Reference Count of 2.
If there is no weaken statement, the reference count of $foo and the reference count of $bar will not be 0 and will not be released even if the scope ends.
When a weaken statement is executed, $foo has a Reference Count of 2 and $bar has a Reference Count of 1.
When the Scope ends, the Reference Count of $bar is decremented by 1 and becomes 0, so it is released correctly.
Even if there are 3 circular references, you can release them correctly by setting Weaken Reference in 1 Field.
{ my $foo = new Foo; my $bar = new Bar; my $baz = new Baz; $foo->{bar} = $bar; $bar->{baz} = $baz; $baz->{foo} = $foo; weaken $foo->{bar}; }
As a syntax related to Weaken Reference, Weaken Reference can be released weaken Statement, and it can be confirmed whether Field is Weaken Reference isweak Operator.
To install SPVM, copy and paste the appropriate command in to your terminal.
cpanm
cpanm SPVM
CPAN shell
perl -MCPAN -e shell install SPVM
For more information on module installation, please visit the detailed CPAN module installation guide.