SPVM - Static Perl Virtual Machine. Fast calcuration & Easy C/C++ Binding
SPVM Module:
# lib/MyMath.spvm package MyMath { sub sum : int ($nums : int[]) { my $total = 0; for (my $i = 0; $i < @$nums; $i++) { $total += $nums->[$i]; } return $total; } }
Use SPVM Module from Perl
use FindBin; use lib "$FindBin::Bin/lib"; use SPVM 'MyMath'; # New int array my $sp_nums = SPVM::new_iarray([3, 6, 8, 9]); # Call subroutine my $total = MyMath->sum($sp_nums); print $total . "\n";
SPVM is Static Perl Virtual Machine. Provide fast calcuration & easy C/C++ Binding.
Features:
Fast culcuration, Fast array operation, Small memory
Perl syntax, Static typing, Switch syntax, Have language specification
Enum, Type inference, Anon subroutine, Variable captures
Array initialization,
Reference count GC, Weaken reference, Module system
Exception, Package variable
Object oriented, Inteface, Value type, Value array type, Reference type
Easy way to C/C++ binding, Automatically Perl binding, C99 math functions
Dynamic linking, Subroutine precompile, AOT compile(create exe file)
Native API(C level api), C99 standard
print, warn, time
SPVM::CORE - Standard Functions
SPVM::Byte, SPVM::Short, SPVM::Int, SPVM::Long, SPVM::Float, SPVM::Double
SPVM::Document::ExchangeAPI - Exchange API is perl functions to exchange Perl data to SPVM data, and reverse.
SPVM::Document::NativeAPI - Native API is C level functions to manipulate SPVM data.
SPVM::Document::Extension - Extension is the way to C/C++ Binding to SPVM
SPVM::Document::Language - SPVM Language Specification
See also SPVM::Document::ExchangeAPI.
Package can contain field declaration, subroutine declaration.
package Point { has x : int; has y : int; sub new : Point ($x : int, $y : int) { my $self = new Point; $self->{x} = $x; $self->{y} = $y; return $self; } sub clear ($self : self) { $self->{x} = 0; $self->{y} = 0; } }
Package can also contain package variable declaration and enumeration declaration and use declaration.
package Foo { use Point; our $FOO : int; our $BAR : int; enum { FLAG1 FLAG2; } }
use Point;
has x : int; has y : long;
Field is public by default.
You can make field private by private keyword.
has x : private int;
sub sub : int ($num1 : int, $num2 : int) { return $num1 + $num2; }
my $num : int; my $nums : int[];
Exmpales:
# Numeric Type my $value : byte; my $value : short; my $value : int; my $value : long; my $value : float; my $value : double; my $obj : Point; # Array Type my $values : byte[]; my $values : short[]; my $values : int[]; my $values : long[]; my $values : float[]; my $values : double[]; my $values : Point[]; # Multiple Dimension Array Type my $values : byte[][]; my $values : short[][]; my $values : int[][]; my $values : long[][]; my $values : float[][]; my $values : double[][]; my $values : Point[][];
You can initialize variable.
my $value : int = 1;
You can omit type name if initial value is exists. This is type inference.
my $value = 1;
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];
Int Literal is composed of
[+|-][0x][0123456789abcdefABCDEF]...[L|f|d]
For example:
123 -123 0xff 0xFF 123L 123d
Default Number Literal Type is int.
int
# Type is int 123
You can use hex number literal by start 0x.
0x
a, b, c, d, e, f, A, B, C, D, E, F is used as hex number.
a
b
c
d
e
f
A
B
C
D
E
F
0xAF 0xaf
You can use octal number literal by start 0.
0
0x177 0x777
You can use binary number literal by start 0b.
0b
0b101 0b001
You can use under line _ in number literal. Under line is meanless, only for visuality.
_
123_456 0xAB_CD
You can use type specifier to specify integer leteral type.
L
# Long 123L
# Float 123f
# Double 123d
If you use . in number literal, the number is floating point literal. Default type of floating point value is double.
.
double
1.23 -1.23
You can use E or e to specify exponential notation.
1.23E+12 1.23E-12 1.23e+12 1.23e-12
# Float 1.23f
# Double 1.23d
If you know more Type, see "Type" section.
my $string_length = length "abc";
String Literal is the following.
"abc"
Type of String literal is const byte[].
const byte[]
my $string : const byte[] = "abc";
string is short name of const byte[]. You can also write the following.
string
my $string : string = "abc";
If you use type inference, you can also write the follwoing.
my $string = "abc";
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.
Undefined Literal is:
undef
Numeric types are byte, short, int, long, float, double.
byte
short
long
float
[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.
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
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 "Variable Declaration" section.
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 new keyword.
new
my $values : int[] = new int[3];
If you know more Array Creating, see "New Array" section.
Multiple Dimention Array Type is a Array Type.
Two Dimension Array Type
byte[][]; short[][]; int[][]; long[][]; float[][]; double[][]; PackageName[][];
Three Dimension Array Type
byte[][][]; short[][][]; int[][][]; long[][][]; float[][][]; double[][][]; PackageName[][][];
Max Dimension is 255.
255
You can create Multiple Dimension Array by new keyword.
my $values : int[][] = new int[][3];
This mean that Multiple Dimension Array is created, the multiple dimension array have 3 int[] type array. The elems is initialized by undef.
int[]
If you know Multiple Dimension Array Creating, see "New Multiple Dimention Array".
If Package is defined, Package name is used as Type.
PackageName
If you know more Package Definition, see "Package Definition" section.
You can create Object by new subroutine. This is Default Constructor.
my $obj : PackageName = PackageName->new;
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];
Array Initialization Syntax:
my $values = new int[] {1, 2, 3}; my $points = new Point[] {Point->new(), Point->new(), Point->new()};
You can use the three ways to get Array Length.
@$values; @{$values}; len $values;
Get Array Element:
# Get $values->[0];
Set Array Element:
# Set $values->[0] = 5;
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 (1) { } elsif (2) { } else { }
my $values = new int[10]; for (my $i = 0; $i < @$values; $i++) { $values->[$i] = 0; }
my $values = new int[10]; my $i = 0; while ($i < @$values) { $values->[$i] = 0; }
Comment:
# Comment
Pod syntax:
=pod AAAA BBBB =cut
Script Ending:
__END__
Throw Exception:
croak "Error";
Catch Exception:
eval { croak "Error"; };
if (my $error = $@) { }
Exception message is assigned to $@.
Constructor is new operator.
new Point;
new operator is private. new operator is only used in same package.
If new subroutine is not defined, Default Constructor is defined automatically.
sub new ($class : class) { return new Point }
This is used from other package.
my $point = Point->new();
Destructor.
package Foo { sub DESTROY : void ($self : Foo) { } }
package Foo { enum { ONE, TWO, THREE } enum { FORE = 4, FIVE, } }
Enumeration default value is 0. and up to 1, 2, 3 if value is not specified.
weaken $foo->{bar}; weaken $foo->[0];
package TestCase::Extension { native sub sum : int ($num1 : int, $num2 : int); }
my $foo = 1;
Special Assign Operator
+= -= *= /= &= |= ^= %= <<= >>= >>>=
+ - * / %
== != > < <= >=
&& || !
<< >> >>> & | ^ ~
++ --
# lib/MyMathNative.spvm package MyMathNative { # Sub Declaration native sub sum int ($nums : int[]); }
C Source File;
// lib/MyMathNative.native.c #include <spvm_native.h> int32_t SPNATIVE__MyMathNative__sum(SPVM_ENV* env, SPVM_VALUE* stack) { // First argument void* sp_nums = stack[0].oval; // Array length int32_t length = env->len(env, sp_nums); // Elements pointer int32_t* nums = env->ielems(env, sp_nums); // Culcurate total int32_t total = 0; { int32_t i; for (i = 0; i < length; i++) { total += nums[i]; } } // Return value is set to stack[0] stack[0].ival = total; // If function success, return SPVM_SUCCESS return SPVM_SUCCESS; }
Use Extension Module from Perl:
use FindBin; use lib "$FindBin::Bin/lib"; # Use SPVM module use SPVM 'MyMathNative'; # New SPVM int array my $sp_nums = SPVM::new_iarray([3, 6, 8, 9]); # Call SPVM subroutine my $total = MyMathNative->sum($sp_nums); print $total . "\n";
See also SPVM::Document::Extension, SPVM::Document::NativeAPI.
SPVM build directory for precompile and native subroutine.
If SPVM_BUILD_DIR environment variable is not specified, spvm_build directory of script directory is set to build directory.
For exmple, If your script is placed at "/path/app.pl", build directory is "/path/spvm_build".
SPVM is before 1.0 under development! I will change implementation and specification without warnings.
If you have problems or find bugs, comment to GitHub Issue.
SPVM(GitHub).
Yuki Kimoto <kimoto.yuki@gmail.com<gt>
moti<lt>motohiko.ave@gmail.com<gt>
akinomyoga, NAGAYASU Shinya, Reini Urban, chromatic, Kazutake Hiramatsu
MIT License
Copyright (c) [2018] [Yuki Kimoto]
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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.