System type methods
For each type you can define methods that will simplify the work with variables of this type and increase its possibilities. Let’s take some abstract type.
type test<index = uint >
{
uint mem
str name
uint itype
ubyte dim0
ubyte dim1
uint count
}
Initialization
In Gentee the initialization of variables and fields of any type is automatic. If you want to perform additional actions during initialization of a type variable, define the method init. We should note that all number fields are initialized as zeroes, and fields of other types are also initialized according to descriptions of those types. For example, if the field has a str type, it will be initialized with an empty string at once.
method test test.init
{
this.mem = malloc( 4096 )
this.name = "TEST"
itype = uint
return this
}
Deletion
If before deleting a variable of this type you want to perform additional actions, specify them in the method delete.
method test.delete : mfree( this.mem )
Using the of operator
Let’s assume that a variable of this type can contain variables of another type. In this case you should have an opportunity to indicate it when you describe the variable. For example, test mytest of double. You should define the oftype method for the compiler to understand the of operator. It should have a parameter giving the element type.
method test.oftype( uint itype )
{
this.itype = itype
}
Specifying size and dimension
Let’s assume that when you describe a variable you want to create several elements at the same time and also specify the dimension of this variable. For example, test mytest[10,20] of double. To do this, you should describe one array method for each possible dimension.
method test.array( uint first )
{
this.count = first
this.dim0 = first
}
method test.array( uint first second )
{
this.array( first * count )
this.dim0 = first
this.dim1 = second
}
Addressing by an index
If you want to get the i-th element of the variable of this type using brackets, you should describe one index method for each dimension. You can specify not only numbers, but any other types as indexes. To do this, you only need to define a index method with a parameter of a corresponding type. Note that the index method must return the pointer to the element it finds!
method uint test.index( uint first )
{
return this.mem + first * sizeof( this.itype )
}
method uint test.index( uint first second )
{
return this.index( this.dim0 * first + second )
}
method uint test.index( str num )
{
return this.index( uint( num ))
}
...
test mytest[10]
mytest["0"] = 10
mytest[1] = 20
print("0 = \( mytest[0] ) 1 = \(mytest[ "1" ])")
Using the foreach operator
The Gentee language has a foreach operator that scans all elements of a variable of specified type. If you want to use this operator for your type, you should define the eof, first, next methods with a fordata parameter. The icur field of fordata stores the index of the current element during scanning. You should zero it in the first method and increase in the next method.
method uint test.eof( fordata fd )
{
return ?( fd.icur < this.count, 0, 1 )
}
method uint test.first( fordata fd )
{
return this.index( fd.icur = 0 )
}
method uint test.next( fordata fd )
{
return this.index( ++fd.icur )
}
...
test mytest[10]
uint sum
foreach curtest, mytest
{
sum += curtest
}
Redefining operators
You can use all kinds of operations like =, +, *, ==, !=, * etc. for variables of any type. To do this, you need to describe corresponding commands of operator. You can find more details at the Redefining operator operations page.
operator test =( test left, collection right )
{
uint i
fornum i=0, *right
{
if right.gettype(i) == uint
{
left[i] = right[i]->uint
}
}
return left
}
...
test mytest[10] = %{ 0, 1, 2, 3, 4, 5, 99, 8 }