Системные методы для типов
Для каждого типа можно определить методы, которые позволят упростить работу с переменными данного типа и расширит его возможности. Рассмотрим абстрактный тип.
type test<index = uint >
{
uint mem
str name
uint itype
ubyte dim0
ubyte dim1
uint count
}
Инициализация
В Gentee происходит автоматическая инициализация переменных и полей любого типа. Если вы хотите произвести дополнительные действия при инициализации переменной типа, то определите метод init. Следует заметить, что все числовые поля инициализируются нулями, поля других типов также инициализируются в соответствии с описаниями тех типов. Например, если поле имеет тип str, то оно сразу будет инициализировано пустой строкой.
method test test.init
{
this.mem = malloc( 4096 )
this.name = "TEST"
itype = uint
return this
}
Уничтожение
Если вы перед уничтожением переменной данного типа хотите произвести дополнительные действия, то укажите их в методе delete.
method test.delete : mfree( this.mem )
Использование оператора of
Предположим, переменная данного типа может содержать элементы другого типа. В этом случае вы должны иметь возможность указать это при описании переменной. Например, test mytest of double. Для того чтобы компилятор мог понять оператор of необходимо определить метод oftype. У него должен быть параметр, в котором будет передан тип элементов.
method test.oftype( uint itype )
{
this.itype = itype
}
Указание размера и размерности
Предположим, что при описании переменной вы сразу хотите создать несколько элементов, а также указать размерность данной переменной. Например, test mytest[10,20] of double. Для этого вы должны описать по одному методу array для каждой возможной размерности.
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
}
Обращение по индексу
Если вы хотите получить i-й элемент переменной данного типа с помощью квадратных скобок, то вам следует описать по одному методу index для каждой размерности. В качестве индекса можно указывать не только числа, но любые другие типы. Для этого достаточно определить метод index с параметром соответствующего типа. Обратите внимание, что метод index должен возвращать указатель на найденный элемент!
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" ])")
Использование оператора foreach
В языке Gentee имеется оператор foreach, который перебирает все элементы у переменной определенного типа. Если вы хотите использовать этот оператор для вашего типа, то вы должны определить методы eof, first, next с параметром fordata. В поле icur у fordata хранится индекс текущего элемента при переборе. Вы должны обнулить его в методе first и увеличивать в методе next.
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
}
Переопределение операторов
Вы можете использовать всевозможные операции =, +, *, ==, !=, * и т.д. для переменных любого типа. Для этого необходимо описать соответствующие команды operator. Подробнее это рассматривается на странице Переопределение операций operator.
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 }