SPVM::D...e::Class(3)
π SPVM::D...e::Class(3) π
User Contributed Perl Documentation
β¨ Name β¨
SPVM::Document::Language::Class - Classes in the SPVM Language
πΈ Description πΈ
This doc is literally all about classes, bestie. π
π Class π
SPVM is an object-oriented programming language, and it has class syntax β periodt. This section is the class-syntax tour.
If you want the grammar tea, see SPVM::Document::Language::SyntaxParsing for the grammar of the SPVM language. π«Ά
π Class Definition π
The class keyword defines a class type. Iconic behavior, honestly.
class CLASS_NAME {
}
class CLASS_NAME;
class CLASS_NAME : ATTRIBUTES {
}
class CLASS_NAME : ATTRIBUTES;
CLASS_NAME is a class name.
ATTRIBUTES is one of:
ATTRIBUTES ATTRIBUTE
ATTRIBUTE
ATTRIBUTE is a class attribute.
A class type is also simply called a class.
The new operator creates an object from a class. β¨
Compilation Errors:
CLASS_NAMEmust be a class name. Otherwise, a compilation error occurs.- If more than one class is defined in a class file, a compilation error occurs.
Examples:
# Examepls of class definitions
class Point {
}
π¦ Class Attributes π¦
The List of Class Attributes:
Compilation Errors:
- Only one of
private,protectedorpublicmust be specified. Otherwise, a compilation error occurs. - If more than one of
interface_t,mulnum_t, andpointerare specified, a compilation error occurs.
Examples:
# Examples of class attributes
class Point : public {
}
class Point : public pointer {
}
π Pointer Class π
The pointer class is a class with the pointer class attribute.
class CLASS_NAME : pointer {
}
An object of a pointer class has the pointer to a native address that is normally a pointer to a C language struct, or a C++ language struct or class. No cap, that's the pointer vibe.
Examples:
# Examples of the pointer attribute
class Foo : pointer {
}
π Class File π
A class file is a file where a class is defined.
The name of a class file is the same as a class name, but all :: are replaced to / and .spvm is added at the end of it.
# Foo
Foo.spvm
# Foo::Bar
Foo/Bar.spvm
# Foo::Bar::Baz
Foo/Bar/Baz.spvm
Compilation Errors:
- A class definition must be written in its corresponding class file. Otherwise, a compilation error occurs.
β version Statement β
The version statement declares the version of a class.
version VERSION_STRING;
This statement declares the version of a class given version string VERSION_STRING.
Compilation Errors:
- If the version has already been declared, a compilation error occurs.
VERSION_STRINGmust be a version string. Otherwise, a compilation error occurs.
Examples:
class MyClass {
version "1.001";
}
class MyClass {
version "10.001003";
}
π Version String π
The version string is the string that represents version of a class.
A version string must be written by the following rules:
- The type of a version string is string type.
- It consists of
"0-9",".". - The count of
"."is less than or equal to 1. - It begins with
"0-9". - It ends with
"0-9". - The count of
"0-9"after"."is divisible by 3. - It is able to be parsed by the
strtodfunction in the C language.
Compilation Errors:
- If a version string is not valid, a compilation error occurs.
Examples:
# Examples of version strings
"1.001"
"10.001003"
"1"
"10000"
π§ Version Number π§
A version number is a floating point number created from a version string using the strtod function in the C language.
Examples:
# Examples of version numbers
# "1.001"
1.001
# "10.001003"
10.001003
π version_from Statement π
The version_from statement allows you to make the version of the current class dependent on another class.
version_from CLASS_NAME;
CLASS_NAME is a class name.
It means the version of the current class is considered to be the same as the version of the class specified by CLASS_NAME.
The class specified by CLASS_NAME is loaded by use statement.
Compilation Errors:
- If
version_fromhas already been declared, a compilation error occurs.
Examples:
class MyClass::Foo {
version_from MyClass;
}
class MyClass {
version "1.001";
}
π use Statement π
The use statement loads a class.
use BASIC_TYPE;
use BASIC_TYPE as CLASS_NAME;
This statement searches for the type BASIC_TYPE in class search directories from the beginning, and if found, loads the type.
BASIC_TYPE is a class type, an interface type, or a multi-numeric type.
See require statement about how to load a type without causing a compile error when loading fails,
The following use statement with as:
use BASIC_TYPE as CLASS_NAME;
is expanded to the following code using alias statement.
use BASIC_TYPE;
alias BASIC_TYPE as CLASS_NAME
Compilation Errors:
BASIC_TYPEmust be a class name. Otherwise, a compilation error occurs.CLASS_NAMEmust be a class name. Otherwise, a compilation error occurs.- If
BASIC_TYPEdoes not found, a compilation error occurs.
Examples:
# Examples of use statement
class MyClass {
use Foo;
}
class MyClass {
use Sys::Socket::Constant as SOCKET;
}
π Class Search Directories π
Class search directories are directories in which classes are searched for.
These are set outside the program.
Directories set by -I option of spvm command and spvmcc command are added to class search directories.
And directories with /SPVM added to the end of each value of Perl's @INC (https://perldoc.perl.org/perlvar#@INC) are added to the end of the class search directories. π«Ά
πΈ Default Loaded Classes πΈ
The following classes are loaded by default:
ByteShortIntLongFloatDoubleBoolErrorError::SystemError::NotSupportedError::CompileCommandInfoAddressError::CompileSPVMError::MethodCallNotPermittedStringableCountableCallerInfo
π¦ alias Statement π¦
The alias statement creates a class alias name for a type.
alias BASIC_TYPE as CLASS_NAME;
This statement creates a class alias name CLASS_NAME for a type BASIC_TYPE.
BASIC_TYPE is a class type, an interface type, or a multi-numeric type.
Compilation Errors:
BASIC_TYPEmust be a class name. Otherwise, a compilation error occurs.CLASS_NAMEmust be a class name. Otherwise, a compilation error occurs.
Examples:
class MyClass {
use Sys::Socket::Constant;
alias Sys::Socket::Constant as SOCKET;
SOCKET->AF_INET;
}
π allow Statement π
The allow statement allows a type private accesses to the current class.
allow BASIC_TYPE;
By default, objects of private classes cannot be created by new operator from other classes.
And private methods, private fields, and private class variables cannot be accessed from other classes.
This statement allows the type BASIC_TYPE private accesses to the current class.
BASIC_TYPE is loaded by use statement.
Examples:
# Allowing private access
class MyClass {
allow SomeClass;
}
π Inheritance π
A class inherits a class using the extends keyword.
class CLASS_NAME extends PARENT_CLASS_NAME {
}
The class CLASS_NAME that inherits the parent class PARENT_CLASS_NAME is defined.
The field definitions of the parent class PARENT_CLASS_NAME are added to the end of the field definitions of the class CLASS_NAME to the end of its fields.
The interface statements of the parent class PARENT_CLASS_NAME are added to the end of interface statements of the class CLASS_NAME.
The instance of the class CLASS_NAME can call instance methods of the parent class PARENT_CLASS_NAME and its super classes.
Compilation Errors:
- The parent class
PARENT_CLASS_NAMEmust be a class type. Otherwise, a compilation error occurs. - The name of the parent class must be different from the name of the class. Otherwise, a compilation error occurs.
- The all super classes must be different from its own class. Otherwise, a compilation error occurs.
- The field that name is the same as the field of the super class cannot be defined. Otherwise, a compilation error occurs.
- The class
CLASS_NAMEinterpreted by an interface must satisfy interface requirement to the parent classPARENT_CLASS_NAME. Otherwise, a compilation error occurs.
Examples:
class Point3D extends Point {
has z : rw protected int;
static method new : Point3D ($x : int = 0, $y : int = 0, $z : int = 0) {
my $self = new Point3D;
$self->{x} = $x;
$self->{y} = $y;
$self->{z} = $z;
return $self;
}
method clear : void () {
$self->SUPER::clear;
$self->{z} = 0;
}
method to_string : string () {
my $x = $self->x;
my $y = $self->y;
my $z = $self->z;
my $string = "($x,$y,$z)";
return $string;
}
method clone : object () {
my $self_clone = Point3D->new($self->x, $self->y, $self->z);
return $self_clone;
}
}
β Interface β
This section describes interfaces.
π Interface Definition π
A class definition with the interface_t class attribute defines an interface type.
class CLASS_NAME : interface_t {
}
An interface type is also simply called an interface.
Objects cannot be created from interface types.
Normally, an interface has interface methods.
Compilation Errors:
- An interface cannot have field definitions. If so, a compilation error occurs.
- An interface cannot have class variable definitions. If so, a compilation error occurs.
Examples:
# Examples of interface definitions
class TestCase::Pointable : interface_t {
interface Stringable;
method x : int ();
method y : int();
method to_string : string ();
}
class Stringable: interface_t {
method to_string : string ();
method call_to_string : string () {
return "foo " . $self->to_string;
}
}
class Stringable: interface_t {
required method to_string : string ();
method foo : int ($num : long);
}
π interface Statement π
The interface statement checks if the current class satisfies interface requirement to an interface.
π Interface
interface BASIC_TYPE;
BASIC_TYPE gets loaded by a use statement β that's the whole vibe, it's how the class pulls in the interface it's promising to be.
β οΈ Compilation error tea:BASIC_TYPEhas to actually be an interface type. If it's not β boom, compilation error. Also, your current class must satisfy the interface requirement for the interface typeBASIC_TYPE, otherwiseβ¦ you guessed it, compilation error. The compiler is not letting that slide, fr fr.
Example, bestie:
# Examples of interface statement
class Point {
interface Stringable;
method to_string : string () {
my $x = $self->x;
my $y = $self->y;
my $string = "($x,$y)";
return $string;
}
}
π¦ Anon Class
Okay so an anon class is literally a class where you never name it. No name, just vibes. Anonymous. Iconic behaviour honestly.
β¨ Anon Class Definition
Here's the syntax, it's giving minimalism:
class {
}
An anon class cannot be defined in a class file. Nope, not happening. It can only be defined in source code that's compiled by the compile_anon_class compiler native API.
An anon class still has a class name though β autogenerated cuties like "eval::anon_class::0", "eval::anon_class::1", "eval::anon_class::2".
eval::anon_class::123
Examples:
# Examples of the anon class definition
class {
static method sum : int ($num1 : int, $num2 : int) {
return $num1 + $num2;
}
}
π Anon Method Class
An anon method class is the class that gets defined by an anon method operator. Sneaky little class factory, lowkey.
π Anon Method Class Definition
The anon method class definition has this syntax:
ANON_METHOD_CLASS_FIELD_DEFINITION METHOD_DEFINITION
ANON_METHOD_CLASS_FIELD_DEFINITION is an anon method class field definition.
METHOD_DEFINITION is a method definition.
The anon method class definition defines the class that this method belongs to. Like, the method gets a whole class of its own β main character energy.
The name of this class is a string that joins the outmost class, the string "anon_method", the line number, and the position of columns where the anon method class definition is written β all glued together with "::".
MyClass::anon_method::3::23
An anon method class has the same access control as its outmost class. Same alias names too. It's literally inheriting the whole look.
β οΈ Compilation errors, heads up: - The method name of METHOD_DEFINITION must be an empty string. Otherwise, compilation error. - The method must be an instance method. Otherwise, compilation error. No static shenanigans.
Examples:
# Examples of the anon method definition
class Foo::Bar {
method my_method : void () {
my $comparator = (Comparator)method : int ($x1 : object, $x2 : object) {
my $point1 = (Point)$x1;
my $point2 = (Point)$x2;
return $point1->x <=> $point2->x;
};
}
}
πΈ Anon Method Class Field Definition
An anon method class field definition defines the fields of an anon class β and that anon class is a part of the anon method class definition. Nested cuties.
[ANON_METHOD_CLASS_FIELD_DEFINITION_ITEM1, ANON_METHOD_CLASS_FIELD_DEFINITION_ITEM, ANON_METHOD_CLASS_FIELD_DEFINITION_ITEMn]
ANON_METHOD_CLASS_FIELD_DEFINITION_ITEM is one of:
has FIELD_NAME : TYPE
has FIELD_NAME : TYPE = OPERAND
VAR : TYPE
VAR : TYPE = OPERAND
has FIELD_NAME : ATTRIBUTE1 ATTRIBUTE2 ATTRIBUTEn TYPE
has FIELD_NAME : ATTRIBUTE1 ATTRIBUTE2 ATTRIBUTEn TYPE = OPERAND
VAR : ATTRIBUTE1 ATTRIBUTE2 ATTRIBUTEn TYPE
VAR : ATTRIBUTE1 ATTRIBUTE2 ATTRIBUTEn TYPE = OPERAND
FIELD_NAME is a field name.
TYPE is a type.
OPERAND is an operator.
"VAR : TYPE = OPERAND" gets expanded to "has FIELD_NAME : TYPE = OPERAND". The FIELD_NAME is the same as the name of VAR, but the "$" is removed. And VAR is declared at the top of this anon method and set to the value of its corresponding field. Cute, right? It's giving "shortcut".
"VAR : TYPE" is the same as above, but it expands to "has FIELD_NAME : TYPE = VAR".
ATTRIBUTE is a field attribute.
β οΈ Compilation errors caused by Field Definition could occur. So like, behave.
Examples β three flavours, pick your fave:
# Examples of the anon method class field definition
class Foo::Bar {
method my_method : void () {
my $foo = 1;
my $bar = 5L;
my $comparator = (Comparator)[has foo : int = $foo, has bar : long = $bar] method : int ($x1 : object, $x2 : object) {
my $foo = $self->{foo};
my $bar = $self->{bar};
say "$foo";
say "$bar";
};
}
}
# More simple
class Foo::Bar {
method my_method : void () {
my $foo = 1;
my $bar = 5L;
my $comparator = (Comparator)[$foo : int, $bar : long] method : int ($x1 : object, $x2 : object) {
say "$foo";
say "$bar";
};
}
}
# Change variable names
class Foo::Bar {
method my_method : void () {
my $foo = 1;
my $bar = 5L;
my $comparator = (Comparator)[$foo_x : int = $foo, $bar_x : long = $bar] method : int ($x1 : object, $x2 : object) {
say "$foo_x";
say "$bar_x";
};
}
}
π Outmost Class
An outmost class is the outmost defined class. Basically it's the same thing as the class defined by a class definition. The outermost layer of the onion. π§
class OutmostClass {
}
Examples:
# Examples of the outmost class
class MyClass {
static method my_method : void () {
# The __PACKAGE__ operator returns the outmost class "MyClass".
my $outmost_class_name = __PACKAGE__;
# Anon method
my $cb = method : void () {
# The __PACKAGE__ operator returns the outmost class "MyClass".
my $outmost_class_name = __PACKAGE__;
};
}
}
See how __PACKAGE__ keeps pointing at MyClass even from inside the anon method? That's the outmost class doing its job. Consistent queen. π
π₯ Multi-Numeric Type Definition
A multi-numeric type gets defined by a class definition that has the "mulnum_t" class attribute.
class CLASS_NAME : mulnum_t {
has FIELD_NAME1 : NUMERIC_TYPE;
has FIELD_NAME2 : NUMERIC_TYPE;
has FIELD_NAMEn : NUMERIC_TYPE;
}
Rules of the game, no skips:
- A multi-numeric field must have at least one field.
- The type of a field must be a numeric type.
- The types of all fields must be the same. Every single one, periodt.
- The length of fields must be less than or equal to 255.
CLASS_NAMEmust end with a multi-numeric type suffix corresponding to the type of the fields.FIELD_LENGTHof the multi-numeric type suffix must be the same as the length of the fields.TYPE_SUFFIXof the multi-numeric type suffix must correspond to the type of the fields.- A multi-numeric type cannot have instance methods. None. Zero.
- A multi-numeric type cannot have class variables. Also none.
β οΈ Compilation errors: if the definition of the multi-numeric type is invalid, a compilation error occurs. The compiler said what it said.
Examples:
# Examples of the multi-numeric type definition
class Complex_2f : mulnum_t {
re : float;
im : float;
}
class Complex_2d : mulnum_t {
re : double;
im : double;
}
class Quaternion_4f : mulnum_t {
re : float;
i : float;
j : float;
k : float;
}
class Quaternion_4d : mulnum_t {
re : double;
i : double;
j : double;
k : double;
}
β Multi-Numeric Type Suffix
The multi-numeric type must end with this suffix:
_(non-spaces)FIELD_LENGTH(non-spaces)TYPE_SUFFIX
FIELD_LENGTH is the length of fields.
TYPE_SUFFIX is a type suffix.
The List of Type Suffixes: β and that's it, bestie, the list prints out empty in this doc, so there's literally nothing to list here π
Examples:
# Examples of the multi-numeric type suffix
_2f;
_2d;
_4f;
_4d;
π Enumeration
Enumeration is a syntax that defines 32-bit integers that belong to a class. Little ints with a home. π
π Enumeration Definition
The "enum" keyword defines an enumeration:
enum {
ITEM1,
ITEM2,
ITEMn
}
A "," after the last enumeration item is allowed. Trailing comma girlies, you're safe.
enum {
ITEM1,
ITEM2,
ITEM3,
}
ITEM is one of:
NAME
NAME = VALUE
NAME is a method name.
VALUE is an integer literal within int type. VALUE gets converted to the value of int type.
If VALUE of ITEM1 is omitted, it's set to 0.
If VALUE of ITEMn is omitted, it's set to the value of the previous item plus 1.
The return type of the method is int type.
Every enumeration item gets converted into a method definition that defines a class method returning the value of that enumeration item. It's a glow-up, honestly.
# Definition of an enumeration
class MyClass {
enum {
NAME = 5,
}
}
# This are replaced with a definition of a class method
class MyClass {
static method NAME : int () { return 5; }
}
(That comment's grammar is kept verbatim from the source, don't come for me π)
See also "Inline Expansion of Method Call to Get an Enuemration Value". (Also verbatim, spelling and all β iykyk.)
β οΈ Compilation errors: -NAMEmust be a method name. Otherwise, a compilation error occurs. -VALUEmust be an integer literal within int type. Otherwise, a compilation error occurs.
Examples:
# Examples of enumerations
class MyClass {
enum {
FLAG1,
FLAG2,
FLAG3,
}
static method main : void () {
my $flag1 = MyClass->FLAG1;
}
}
class MyClass {
enum {
FLAG1,
FLAG2 = 2,
FLAG3,
}
}
π Enumeration Attributes
The List of Enumeration Attributes: β again, this list comes through empty in the source, so there's nothing printed here to show you π«Ά
β οΈ Compilation errors: one of"private","protected"and"public"must be specified. Otherwise, a compilation error occurs. Pick one, bestie, the compiler isn't accepting "whatever feels right".
π Class Variable π
ok so a class variable is a global variable that belongs to a class. think of it as the class's shared locker β everybody in the class can get to it ποΈβ¨
β¨ Class Variable Definition β¨
the our keyword is the one that defines a class variable, no cap:
our CLASS_VARIABLE_NAME : OPT_ATTRIBUTES TYPE;
CLASS_VARIABLE_NAMEβ the class variable's name, and it's gotta be a name that does not contain"::".TYPEβ a type.OPT_ATTRIBUTESβ one of these two moods:
EMPTY
ATTRIBUTES
EMPTY means, like, nothing exists. ATTRIBUTES is one of:
ATTRIBUTES ATTRIBUTE
ATTRIBUTE
and ATTRIBUTE is a class variable attribute π
every single class variable gets initialized by its type's initial value. that's the vibe from the start β¨
you get the value of a class variable through the operation of getting a class variable, and you set it through the operation of setting a class variable. matching set, iykyk.
Compilation Errors (these will humble you π):
CLASS_VARIABLE_NAMEmust be a class variable name that does not contain"::". otherwise, a compilation error occurs.TYPEmust be a numeric type or an object type.ATTRIBUTEmust be a class variable attribute. otherwise, a compilation error occurs.- if two or more class variables that have the same name are defined, a compilation error occurs.
Examples:
class MyClass {
our $NUM_BYTE : byte;
our $NUM_SHORT : short;
our $NUM_INT : int;
our $NUM_LONG : long;
our $NUM_FLOAT : float;
our $NUM_DOUBLE : double;
our $POINT : Point;
our $NUM_PUBLIC : public int;
our $NUM_RO : ro int;
our $NUM_RW : rw int;
}
look at all those lil variables living their best lives π
πΈ Class Variable Attributes πΈ
the list of class variable attributes:
(that's the list, bestie β it lives right there in the original π)
Compilation Errors:
- one of
"private","protected"and"public"must be specified. otherwise, a compilation error occurs. - one of
"ro","wo", and"rw"must be specified. otherwise, a compilation error occurs.
like, you have to pick one from each column. no indecisive energy allowed π«
π Class Variable Getter Method π
a class variable getter method is a method that performs the operation of getting a class variable. it's the "gimme" method π«Ά
- it's a class method that has no arguments.
- if the type of the class variable is
bytetype orshorttype, the return type isinttype. otherwise, it's the same type as the class variable. - the method name is the same as the class variable name, but the
"$"gets removed. so if your class variable is$FOO, the method name is"FOO"β¨
Examples:
# Examples of class variable getter methods
class MyClass {
our $VALUE : ro int;
static method main : void {
my $num = Foo->VALUE;
}
}
a user defined class variable getter can be defined with the get keyword:
class MyClass {
our $VALUE : ro int
get {
return $VALUE;
}
;
}
and yes, you can define a user defined getter and setter at the same time. two for one, we love efficiency π
class MyClass {
our $VALUE : rw int
get {
return $VALUE;
}
set {
$VALUE = $_;
}
;
}
π Class Variable Setter Method π
a class variable setter method is a method that performs the operation of setting a class variable. the "here, take this" method π
- it's a class method that has an argument.
- if the type of the class variable is
bytetype orshorttype, the argument type isinttype. otherwise, it's the same type as the class variable. - the return type is
voidtype. - the method name is the same as the class variable name, but the
"$"is removed and"SET_"is added to the beginning of it. so if the class variable name is$FOO, the method name is"SET_FOO"π
Examples:
# Examples of class variable setter methods
class MyClass {
our $NUM : wo int;
static method main : void {
Foo->SET_NUM(3);
}
}
a user defined class variable setter can be defined with the set keyword. the passed value gets assigned to $_:
class MyClass {
our $VALUE : wo int
set {
$VALUE = $_;
}
;
}
and the argument can be replaced if you're feeling fancy:
class MyClass {
our $VALUE : wo int
set ($VAL : object) {
$VALUE = (int)$VAL;
}
;
}
π¦ Field π¦
a field is a data member of a class. it's the class's own personal data, main character energy π
β Field Definition β
the has keyword defines a field:
has FIELD_NAME : OPT_ATTRIBUTES TYPE;
FIELD_NAMEβ a field name.TYPEβ a type.OPT_ATTRIBUTESβ one of:
EMPTY
ATTRIBUTES
EMPTY means nothing exists (again). ATTRIBUTES is one of:
ATTRIBUTES ATTRIBUTE
ATTRIBUTE
and ATTRIBUTE is a field attribute πΈ
every field of an object gets initialized by its type's initial value when the object is created. fresh object, fresh fields β¨
the value of a field is got by the operation of getting a field, and set by the operation of setting a field.
Compilation Errors:
FIELD_NAMEmust be a field name. otherwise, a compilation error occurs.TYPEmust be a numeric type or an object type.ATTRIBUTEmust be a field attribute. otherwise, a compilation error occurs.- if two or more fields that have the same name are defined, a compilation error occurs.
- if the field is already defined with a different type in the super class, a compilation error occurs. (inheritance said no π)
Examples:
class MyClass {
has num_byte : byte;
has num_short : short;
has num_int : int;
has num_long : long;
has num_float : float;
has num_double : double;
has num_public : public int;
has num_ro : ro int;
has num_rw : rw int;
}
π Field Attributes π
the list of field attributes:
(same deal β that's the list, it's right there in the original π)
Compilation Errors:
- one of
"private","protected"and"public"must be specified. otherwise, a compilation error occurs. - one of
"ro","wo", and"rw"must be specified. otherwise, a compilation error occurs.
π§ Field Getter Method π§
a field getter method is a method that performs the operation of getting a field.
- it's an instance method that has no arguments.
- if the type of the field is
bytetype orshorttype, the return type isinttype. otherwise, it's the same type as the field. - the method name is the same as the field name. if the field name is
"foo", the method name is"foo". yes, same name. iconic, no notes π
Examples:
# Examples of field getter methods
class MyClass {
has value : ro int;
static method new {
return new Foo;
}
static method main : void {
my $foo = Foo->new;
my $value = $foo->value;
}
}
a user defined field getter can be defined with the get keyword:
class MyClass {
has value : ro int
get {
return $self->{value};
}
;
}
user defined getter and setter can be defined at once β combo move π«Ά
class MyClass {
has value : rw int
get {
return $self->{value};
}
set {
$self->{value} = $_;
}
;
}
π₯ Field Setter Method π₯
a field setter method is a method that performs the operation of setting a field.
- it's an instance method that has an argument.
- if the type of the field is
bytetype orshorttype, the argument type isinttype. otherwise, it's the same type as the field. - the return type is
voidtype. - the method name is the same as the field name, but
"set_"is added to the beginning of it. if the field name is"foo", the method name is"set_foo"β
Examples:
# Examples of field setter methods
class MyClass {
has value : wo int;
static method new {
return new Foo;
}
static method main : void {
my $foo = Foo->new;
$foo->set_value(3);
}
}
a user defined field setter can be defined with the set keyword. the passed value is assigned to $_:
class MyClass {
has value : wo int
set {
$self->{value} = $_;
}
;
}
the argument can be replaced:
class MyClass {
has value : wo int
set ($value : object) {
$self->{value} = (int)$value;
}
;
}
the return type can be replaced too:
class MyClass {
has value : wo int
set : MyClass ($value : object) {
$self->{value} = (int)$value;
return $self;
}
;
}
and if there's no method block but a return type is specified, the default setter returns the invocant. it just hands you back the object. self-care π
class MyClass {
has value : wo int
set : MyClass
;
}
π Field Existence π
an object has field existence flags. lil checkboxes for every field β
when a new object is created, these flags are zero.
when one of the field set operations is performed, this flag is set to 1.
# The field existence flag for "value" field is set to 1.
$object->{value} = 1;
you can check if a field exists using the exists operator:
my $exists = exists $object->{value};
you can delete a field using the delete operator:
delete $object->{value};
the field existence flag is set to 0, and the value of the field is set to 0 in the case of numeric types or undef in the case of object types. gone, reduced to atoms πβ¨
π Method π
πΈ Method Definition πΈ
the method keyword defines a method:
OPT_ATTRIBUTES method METHOD_NAME : RETURN_TYPE (OPT_ARG_ITEMS) { }
OPT_ATTRIBUTES method METHOD_NAME : RETURN_TYPE (OPT_ARG_ITEMS);
OPT_ATTRIBUTES is one of:
EMPTY
ATTRIBUTES
EMPTY means nothing exists. ATTRIBUTES is one of:
ATTRIBUTES ATTRIBUTE
ATTRIBUTE
and ATTRIBUTE is a method attribute π
METHOD_NAMEβ a method name.RETURN_TYPEβ a type.
OPT_ARG_ITEMS is one of:
EMPTY
ARG_ITEMS
EMPTY means nothing exists (you're sensing a pattern here, right? π). ARG_ITEMS is one of:
ARG_ITEMS , ARG_ITEM
ARG_ITEM
and ARG_ITEM is one of:
ARG_NAME : ARG_TYPE
ARG_NAME : ARG_TYPE = VALUE
ARG_NAMEβ a local variable name. the local variable specified byARG_NAMEis declared at the beginning of the method implementation.ARG_TYPEβ a type.VALUEβ a literal or"undef".
a method with the "static" method attribute is a class method. a method without the "static" method attribute is an instance method. that's the whole vibe check right there π¦
an argument with VALUE is an optional argument. if a method call does not give a value to an optional argument, VALUE is given to the argument. it's got a backup plan built in π«Ά
a interface method defined in an interface is an interface method.
a method with the "native" method attribute is a native method.
Compilation Errors:
- the count of
ARGSmust be less than or equal to255. otherwise, a compilation error occurs. (255 is the limit, bestie β do not test it π) ARG_TYPEmust be a numeric type, a multi-numeric type, an object type, or a reference type. otherwise, a compilation error occurs.RETURN_TYPEβ has to be void type, a numeric type, a multi-numeric type, or an object type. Anything else? π compilation error, bestie.- Methods that aren't interface methods or native methods must have a method block. No block = compilation error, no cap.
VALUEhas to satisfy the assignment requirement toARG_TYPE. If it doesn't, compilation error, sorry π«ΆMETHOD_NAMEmust not be"INIT". Try it and get a compilation error. Periodt.- A non-optional argument must not come after an optional argument. Do it anyway and boom π₯ compilation error.
Examples, because we love a visual:
class MyClass {
# Class method
static method substr : string ($string : string, $offset : int, $length : int = -1) {
# ...
}
# Instance method
method clear : void () {
}
}
π Method Attributes π
The List of Method Attributes:
Compilation Errors:
- One of
"private","protected"and"public"must be specified. Otherwise, a compilation error occurs. Pick one, babes, you can't sit with all three π "required"must be specified to an interface method. Otherwise, a compilation error occurs.
Examples of each flavor:
# private method
private method : int sum ($num1 : int, $num2 : int) {
return $num1 + $num2;
}
# precompile method
precompile method : int sum ($num1 : int, $num2 : int) {
return $num1 + $num2;
}
# native method
native method : int sum ($num1 : int, $num2 : int);
β¨ Class Method β¨
A method defined with the "static" method attribute is a class method.
A class method can be called by a class method call. That's the whole vibe β¨
πΈ Instance Method πΈ
A method defined without the "static" method attribute is an instance method.
An instance method can be called by an instance method call. Main character energy, honestly π
π¦ Interface Method π¦
An instance method defined in an interface is an interface method.
Normally, an interface method does not have a method block.
method my_method : int ();
But β plot twist β an interface method can have a method block:
method my_method : int () {
}
An interface method can have the "required" method attribute, which means classes must define a method with the same name that implements this interface method. Like, it's required required.
required method my_method : int ();
π§ INIT Block π§
An "INIT" block is a special scope block to initialize class variables or perform setup tasks.
our $FOO : int;
INIT {
$FOO = 1;
}
Multiple "INIT" blocks can be defined. Stack 'em up, bestie:
INIT {
# First setup
}
INIT {
# Second setup
}
All "INIT" blocks in a class are merged into a single INIT method at compile time. Iconic efficiency.
π INIT Method π
An "INIT" method is a special method that is automatically generated by the compiler. You don't write it, it just exists.
It consists of all INIT blocks in a class. If no "INIT" block exists, an empty "INIT" method is generated. Still shows up. Still doing the work (of nothing).
This method has no arguments and its return type is the "void" type.
The "INIT" methods of the parent class and classes loaded via use statements are called at the beginning of the "INIT" method of the current class.
Note that the execution order of"INIT"methods among different classes is not generally guaranteed. However, the"INIT"methods of Default Loaded Classes are guaranteed to be called before any user-defined"INIT"methods. So like, mostly chaos, but one specific bit of order π
This method is automatically called after all classes are loaded, and before the first method in the program is called. It can also be called manually.
Examples, because examples ate:
# Examples of INIT blocks
class MyClass {
use Point;
our $NUM : int;
our $STRING : string;
our $POINT : Point;
INIT {
$NUM = 3;
$STRING = "abc";
}
INIT {
$POINT = Point->new(1, 2);
}
INIT {
OtherClass->INIT;
}
}
π END Block π
An "END" block is a special scope block to perform cleanup tasks.
END {
# Cleanup tasks
}
Multiple "END" blocks can be defined:
END {
# First cleanup
}
END {
# Second cleanup
}
All "END" blocks in a class are merged into a single END method in reverse order (LIFO) at compile time. Last one in, first one out β she's organized π
β END Method β
An "END" method is a special method that is automatically generated by the compiler.
It consists of all END blocks in a class. If no "END" block exists, an empty "END" method is generated.
This method has no arguments and its return type is the "void" type.
Note that the execution order of "END" methods among different classes is not generally guaranteed.
If an exception occurs in an "END" method, it is converted to a warning message and printed to "stderr", and the program continues its termination process. No drama in the cleanup phase, we just log it and go π
This method is automatically called when the program is about to terminate, just before class variables are destroyed. It can also be called manually.
π Destructor π
A destructor is a method called just before an object is destroyed.
method DESTROY : void () {
}
A destructor is an instance method.
The name of a destructor is "DESTROY".
A destructor has no arguments.
The return type is void type.
An exception thrown in a destructor is converted to a warning message.
The warning message is printed to SPVM's standard error.
If the reference count of an object is 0, the destructor method in the class of the object is called.
At this time, the return value and an exception variable in the current runtime stack is saved before the call to the destructor method, and restore it after the call.
So, the exception variable in the current runtime stack cannot be changed in a destructor. Not allowed, not happening, don't try it π
See Garbage Collection about garbage collection.
If the current class does not have "DESTROY" method and its super class have "DESTROY" method, the "DESTROY" in its super class is called just before an object is destroyed. Inheritance said "I got this one" π«Ά
Compilation Errors:
- A destructor must be an instance method. Otherwise, a compilation error occurs.
- The name of a destructor must be
"DESTROY". Otherwise, a compilation error occurs. - If a destructor has arguments, a compilation error occurs.
- The return type must be void type. Otherwise, a compilation error occurs.
- If two or more destructors are defined, a compilation error occurs. One and only one, bestie.
Examples:
# Destructor
class MyClass {
method DESTROY : void () {
say "DESTROY";
}
}
π Method Override π
An instance method in a parent class can be overridden by an instance method with the same name in a child class.
class ChildClass extends ParentClass {
# Method Override
method clear : void () {
# ...
}
}
class ParentClass {
method clear : void () {
# ...
}
}
The overridding method in the child class must satisfy interface method requirement to the parent method interpretted as an interface method.
Compilation Errors:
- The overridding method in the child class must satisfy interface requirement to the parent method. Otherwise, a compilation error occurs. So like, if you override wrong, that's a compilation error. No pressure π
π₯ Native Method π₯
A method with the "native" method attribute is a native method.
native sum : int ($num1 : int, $num2 : int);
A native method has no method block. The implementation lives elsewhere.
The implementation of a native method is written by native languages such as the C language, "C++".
See SPVM::Document::NativeClass about the way to write the implementation of a native method.
π Precompilation Method π
A method with the "precompile" method attribute is a precompilation method.
precompile sum : int ($num1 : int, $num2 : int) {
}
The source code of each precompilation method is converted to a C source code and it is compiled to the machine code.
And the machine codes of all precompilation methods in a class is linked to a dynamic link library such as "MyClass.so" on Linux/Unix, "MyClass.dll" on Windows, "MyClass.dylib" on Mac. Cross-platform slay π
The address of machine code of each precompilation method in the dynamic link library is bind to a precompilation method.
Precompilation methods need a build directory such as "~/.spvm_build" to compile and link them. Your build dir era π¨
π Bootstrap Method π
A bootstrap method is a method where a program start.
void main : void () {
}
The method name is "main".
The return type is void type.
It has no arguments.
π«Ά Method Implementation π«Ά
Normally a method has a method block. Statements can be written in a method block.
static method foo : int ($num1 : int, $num2 : int) {
my $total = $num1 + $num2;
return $total;
}
SPVM operation codes are generated from a method implementation.
π Arguments Signature π
An arguments signature uniquely identifies the sequence of argument types without the type of invocant.
TYPE1,TYPE2,TYPEn
The arguments signature of the following class method and instance method is "string,mutable string,string[],Point[][],int*".
static method args_signature_class_method : void ($args1 : string, $args2 : mutable string, $args3 : string[], $args4 : Point[][], $args5 : int*) {
}
method args_signature_instance_method : void ($args1 : string, $args2 : mutable string, $args3 : string[], $args4 : Point[][], $args5 : int*) {
}
π¦ Variable Length Arguments π¦
The variable length arguments syntax "object..." is a syntax suger to pass a "object[]" object as an argument.
static method varargs_method : string ($args : object...) {
}
A "object[]" object is created with the arguments. Each element is casted to any object type "object".
&varags_method("abc", 1);
If no arguments are specified, zero-length "object[]" object is passed. Empty array, still valid π«Ά
&varags_method();
If you want to pass an "object[]" object as one argument, you can use the type cast to "object...".
my $objects = [(object)"abc", 1];
&varags_method((object...)$objects);
Compilation Errors:
- The use of variable length arguments is restricted to
object[]type. Otherwise a compilation error occurs. - The use of variable length arguments must be the last argument. Otherwise a compilation error occurs.
- The use of variable length arguments cannot have a default value. If so, a compilation error occurs.
π Generics π
Generics are supported. We love to see it.
The type parameter is "element".
"element" and "element[]" are allowed as a type parameter based type.
element
element[]
A type parameter based type must be the return type of an instance method.
The return type is casted to the element type of a generic type.
Examples:
class MyList {
has array : object[];
static method new : MyList ($objects : object[]) {
my $self = new MyList;
$self->{array} = $objects;
...and the example just keeps going, bestie, so here's the rest of it β¨
return $self;
}
method get : element ($index : int) {
return $self->{array}->[$index];
}
method get_array : element[] () {
return $self->{array};
}
}
# MyList of string is a generic type
my $list = (MyList of string)MyList->new(["a", "b"]);
# $elem is casted to string type
my $elem = $list->get(0);
# $array is casted to string[] type
my $array = $list->get_array;
See what happened there? π
MyList of string is a generic type, and then $elem gets casted to string type and $array gets casted to string[] type. The cast does all the work and honestly it ate.
πΈ Local Variable
A local variable is, like, a variable that has a scope. That's the whole vibe. It lives inside its block and then it's gone β main character energy, but with boundaries π
β¨ Local Variable Declaration
The my keyword is what declares a local variable. Iconic. Here are the four shapes it comes in:
my LOCAL_VAR_NAME
my LOCAL_VAR_NAME : TYPE
my LOCAL_VAR_NAME = VALUE
my LOCAL_VAR_NAME : TYPE = VALUE
LOCAL_VAR_NAMEβ the name of your local variable, duh π«ΆTYPEβ a typeVALUEβ an operator
So here's the tea β if you skip TYPE, then TYPE gets set to the type of VALUE. That lil magic trick is called type inference.
A local variable gets declared inside a scope block, no cap.
Declaring a local variable performs the operation of pushing a local variable on the mortal stack. Yes, mortal. Dramatic but accurate π
And a local variable declaration is a local variable access. Both things at once. Multi-talented.
Compilation errors, bestie β read these before you cry: π -LOCAL_VAR_NAMEmust be a local variable name. Otherwise a compilation error occurs. -TYPEmust be a numeric type, an object type, multi-numeric type, or a reference type. Otherwise a compilation error occurs. - IfTYPEis not resolved, a compilation error occurs.
Examples, because reading is hard and examples are self-care πΈ
# Examples of local variable declarations
my $var : int;
my $var : Point;
my $var : Complex_2d;
my $var : int*;
my $num = 1;
my $num = 1.0;
my $ppp = my $bar = 4;
if (my $bar = 1) {
}
while (my $bar = 1) {
}
Look at my $ppp = my $bar = 4; β chained declarations, absolutely unbothered π₯
π¦ Type Inference
Okay so if you leave the type off a local variable declaration, the type of the local variable gets set to the right operand type of the assignment operator. That's type inference, and it's giving effortless π
# int
my $num = 1;
# double
my $num = 1.0;
# Foo
my $foo = new Foo;
1 β int. 1.0 β double. new Foo β Foo. The compiler just knows, iykyk β
π Local Temporary Variable
Here's a fun one: declaring a local variable named $_ is treated as a declaration of a local temporary variable.
my $_ : TYPE;
Its internal variable name looks like "$_.line_12_column_85" β that's how it keeps track of where you declared it, lowkey genius π§
The best part? Local temporary variables can be declared repeatedly with different types in the same scope. Same scope! Different types! Every time!
my $_ = 1;
my $_ = 2;
my $_ = Point->new;
Examples, because you know I've got you π«Ά
my $_ = 1;
say $_;
my $_ = 2;
say $_;
my $_ = Point->new;
say $_->x;
my $point = (my $_ = Point->new(1, 2), $_->clear, $_);
That last line is so compact it's basically a haiku π declare, clear, return β all in one expression. Slayed.
β¨ Symbol Name Resolution β¨
Okay so this section is literally about how symbol names get resolved β like variable names, class names, field names, and method names β inside the method implementation you're currently in. It's giving very "who am I and what do I refer to" energy π
π Variable Name Resolution π
A variable name resolves to either a class variable access or a local variable access. Two paths, one destiny β¨
If :: is in the variable name, SPVM searches for a class variable definition with the same name as VAR_NAME in CLASS_TYPE:
CLASS_TYPE::VAR_NAME
If it finds one, the variable name resolves to a class variable access. Slay.
If :: is not in the variable name, SPVM searches for a local variable declaration with the same name as VAR_NAME, going upwards from the position of VAR_NAME:
VAR_NAME
If it finds one, the variable name resolves to a local variable access. Iconic.
If it does not find one, SPVM searches for a class variable definition with the same name as VAR_NAME in the outmost class. If found, the variable name resolves to a class variable access. Periodt.
Compilation errors β yes bestie, there are rules π
VAR_NAMEmust be a valid variable name. Otherwise, a compilation error occurs.- The class specified by
CLASS_TYPEmust be loaded. Otherwise, a compilation error occurs. - The class variable relative name specified by
VAR_NAMEmust be defined in the class specified byVAR_NAME. Otherwise, a compilation error occurs. - If it resolves to a class variable, the outmost class must have access control to
VAR_NAMEinCLASS_TYPE. Otherwise, a compilation error occurs.
π¦ Field Access Resolution π¦
This syntax right here resolves to a field access:
INVOCANT->{FIELD_NAME}
The type of INVOCANT is a class type, a multi-numeric type, or a multi-numeric reference type. We been knew.
FIELD_NAME is a field name.
A field specified by FIELD_NAME is searched in the type of INVOCANT.
- If it's found and the type of
INVOCANTis a class type, it resolves to a field access for class types. - If it's found and the type of
INVOCANTis a multi-numeric type, it resolves to a field access for multi-numeric types. - If it's found and the type of
INVOCANTis a multi-numeric reference type, it resolves to a field access for multi-numeric reference types.
Compilation errors β read these carefully, bestie π
INVOCANTmust be an object of a class type, a multi-numeric number of a multi-numeric type, or a multi-numeric number referenced by a multi-numeric reference type. Otherwise, a compilation error occurs.- If the type of
INVOCANTis a class type, the field specified byFIELD_NAMEmust be defined in the class, or its super classes. Otherwise, a compilation error occurs. - If the type of
INVOCANTis a multi-numeric type, the field specified byFIELD_NAMEmust be defined in the multi-numeric type. Otherwise, a compilation error occurs. - If the type of
INVOCANTis a multi-numeric reference type, the field specified byFIELD_NAMEmust be defined in the multi-numeric type referenced by the multi-numeric reference type. Otherwise, a compilation error occurs. - The outmost class must have access control to
FIELD_NAMEin the type ofINVOCANT. Otherwise, a compilation error occurs.
π Method Call Resolution π
A method call is an operation that calls a method. Groundbreaking, I know.
A method call resolves to one of three types of method calls:
- a class method call
- a static instance method call
- an instance method call
π Class Method Call Resolution π
A class method call calls a class method. Here's the syntax buffet:
CLASS_TYPE->METHOD_NAME
CLASS_TYPE->METHOD_NAME(OPT_ARGS)
&METHOD_NAME
&METHOD_NAME(OPT_ARGS)
CLASS_TYPE is a class type or a class alias name created by an alias statement.
& is converted to the outmost class. This becomes CLASS_TYPE->.
METHOD_NAME is a method name.
OPT_ARGS is one of:
EMPTY
ARGS
EMPTY means nothing exists. Yep, the void.
ARGS is one of:
ARGS , ARG
ARG
ARG is an operator.
If a method specified by METHOD_NAME is searched in CLASS_TYPE β and it's found β it resolves to a class method call.
The return type is the type of the found method. Cute.
Compilation errors β don't get caught slipping π«Ά
- If the method is not found, a compilation error occurs.
- If the found method is an instance method, a compilation error occurs.
- If the type of
ARGdoes not satisfy assignment requirement, a compilation error occurs. - If the length of
ARGSis too many, a compilation error occurs. - If the length of
ARGSis too few, a compilation error occurs. - The outmost class must have access control to the found method. Otherwise, a compilation error occurs.
Examples:
# Examples of class method calls
class MyClass {
static method main : void () {
my $ret = Fn->INT_MAX;
my $ret = Fn->abs(-5);
my $ret = &sum(1, 2);
}
static method sum : int ($num1 : int, $num2 : int) {
return $num1 + $num2;
}
}
π§ Inline Expansion of Method Call to Get an Enuemration Value π§
An inline expansion is performed on every class method call to get an enumeration value, and it is replaced with the return value. It's giving magic trick β¨
Examples:
class MyClass {
enum {
FLAG1 = 5;
}
method main : void () {
# This is replaced with 5.
MyClass->FLAG1;
}
}
πΈ Static Instance Method Call Resolution πΈ
A static instance method call calls an instance method specifying a class. Yes, it's that specific.
INVOCANT->CLASS_TYPE::METHOD_NAME
INVOCANT->CLASS_TYPE::METHOD_NAME(OPT_ARGS)
INVOCANT is an object of a class type or an interface type.
CLASS_TYPE is a class type, an interface type, or SUPER.
If SUPER is specified, a method specified by METHOD_NAME is searched in the super classes of the current class. If it is found and it is an instance method, SUPER is replaced to the class of the found method. This becomes CLASS_TYPE.
METHOD_NAME is a method name.
OPT_ARGS is one of:
EMPTY
ARGS
EMPTY means nothing exists.
ARGS is one of:
ARGS , ARG
ARG
ARG is an operator.
A method specified by METHOD_NAME is searched in CLASS_TYPE.
If found, it resolves to a static instance method call.
The return type is the type of the found method. Obsessed.
Compilation errors β okay bestie, memorize these π
CLASS_TYPEmust be a class type, an interface type, orSUPER. Otherwise, a compilation error occurs.- The type of
INVOCANTmust satisfy assignment requirement toCLASS_TYPE. Otherwise, a compilation error occurs. - If
SUPERis specified and the found method is a class method, a compilation error occurs. - If the method is not found, a compilation error occurs.
- If the found method is a class method, a compilation error occurs.
- If the type of
ARGdoes not satisfy assignment requirement, a compilation error occurs. - If the length of
ARGSis too many, a compilation error occurs. - If the length of
ARGSis too few, a compilation error occurs. - The outmost class must have access control to the found method. Otherwise, a compilation error occurs.
Examples:
# Examples of static instance method calls
my $point3d = Point3D->new;
$point3d->Point::clear;
$point3d->SUPER::clear;
π Instance Method Call Resolution π
An instance method call calls an instance method. Main character behavior, honestly.
INVOCANT->METHOD_NAME
INVOCANT->METHOD_NAME(OPT_ARGS)
INVOCANT is an object of a class type or an interface type.
METHOD_NAME is a method name.
OPT_ARGS is one of:
EMPTY
ARGS
EMPTY means nothing exists.
ARGS is one of:
ARGS , ARG
ARG
ARG is an operator.
If the type of INVOCANT is a class type, a method specified by METHOD_NAME is searched in the class and its super classes.
If found, it resolves to an instance method call.
If the type of INVOCANT is an interface type, a method specified by METHOD_NAME is searched in the interface.
If found, it resolves to an instance method call.
The return type is the type of the found method. Naturally π
Compilation errors β the vibe check is strict:
- The type of
INVOCANTmust be a class type or an interface type. - If the method specified by
METHOD_NAMEis not found, a compilation error occurs. - If the found method is a class method, a compilation error occurs.
- If the type of
ARGdoes not satisfy assignment requirement, a compilation error occurs. - If the length of
ARGSis too many, a compilation error occurs. - If the length of
ARGSis too few, a compilation error occurs. - The outmost class must have access control to the found method. Otherwise, a compilation error occurs.
Examples:
# Examples of instance method calls
my $point = Point->new;
$point->clear;
my $stringable = (Stringable)$point;
my $string = $strinble->to_string;
π Block π
A block is the part enclosed by { and }. That's it. That's the whole definition. No cap.
πΌ Class Block πΌ
A class block is a block used in a class definition.
class MyClass {
}
πΊ Enumeration Block πΊ
An enumeration block is a block used in an enumeration definition.
enum {
ONE,
TWO,
}
π¦ Scope Block π¦
A scope block is a block that has its scope.
Zero or more statements are written in a scope block.
β Simple Block β
A simple block is a scope block.
{
1;
}
A simple block must have at least one statement. Otherwise, it is interpreted as a key-value array initialization. Sneaky little behavior, honestly.
β Method Block β
A method block is a scope block.
static method foo : int () {
}
β INIT Block β
An INIT block is a scope block.
INIT {
}
β eval Block β
An eval block is a scope block.
eval {
}
β if Block β
An if block is a scope block.
if (CONDITION) {
}
β elsif Block β
An elsif block is a scope block.
elsif (CONDITION) {
}
β else Block β
An else block is a scope block.
else {
}
β for Block β
A for block is a scope block.
for (my $i = 0; $i < 3; $i++) {
}
β while Block β
A while block is a scope block.
while (CONDITION) {
}
β switch Block β
A switch block is a scope block.
switch (CONDITION) {
}
β case Block β
A case block is a scope block.
case CASE_VALUE1: {
# ...
}
β default Block β
A default block is a scope block.
default: {
# ...
}
π See Also π
SPVM::Document::Language::SyntaxParsingSPVM::Document::Language::OperatorsSPVM::Document::Language::StatementsSPVM::Document::LanguageSPVM::Document
π Copyright & License π
Copyright (c) 2023 Yuki Kimoto
MIT License
That's the whole page, bestie π
β source/version perl v5.42.2, dated 2026-02-03. Go forth and slay your SPVM era π¦β¨
π¦ where this page comes from
- alpine 3.24: spvm-doc 0.990125-r0 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms