ru.malik.elaborarer.avt.constant.pas

Переключить прокрутку окна
Загрузить этот исходный код

{
    Этот исходный код является частью проекта ПВТ-ОО.

    Copyright © 2021 Малик Разработчик

    Это свободная программа: вы можете перераспространять её и/или
    изменять её на условиях Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она может быть полезна,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <http://www.gnu.org/licenses/>.
}

unit ru.malik.elaborarer.avt.constant;

{$MODE DELPHI}

interface

uses
    pascalx.lang,
    pascalx.utils,
    ru.malik.elaborarer.avt.programme,
    ru.malik.elaborarer.avt.lexer,
    ru.malik.elaborarer.avt.operation;

{$ASMMODE INTEL,CALLING REGISTER,TYPEINFO ON}

(*
    Имена должны сопоставляться с объектами программы только с помощью функций resolveName и resolveMember! (сделано)
*)

{%region public }
type
    AVTUnaryOperatorStackItem = class(_Object)
    private
        fldPosition: int;
        fldOperatorKind: int;
        fldTypeCast: AVTType;
    public
        constructor create(position, operatorKind: int; typeCast: AVTType = nil);
        property position: int read fldPosition write fldPosition;
        property operatorKind: int read fldOperatorKind write fldOperatorKind;
        property typeCast: AVTType read fldTypeCast write fldTypeCast;
    end;

    AVTConstantExpression = class(AVTOperation)
    protected
        class function parseFullyQualifiedTypeName(packageRef: AVTPackage; typeRef: AVTTypeStructured; pos: int): AVTTypeStructured; static;
        class function tryParseFullyQualifiedTypeName(packageRef: AVTPackage; typeRef: AVTTypeStructured; pos: int): AVTTypeStructured; static;
        class function resolveMember(where: AVTTypeStructured; const simpleName: AnsiString; typeRef: AVTTypeStructured; pos: int): AVTMember; static;
    public
        class function itemToString(itemRef: AVTItemExt): AnsiString; static;
        class function commonType(type1Ref, type2Ref: AVTType): AVTType; static;
    private
        fldTypeClassRef: AVTTypeStructured;
        fldTypeStringRef: AVTTypeStructured;
        function parsePostfix(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parsePrimary(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parsePrefix(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parseMultiplicative(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parseAdditive(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parseShift(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parseRelational(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parseEquality(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parseBitAnd(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parseBitXor(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parseBitOr(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parseBoolAnd(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parseBoolOr(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function parseConditional(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
        function tryParseType(typeRef: AVTTypeStructured; source: AVTSource; pos: int): AVTType;
    protected
        procedure parseFieldInitialValue(fieldRef: AVTField);
        procedure parsePropertyImplementation(propertyRef: AVTProperty);
        function parseConstantExpression(dst: AVTConstant; typeRef: AVTTypeStructured; pos: int): int;
        function parseType(typeRef: AVTTypeStructured; pos: int): AVTType;
        function resolveName(const simpleName: AnsiString; typeRef: AVTTypeStructured; pos: int): AVTItem;
    public
        procedure cast(dst, op0: AVTConstant; typeNewRef: AVTTypePrimitive);
        function getPrimitiveType(kind: int): AVTTypePrimitive;
        function getStringType(): AVTTypeStructured;
        function getClassType(): AVTTypeStructured;
    end;
{%endregion}

implementation

{%region AVTUnaryOperatorStackItem }
    constructor AVTUnaryOperatorStackItem.create(position, operatorKind: int; typeCast: AVTType);
    begin
        inherited create();
        self.fldPosition := position;
        self.fldOperatorKind := operatorKind;
        self.fldTypeCast := typeCast;
    end;
{%endregion}

{%region AVTConstantExpression }
    class function AVTConstantExpression.parseFullyQualifiedTypeName(packageRef: AVTPackage; typeRef: AVTTypeStructured; pos: int): AVTTypeStructured;
    var
        simpleName: AnsiString;
        source: AVTSource;
        nextPackageRef: AVTPackage;
        nextTypeRef: AVTTypeStructured;
    begin
        source := typeRef.source;
        repeat
            if source.getLexemeType(pos) <> CHAR_PERIOD then begin
                raise AVTCompilerException.create('"." expected', source, pos);
            end;
            inc(pos);
            if source.getLexemeType(pos) <> LITR_NAME then begin
                raise AVTCompilerException.create('Type or package name expected', source, pos);
            end;
            simpleName := source.getLexemeAnsiString(pos);
            nextTypeRef := packageRef.getType(simpleName) as AVTTypeStructured;
            if nextTypeRef <> nil then break;
            nextPackageRef := packageRef.getSubpackage(simpleName);
            if nextPackageRef = nil then begin
                raise AVTCompilerException.create('Package not found: ' + packageRef.fullName + '.' + simpleName, source, pos);
            end;
            packageRef := nextPackageRef;
            inc(pos);
        until false;
        if not nextTypeRef.isVisible(nil, typeRef) then begin
            raise AVTCompilerException.create('The type ' + nextTypeRef.fullName + ' is not visible', source, pos);
        end;
        source.position := pos + 1;
        result := nextTypeRef;
    end;

    class function AVTConstantExpression.tryParseFullyQualifiedTypeName(packageRef: AVTPackage; typeRef: AVTTypeStructured; pos: int): AVTTypeStructured;
    var
        simpleName: AnsiString;
        source: AVTSource;
        nextPackageRef: AVTPackage;
        nextTypeRef: AVTTypeStructured;
    begin
        source := typeRef.source;
        repeat
            if source.getLexemeType(pos) <> CHAR_PERIOD then begin
                result := nil;
                exit;
            end;
            inc(pos);
            if source.getLexemeType(pos) <> LITR_NAME then begin
                result := nil;
                exit;
            end;
            simpleName := source.getLexemeAnsiString(pos);
            nextTypeRef := packageRef.getType(simpleName) as AVTTypeStructured;
            if nextTypeRef <> nil then break;
            nextPackageRef := packageRef.getSubpackage(simpleName);
            if nextPackageRef = nil then begin
                result := nil;
                exit;
            end;
            packageRef := nextPackageRef;
            inc(pos);
        until false;
        if not nextTypeRef.isVisible(nil, typeRef) then begin
            result := nil;
            exit;
        end;
        source.position := pos + 1;
        result := nextTypeRef;
    end;

    class function AVTConstantExpression.resolveMember(where: AVTTypeStructured; const simpleName: AnsiString; typeRef: AVTTypeStructured; pos: int): AVTMember;
    var
        member: AVTMember;
    begin
        member := where.getMember(simpleName);
        if (member is AVTField) or (member is AVTProperty) then begin
            member := where.findField(simpleName, typeRef, pos);
        end;
        if (member <> nil) and not(member is AVTMethod) and not member.isVisible(where, typeRef) then begin
            raise AVTCompilerException.create('The field ' + simpleName + ' is not visible', typeRef.source, pos);
        end;
        result := member;
    end;

    class function AVTConstantExpression.itemToString(itemRef: AVTItemExt): AnsiString;
    begin
        if itemRef = nil then begin
            result := 'null';
            exit;
        end;
        result := itemRef.fullName;
    end;

    class function AVTConstantExpression.commonType(type1Ref, type2Ref: AVTType): AVTType;
    begin
        if type1Ref <> nil then begin
            result := type1Ref.getCommonType(type2Ref);
            exit;
        end;
        if type2Ref <> nil then begin
            result := type2Ref.getCommonType(type1Ref);
            exit;
        end;
        result := nil;
    end;

    function AVTConstantExpression.parsePostfix(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    label
        label0;
    var
        index: int;
        operatorPos: int;
        op1: AVTConstant;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
    begin
        repeat
            operatorPos := pos;
            case source.getLexemeType(pos) of
            CHAR_BRACKET_OPENED: begin
                op1 := AVTConstant.create();
                try
                    pos := parseConditional(op1, typeRef, source, pos + 1);
                    if source.getLexemeType(pos) <> CHAR_BRACKET_CLOSED then begin
                        raise AVTCompilerException.create('"]" expected', source, pos);
                    end;
                    inc(pos);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    if not(typeOperand1Ref is AVTTypePrimitive) then begin
                        goto label0;
                    end;
                    case AVTTypePrimitive(typeOperand1Ref).primitiveKind of
                    AVT_BYTE: begin
                        index := op1.value.asByte;
                    end;
                    AVT_SHORT: begin
                        index := op1.value.asShort;
                    end;
                    AVT_INT: begin
                        index := op1.value.asInt;
                    end
                    else
                        goto label0;
                    end;
                    if typeOperand0Ref = getStringType() then begin
                        if dst.value.isNull then begin
                            raise AVTCompilerException.create('Null pointer error', source, operatorPos);
                        end;
                        if (index < 0) or (index >= length(dst.value.asString)) then begin
                            raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
                        end;
                        dst.value.asChar := dst.value.asString[index + 1];
                        dst.value.asString := '';
                        dst.valueType := getPrimitiveType(AVT_CHAR);
                        continue;
                    end;
                    if typeOperand0Ref is AVTTypePrimitive then begin
                        case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
                        AVT_BYTE2, AVT_BYTE4, AVT_BYTE8: begin
                            if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
                                raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
                            end;
                            dst.value.asByte := dst.value.asByte8[index];
                            dst.valueType := getPrimitiveType(AVT_BYTE);
                            continue;
                        end;
                        AVT_SHORT2, AVT_SHORT4, AVT_SHORT8: begin
                            if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
                                raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
                            end;
                            dst.value.asShort := dst.value.asShort8[index];
                            dst.valueType := getPrimitiveType(AVT_SHORT);
                            continue;
                        end;
                        AVT_INT2, AVT_INT4, AVT_INT8: begin
                            if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
                                raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
                            end;
                            dst.value.asInt := dst.value.asInt8[index];
                            dst.valueType := getPrimitiveType(AVT_INT);
                            continue;
                        end;
                        AVT_LONG2, AVT_LONG4, AVT_LONG8: begin
                            if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
                                raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
                            end;
                            dst.value.asLong := dst.value.asLong8[index];
                            dst.valueType := getPrimitiveType(AVT_LONG);
                            continue;
                        end;
                        AVT_FLOAT2, AVT_FLOAT4, AVT_FLOAT8: begin
                            if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
                                raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
                            end;
                            dst.value.asFloat := dst.value.asFloat8[index];
                            dst.valueType := getPrimitiveType(AVT_FLOAT);
                            continue;
                        end;
                        AVT_DOUBLE2, AVT_DOUBLE4, AVT_DOUBLE8: begin
                            if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
                                raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
                            end;
                            dst.value.asDouble := dst.value.asDouble8[index];
                            dst.valueType := getPrimitiveType(AVT_DOUBLE);
                            continue;
                        end;
                        end;
                    end;
                    label0:
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator [] is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            CHAR_PERIOD: begin
                inc(pos);
                if (source.getLexemeType(pos) <> LITR_NAME) or (source.getLexemeAnsiString(pos) <> 'length') then begin
                    raise AVTCompilerException.create('"length" expected', source, pos);
                end;
                inc(pos);
                if dst.valueType = getStringType() then begin
                    if dst.value.isNull then begin
                        raise AVTCompilerException.create('Null pointer error', source, operatorPos);
                    end;
                    dst.value.asInt := length(dst.value.asString);
                    dst.value.asString := '';
                    dst.valueType := getPrimitiveType(AVT_INT);
                    continue;
                end;
                raise AVTCompilerException.create('Expression of the type avt.lang.String expected', source, operatorPos);
            end
            else
                break;
            end;
        until false;
        result := pos;
    end;

    function AVTConstantExpression.parsePrimary(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        i: int;
        lxt: int;
        lim: int;
        kind: int;
        name: AnsiString;
        found: AVTItem;
        field: AVTField;
        member: AVTMember;
        element: AVTConstant;
        typeParsedRef: AVTType;
        typeElementRef: AVTType;
        typePrimitiveRef: AVTTypePrimitive;
    begin
        dst.clear();
        lxt := source.getLexemeType(pos);
        case lxt of
        AVT_NEW: begin
            inc(pos);
            lxt := source.getLexemeType(pos);
            case lxt of
            AVT_BYTE2, AVT_BYTE4, AVT_BYTE8: begin
                kind := AVT_BYTE;
            end;
            AVT_SHORT2, AVT_SHORT4, AVT_SHORT8: begin
                kind := AVT_SHORT;
            end;
            AVT_INT2, AVT_INT4, AVT_INT8: begin
                kind := AVT_INT;
            end;
            AVT_LONG2, AVT_LONG4, AVT_LONG8: begin
                kind := AVT_LONG;
            end;
            AVT_FLOAT2, AVT_FLOAT4, AVT_FLOAT8: begin
                kind := AVT_FLOAT;
            end;
            AVT_DOUBLE2, AVT_DOUBLE4, AVT_DOUBLE8: begin
                kind := AVT_DOUBLE;
            end
            else
                raise AVTCompilerException.create('Vector type expected', source, pos);
            end;
            typePrimitiveRef := getPrimitiveType(kind);
            inc(pos);
            if source.getLexemeType(pos) <> CHAR_CURLY_OPENED then begin
                raise AVTCompilerException.create('"{" expected', source, pos);
            end;
            inc(pos);
            lim := (1 shl (lxt and 3)) - 1;
            element := AVTConstant.create();
            try
                for i := 0 to lim do begin
                    pos := parseConditional(element, typeRef, source, pos);
                    typeElementRef := element.valueType;
                    if not typePrimitiveRef.isConvertableFrom(typeElementRef) then begin
                        raise AVTCompilerException.create('Can not assign value of the type ' + itemToString(typeElementRef) + ' to vector element of the type ' + itemToString(typePrimitiveRef), source, pos);
                    end;
                    cast(element, element, typePrimitiveRef);
                    case kind of
                    AVT_BYTE: dst.value.asByte8[i] := element.value.asByte;
                    AVT_SHORT: dst.value.asShort8[i] := element.value.asShort;
                    AVT_INT: dst.value.asInt8[i] := element.value.asInt;
                    AVT_LONG: dst.value.asLong8[i] := element.value.asLong;
                    AVT_FLOAT: dst.value.asFloat8[i] := element.value.asFloat;
                    AVT_DOUBLE: dst.value.asDouble8[i] := element.value.asDouble;
                    end;
                    if i < lim then begin
                        if source.getLexemeType(pos) <> CHAR_COMMA then begin
                            raise AVTCompilerException.create('"," expected', source, pos);
                        end;
                    end else begin
                        if source.getLexemeType(pos) <> CHAR_CURLY_CLOSED then begin
                            raise AVTCompilerException.create('"}" expected', source, pos);
                        end;
                    end;
                    inc(pos);
                end;
            finally
                element.free();
            end;
            dst.valueType := getPrimitiveType(lxt);
        end;
        AVT_NULL: begin
            dst.value.isNull := true;
            inc(pos);
        end;
        CHAR_PARENTH_OPENED: begin
            pos := parseConditional(dst, typeRef, source, pos + 1);
            if source.getLexemeType(pos) <> CHAR_PARENTH_CLOSED then begin
                raise AVTCompilerException.create('")" expected', source, pos);
            end;
            inc(pos);
        end;
        LITR_NAME, AVT_VOID..AVT_DOUBLE8: begin
            if lxt <> LITR_NAME then begin
                found := parseType(typeRef, pos);
                pos := source.position;
            end else begin
                name := source.getLexemeAnsiString(pos);
                found := resolveName(name, typeRef, pos);
                if found = nil then begin
                    raise AVTCompilerException.create(name + ' can not be resolved to a field', source, pos);
                end;
                if (found is AVTPackage) or (found is AVTType) then begin
                    found := parseType(typeRef, pos);
                    pos := source.position;
                end else begin
                    if found is AVTMethod then begin
                        raise AVTCompilerException.create('Methods is not allowed here', source, pos);
                    end;
                    if found is AVTProperty then begin
                        raise AVTCompilerException.create('Properties is not allowed here', source, pos);
                    end;
                    inc(pos);
                end;
            end;
            field := nil;
            if found is AVTType then begin
                typeParsedRef := AVTType(found);
                if source.getLexemeType(pos) <> CHAR_PERIOD then begin
                    raise AVTCompilerException.create('"." expected', source, pos);
                end;
                inc(pos);
                case source.getLexemeType(pos) of
                LITR_NAME: begin
                    if not(typeParsedRef is AVTTypeStructured) then begin
                        raise AVTCompilerException.create('"class" expected', source, pos);
                    end;
                    name := source.getLexemeAnsiString(pos);
                    member := resolveMember(AVTTypeStructured(typeParsedRef), name, typeRef, pos);
                    if member is AVTMethod then begin
                        raise AVTCompilerException.create('Methods is not allowed here', source, pos);
                    end;
                    if member is AVTProperty then begin
                        raise AVTCompilerException.create('Properties is not allowed here', source, pos);
                    end;
                    if not(member is AVTField) then begin
                        raise AVTCompilerException.create(name + ' can not be resolved or is not a field', source, pos);
                    end;
                    field := AVTField(member);
                    inc(pos);
                end;
                AVT_CLASS: begin
                    if typeParsedRef is AVTTypeArray then begin
                        AVTTypeArray(typeParsedRef).makeCompilable();
                    end;
                    dst.value.asClass := typeParsedRef;
                    dst.valueType := getClassType();
                    inc(pos);
                end
                else
                    if not(typeParsedRef is AVTTypeStructured) then begin
                        raise AVTCompilerException.create('"class" expected', source, pos);
                    end;
                    raise AVTCompilerException.create('Field name or "class" expected', source, pos);
                end;
            end else
            if found is AVTField then begin
                field := AVTField(found);
            end else begin
                raise AVTCompilerException.create('Field name expected', source, pos);
            end;
            if field <> nil then begin
                if ((field.flags and (FLAG_STATIC or FLAG_FINAL)) <> (FLAG_STATIC or FLAG_FINAL)) or (field.implementationPosition < 0) then begin
                    raise AVTCompilerException.create('The field ' + field.simpleName + ' is not a constant value', source, pos - 1);
                end;
                if field.valueConstCreating then begin
                    raise AVTCompilerException.create('The value of the field ' + field.simpleName + ' is defined through itself', source, pos - 1);
                end;
                if not field.valueConstCreated then begin
                    parseFieldInitialValue(field);
                end;
                dst.assign(field.valueConst);
            end;
        end;
        LITR_STRING: begin
            dst.value.asString := source.getLexemeUnicodeString(pos);
            dst.valueType := getStringType();
            inc(pos);
        end;
        LITR_BOOLEAN: begin
            dst.value.asBoolean := source.getLexemeBoolean(pos);
            dst.valueType := getPrimitiveType(AVT_BOOLEAN);
            inc(pos);
        end;
        LITR_CHAR: begin
            dst.value.asChar := source.getLexemeChar(pos);
            dst.valueType := getPrimitiveType(AVT_CHAR);
            inc(pos);
        end;
        LITR_REAL: begin
            dst.value.asReal := source.getLexemeReal(pos);
            dst.valueType := getPrimitiveType(AVT_REAL);
            inc(pos);
        end;
        LITR_BYTE: begin
            dst.value.asByte := source.getLexemeByte(pos);
            dst.valueType := getPrimitiveType(AVT_BYTE);
            inc(pos);
        end;
        LITR_SHORT: begin
            dst.value.asShort := source.getLexemeShort(pos);
            dst.valueType := getPrimitiveType(AVT_SHORT);
            inc(pos);
        end;
        LITR_INT: begin
            dst.value.asInt := source.getLexemeInt(pos);
            dst.valueType := getPrimitiveType(AVT_INT);
            inc(pos);
        end;
        LITR_LONG: begin
            dst.value.asLong := source.getLexemeLong(pos);
            dst.valueType := getPrimitiveType(AVT_LONG);
            inc(pos);
        end;
        LITR_FLOAT: begin
            dst.value.asFloat := source.getLexemeFloat(pos);
            dst.valueType := getPrimitiveType(AVT_FLOAT);
            inc(pos);
        end;
        LITR_DOUBLE: begin
            dst.value.asDouble := source.getLexemeDouble(pos);
            dst.valueType := getPrimitiveType(AVT_DOUBLE);
            inc(pos);
        end
        else
            raise AVTCompilerException.create('Error in expression', source, pos);
        end;
        result := parsePostfix(dst, typeRef, source, pos);
    end;

    function AVTConstantExpression.parsePrefix(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        i: int;
        lexemeType: int;
        operatorPos: int;
        primitiveKind: int;
        stack: Vector;
        typeCastRef: AVTType;
        typeOperandRef: AVTType;
        item: AVTUnaryOperatorStackItem;
    begin
        stack := nil;
        try
            repeat
                lexemeType := source.getLexemeType(pos);
                case lexemeType of
                OPER_BOOL_NOT, OPER_BIT_NOT, OPER_VECT_PACK, OPER_VECT_UNPCKL, OPER_VECT_UNPCKU: begin
                    if stack = nil then stack := Vector.create();
                    stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(pos, lexemeType)));
                    inc(pos);
                end;
                OPER_SCAL_ADD: begin
                    if stack = nil then stack := Vector.create();
                    stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(pos, OPER_SCAL_PLUS)));
                    inc(pos);
                end;
                OPER_SCAL_SUB: begin
                    if stack = nil then stack := Vector.create();
                    stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(pos, OPER_SCAL_MINUS)));
                    inc(pos);
                end;
                OPER_VECT_ADD: begin
                    if stack = nil then stack := Vector.create();
                    stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(pos, OPER_VECT_PLUS)));
                    inc(pos);
                end;
                OPER_VECT_SUB: begin
                    if stack = nil then stack := Vector.create();
                    stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(pos, OPER_VECT_MINUS)));
                    inc(pos);
                end;
                CHAR_PARENTH_OPENED: begin
                    operatorPos := pos;
                    typeCastRef := tryParseType(typeRef, source, pos + 1);
                    pos := source.position;
                    if (typeCastRef = nil) or (source.getLexemeType(pos) <> CHAR_PARENTH_CLOSED) then begin
                        pos := operatorPos;
                        break;
                    end;
                    if stack = nil then stack := Vector.create();
                    stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(operatorPos, OPER_TYPE_CAST, typeCastRef)));
                    inc(pos);
                end
                else
                    break;
                end;
            until false;
            pos := parsePrimary(dst, typeRef, source, pos);
            if stack <> nil then for i := stack.size() - 1 downto 0 do begin
                item := stack.elementAt(i).objectValue() as AVTUnaryOperatorStackItem;
                typeOperandRef := dst.valueType;
                operatorPos := item.position;
                case item.operatorKind of
                OPER_BOOL_NOT: begin
                    if (typeOperandRef <> nil) and typeOperandRef.isBoolean() then begin
                        dst.value.asBoolean := not dst.value.asBoolean;
                        continue;
                    end;
                    raise AVTCompilerException.create('The operator ! is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
                end;
                OPER_BIT_NOT: begin
                    if typeOperandRef is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
                        if primitiveKind = AVT_CHAR then begin
                            primitiveKind := AVT_INT;
                            dst.value.asInt := int(dst.value.asChar);
                        end;
                        case primitiveKind of
                        AVT_BYTE: begin
                            byteBitNot(dst, dst);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2BitNot(dst, dst);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4BitNot(dst, dst);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8BitNot(dst, dst);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortBitNot(dst, dst);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2BitNot(dst, dst);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4BitNot(dst, dst);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8BitNot(dst, dst);
                            continue;
                        end;
                        AVT_INT: begin
                            intBitNot(dst, dst);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2BitNot(dst, dst);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4BitNot(dst, dst);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8BitNot(dst, dst);
                            continue;
                        end;
                        AVT_LONG: begin
                            longBitNot(dst, dst);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2BitNot(dst, dst);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4BitNot(dst, dst);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8BitNot(dst, dst);
                            continue;
                        end;
                        end;
                    end;
                    raise AVTCompilerException.create('The operator ~ is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
                end;
                OPER_SCAL_PLUS: begin
                    if typeOperandRef is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
                        if primitiveKind = AVT_CHAR then begin
                            primitiveKind := AVT_INT;
                            dst.value.asInt := int(dst.value.asChar);
                        end;
                        case primitiveKind of
                        AVT_BYTE: begin
                            byteScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8ScalPlus(dst, dst);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalPlus(dst, dst);
                            continue;
                        end;
                        end;
                    end;
                    raise AVTCompilerException.create('The operator + is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
                end;
                OPER_SCAL_MINUS: begin
                    if typeOperandRef is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
                        if primitiveKind = AVT_CHAR then begin
                            primitiveKind := AVT_INT;
                            dst.value.asInt := int(dst.value.asChar);
                        end;
                        case primitiveKind of
                        AVT_BYTE: begin
                            byteScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8ScalMinus(dst, dst);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalMinus(dst, dst);
                            continue;
                        end;
                        end;
                    end;
                    raise AVTCompilerException.create('The operator - is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
                end;
                OPER_VECT_PACK: begin
                    if typeOperandRef is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
                        if primitiveKind = AVT_CHAR then begin
                            primitiveKind := AVT_INT;
                            dst.value.asInt := int(dst.value.asChar);
                        end;
                        case primitiveKind of
                        AVT_BYTE: begin
                            castByte8ToShort8(dst, dst, AVT_SHORT);
                            shortVectPack(dst, dst);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            castByte8ToShort8(dst, dst, AVT_SHORT2);
                            short2VectPack(dst, dst);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            castByte8ToShort8(dst, dst, AVT_SHORT4);
                            short4VectPack(dst, dst);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            castByte8ToShort8(dst, dst, AVT_SHORT8);
                            short8VectPack(dst, dst);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectPack(dst, dst);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectPack(dst, dst);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectPack(dst, dst);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectPack(dst, dst);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectPack(dst, dst);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectPack(dst, dst);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectPack(dst, dst);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectPack(dst, dst);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectPack(dst, dst);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectPack(dst, dst);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectPack(dst, dst);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectPack(dst, dst);
                            continue;
                        end;
                        end;
                    end;
                    raise AVTCompilerException.create('The operator @@@@ is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
                end;
                OPER_VECT_UNPCKL: begin
                    if typeOperandRef is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
                        if primitiveKind = AVT_CHAR then begin
                            primitiveKind := AVT_INT;
                            dst.value.asInt := int(dst.value.asChar);
                        end;
                        case primitiveKind of
                        AVT_BYTE: begin
                            byteVectUnpckl(dst, dst);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectUnpckl(dst, dst);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectUnpckl(dst, dst);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectUnpckl(dst, dst);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectUnpckl(dst, dst);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectUnpckl(dst, dst);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectUnpckl(dst, dst);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectUnpckl(dst, dst);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectUnpckl(dst, dst);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectUnpckl(dst, dst);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectUnpckl(dst, dst);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectUnpckl(dst, dst);
                            continue;
                        end;
                        end;
                    end;
                    raise AVTCompilerException.create('The operator #### is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
                end;
                OPER_VECT_UNPCKU: begin
                    if typeOperandRef is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
                        if primitiveKind = AVT_CHAR then begin
                            primitiveKind := AVT_INT;
                            dst.value.asInt := int(dst.value.asChar);
                        end;
                        case primitiveKind of
                        AVT_BYTE: begin
                            byteVectUnpcku(dst, dst);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectUnpcku(dst, dst);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectUnpcku(dst, dst);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectUnpcku(dst, dst);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectUnpcku(dst, dst);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectUnpcku(dst, dst);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectUnpcku(dst, dst);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectUnpcku(dst, dst);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectUnpcku(dst, dst);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectUnpcku(dst, dst);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectUnpcku(dst, dst);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectUnpcku(dst, dst);
                            continue;
                        end;
                        end;
                    end;
                    raise AVTCompilerException.create('The operator ^^^^ is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
                end;
                OPER_VECT_PLUS: begin
                    if typeOperandRef is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
                        if primitiveKind = AVT_CHAR then begin
                            primitiveKind := AVT_INT;
                            dst.value.asInt := int(dst.value.asChar);
                        end;
                        case primitiveKind of
                        AVT_BYTE: begin
                            byteVectPlus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectPlus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectPlus(dst, dst);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectPlus(dst, dst);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectPlus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectPlus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectPlus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectPlus(dst, dst);
                            continue;
                        end;
                        end;
                    end;
                    raise AVTCompilerException.create('The operator ++++ is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
                end;
                OPER_VECT_MINUS: begin
                    if typeOperandRef is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
                        if primitiveKind = AVT_CHAR then begin
                            primitiveKind := AVT_INT;
                            dst.value.asInt := int(dst.value.asChar);
                        end;
                        case primitiveKind of
                        AVT_BYTE: begin
                            byteVectMinus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectMinus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectMinus(dst, dst);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectMinus(dst, dst);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectMinus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectMinus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectMinus(dst, dst);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectMinus(dst, dst);
                            continue;
                        end;
                        end;
                    end;
                    raise AVTCompilerException.create('The operator ---- is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
                end;
                OPER_TYPE_CAST: begin
                    typeCastRef := item.typeCast;
                    if typeOperandRef = nil then begin
                        if typeCastRef is AVTTypeStructured then begin
                            dst.valueType := typeCastRef;
                            continue;
                        end;
                    end else begin
                        if typeOperandRef.isBoolean() and typeCastRef.isBoolean() then begin
                            continue;
                        end;
                        if typeOperandRef.isNumeric() and typeCastRef.isNumeric() then begin
                            cast(dst, dst, typeCastRef as AVTTypePrimitive);
                            continue;
                        end;
                        if (typeOperandRef is AVTTypeStructured) and (typeCastRef is AVTTypeStructured) and typeCastRef.isAssignableFrom(typeOperandRef) then begin
                            dst.valueType := typeCastRef;
                            continue;
                        end;
                    end;
                    raise AVTCompilerException.create('Can not cast from ' + itemToString(typeOperandRef) + ' to ' + itemToString(typeCastRef), source, operatorPos);
                end;
                end;
            end;
        finally
            stack.free();
        end;
        result := pos;
    end;

    function AVTConstantExpression.parseMultiplicative(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        operatorPos: int;
        op1: AVTConstant;
        typeCommonRef: AVTType;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
    begin
        pos := parsePrefix(dst, typeRef, source, pos);
        repeat
            operatorPos := pos;
            case source.getLexemeType(pos) of
            OPER_SCAL_MUL: begin
                op1 := AVTConstant.create();
                try
                    pos := parsePrefix(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8ScalMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalMul(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator * is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_SCAL_DIV: begin
                op1 := AVTConstant.create();
                try
                    pos := parsePrefix(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            if op1.value.asByte = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            byteScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            if op1.value.asShort = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            shortScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            if op1.value.asInt = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            intScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            if op1.value.asLong = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            longScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2ScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4ScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8ScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2ScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4ScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8ScalDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalDiv(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator / is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_SCAL_DIVU: begin
                op1 := AVTConstant.create();
                try
                    pos := parsePrefix(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            if op1.value.asByte = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            byteScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            if op1.value.asShort = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            shortScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            if op1.value.asInt = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            intScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            if op1.value.asLong = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            longScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2ScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4ScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8ScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2ScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4ScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8ScalDivu(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalDivu(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator // is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_SCAL_REM: begin
                op1 := AVTConstant.create();
                try
                    pos := parsePrefix(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            if op1.value.asByte = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            byteScalRem(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            if op1.value.asShort = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            shortScalRem(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            if op1.value.asInt = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            intScalRem(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            if op1.value.asLong = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            longScalRem(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalRem(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalRem(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalRem(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator % is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_SCAL_REMU: begin
                op1 := AVTConstant.create();
                try
                    pos := parsePrefix(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            if op1.value.asByte = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            byteScalRemu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            if op1.value.asShort = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            shortScalRemu(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            if op1.value.asInt = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            intScalRemu(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            if op1.value.asLong = 0 then begin
                                raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
                            end;
                            longScalRemu(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalRemu(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalRemu(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalRemu(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator %% is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_MUL: begin
                op1 := AVTConstant.create();
                try
                    pos := parsePrefix(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectMul(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectMul(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator **** is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_MULS: begin
                op1 := AVTConstant.create();
                try
                    pos := parsePrefix(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectMuls(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectMuls(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectMuls(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectMuls(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectMuls(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectMuls(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectMuls(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectMuls(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator |**| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_MULU: begin
                op1 := AVTConstant.create();
                try
                    pos := parsePrefix(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectMulu(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectMulu(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectMulu(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectMulu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectMulu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectMulu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectMulu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectMulu(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator #**# is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_DIV: begin
                op1 := AVTConstant.create();
                try
                    pos := parsePrefix(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            castByte8ToFloat8(dst, dst, AVT_FLOAT);
                            castByte8ToFloat8(op1, op1, AVT_FLOAT);
                            floatVectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            castByte8ToFloat8(dst, dst, AVT_FLOAT2);
                            castByte8ToFloat8(op1, op1, AVT_FLOAT2);
                            float2VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            castByte8ToFloat8(dst, dst, AVT_FLOAT4);
                            castByte8ToFloat8(op1, op1, AVT_FLOAT4);
                            float4VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            castByte8ToFloat8(dst, dst, AVT_FLOAT8);
                            castByte8ToFloat8(op1, op1, AVT_FLOAT8);
                            float8VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            castShort8ToFloat8(dst, dst, AVT_FLOAT);
                            castShort8ToFloat8(op1, op1, AVT_FLOAT);
                            floatVectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            castShort8ToFloat8(dst, dst, AVT_FLOAT2);
                            castShort8ToFloat8(op1, op1, AVT_FLOAT2);
                            float2VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            castShort8ToFloat8(dst, dst, AVT_FLOAT4);
                            castShort8ToFloat8(op1, op1, AVT_FLOAT4);
                            float4VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            castShort8ToFloat8(dst, dst, AVT_FLOAT8);
                            castShort8ToFloat8(op1, op1, AVT_FLOAT8);
                            float8VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            castInt8ToDouble8(dst, dst, AVT_DOUBLE);
                            castInt8ToDouble8(op1, op1, AVT_DOUBLE);
                            doubleVectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            castInt8ToDouble8(dst, dst, AVT_DOUBLE2);
                            castInt8ToDouble8(op1, op1, AVT_DOUBLE2);
                            double2VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            castInt8ToDouble8(dst, dst, AVT_DOUBLE4);
                            castInt8ToDouble8(op1, op1, AVT_DOUBLE4);
                            double4VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            castInt8ToDouble8(dst, dst, AVT_DOUBLE8);
                            castInt8ToDouble8(op1, op1, AVT_DOUBLE8);
                            double8VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectDiv(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectDiv(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator //// is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end
            else
                break;
            end;
        until false;
        result := pos;
    end;

    function AVTConstantExpression.parseAdditive(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        operatorPos: int;
        op1: AVTConstant;
        typeStringRef: AVTType;
        typeCommonRef: AVTType;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
    begin
        pos := parseMultiplicative(dst, typeRef, source, pos);
        repeat
            operatorPos := pos;
            case source.getLexemeType(pos) of
            OPER_SCAL_ADD: begin
                op1 := AVTConstant.create();
                try
                    pos := parseMultiplicative(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypeStructured then begin
                        typeStringRef := getStringType();
                        if typeStringRef.isAssignableFrom(typeCommonRef) and not dst.value.isNull and not op1.value.isNull then begin
                            dst.value.asString := dst.value.asString + op1.value.asString;
                            dst.valueType := typeStringRef;
                            continue;
                        end;
                    end else
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8ScalAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalAdd(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator + is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_SCAL_SUB: begin
                op1 := AVTConstant.create();
                try
                    pos := parseMultiplicative(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8ScalSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalSub(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator - is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_ADD: begin
                op1 := AVTConstant.create();
                try
                    pos := parseMultiplicative(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectAdd(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectAdd(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator ++++ is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_ADDS: begin
                op1 := AVTConstant.create();
                try
                    pos := parseMultiplicative(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectAdds(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectAdds(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectAdds(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectAdds(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectAdds(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectAdds(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectAdds(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectAdds(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator |++| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_ADDU: begin
                op1 := AVTConstant.create();
                try
                    pos := parseMultiplicative(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectAddu(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectAddu(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectAddu(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectAddu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectAddu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectAddu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectAddu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectAddu(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator #++# is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_SUB: begin
                op1 := AVTConstant.create();
                try
                    pos := parseMultiplicative(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectSub(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectSub(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator ---- is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_SUBS: begin
                op1 := AVTConstant.create();
                try
                    pos := parseMultiplicative(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectSubs(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectSubs(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectSubs(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectSubs(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectSubs(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectSubs(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectSubs(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectSubs(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator |--| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_SUBU: begin
                op1 := AVTConstant.create();
                try
                    pos := parseMultiplicative(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectSubu(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectSubu(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectSubu(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectSubu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectSubu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectSubu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectSubu(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectSubu(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator #--# is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end
            else
                break;
            end;
        until false;
        result := pos;
    end;

    function AVTConstantExpression.parseShift(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        primitiveKind: int;
        operatorPos: int;
        op1: AVTConstant;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
    begin
        pos := parseAdditive(dst, typeRef, source, pos);
        repeat
            operatorPos := pos;
            case source.getLexemeType(pos) of
            OPER_SCAL_SAR: begin
                op1 := AVTConstant.create();
                try
                    pos := parseAdditive(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    if typeOperand1Ref is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
                    end else begin
                        primitiveKind := 0;
                    end;
                    if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
                        case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
                        AVT_CHAR: begin
                            dst.value.asInt := int(dst.value.asChar);
                            intScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE: begin
                            byteScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2ScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4ScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8ScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2ScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4ScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8ScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2ScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4ScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8ScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2ScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4ScalSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8ScalSar(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator >> is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_SCAL_SAL: begin
                op1 := AVTConstant.create();
                try
                    pos := parseAdditive(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    if typeOperand1Ref is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
                    end else begin
                        primitiveKind := 0;
                    end;
                    if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
                        case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
                        AVT_CHAR: begin
                            dst.value.asInt := int(dst.value.asChar);
                            intScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE: begin
                            byteScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2ScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4ScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8ScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2ScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4ScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8ScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2ScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4ScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8ScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2ScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4ScalSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8ScalSal(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator << is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_SCAL_SHR: begin
                op1 := AVTConstant.create();
                try
                    pos := parseAdditive(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    if typeOperand1Ref is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
                    end else begin
                        primitiveKind := 0;
                    end;
                    if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
                        case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
                        AVT_CHAR: begin
                            dst.value.asInt := int(dst.value.asChar);
                            intScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE: begin
                            byteScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2ScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4ScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8ScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2ScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4ScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8ScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2ScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4ScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8ScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2ScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4ScalShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8ScalShr(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator >>> is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_SAR: begin
                op1 := AVTConstant.create();
                try
                    pos := parseAdditive(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    if typeOperand1Ref is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
                    end else begin
                        primitiveKind := 0;
                    end;
                    if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
                        case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
                        AVT_CHAR: begin
                            dst.value.asInt := int(dst.value.asChar);
                            intVectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE: begin
                            byteVectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectSar(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectSar(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator >>>> is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_SAL: begin
                op1 := AVTConstant.create();
                try
                    pos := parseAdditive(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    if typeOperand1Ref is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
                    end else begin
                        primitiveKind := 0;
                    end;
                    if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
                        case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
                        AVT_CHAR: begin
                            dst.value.asInt := int(dst.value.asChar);
                            intVectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE: begin
                            byteVectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectSal(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectSal(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator <<<< is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_SHR: begin
                op1 := AVTConstant.create();
                try
                    pos := parseAdditive(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    if typeOperand1Ref is AVTTypePrimitive then begin
                        primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
                    end else begin
                        primitiveKind := 0;
                    end;
                    if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
                        case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
                        AVT_CHAR: begin
                            dst.value.asInt := int(dst.value.asChar);
                            intVectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE: begin
                            byteVectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectShr(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectShr(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator >>>>> is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end
            else
                break;
            end;
        until false;
        result := pos;
    end;

    function AVTConstantExpression.parseRelational(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        operatorPos: int;
        op1: AVTConstant;
        typeCommonRef: AVTType;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
    begin
        pos := parseShift(dst, typeRef, source, pos);
        repeat
            operatorPos := pos;
            case source.getLexemeType(pos) of
            OPER_SCAL_G: begin
                op1 := AVTConstant.create();
                try
                    pos := parseShift(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteScalG(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalG(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalG(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalG(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalG(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalG(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalG(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator > is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_SCAL_GE: begin
                op1 := AVTConstant.create();
                try
                    pos := parseShift(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteScalGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalGE(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator >= is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_SCAL_L: begin
                op1 := AVTConstant.create();
                try
                    pos := parseShift(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteScalL(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalL(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalL(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalL(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalL(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalL(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalL(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator < is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_SCAL_LE: begin
                op1 := AVTConstant.create();
                try
                    pos := parseShift(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteScalLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalLE(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator <= is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_G: begin
                op1 := AVTConstant.create();
                try
                    pos := parseShift(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectG(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectG(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator |>>| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_GE: begin
                op1 := AVTConstant.create();
                try
                    pos := parseShift(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectGE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectGE(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator |>=| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_L: begin
                op1 := AVTConstant.create();
                try
                    pos := parseShift(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectL(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectL(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator |<<| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_LE: begin
                op1 := AVTConstant.create();
                try
                    pos := parseShift(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectLE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectLE(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator |<=| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end
            else
                break;
            end;
        until false;
        result := pos;
    end;

    function AVTConstantExpression.parseEquality(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        operatorPos: int;
        op1: AVTConstant;
        typeCommonRef: AVTType;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
    begin
        pos := parseRelational(dst, typeRef, source, pos);
        repeat
            operatorPos := pos;
            case source.getLexemeType(pos) of
            OPER_SCAL_E: begin
                op1 := AVTConstant.create();
                try
                    pos := parseRelational(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef = nil then begin
                        dst.clear();
                        dst.value.asBoolean := true;
                        dst.valueType := getPrimitiveType(AVT_BOOLEAN);
                        continue;
                    end;
                    if typeCommonRef is AVTTypeStructured then begin
                        if dst.value.isNull then begin
                            dst.value.asBoolean := op1.value.isNull;
                        end else begin
                            if op1.value.isNull then begin
                                dst.value.asBoolean := false;
                            end else begin
                                dst.value.asBoolean := dst.value.asString = op1.value.asString;
                            end;
                            dst.value.asString := '';
                        end;
                        dst.valueType := getPrimitiveType(AVT_BOOLEAN);
                        continue;
                    end;
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BOOLEAN: begin
                            dst.value.asBoolean := dst.value.asBoolean = op1.value.asBoolean;
                            dst.valueType := getPrimitiveType(AVT_BOOLEAN);
                            continue;
                        end;
                        AVT_BYTE: begin
                            byteScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8ScalE(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalE(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator == is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_SCAL_NE: begin
                op1 := AVTConstant.create();
                try
                    pos := parseRelational(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef = nil then begin
                        dst.clear();
                        dst.value.asBoolean := false;
                        dst.valueType := getPrimitiveType(AVT_BOOLEAN);
                        continue;
                    end;
                    if typeCommonRef is AVTTypeStructured then begin
                        if dst.value.isNull then begin
                            dst.value.asBoolean := not op1.value.isNull;
                        end else begin
                            if op1.value.isNull then begin
                                dst.value.asBoolean := true;
                            end else begin
                                dst.value.asBoolean := dst.value.asString <> op1.value.asString;
                            end;
                            dst.value.asString := '';
                        end;
                        dst.valueType := getPrimitiveType(AVT_BOOLEAN);
                        continue;
                    end;
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BOOLEAN: begin
                            dst.value.asBoolean := dst.value.asBoolean <> op1.value.asBoolean;
                            dst.valueType := getPrimitiveType(AVT_BOOLEAN);
                            continue;
                        end;
                        AVT_BYTE: begin
                            byteScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8ScalNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_REAL: begin
                            realScalNE(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator != is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_E: begin
                op1 := AVTConstant.create();
                try
                    pos := parseRelational(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectE(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator |==| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end;
            OPER_VECT_NE: begin
                op1 := AVTConstant.create();
                try
                    pos := parseRelational(op1, typeRef, source, pos + 1);
                    typeOperand0Ref := dst.valueType;
                    typeOperand1Ref := op1.valueType;
                    typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        case AVTTypePrimitive(typeCommonRef).primitiveKind of
                        AVT_BYTE: begin
                            byteVectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE2: begin
                            byte2VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE4: begin
                            byte4VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_BYTE8: begin
                            byte8VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT: begin
                            shortVectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT2: begin
                            short2VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT4: begin
                            short4VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_SHORT8: begin
                            short8VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT: begin
                            intVectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT2: begin
                            int2VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT4: begin
                            int4VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_INT8: begin
                            int8VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG: begin
                            longVectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG2: begin
                            long2VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG4: begin
                            long4VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_LONG8: begin
                            long8VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT: begin
                            floatVectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT2: begin
                            float2VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT4: begin
                            float4VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_FLOAT8: begin
                            float8VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE: begin
                            doubleVectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE2: begin
                            double2VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE4: begin
                            double4VectNE(dst, dst, op1);
                            continue;
                        end;
                        AVT_DOUBLE8: begin
                            double8VectNE(dst, dst, op1);
                            continue;
                        end;
                        end;
                    end;
                finally
                    op1.free();
                end;
                raise AVTCompilerException.create('The operator |!=| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
            end
            else
                break;
            end;
        until false;
        result := pos;
    end;

    function AVTConstantExpression.parseBitAnd(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        operatorPos: int;
        op1: AVTConstant;
        typeCommonRef: AVTType;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
    begin
        pos := parseEquality(dst, typeRef, source, pos);
        while source.getLexemeType(pos) = OPER_BIT_AND do begin
            operatorPos := pos;
            op1 := AVTConstant.create();
            try
                pos := parseEquality(op1, typeRef, source, pos + 1);
                typeOperand0Ref := dst.valueType;
                typeOperand1Ref := op1.valueType;
                typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                if typeCommonRef is AVTTypePrimitive then begin
                    cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                    cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                    case AVTTypePrimitive(typeCommonRef).primitiveKind of
                    AVT_BOOLEAN: begin
                        dst.value.asBoolean := dst.value.asBoolean and op1.value.asBoolean;
                        continue;
                    end;
                    AVT_BYTE: begin
                        byteBitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_BYTE2: begin
                        byte2BitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_BYTE4: begin
                        byte4BitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_BYTE8: begin
                        byte8BitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT: begin
                        shortBitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT2: begin
                        short2BitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT4: begin
                        short4BitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT8: begin
                        short8BitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT: begin
                        intBitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT2: begin
                        int2BitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT4: begin
                        int4BitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT8: begin
                        int8BitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG: begin
                        longBitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG2: begin
                        long2BitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG4: begin
                        long4BitAnd(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG8: begin
                        long8BitAnd(dst, dst, op1);
                        continue;
                    end;
                    end;
                end;
            finally
                op1.free();
            end;
            raise AVTCompilerException.create('The operator & is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
        end;
        result := pos;
    end;

    function AVTConstantExpression.parseBitXor(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        operatorPos: int;
        op1: AVTConstant;
        typeCommonRef: AVTType;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
    begin
        pos := parseBitAnd(dst, typeRef, source, pos);
        while source.getLexemeType(pos) = OPER_BIT_XOR do begin
            operatorPos := pos;
            op1 := AVTConstant.create();
            try
                pos := parseBitAnd(op1, typeRef, source, pos + 1);
                typeOperand0Ref := dst.valueType;
                typeOperand1Ref := op1.valueType;
                typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                if typeCommonRef is AVTTypePrimitive then begin
                    cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                    cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                    case AVTTypePrimitive(typeCommonRef).primitiveKind of
                    AVT_BOOLEAN: begin
                        dst.value.asBoolean := dst.value.asBoolean xor op1.value.asBoolean;
                        continue;
                    end;
                    AVT_BYTE: begin
                        byteBitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_BYTE2: begin
                        byte2BitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_BYTE4: begin
                        byte4BitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_BYTE8: begin
                        byte8BitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT: begin
                        shortBitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT2: begin
                        short2BitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT4: begin
                        short4BitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT8: begin
                        short8BitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT: begin
                        intBitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT2: begin
                        int2BitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT4: begin
                        int4BitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT8: begin
                        int8BitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG: begin
                        longBitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG2: begin
                        long2BitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG4: begin
                        long4BitXor(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG8: begin
                        long8BitXor(dst, dst, op1);
                        continue;
                    end;
                    end;
                end;
            finally
                op1.free();
            end;
            raise AVTCompilerException.create('The operator ^ is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
        end;
        result := pos;
    end;

    function AVTConstantExpression.parseBitOr(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        operatorPos: int;
        op1: AVTConstant;
        typeCommonRef: AVTType;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
    begin
        pos := parseBitXor(dst, typeRef, source, pos);
        while source.getLexemeType(pos) = OPER_BIT_OR do begin
            operatorPos := pos;
            op1 := AVTConstant.create();
            try
                pos := parseBitXor(op1, typeRef, source, pos + 1);
                typeOperand0Ref := dst.valueType;
                typeOperand1Ref := op1.valueType;
                typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                if typeCommonRef is AVTTypePrimitive then begin
                    cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                    cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                    case AVTTypePrimitive(typeCommonRef).primitiveKind of
                    AVT_BOOLEAN: begin
                        dst.value.asBoolean := dst.value.asBoolean or op1.value.asBoolean;
                        continue;
                    end;
                    AVT_BYTE: begin
                        byteBitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_BYTE2: begin
                        byte2BitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_BYTE4: begin
                        byte4BitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_BYTE8: begin
                        byte8BitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT: begin
                        shortBitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT2: begin
                        short2BitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT4: begin
                        short4BitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_SHORT8: begin
                        short8BitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT: begin
                        intBitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT2: begin
                        int2BitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT4: begin
                        int4BitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_INT8: begin
                        int8BitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG: begin
                        longBitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG2: begin
                        long2BitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG4: begin
                        long4BitOr(dst, dst, op1);
                        continue;
                    end;
                    AVT_LONG8: begin
                        long8BitOr(dst, dst, op1);
                        continue;
                    end;
                    end;
                end;
            finally
                op1.free();
            end;
            raise AVTCompilerException.create('The operator | is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
        end;
        result := pos;
    end;

    function AVTConstantExpression.parseBoolAnd(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        operatorPos: int;
        op1: AVTConstant;
        typeCommonRef: AVTType;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
    begin
        pos := parseBitOr(dst, typeRef, source, pos);
        while source.getLexemeType(pos) = OPER_BOOL_AND do begin
            operatorPos := pos;
            op1 := AVTConstant.create();
            try
                pos := parseBitOr(op1, typeRef, source, pos + 1);
                typeOperand0Ref := dst.valueType;
                typeOperand1Ref := op1.valueType;
                typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                if typeCommonRef is AVTTypePrimitive then begin
                    cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                    cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                    if typeCommonRef.isBoolean() then begin
                        dst.value.asBoolean := dst.value.asBoolean and op1.value.asBoolean;
                        continue;
                    end;
                end;
            finally
                op1.free();
            end;
            raise AVTCompilerException.create('The operator && is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
        end;
        result := pos;
    end;

    function AVTConstantExpression.parseBoolOr(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    var
        operatorPos: int;
        op1: AVTConstant;
        typeCommonRef: AVTType;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
    begin
        pos := parseBoolAnd(dst, typeRef, source, pos);
        while source.getLexemeType(pos) = OPER_BOOL_OR do begin
            operatorPos := pos;
            op1 := AVTConstant.create();
            try
                pos := parseBoolAnd(op1, typeRef, source, pos + 1);
                typeOperand0Ref := dst.valueType;
                typeOperand1Ref := op1.valueType;
                typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
                if typeCommonRef is AVTTypePrimitive then begin
                    cast(dst, dst, AVTTypePrimitive(typeCommonRef));
                    cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                    if typeCommonRef.isBoolean() then begin
                        dst.value.asBoolean := dst.value.asBoolean or op1.value.asBoolean;
                        continue;
                    end;
                end;
            finally
                op1.free();
            end;
            raise AVTCompilerException.create('The operator || is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
        end;
        result := pos;
    end;

    function AVTConstantExpression.parseConditional(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
    label
        label0;
    var
        operatorPos: int;
        op1: AVTConstant;
        op2: AVTConstant;
        typeCommonRef: AVTType;
        typeOperand0Ref: AVTType;
        typeOperand1Ref: AVTType;
        typeOperand2Ref: AVTType;
    begin
        pos := parseBoolOr(dst, typeRef, source, pos);
        if source.getLexemeType(pos) = CHAR_QUESTION then begin
            op1 := nil;
            op2 := nil;
            try
                op1 := AVTConstant.create();
                op2 := AVTConstant.create();
                pos := parseConditional(op1, typeRef, source, pos + 1);
                operatorPos := pos;
                if source.getLexemeType(pos) <> CHAR_COLON then begin
                    raise AVTCompilerException.create('":" expected', source, pos);
                end;
                pos := parseConditional(op2, typeRef, source, pos + 1);
                typeOperand0Ref := dst.valueType;
                typeOperand1Ref := op1.valueType;
                typeOperand2Ref := op2.valueType;
                if (typeOperand0Ref <> nil) and typeOperand0Ref.isBoolean() then begin
                    typeCommonRef := commonType(typeOperand1Ref, typeOperand2Ref);
                    if (typeCommonRef = nil) or (typeCommonRef is AVTTypeStructured) then begin
                        op1.valueType := typeCommonRef;
                        op2.valueType := typeCommonRef;
                    end else
                    if typeCommonRef is AVTTypePrimitive then begin
                        cast(op1, op1, AVTTypePrimitive(typeCommonRef));
                        cast(op2, op2, AVTTypePrimitive(typeCommonRef));
                    end else begin
                        goto label0;
                    end;
                    if dst.value.asBoolean = true then begin
                        dst.assign(op1);
                    end else begin
                        dst.assign(op2);
                    end;
                    { continue; }
                    result := pos;
                    exit;
                end;
                label0:
            finally
                op1.free();
                op2.free();
            end;
            raise AVTCompilerException.create('The operator ?: is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref) + ', ' + itemToString(typeOperand2Ref), source, operatorPos);
        end;
        result := pos;
    end;

    function AVTConstantExpression.tryParseType(typeRef: AVTTypeStructured; source: AVTSource; pos: int): AVTType;
    var
        lxt: int;
        dimensions: int;
        app: AVTProgramme;
        itemParsedRef: AVTItem;
        typeParsedRef: AVTType;
    begin
        app := programme;
        lxt := source.getLexemeType(pos);
        if lxt = AVT_VOID then begin
            source.position := pos + 1;
            result := app.systemPackage.getType(AVTTypePrimitive.getName(AVT_VOID));
            exit;
        end;
        typeParsedRef := nil;
        if (lxt >= AVT_BOOLEAN) and (lxt <= AVT_DOUBLE8) then begin
            typeParsedRef := app.systemPackage.getType(AVTTypePrimitive.getName(lxt));
            inc(pos);
        end else
        if lxt = LITR_NAME then begin
            itemParsedRef := resolveName(source.getLexemeAnsiString(pos), typeRef, pos);
            if itemParsedRef is AVTPackage then begin
                typeParsedRef := tryParseFullyQualifiedTypeName(AVTPackage(itemParsedRef), typeRef, pos + 1);
                pos := source.position;
            end else
            if itemParsedRef is AVTType then begin
                typeParsedRef := AVTType(itemParsedRef);
                inc(pos);
            end;
        end;
        if typeParsedRef = nil then begin
            result := nil;
            exit;
        end;
        dimensions := 0;
        while (dimensions < 99) and (source.getLexemeType(pos) = CHAR_BRACKET_OPENED) and (source.getLexemeType(pos + 1) = CHAR_BRACKET_CLOSED) do begin
            typeParsedRef := app.getArrayOf(typeParsedRef);
            inc(dimensions);
            inc(pos, 2);
        end;
        source.position := pos;
        result := typeParsedRef;
    end;

    procedure AVTConstantExpression.parseFieldInitialValue(fieldRef: AVTField);
    var
        newClinit: boolean;
        pos: int;
        code: AVTCode;
        node: AVTNode;
        source: AVTSource;
        copy: AVTConstant;
        value: AVTConstant;
        fieldType: AVTType;
        constType: AVTType;
        methodRef: AVTMethod;
        typeVoidRef: AVTType;
        typeRef: AVTTypeStructured;
    begin
        pos := fieldRef.implementationPosition;
        if (pos < 0) or fieldRef.valueConstCreated then exit;
        source := fieldRef.source;
        fieldRef.makeValueConstCreating();
        try
            value := fieldRef.createValueConst();
            pos := parseConstantExpression(value, fieldRef.parentType, pos);
            fieldType := fieldRef.valueType;
            constType := value.valueType;
            if not fieldType.isConvertableFrom(constType) then begin
                raise AVTCompilerException.create('Can not assign value of the type ' + itemToString(constType) + ' to field of the type ' + itemToString(fieldType), source, pos);
            end;
            if fieldType is AVTTypePrimitive then begin
                cast(value, value, AVTTypePrimitive(fieldType));
            end else begin
                value.valueType := fieldType;
            end;
        finally
            fieldRef.makeValueConstCreated();
        end;
        if source.getLexemeType(pos) <> CHAR_SEMICOLON then begin
            raise AVTCompilerException.create('";" expected', source, pos);
        end;
        if ((fieldRef.flags and (FLAG_STATIC or FLAG_FINAL)) = FLAG_STATIC) and (fieldType is AVTTypeStructured) and not value.value.isNull then begin
            typeRef := fieldRef.parentType;
            with typeRef.members(SPECNAME_CLASS_INIT) do begin
                if hasMoreElements() then begin
                    newClinit := false;
                    methodRef := nextElement().objectValue() as AVTMethod;
                end else begin
                    newClinit := true;
                    methodRef := AVTClassInit.create(typeRef, -1);
                end;
            end;
            typeVoidRef := getPrimitiveType(AVT_VOID);
            code := methodRef.code;
            node := code.root;
            if newClinit then begin
                node.setData(-1, typeVoidRef, AVT_ENTER);
            end;
            copy := AVTConstant.create();
            copy.assign(value);
            node := code.appendNode(node, -1, typeVoidRef, STORE_STATIC, fieldRef);
            code.appendNode(node).setData(-1, fieldType, LOAD_CONST, copy);
        end;
    end;

    procedure AVTConstantExpression.parsePropertyImplementation(propertyRef: AVTProperty);
    label
        label0;
    var
        isAbstract: boolean;
        isConstant: boolean;
        hasIndex: boolean;
        hasRead: boolean;
        hasWrite: boolean;
        hasStored: boolean;
        pos: int;
        writePos: int;
        storedPos: int;
        argumentIndex: int;
        name: AnsiString;
        itemRef: AVTItem;
        fieldRef: AVTField;
        methodRef: AVTMethod;
        arguments: Vector;
        source: AVTSource;
        constant: AVTConstant;
        typeConstantRef: AVTType;
        typePropertyRef: AVTType;
        typeArgumentRef: AVTType;
        typeRef: AVTTypeStructured;
        overriddenRef: AVTProperty;
    begin
        pos := propertyRef.implementationPosition;
        if pos < 0 then exit;
        source := propertyRef.source;
        typeRef := propertyRef.parentType;
        typePropertyRef := propertyRef.valueType;
        isAbstract := propertyRef.isAbstract();
        hasIndex := false;
        hasRead := false;
        hasWrite := false;
        hasStored := false;
        writePos := -1;
        storedPos := -1;
        begin
            { INDEX }
            if (source.getLexemeType(pos) = LITR_NAME) and (source.getLexemeAnsiString(pos) = 'index') then begin
                if isAbstract then begin
                    raise AVTCompilerException.create('The index specifier is an invalid specifier for an abstract property', source, pos);
                end;
                inc(pos);
                if source.getLexemeType(pos) <> CHAR_EQUALS then begin
                    raise AVTCompilerException.create('"=" expected', source, pos);
                end;
                inc(pos);
                constant := AVTConstant.create();
                try
                    pos := parseConstantExpression(constant, typeRef, pos);
                    typeConstantRef := constant.valueType;
                    if not(typeConstantRef is AVTTypePrimitive) then begin
                        raise AVTCompilerException.create('Type mismatch: can not convert from ' + itemToString(typeConstantRef) + ' to int', source, pos);
                    end;
                    case AVTTypePrimitive(typeConstantRef).primitiveKind of
                    AVT_BYTE: begin
                        propertyRef.index := constant.value.asByte;
                    end;
                    AVT_SHORT: begin
                        propertyRef.index := constant.value.asShort;
                    end;
                    AVT_INT: begin
                        propertyRef.index := constant.value.asInt;
                    end
                    else
                        raise AVTCompilerException.create('Type mismatch: can not convert from ' + itemToString(typeConstantRef) + ' to int', source, pos);
                    end;
                finally
                    constant.free();
                end;
                hasIndex := true;
                if source.getLexemeType(pos) <> CHAR_COMMA then goto label0;
                inc(pos);
            end;

            { READ }
            if (source.getLexemeType(pos) = LITR_NAME) and (source.getLexemeAnsiString(pos) = 'read') then begin
                inc(pos);
                if isAbstract then begin
                    propertyRef.readMember := nil;
                end else begin
                    if source.getLexemeType(pos) <> CHAR_EQUALS then begin
                        raise AVTCompilerException.create('"=" expected', source, pos);
                    end;
                    inc(pos);
                    isConstant := true;
                    if source.getLexemeType(pos) = LITR_NAME then begin
                        name := source.getLexemeAnsiString(pos);
                        itemRef := resolveName(name, typeRef, pos);
                        if (itemRef is AVTField) and not itemRef.isStatic() then begin
                            fieldRef := AVTField(itemRef);
                            if not typePropertyRef.isAssignableFrom(fieldRef.valueType) then begin
                                raise AVTCompilerException.create('The field ' + fieldRef.simpleName + ' can not be used as the read member for the property ' + propertyRef.simpleName, source, pos);
                            end;
                            propertyRef.readMember := fieldRef;
                            isConstant := false;
                            inc(pos);
                        end else
                        if itemRef is AVTMethod then begin
                            arguments := Vector.create();
                            try
                                if hasIndex then begin
                                    arguments.append(ValueOfObject.create(getPrimitiveType(AVT_INT), false));
                                end;
                                methodRef := typeRef.findMethod(name, arguments, typeRef, pos);
                                if methodRef.isStatic() or not typePropertyRef.isAssignableFrom(methodRef.returnType) then begin
                                    raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can not be used as the read member for the property ' + propertyRef.simpleName, source, pos);
                                end;
                                if not methodRef.isIdentityArgumentTypes(arguments) then begin
                                    raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' is not applicable for the arguments ' + arguments.toString(), source, pos);
                                end;
                            finally
                                arguments.free();
                            end;
                            if not methodRef.isVisible(typeRef, typeRef) then begin
                                raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' from the type ' + methodRef.parentType.fullName + ' is not visible', source, pos);
                            end;
                            if methodRef.mightThrown() then begin
                                raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can throw an exception', source, pos);
                            end;
                            propertyRef.readMember := methodRef;
                            isConstant := false;
                            inc(pos);
                        end;
                    end;
                    if isConstant then begin
                        constant := AVTConstant.create();
                        try
                            pos := parseConstantExpression(constant, typeRef, pos);
                            typeConstantRef := constant.valueType;
                            if not typePropertyRef.isConvertableFrom(typeConstantRef) then begin
                                raise AVTCompilerException.create('Type mismatch: can not convert from ' + itemToString(typeConstantRef) + ' to ' + itemToString(typePropertyRef), source, pos);
                            end;
                            if typePropertyRef is AVTTypePrimitive then begin
                                cast(constant, constant, AVTTypePrimitive(typePropertyRef));
                            end else begin
                                constant.valueType := typePropertyRef;
                            end;
                            propertyRef.readMember := constant;
                        finally
                            constant.free();
                        end;
                    end;
                end;
                hasRead := true;
                if source.getLexemeType(pos) <> CHAR_COMMA then goto label0;
                inc(pos);
            end;

            { WRITE }
            writePos := pos;
            if (source.getLexemeType(pos) = LITR_NAME) and (source.getLexemeAnsiString(pos) = 'write') then begin
                inc(pos);
                if isAbstract then begin
                    propertyRef.writeMember := nil;
                end else begin
                    if source.getLexemeType(pos) <> CHAR_EQUALS then begin
                        raise AVTCompilerException.create('"=" expected', source, pos);
                    end;
                    inc(pos);
                    isConstant := true;
                    if source.getLexemeType(pos) = LITR_NAME then begin
                        name := source.getLexemeAnsiString(pos);
                        itemRef := resolveName(name, typeRef, pos);
                        if (itemRef is AVTField) and not itemRef.isStatic() then begin
                            fieldRef := AVTField(itemRef);
                            if fieldRef.isFinal() or not fieldRef.valueType.isAssignableFrom(typePropertyRef) then begin
                                raise AVTCompilerException.create('The field ' + fieldRef.simpleName + ' can not be used as the write member for the property ' + propertyRef.simpleName, source, pos);
                            end;
                            propertyRef.writeMember := fieldRef;
                            isConstant := false;
                            inc(pos);
                        end else
                        if itemRef is AVTMethod then begin
                            arguments := Vector.create();
                            try
                                if hasIndex then begin
                                    arguments.append(ValueOfObject.create(getPrimitiveType(AVT_INT), false));
                                end;
                                arguments.append(ValueOfObject.create(typePropertyRef, false));
                                methodRef := typeRef.findMethod(name, arguments, typeRef, pos);
                                if methodRef.isStatic() or not methodRef.returnType.isVoid() then begin
                                    raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can not be used as the write member for the property ' + propertyRef.simpleName, source, pos);
                                end;
                                if methodRef.getArgumentsCount() <> arguments.size() then begin
                                    raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' is not applicable for the arguments ' + arguments.toString(), source, pos);
                                end;
                                argumentIndex := 0;
                                if hasIndex then begin
                                    typeArgumentRef := methodRef.getArgumentAt(0).valueType;
                                    if not(typeArgumentRef is AVTTypePrimitive) or (AVTTypePrimitive(typeArgumentRef).primitiveKind <> AVT_INT) then begin
                                        raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' is not applicable for the arguments ' + arguments.toString(), source, pos);
                                    end;
                                    inc(argumentIndex);
                                end;
                                typeArgumentRef := methodRef.getArgumentAt(argumentIndex).valueType;
                                if not typeArgumentRef.isAssignableFrom(typePropertyRef) then begin
                                    raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' is not applicable for the arguments ' + arguments.toString(), source, pos);
                                end;
                            finally
                                arguments.free();
                            end;
                            if not methodRef.isVisible(typeRef, typeRef) then begin
                                raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' from the type ' + methodRef.parentType.fullName + ' is not visible', source, pos);
                            end;
                            if methodRef.mightThrown() then begin
                                raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can throw an exception', source, pos);
                            end;
                            propertyRef.writeMember := methodRef;
                            isConstant := false;
                            inc(pos);
                        end;
                    end;
                    if isConstant then begin
                        raise AVTCompilerException.create('Write member expected', source, pos);
                    end;
                end;
                hasWrite := true;
                if source.getLexemeType(pos) <> CHAR_COMMA then goto label0;
                inc(pos);
            end;

            { STORED }
            storedPos := pos;
            if (source.getLexemeType(pos) = LITR_NAME) and (source.getLexemeAnsiString(pos) = 'stored') then begin
                if isAbstract then begin
                    raise AVTCompilerException.create('The stored specifier is an invalid specifier for an abstract property', source, pos);
                end;
                inc(pos);
                if source.getLexemeType(pos) <> CHAR_EQUALS then begin
                    raise AVTCompilerException.create('"=" expected', source, pos);
                end;
                inc(pos);
                isConstant := true;
                if source.getLexemeType(pos) = LITR_NAME then begin
                    name := source.getLexemeAnsiString(pos);
                    itemRef := resolveName(name, typeRef, pos);
                    if (itemRef is AVTField) and not itemRef.isStatic() then begin
                        fieldRef := AVTField(itemRef);
                        if not fieldRef.valueType.isBoolean() then begin
                            raise AVTCompilerException.create('The field ' + fieldRef.simpleName + ' can not be used as the stored member for the property ' + propertyRef.simpleName, source, pos);
                        end;
                        propertyRef.storedMember := fieldRef;
                        isConstant := false;
                        inc(pos);
                    end else
                    if itemRef is AVTMethod then begin
                        arguments := Vector.create();
                        try
                            if hasIndex then begin
                                arguments.append(ValueOfObject.create(getPrimitiveType(AVT_INT), false));
                            end;
                            methodRef := typeRef.findMethod(name, arguments, typeRef, pos);
                            if methodRef.isStatic() or not methodRef.returnType.isBoolean() then begin
                                raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can not be used as the stored member for the property ' + propertyRef.simpleName, source, pos);
                            end;
                            if not methodRef.isIdentityArgumentTypes(arguments) then begin
                                raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' is not applicable for the arguments ' + arguments.toString(), source, pos);
                            end;
                        finally
                            arguments.free();
                        end;
                        if not methodRef.isVisible(typeRef, typeRef) then begin
                            raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' from the type ' + methodRef.parentType.fullName + ' is not visible', source, pos);
                        end;
                        if methodRef.mightThrown() then begin
                            raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can throw an exception', source, pos);
                        end;
                        propertyRef.storedMember := methodRef;
                        isConstant := false;
                        inc(pos);
                    end;
                end;
                if isConstant then begin
                    constant := AVTConstant.create();
                    try
                        pos := parseConstantExpression(constant, typeRef, pos);
                        typeConstantRef := constant.valueType;
                        if (typeConstantRef = nil) or not typeConstantRef.isBoolean() then begin
                            raise AVTCompilerException.create('Type mismatch: can not convert from ' + itemToString(typeConstantRef) + ' to boolean', source, pos);
                        end;
                        propertyRef.storedMember := constant;
                    finally
                        constant.free();
                    end;
                end;
                hasStored := true;
            end;
        end;
        label0:
        if source.getLexemeType(pos) <> CHAR_CURLY_CLOSED then begin
            raise AVTCompilerException.create('"}" expected', source, pos);
        end;
        if not hasRead and not hasWrite then begin
            raise AVTCompilerException.create('The read or write specifier is required for a property', source, pos);
        end;
        if storedPos < 0 then storedPos := pos;
        if writePos < 0 then writePos := storedPos;
        with propertyRef.overriddenMembers() do while hasMoreElements() do begin
            overriddenRef := nextElement().objectValue() as AVTProperty;
            if (overriddenRef.readSynthetic <> nil) and not hasRead then begin
                raise AVTCompilerException.create('The inherited property ' + overriddenRef.simpleName + ' in the type ' + overriddenRef.parentType.fullName + ' requires the read specifier', source, writePos);
            end;
            if (overriddenRef.writeSynthetic <> nil) and not hasWrite then begin
                raise AVTCompilerException.create('The inherited property ' + overriddenRef.simpleName + ' in the type ' + overriddenRef.parentType.fullName + ' requires the write specifier', source, storedPos);
            end;
            if (overriddenRef.storedSynthetic <> nil) and not hasStored then begin
                hasStored := true;
                if isAbstract then begin
                    propertyRef.storedMember := nil;
                end else begin
                    constant := AVTConstant.create(getPrimitiveType(AVT_BOOLEAN));
                    try
                        constant.value.asBoolean := false;
                        propertyRef.storedMember := constant;
                    finally
                        constant.free();
                    end;
                end;
            end;
        end;
    end;

    function AVTConstantExpression.parseConstantExpression(dst: AVTConstant; typeRef: AVTTypeStructured; pos: int): int;
    begin
        result := parseConditional(dst, typeRef, typeRef.source, pos);
    end;

    function AVTConstantExpression.parseType(typeRef: AVTTypeStructured; pos: int): AVTType;
    var
        lxt: int;
        dimensions: int;
        app: AVTProgramme;
        source: AVTSource;
        itemParsedRef: AVTItem;
        typeParsedRef: AVTType;
    begin
        app := programme;
        source := typeRef.source;
        lxt := source.getLexemeType(pos);
        if lxt = AVT_VOID then begin
            source.position := pos + 1;
            result := app.systemPackage.getType(AVTTypePrimitive.getName(AVT_VOID));
            exit;
        end;
        typeParsedRef := nil;
        if (lxt >= AVT_BOOLEAN) and (lxt <= AVT_DOUBLE8) then begin
            typeParsedRef := app.systemPackage.getType(AVTTypePrimitive.getName(lxt));
            inc(pos);
        end else
        if lxt = LITR_NAME then begin
            itemParsedRef := resolveName(source.getLexemeAnsiString(pos), typeRef, pos);
            if itemParsedRef is AVTPackage then begin
                typeParsedRef := parseFullyQualifiedTypeName(AVTPackage(itemParsedRef), typeRef, pos + 1);
                pos := source.position;
            end else
            if itemParsedRef is AVTType then begin
                typeParsedRef := AVTType(itemParsedRef);
                inc(pos);
            end;
        end;
        if typeParsedRef = nil then begin
            raise AVTCompilerException.create('Type expected', source, pos);
        end;
        dimensions := 0;
        while (dimensions < 99) and (source.getLexemeType(pos) = CHAR_BRACKET_OPENED) and (source.getLexemeType(pos + 1) = CHAR_BRACKET_CLOSED) do begin
            typeParsedRef := app.getArrayOf(typeParsedRef);
            inc(dimensions);
            inc(pos, 2);
        end;
        source.position := pos;
        result := typeParsedRef;
    end;

    function AVTConstantExpression.resolveName(const simpleName: AnsiString; typeRef: AVTTypeStructured; pos: int): AVTItem;
    label
        label0;
    var
        item: AVTItem;
        source: AVTSource;
    begin
        source := typeRef.source;
        item := typeRef.getMember(simpleName);
        if (item is AVTField) or (item is AVTProperty) then begin
            item := typeRef.findField(simpleName, typeRef, pos);
        end;
        if item = nil then begin
            item := source.getDeclaredType(simpleName);
            if item <> nil then goto label0;
            item := source.getImportedType(simpleName);
            if item <> nil then goto label0;
            item := source.package.getType(simpleName);
            if item <> nil then goto label0;
            item := source.findImportedType(simpleName, typeRef, pos);
            if item <> nil then goto label0;
            item := programme.getPackage(simpleName);
        end;
        label0:
        if not(item is AVTMethod) and (item is AVTItemExt) and not AVTItemExt(item).isVisible(typeRef, typeRef) then begin
            if item is AVTMember then begin
                raise AVTCompilerException.create('The field ' + simpleName + ' is not visible', source, pos);
            end;
            raise AVTCompilerException.create('The type ' + simpleName + ' is not visible', source, pos);
        end;
        result := item;
    end;

    procedure AVTConstantExpression.cast(dst, op0: AVTConstant; typeNewRef: AVTTypePrimitive);
    var
        i: int;
        len1: int;
        len2: int;
        base1: int;
        base2: int;
        typeNewKind: int;
        typeRef: AVTType;
        typeSrcRef: AVTTypePrimitive;
    begin
        if dst = nil then begin
            raise NullPointerException.create('AVTConstantExpression.cast: ' + msgNullPointerArgument + 'dst');
        end;
        if op0 = nil then begin
            raise NullPointerException.create('AVTConstantExpression.cast: ' + msgNullPointerArgument + 'op0');
        end;
        if typeNewRef = nil then begin
            raise NullPointerException.create('AVTConstantExpression.cast: ' + msgNullPointerArgument + 'typeNewRef');
        end;
        typeRef := op0.valueType;
        if not(typeRef is AVTTypePrimitive) or typeRef.isVoid() then begin
            raise IllegalArgumentException.create('AVTConstantExpression.cast: ' + msgIllegalArgument + 'op0');
        end;
        typeNewKind := typeNewRef.primitiveKind;
        if typeNewKind = AVT_VOID then begin
            raise IllegalArgumentException.create('AVTConstantExpression.cast: ' + msgIllegalArgument + 'typeNewRef');
        end;
        if dst <> op0 then dst.assignValue(op0);
        typeSrcRef := AVTTypePrimitive(typeRef);
        len1 := typeSrcRef.compoundLength;
        len2 := typeNewRef.compoundLength;
        base1 := typeSrcRef.compoundBase;
        base2 := typeNewRef.compoundBase;
        if base1 > AVT_REAL then for i := intMin(len1, len2) to 7 do begin
            case base1 of
            AVT_BYTE: dst.value.asByte8[i] := 0;
            AVT_SHORT: dst.value.asShort8[i] := 0;
            AVT_INT: dst.value.asInt8[i] := 0;
            AVT_LONG: dst.value.asLong8[i] := 0;
            AVT_FLOAT: dst.value.asFloat8[i] := 0.0;
            AVT_DOUBLE: dst.value.asDouble8[i] := 0.0;
            end;
        end;
        if base1 = AVT_CHAR then begin
            base1 := AVT_INT;
            dst.value.asInt := int(dst.value.asChar);
        end;
        case base2 of
        AVT_BYTE: begin
            case base1 of
            AVT_SHORT: castShort8ToByte8(dst, dst, typeNewKind);
            AVT_INT: castInt8ToByte8(dst, dst, typeNewKind);
            AVT_LONG: castLong8ToByte8(dst, dst, typeNewKind);
            AVT_FLOAT: castFloat8ToByte8(dst, dst, typeNewKind);
            AVT_DOUBLE: castDouble8ToByte8(dst, dst, typeNewKind);
            AVT_REAL: castRealToByte8(dst, dst, typeNewKind);
            else dst.valueType := typeNewRef;
            end;
        end;
        AVT_SHORT: begin
            case base1 of
            AVT_BYTE: castByte8ToShort8(dst, dst, typeNewKind);
            AVT_INT: castInt8ToShort8(dst, dst, typeNewKind);
            AVT_LONG: castLong8ToShort8(dst, dst, typeNewKind);
            AVT_FLOAT: castFloat8ToShort8(dst, dst, typeNewKind);
            AVT_DOUBLE: castDouble8ToShort8(dst, dst, typeNewKind);
            AVT_REAL: castRealToShort8(dst, dst, typeNewKind);
            else dst.valueType := typeNewRef;
            end;
        end;
        AVT_INT, AVT_CHAR: begin
            case base1 of
            AVT_BYTE: castByte8ToInt8(dst, dst, typeNewKind);
            AVT_SHORT: castShort8ToInt8(dst, dst, typeNewKind);
            AVT_LONG: castLong8ToInt8(dst, dst, typeNewKind);
            AVT_FLOAT: castFloat8ToInt8(dst, dst, typeNewKind);
            AVT_DOUBLE: castDouble8ToInt8(dst, dst, typeNewKind);
            AVT_REAL: castRealToInt8(dst, dst, typeNewKind);
            else dst.valueType := typeNewRef;
            end;
        end;
        AVT_LONG: begin
            case base1 of
            AVT_BYTE: castByte8ToLong8(dst, dst, typeNewKind);
            AVT_SHORT: castShort8ToLong8(dst, dst, typeNewKind);
            AVT_INT: castInt8ToLong8(dst, dst, typeNewKind);
            AVT_FLOAT: castFloat8ToLong8(dst, dst, typeNewKind);
            AVT_DOUBLE: castDouble8ToLong8(dst, dst, typeNewKind);
            AVT_REAL: castRealToLong8(dst, dst, typeNewKind);
            else dst.valueType := typeNewRef;
            end;
        end;
        AVT_FLOAT: begin
            case base1 of
            AVT_BYTE: castByte8ToFloat8(dst, dst, typeNewKind);
            AVT_SHORT: castShort8ToFloat8(dst, dst, typeNewKind);
            AVT_INT: castInt8ToFloat8(dst, dst, typeNewKind);
            AVT_LONG: castLong8ToFloat8(dst, dst, typeNewKind);
            AVT_DOUBLE: castDouble8ToFloat8(dst, dst, typeNewKind);
            AVT_REAL: castRealToFloat8(dst, dst, typeNewKind);
            else dst.valueType := typeNewRef;
            end;
        end;
        AVT_DOUBLE: begin
            case base1 of
            AVT_BYTE: castByte8ToDouble8(dst, dst, typeNewKind);
            AVT_SHORT: castShort8ToDouble8(dst, dst, typeNewKind);
            AVT_INT: castInt8ToDouble8(dst, dst, typeNewKind);
            AVT_LONG: castLong8ToDouble8(dst, dst, typeNewKind);
            AVT_FLOAT: castFloat8ToDouble8(dst, dst, typeNewKind);
            AVT_REAL: castRealToDouble8(dst, dst, typeNewKind);
            else dst.valueType := typeNewRef;
            end;
        end;
        AVT_REAL: begin
            case base1 of
            AVT_BYTE: castByte8ToReal(dst, dst, typeNewKind);
            AVT_SHORT: castShort8ToReal(dst, dst, typeNewKind);
            AVT_INT: castInt8ToReal(dst, dst, typeNewKind);
            AVT_LONG: castLong8ToReal(dst, dst, typeNewKind);
            AVT_FLOAT: castFloat8ToReal(dst, dst, typeNewKind);
            AVT_DOUBLE: castDouble8ToReal(dst, dst, typeNewKind);
            else dst.valueType := typeNewRef;
            end;
        end
        else
            dst.valueType := typeNewRef;
        end;
        if base2 = AVT_CHAR then begin
            dst.value.asChar := wchar(dst.value.asInt);
        end;
    end;

    function AVTConstantExpression.getPrimitiveType(kind: int): AVTTypePrimitive;
    begin
        result := programme.systemPackage.getType(AVTTypePrimitive.getName(kind)) as AVTTypePrimitive;
    end;

    function AVTConstantExpression.getStringType(): AVTTypeStructured;
    var
        packageAvtLangRef: AVTPackage;
        typeStringRef: AVTTypeStructured;
    begin
        typeStringRef := fldTypeStringRef;
        if typeStringRef <> nil then begin
            result := typeStringRef;
            exit;
        end;
        packageAvtLangRef := programme.getPackage('avt.lang');
        if packageAvtLangRef = nil then begin
            result := nil;
            exit;
        end;
        typeStringRef := packageAvtLangRef.getType('String') as AVTTypeStructured;
        fldTypeStringRef := typeStringRef;
        result := typeStringRef;
    end;

    function AVTConstantExpression.getClassType(): AVTTypeStructured;
    var
        packageAvtLangRef: AVTPackage;
        typeClassRef: AVTTypeStructured;
    begin
        typeClassRef := fldTypeClassRef;
        if typeClassRef <> nil then begin
            result := typeClassRef;
            exit;
        end;
        packageAvtLangRef := programme.getPackage('avt.lang');
        if packageAvtLangRef = nil then begin
            result := nil;
            exit;
        end;
        typeClassRef := packageAvtLangRef.getType('Class') as AVTTypeStructured;
        fldTypeClassRef := typeClassRef;
        result := typeClassRef;
    end;
{%endregion}

end.