buildnms.pas

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

{
    Этот исходный текст является частью Продвинутого векторного транслятора.

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

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

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

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

unit BuildNms;

{$MODE DELPHI,EXTENDEDSYNTAX ON}

interface

uses
    Lang, TranIntf, TranType, TranProg, BuildLex;

{$ASMMODE INTEL,CALLING REGISTER,INLINE ON,GOTO ON}
{$H+,I-,J-,M-,Q-,R-,T-}

type
    TranslatorNamespacesBuilder = class;
    TranslatorLocalConstantInt = class;
    TranslatorLocalConstantLong = class;
    TranslatorLocalConstantReal = class;
    TranslatorLocalConstantUltra = class;
    TranslatorLocalConstantXVector = class;

    TranslatorNamespacesBuilder = class(RefCountInterfacedObject, BuilderOfNamespaces)
    public
        const EXTENSION_SSE3 = 0;
        const EXTENSION_SSSE3 = 1;
        const EXTENSION_SSE4_1 = 2;
        const NAMESPACE_SYSTEM = 'System';
        const STRUCTURE_POINTER = 'Pointer';
        const EXCEPTION_THROWABLE = 'Throwable';
        const EXCEPTION_EXCEPTION = 'Exception';
        const FUNCTION_INITIALIZATION = 'initialization';
        const FUNCTION_FINALIZATION = 'finalization';
        const FUNCTION_NEW_STRUCT = 'new.struct';
        const FUNCTION_NEW_ARRAY = 'new.array';
        const FUNCTION_DISPOSE = 'dispose';
        const FUNCTION_MAIN = 'main';
        class function pack4IntUS(const value: ultra): long;

    public
        constructor create(operandSize, extension: int);
        procedure clear(); virtual;
        procedure addLexer(lexemes: Lexer); virtual;
        procedure buildNamespaces(); virtual;
        function getNamespacesCount(): int; virtual;
        function getNamespace(index: int): Namespace; virtual;
        function getSystemNamespace(): Namespace; virtual;
        function getEntryPoint(): GlobalFunction; virtual;
        function findNamespace(const name: UnicodeString): Namespace; virtual;
    strict private
        fldOperandSize: int;
        fldExtension: int;
        fldStayPosition: int;
        initTypesCount: int;
        lexersCount: int;
        namespacesCount: int;
        typesCount: int;
        lexers: Lexer_Array1d;
        namespaces: Namespace_Array1d;
        types: TypeDescriptor_Array1d;
        systemNamespace: Namespace;
        entryPoint: GlobalFunction;
        procedure addNamespace(space: Namespace);
        procedure parseFields(structure: TypeStructure; lexemes: Lexer);
        function parseEntry(where: Namespace; lexemes: Lexer; position: int): int;
        function parseConstant(where: Namespace; lexemes: Lexer; position: int;
                epublic: boolean): int;
        function parseException(where: Namespace; lexemes: Lexer; position: int;
                epublic: boolean): int;
        function parseStructure(where: Namespace; lexemes: Lexer; position: int;
                epublic: boolean): int;
        function parseVarOrFunc(where: Namespace; lexemes: Lexer; position: int;
                epublic: boolean): int;
        function parseArguments(where: Namespace; lexemes: Lexer; position: int;
                destination: TypeFunction): int;
        function parseConstElem(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstPref(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstMult(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstAdd(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstShift(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstRel(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstEqual(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstBAnd(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstBXor(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstBOr(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstLAnd(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstLOr(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
        function parseConstCond(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
    strict private
        fldTypVoid: TypePrimitive;
        fldTypBoolean: TypePrimitive;
        fldTypChar: TypePrimitive;
        fldTypByte: TypePrimitive;
        fldTypShort: TypePrimitive;
        fldTypInt: TypePrimitive;
        fldTypLong: TypePrimitive;
        fldTypUltra: TypePrimitive;
        fldTypFloat: TypePrimitive;
        fldTypDouble: TypePrimitive;
        fldTypReal: TypePrimitive;
        fldTypXVector: TypePrimitive;
    protected
        property stayPosition: int read fldStayPosition write fldStayPosition;
        property operandSize: int read fldOperandSize;
        property extension: int read fldExtension;
        property typeVoid: TypePrimitive read fldTypVoid;
        property typeBoolean: TypePrimitive read fldTypBoolean;
        property typeChar: TypePrimitive read fldTypChar;
        property typeByte: TypePrimitive read fldTypByte;
        property typeShort: TypePrimitive read fldTypShort;
        property typeInt: TypePrimitive read fldTypInt;
        property typeLong: TypePrimitive read fldTypLong;
        property typeUltra: TypePrimitive read fldTypUltra;
        property typeFloat: TypePrimitive read fldTypFloat;
        property typeDouble: TypePrimitive read fldTypDouble;
        property typeReal: TypePrimitive read fldTypReal;
        property typeXVector: TypePrimitive read fldTypXVector;
        function possibleAssign(dstTypeKind: int; constant: GlobalConstant): boolean; virtual;
        function skipCurlyBrackets(lexemes: Lexer; position: int): int; virtual;
        function skipParenthesis(lexemes: Lexer; position: int): int; virtual;
        function getCommonTypeKind(kind1, kind2: int): int; virtual;
        function castConstTo(newTypeKind: int; constant: GlobalConstant): GlobalConstant; virtual;
        function tryParseType(where: Namespace; position: int): TypeDescriptor; virtual;
        function parseConst(where: Namespace; position: int): GlobalConstant; virtual;
        function parseType(where: Namespace; position: int): TypeDescriptor; virtual;
        function getCanonicalType(theType: TypeDescriptor): TypeDescriptor; virtual;
    end;

    TranslatorLocalConstantInt = class(TranslatorGlobalConstantInt)
    public
        constructor create(constType: TypeDescriptor; const constValue: boolean); overload;
        constructor create(constType: TypeDescriptor; const constValue: int); overload;
    end;

    TranslatorLocalConstantLong = class(TranslatorGlobalConstantLong)
    public
        constructor create(constType: TypeDescriptor; const constValue: int64);
    end;

    TranslatorLocalConstantReal = class(TranslatorGlobalConstantReal)
    public
        constructor create(constType: TypeDescriptor; const constValue: real);
    end;

    TranslatorLocalConstantUltra = class(TranslatorGlobalConstantUltra)
    public
        constructor create(constType: TypeDescriptor; const constValue: ultra);
    end;

    TranslatorLocalConstantXVector = class(TranslatorGlobalConstantXVector)
    public
        constructor create(constType: TypeDescriptor; const constValue: xvector);
    end;

resourcestring
    msgExpressionError = 'Ошибка в выражении.';
    msgExpectedDataType = 'Ожидается тип данных.';
    msgExpectedConstant = 'Ожидается константа.';
    msgExpectedException = 'Ожидается исключение.';
    msgExpectedStructure = 'Ожидается структура.';
    msgExpectedDataTypeCompound = 'Ожидается идентификатор составного типа данных.';
    msgExpectedComma = 'Ожидается запятая (",").';
    msgExpectedPeriod = 'Ожидается точка (".").';
    msgExpectedAssign = 'Ожидается знак равенства ("=").';
    msgExpectedColon = 'Ожидается двоеточие (":").';
    msgExpectedSemicolon = 'Ожидается точка с запятой (";").';
    msgExpectedKeywordNamespace = 'Ожидается ключевое слово "namespace".';
    msgExpectedOpenedParenthesis = 'Ожидается открывающая круглая скобка ("(").';
    msgExpectedClosedParenthesis = 'Ожидается закрывающая круглая скобка (")").';
    msgExpectedOpenedCurlyBracket = 'Ожидается открывающая фигурная скобка ("{").';
    msgExpectedClosedCurlyBracket = 'Ожидается закрывающая фигурная скобка ("}").';
    msgExpectedOpenedSquareBracket = 'Ожидается открывающая квадратная скобка ("[").';
    msgExpectedClosedSquareBracket = 'Ожидается закрывающая квадратная скобка ("]").';
    msgExpectedIdentifierOfNamespace = 'Ожидается идентификатор пространства имён.';
    msgExpectedIdentifierOfDataType = 'Ожидается идентификатор типа данных.';
    msgExpectedIdentifierOfConstant = 'Ожидается идентификатор константы.';
    msgExpectedIdentifierOfException = 'Ожидается идентификатор исключения.';
    msgExpectedIdentifierOfStructure = 'Ожидается идентификатор структуры.';
    msgExpectedIdentifierOfVariable = 'Ожидается идентификатор переменной.';
    msgExpectedIdentifierOfArgument = 'Ожидается идентификатор аргумента.';
    msgExpectedIdentifierOfFunction = 'Ожидается идентификатор функции.';
    msgExpectedIdentifierOfField = 'Ожидается идентификатор поля.';
    msgExceptionNotSupported = 'Исключения не поддерживаются при текущей разрядности кода.';
    msgOperationNotSupportedOS = 'Операция не поддерживается при текущей разрядности кода.';
    msgOperationNotSupportedEX = 'Операция не поддерживается при текущих расширениях x86.';
    msgTypeMustBeBoolean = 'Тип выражения должен быть boolean.';
    msgTypeMustBeShort = 'Тип выражения должен быть short.';
    msgTypeMustBeInt = 'Тип выражения должен быть int.';
    msgTypeMustBeFloat = 'Тип выражения должен быть float.';
    msgTypeMustBeNumeric = 'Тип выражения должен быть числовым.';
    msgTypeMustBeCompound = 'Тип выражения должен быть составным.';
    msgTypeNotApplicableToConst = 'Этот тип данных не подходит для констант.';
    msgTypeNotApplicableToFunc = 'Этот тип данных не подходит для возвращаемого значения функции.';
    msgTypeNotApplicableToVar = 'Этот тип данных не подходит для переменных.';
    msgTypeNotSupported = 'Этот тип данных не поддерживается при текущей разрядности.';
    msgTypeReserved = 'Этот тип данных зарезервирован и не должен использоваться.';
    msgEntryPointNotFound = 'Точка входа в программу не найдена.';
    msgEntryPointAlreadyExists = 'Одна точка входа в программу уже существует.';
    msgInterruptMustReturnVoid = 'Функция-прерывание всегда должна возвращать void.';
    msgNamespaceSystemNotFound = 'Системное пространство имён не найдено: namespace System.';
    msgNamespaceAlreadyExists = 'Пространство имён с таким именем уже существует.';
    msgNamespaceAlreadyImported = 'Пространство имён уже импортировано.';
    msgAlreadyExistsIdentifier = 'Объект с таким идентификатором уже существует.';
    msgAlreadyExistsFinalization = 'Процедура финализации уже существует.';
    msgAlreadyExistsInitialization = 'Процедура инициализации уже существует.';
    msgCannotAssignDataType = 'Нельзя присвоить приёмнику выражение этого типа данных.';
    msgCannotApplyOperation = 'Нельзя применить к данным этого типа эту операцию.';
    msgCannotCastToType = 'Нельзя привести выражение к этому типу данных.';
    msgCompoundIndexOutOfBounds = 'Cоставной тип данных: индекс выходит из диапазона.';
    msgSpecialFunctionError = 'Ошибка в заявлении специальной функции new|dispose.';
    msgSpecialFunctionMustInSystem = 'Специальная функция может быть только внутри System.';
    msgSpecialFunctionMustNoInterrupt = 'Специальная функция не может быть прерыванием.';
    msgIntegerDivisionByZero = 'Ошибка деления целого числа на ноль.';

implementation

{ TranslatorNamespacesBuilder }

class function TranslatorNamespacesBuilder.pack4IntUS(const value: ultra): long; assembler;
var
    oldESI: int;
    oldEDI: int;
asm
    { ВХОД:     edx – value
                ecx – результат }
                mov             [oldESI], esi
                mov             [oldEDI], edi
                mov             esi, edx
                mov             edi, ecx
                mov             ecx, $04
@0:             mov             eax, [esi + ecx*4 - $04]
                cmp             eax, $0000
                jge             @1
                xor             eax, eax
                jmp             @2
@1:             cmp             eax, $ffff
                jle             @2
                mov             eax, $ffff
@2:             mov             [edi + ecx*2 - $02], ax
                loop            @0
                mov             esi, [oldESI]
                mov             edi, [oldEDI]
end;

constructor TranslatorNamespacesBuilder.create(operandSize, extension: int);
var
    typCount: int;
    types: TypeDescriptor_Array1d;
begin
    inherited create();
    types := TypeDescriptor_Array1d(Interface_Array1d_create([
        TranslatorTypePrimitive.create(TranslatorType.KIND_VOID) as TypeDescriptor,
        TranslatorTypePrimitive.create(TranslatorType.KIND_BOOLEAN) as TypeDescriptor,
        TranslatorTypePrimitive.create(TranslatorType.KIND_CHAR) as TypeDescriptor,
        TranslatorTypePrimitive.create(TranslatorType.KIND_BYTE) as TypeDescriptor,
        TranslatorTypePrimitive.create(TranslatorType.KIND_SHORT) as TypeDescriptor,
        TranslatorTypePrimitive.create(TranslatorType.KIND_INT) as TypeDescriptor,
        TranslatorTypePrimitive.create(TranslatorType.KIND_LONG) as TypeDescriptor,
        TranslatorTypePrimitive.create(TranslatorType.KIND_ULTRA) as TypeDescriptor,
        TranslatorTypePrimitive.create(TranslatorType.KIND_FLOAT) as TypeDescriptor,
        TranslatorTypePrimitive.create(TranslatorType.KIND_DOUBLE) as TypeDescriptor,
        TranslatorTypePrimitive.create(TranslatorType.KIND_REAL) as TypeDescriptor,
        TranslatorTypePrimitive.create(TranslatorType.KIND_XVECTOR) as TypeDescriptor
    ]));
    typCount := length(types);
    self.fldOperandSize := operandSize;
    self.fldExtension := extension;
    self.fldStayPosition := -1;
    self.initTypesCount := typCount;
    self.lexersCount := 0;
    self.namespacesCount := 0;
    self.typesCount := typCount;
    self.lexers := nil;
    self.namespaces := nil;
    self.types := types;
    self.systemNamespace := nil;
    self.entryPoint := nil;
    self.fldTypVoid := types[0] as TypePrimitive;
    self.fldTypBoolean := types[1] as TypePrimitive;
    self.fldTypChar := types[2] as TypePrimitive;
    self.fldTypByte := types[3] as TypePrimitive;
    self.fldTypShort := types[4] as TypePrimitive;
    self.fldTypInt := types[5] as TypePrimitive;
    self.fldTypLong := types[6] as TypePrimitive;
    self.fldTypUltra := types[7] as TypePrimitive;
    self.fldTypFloat := types[8] as TypePrimitive;
    self.fldTypDouble := types[9] as TypePrimitive;
    self.fldTypReal := types[10] as TypePrimitive;
    self.fldTypXVector := types[11] as TypePrimitive;
end;

procedure TranslatorNamespacesBuilder.clear();
var
    i: int;
    tc: int;
    nc: int;
    itc: int;
    types: TypeDescriptor_Array1d;
    namespaces: Namespace_Array1d;
begin
    tc := self.typesCount;
    nc := self.namespacesCount;
    itc := self.initTypesCount;
    types := self.types;
    namespaces := self.namespaces;
    self.fldStayPosition := -1;
    self.lexersCount := 0;
    self.namespacesCount := 0;
    self.typesCount := itc;
    self.lexers := nil;
    self.namespaces := nil;
    self.systemNamespace := nil;
    self.entryPoint := nil;
    for i := nc - 1 downto 0 do begin
        namespaces[i].clear();
    end;
    for i := tc - 1 downto itc do begin
        types[i] := nil;
    end;
end;

procedure TranslatorNamespacesBuilder.addLexer(lexemes: Lexer);
var
    c: int;
    lexers: Lexer_Array1d;
    newlexers: Lexer_Array1d;
begin
    c := self.lexersCount;
    lexers := self.lexers;
    if length(lexers) = c then begin
        newlexers := Lexer_Array1d(Interface_Array1d_create((c shl 1) + 1));
        arraycopyInterfaces(lexers, 0, newlexers, 0, c);
        self.lexers := newlexers;
        lexers := newlexers;
    end;
    lexers[c] := lexemes;
    self.lexersCount := c + 1;
end;

procedure TranslatorNamespacesBuilder.buildNamespaces();
var
    i: int;
    j: int;
    t: int;
    lc: int;
    nc: int;
    position: int;
    lexemes: Lexer;
    buffered: Namespace;
    imported: Namespace;
    currentNamespace: Namespace;
    currentEntry: NamespaceEntry;
    lexers: Lexer_Array1d;
    namespaces: Namespace_Array1d;
    identifier: UnicodeString;
begin
    lc := self.lexersCount - 1;
    lexers := self.lexers;
    if lc < 0 then begin
        exit;
    end;
    { Поиск пространств имён в исходном тексте }
    for i := 0 to lc do begin
        lexemes := lexers[i];
        position := 0;
        while lexemes.getType(position) = TranslatorLexer.KW_IMPORT do begin
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
                raise CompileError.create(msgExpectedIdentifierOfNamespace, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.SEMICOLON then begin
                raise CompileError.create(msgExpectedSemicolon, lexemes, position);
            end;
            inc(position);
        end;
        case lexemes.getType(position) of
        TranslatorLexer.KW_NAMESPACE: begin
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
                raise CompileError.create(msgExpectedIdentifierOfNamespace, lexemes, position);
            end;
            identifier := lexemes.getValueUString(position);
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
                raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
            end;
            inc(position);
            currentNamespace := TranslatorNamespace.create(identifier, lexemes, operandSize);
            currentNamespace.declarePosition := position - 2;
            currentNamespace.startPosition := position;
            addNamespace(currentNamespace);
            if identifier = NAMESPACE_SYSTEM then begin
                systemNamespace := currentNamespace;
                namespaces := self.namespaces;
                arraycopyInterfaces(namespaces, 0, namespaces, 1, self.namespacesCount - 1);
                namespaces[0] := currentNamespace;
            end;
            position := skipCurlyBrackets(lexemes, position - 1);
        end;
        TranslatorLexer.OPENED_CURLY_BRACKET: begin
            if entryPoint <> nil then begin
                raise CompileError.create(msgEntryPointAlreadyExists, lexemes, position);
            end;
            currentNamespace := TranslatorNamespace.create('', lexemes, operandSize);
            currentNamespace.startPosition := position;
            entryPoint := currentNamespace.addFunction(true, FUNCTION_MAIN,
                    TranslatorGlobalFunction.CODE_TYPE_NORMAL, typeVoid);
            entryPoint.declarePosition := -1;
            entryPoint.startPosition := position;
            addNamespace(currentNamespace);
            position := skipCurlyBrackets(lexemes, position);
        end;
        TranslatorLexer.IDENTIFIER: begin
            if entryPoint <> nil then begin
                raise CompileError.create(msgEntryPointAlreadyExists, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.OPENED_PARENTHESIS then begin
                raise CompileError.create(msgExpectedOpenedParenthesis, lexemes, position);
            end;
            dec(position);
            currentNamespace := TranslatorNamespace.create('', lexemes, position);
            currentNamespace.startPosition := position;
            entryPoint := currentNamespace.addFunction(true, lexemes.getValueUString(position),
                    TranslatorGlobalFunction.CODE_TYPE_NORMAL, typeVoid);
            entryPoint.declarePosition := position;
            addNamespace(currentNamespace);
            position := skipParenthesis(lexemes, position + 1);
            if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
                raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
            end;
            entryPoint.startPosition := position;
            position := skipCurlyBrackets(lexemes, position);
        end;
        else
            raise CompileError.create(msgExpectedKeywordNamespace, lexemes, position);
        end;
        while lexemes.getType(position) = TranslatorLexer.KW_NAMESPACE do begin
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
                raise CompileError.create(msgExpectedIdentifierOfNamespace, lexemes, position);
            end;
            identifier := lexemes.getValueUString(position);
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
                raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
            end;
            inc(position);
            currentNamespace := TranslatorNamespace.create(identifier, lexemes, operandSize);
            currentNamespace.declarePosition := position - 2;
            currentNamespace.startPosition := position;
            addNamespace(currentNamespace);
            if identifier = NAMESPACE_SYSTEM then begin
                systemNamespace := currentNamespace;
                namespaces := self.namespaces;
                arraycopyInterfaces(namespaces, 0, namespaces, 1, self.namespacesCount - 1);
                namespaces[0] := currentNamespace;
            end;
            position := skipCurlyBrackets(lexemes, position - 1);
        end;
    end;
    { Проверка наличия необходимых элементов: системного пространства имён и точки входа }
    if systemNamespace = nil then begin
        raise CompileError.create(msgNamespaceSystemNotFound, lexers[0], 0);
    end;
    if entryPoint = nil then begin
        raise CompileError.create(msgEntryPointNotFound, lexers[0], 0);
    end;
    { Поиск пространств имён с одинаковыми именами }
    nc := self.namespacesCount - 1;
    namespaces := self.namespaces;
    for i := 1 to nc do begin
        identifier := namespaces[i - 1].name;
        for j := i to nc do begin
            currentNamespace := namespaces[j];
            if currentNamespace.name = identifier then begin
                raise CompileError.create(msgNamespaceAlreadyExists, currentNamespace.lexemes,
                        currentNamespace.declarePosition);
            end;
        end;
    end;
    { Подключение импортов }
    buffered := systemNamespace;
    for i := 0 to nc do begin
        currentNamespace := namespaces[i];
        currentNamespace.addImport(buffered);
        lexemes := currentNamespace.lexemes;
        position := 0;
        while lexemes.getType(position) = TranslatorLexer.KW_IMPORT do begin
            inc(position);
            identifier := lexemes.getValueUString(position);
            imported := findNamespace(identifier);
            if imported = nil then begin
                raise CompileError.create(msgExpectedIdentifierOfNamespace, lexemes, position);
            end;
            if currentNamespace.isImported(identifier) then begin
                raise CompileError.create(msgNamespaceAlreadyImported, lexemes, position);
            end;
            currentNamespace.addImport(imported);
            inc(position, 2);
        end;
    end;
    { Поиск членов пространств имён в исходном тексте }
    for i := 0 to nc do begin
        currentNamespace := namespaces[i];
        if length(currentNamespace.name) <= 0 then begin
            continue;
        end;
        lexemes := currentNamespace.lexemes;
        position := currentNamespace.startPosition;
        t := lexemes.getType(position);
        while (t <> TranslatorLexer.CLOSED_CURLY_BRACKET) and (t <> TranslatorLexer.NULL) do begin
            position := parseEntry(currentNamespace, lexemes, position);
            t := lexemes.getType(position);
        end;
        if t <> TranslatorLexer.CLOSED_CURLY_BRACKET then begin
            raise CompileError.create(msgExpectedClosedCurlyBracket, lexemes, position);
        end;
    end;
    { Добавление аргументов к функции – точке входа }
    position := entryPoint.declarePosition + 2;
    if position > 1 then begin
        currentNamespace := entryPoint.owner;
        lexemes := currentNamespace.lexemes;
        position := parseArguments(currentNamespace, lexemes, position, entryPoint.functionType);
        if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
            raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
        end;
    end;
    { Поиск полей структур в исходном тексте }
    for i := 0 to nc do begin
        currentNamespace := namespaces[i];
        lexemes := currentNamespace.lexemes;
        lc := currentNamespace.getEntriesCount() - 1;
        for j := 0 to lc do begin
            currentEntry := currentNamespace.getEntry(j);
            if currentEntry is TypeStructure then begin
                parseFields(currentEntry as TypeStructure, lexemes);
            end;
        end;
    end;
end;

function TranslatorNamespacesBuilder.getNamespacesCount(): int;
begin
    result := namespacesCount;
end;

function TranslatorNamespacesBuilder.getNamespace(index: int): Namespace;
begin
    if (index < 0) or (index >= namespacesCount) then begin
        raise IndexOutOfBoundsException.create(msgIndexOutOfBounds);
    end;
    result := namespaces[index];
end;

function TranslatorNamespacesBuilder.getSystemNamespace(): Namespace;
begin
    result := systemNamespace;
end;

function TranslatorNamespacesBuilder.getEntryPoint(): GlobalFunction;
begin
    result := entryPoint;
end;

function TranslatorNamespacesBuilder.findNamespace(const name: UnicodeString): Namespace;
var
    i: int;
    current: Namespace;
    namespaces: Namespace_Array1d;
begin
    namespaces := self.namespaces;
    for i := self.namespacesCount - 1 downto 0 do begin
        current := namespaces[i];
        if current.name = name then begin
            result := current;
            exit;
        end;
    end;
    result := nil;
end;

procedure TranslatorNamespacesBuilder.addNamespace(space: Namespace);
var
    c: int;
    namespaces: Namespace_Array1d;
    newnamespaces: Namespace_Array1d;
begin
    c := self.namespacesCount;
    namespaces := self.namespaces;
    if length(namespaces) = c then begin
        newnamespaces := Namespace_Array1d(Interface_Array1d_create((c shl 1) + 1));
        arraycopyInterfaces(namespaces, 0, newnamespaces, 0, c);
        self.namespaces := newnamespaces;
        namespaces := newnamespaces;
    end;
    namespaces[c] := space;
    self.namespacesCount := c + 1;
end;

procedure TranslatorNamespacesBuilder.parseFields(structure: TypeStructure; lexemes: Lexer);
var
    position: int;
    fldPublic: boolean;
    fldType: TypeDescriptor;
    fldName: UnicodeString;
    fldResult: StructureField;
    structureAsEntry: NamespaceEntry;
    where: Namespace;
begin
    structure.updateSize();
    structureAsEntry := structure as NamespaceEntry;
    position := structureAsEntry.startPosition;
    if position < 0 then begin
        exit;
    end;
    where := structureAsEntry.owner;
    repeat
        case lexemes.getType(position) of
        TranslatorLexer.CLOSED_CURLY_BRACKET: begin
            break;
        end;
        TranslatorLexer.NULL: begin
            raise CompileError.create(msgExpectedClosedCurlyBracket, lexemes, position);
        end;
        TranslatorLexer.KW_PUBLIC: begin
            fldPublic := true;
            inc(position);
        end;
        else
            fldPublic := false;
        end;
        fldType := parseType(where, position);
        position := stayPosition;
        if not fldType.isMatchForVariable() then begin
            raise CompileError.create(msgTypeNotApplicableToVar, lexemes, position);
        end;
        fldName := '';
        if lexemes.getType(position) = TranslatorLexer.IDENTIFIER then begin
            fldName := lexemes.getValueUString(position);
            if structure.findField(fldName, true) <> nil then begin
                raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
            end;
            fldResult := structure.addField(fldPublic, fldType, fldName);
            fldResult.declarePosition := position;
            inc(position);
        end else begin
            structure.addField(fldPublic, fldType, fldName);
        end;
        if lexemes.getType(position) <> TranslatorLexer.SEMICOLON then begin
            raise CompileError.create(msgExpectedSemicolon, lexemes, position);
        end;
        inc(position);
    until false;
end;

function TranslatorNamespacesBuilder.parseEntry(where: Namespace; lexemes: Lexer;
        position: int): int;
var
    epublic: boolean;
begin
    epublic := false;
    if lexemes.getType(position) = TranslatorLexer.KW_PUBLIC then begin
        epublic := true;
        inc(position);
    end;
    case lexemes.getType(position) of
    TranslatorLexer.KW_CONST:
        result := parseConstant(where, lexemes, position + 1, epublic);
    TranslatorLexer.KW_EXCEPTION:
        result := parseException(where, lexemes, position + 1, epublic);
    TranslatorLexer.KW_STRUCT:
        result := parseStructure(where, lexemes, position + 1, epublic);
    else
        result := parseVarOrFunc(where, lexemes, position, epublic);
    end;
end;

function TranslatorNamespacesBuilder.parseConstant(where: Namespace; lexemes: Lexer;
        position: int; epublic: boolean): int;
var
    declarePosition: int;
    constTypeKind: int;
    constType: TypeDescriptor;
    constValue: GlobalConstant;
    constResult: GlobalConstant;
    constIdent: UnicodeString;
begin
    constType := parseType(where, position);
    constTypeKind := constType.kind;
    position := stayPosition;
    if not constType.isMatchForConstant() then begin
        raise CompileError.create(msgTypeNotApplicableToConst, lexemes, position);
    end;
    if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
        raise CompileError.create(msgExpectedIdentifierOfConstant, lexemes, position);
    end;
    constIdent := lexemes.getValueUString(position);
    if where.findEntry(constIdent, false) <> nil then begin
        raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
    end;
    declarePosition := position;
    inc(position);
    if lexemes.getType(position) <> TranslatorLexer.ASSIGN then begin
        raise CompileError.create(msgExpectedAssign, lexemes, position);
    end;
    constValue := parseConst(where, position + 1);
    position := stayPosition;
    if not possibleAssign(constTypeKind, constValue) then begin
        raise CompileError.create(msgCannotAssignDataType, lexemes, declarePosition + 1);
    end;
    case constTypeKind of
    TranslatorType.KIND_BOOLEAN, TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
    TranslatorType.KIND_SHORT, TranslatorType.KIND_INT, TranslatorType.KIND_LONG,
    TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
        constResult := where.addConstant(epublic, constIdent, constType,
                constValue.realValue);
    TranslatorType.KIND_ULTRA:
        constResult := where.addConstantUltra(epublic, constIdent, constType,
                constValue.getUltraValue());
    TranslatorType.KIND_XVECTOR:
        constResult := where.addConstantXVector(epublic, constIdent, constType,
                constValue.getXVectorValue());
    else
        constResult := nil;
    end;
    constResult.declarePosition := declarePosition;
    if lexemes.getType(position) <> TranslatorLexer.SEMICOLON then begin
        raise CompileError.create(msgExpectedSemicolon, lexemes, position);
    end;
    result := position + 1;
end;

function TranslatorNamespacesBuilder.parseException(where: Namespace; lexemes: Lexer;
        position: int; epublic: boolean): int;
label
    label0;
var
    declarePosition: int;
    exceptAncestor: GlobalException;
    exceptResult: GlobalException;
    exceptIdent: UnicodeString;
    place: Namespace;
    entry: NamespaceEntry;
    ident: UnicodeString;
begin
    if operandSize < TranslatorType.SIZE_64_BIT then begin
        raise CompileError.create(msgExceptionNotSupported, lexemes, position);
    end;
    if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
        raise CompileError.create(msgExpectedIdentifierOfException, lexemes, position);
    end;
    exceptIdent := lexemes.getValueUString(position);
    if where.findEntry(exceptIdent, false) <> nil then begin
        raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
    end;
    declarePosition := position;
    inc(position);
    if lexemes.getType(position) = TranslatorLexer.OPENED_PARENTHESIS then begin
        inc(position);
        if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
            raise CompileError.create(msgExpectedIdentifierOfException, lexemes, position);
        end;
        ident := lexemes.getValueUString(position);
        entry := where.findEntry(ident, true);
        if entry = nil then begin
            place := findNamespace(ident);
            if place = nil then begin
                raise CompileError.create(msgExpectedException, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.PERIOD then begin
                raise CompileError.create(msgExpectedPeriod, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
                raise CompileError.create(msgExpectedIdentifierOfException, lexemes, position);
            end;
            ident := lexemes.getValueUString(position);
            entry := place.findEntry(ident, false);
            if not (entry is GlobalException) or not where.isVisible(entry) then begin
                raise CompileError.create(msgExpectedIdentifierOfException, lexemes, position);
            end;
            exceptAncestor := entry as GlobalException;
        end else
        if entry is GlobalException then begin
            exceptAncestor := entry as GlobalException;
        end else begin
            raise CompileError.create(msgExpectedIdentifierOfException, lexemes, position);
        end;
        inc(position);
        if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
            raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
        end;
        inc(position);
    end else begin
        exceptAncestor := nil;
        place := systemNamespace;
        if place <> nil then begin
            entry := place.findEntry(EXCEPTION_EXCEPTION, false);
            if entry is GlobalException then begin
                exceptAncestor := entry as GlobalException;
                goto label0;
            end;
            entry := place.findEntry(EXCEPTION_THROWABLE, false);
            if entry is GlobalException then begin
                exceptAncestor := entry as GlobalException;
            end;
            label0:
        end;
    end;
    exceptResult := where.addException(epublic, exceptIdent, exceptAncestor);
    exceptResult.declarePosition := declarePosition;
    if lexemes.getType(position) <> TranslatorLexer.SEMICOLON then begin
        raise CompileError.create(msgExpectedSemicolon, lexemes, position);
    end;
    result := position + 1;
end;

function TranslatorNamespacesBuilder.parseStructure(where: Namespace; lexemes: Lexer;
        position: int; epublic: boolean): int;
var
    declarePosition: int;
    structAncestor: TypeStructure;
    structResult: NamespaceEntry;
    structIdent: UnicodeString;
    place: Namespace;
    entry: NamespaceEntry;
    ident: UnicodeString;
begin
    if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
        raise CompileError.create(msgExpectedIdentifierOfStructure, lexemes, position);
    end;
    structIdent := lexemes.getValueUString(position);
    if where.findEntry(structIdent, false) <> nil then begin
        raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
    end;
    declarePosition := position;
    inc(position);
    if lexemes.getType(position) = TranslatorLexer.OPENED_PARENTHESIS then begin
        inc(position);
        if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
            raise CompileError.create(msgExpectedIdentifierOfStructure, lexemes, position);
        end;
        ident := lexemes.getValueUString(position);
        entry := where.findEntry(ident, true);
        if entry = nil then begin
            place := findNamespace(ident);
            if place = nil then begin
                raise CompileError.create(msgExpectedStructure, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.PERIOD then begin
                raise CompileError.create(msgExpectedPeriod, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
                raise CompileError.create(msgExpectedIdentifierOfStructure, lexemes, position);
            end;
            ident := lexemes.getValueUString(position);
            entry := place.findEntry(ident, false);
            if not (entry is TypeStructure) or not where.isVisible(entry) then begin
                raise CompileError.create(msgExpectedIdentifierOfStructure, lexemes, position);
            end;
            structAncestor := entry as TypeStructure;
        end else
        if entry is TypeStructure then begin
            structAncestor := entry as TypeStructure;
        end else begin
            raise CompileError.create(msgExpectedIdentifierOfStructure, lexemes, position);
        end;
        inc(position);
        if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
            raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
        end;
        inc(position);
    end else begin
        structAncestor := nil;
        place := systemNamespace;
        if place <> nil then begin
            entry := place.findEntry(STRUCTURE_POINTER, false);
            if entry is TypeStructure then begin
                structAncestor := entry as TypeStructure;
            end;
        end;
    end;
    structResult := where.addStructureExt(epublic, structIdent, structAncestor);
    structResult.declarePosition := declarePosition;
    case lexemes.getType(position) of
    TranslatorLexer.OPENED_CURLY_BRACKET: begin
        structResult.startPosition := position + 1;
        position := skipCurlyBrackets(lexemes, position);
    end;
    TranslatorLexer.SEMICOLON: begin
        structResult.startPosition := -1;
        inc(position);
    end;
    else
        raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
    end;
    result := position;
end;

function TranslatorNamespacesBuilder.parseVarOrFunc(where: Namespace; lexemes: Lexer;
        position: int; epublic: boolean): int;
var
    i: int;
    declarePosition: int;
    retKind: int;
    argKind: int;
    codeType: int;
    tempType: TypeDescriptor;
    entryType: TypeDescriptor;
    varResult: GlobalVariable;
    funcResult: GlobalFunction;
    entryName: UnicodeString;
    resFunc: TypeFunction;
    newFunc: TypeFunction;
begin
    codeType := 0;
    case lexemes.getType(position) of
    TranslatorLexer.KW_INITIALIZATION: begin
        declarePosition := position;
        if where.findEntry(FUNCTION_INITIALIZATION, false) <> nil then begin
            raise CompileError.create(msgAlreadyExistsInitialization, lexemes, position);
        end;
        inc(position);
        if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
            raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
        end;
        funcResult := where.addFunction(epublic, FUNCTION_INITIALIZATION, 0, typeVoid);
        funcResult.startPosition := position;
        funcResult.declarePosition := declarePosition;
        result := skipCurlyBrackets(lexemes, position);
        exit;
    end;
    TranslatorLexer.KW_FINALIZATION: begin
        declarePosition := position;
        if where.findEntry(FUNCTION_FINALIZATION, false) <> nil then begin
            raise CompileError.create(msgAlreadyExistsFinalization, lexemes, position);
        end;
        inc(position);
        if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
            raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
        end;
        funcResult := where.addFunction(epublic, FUNCTION_FINALIZATION, 0, typeVoid);
        funcResult.startPosition := position;
        funcResult.declarePosition := declarePosition;
        result := skipCurlyBrackets(lexemes, position);
        exit;
    end;
    TranslatorLexer.KW_INTERRUPT: begin
        codeType := codeType or TranslatorGlobalFunction.CODE_TYPE_INTERRUPT;
        inc(position);
    end;
    end;
    case lexemes.getType(position) of
    TranslatorLexer.KW_ASSEMBLER: begin
        codeType := codeType or TranslatorGlobalFunction.CODE_TYPE_ASSEMBLER;
        inc(position);
    end;
    TranslatorLexer.KW_PUREASSEMBLER: begin
        codeType := codeType or TranslatorGlobalFunction.CODE_TYPE_PUREASSEMBLER;
        inc(position);
    end;
    end;
    case operandSize of
    TranslatorType.SIZE_16_BIT: begin
        retKind := TranslatorType.KIND_CHAR;
        argKind := TranslatorType.KIND_SHORT;
    end;
    TranslatorType.SIZE_32_BIT: begin
        retKind := TranslatorType.KIND_INT;
        argKind := TranslatorType.KIND_INT;
    end;
    TranslatorType.SIZE_64_BIT: begin
        retKind := TranslatorType.KIND_LONG;
        argKind := TranslatorType.KIND_INT;
    end;
    else
        retKind := 0;
        argKind := 0;
    end;
    entryType := parseType(where, position);
    position := stayPosition;
    declarePosition := position;
    case lexemes.getType(position) of
    TranslatorLexer.IDENTIFIER: begin
        if ((codeType and TranslatorGlobalFunction.CODE_TYPE_INTERRUPT) <> 0) and
                (entryType.kind <> TranslatorType.KIND_VOID) then begin
            raise CompileError.create(msgInterruptMustReturnVoid, lexemes, position);
        end;
        entryName := lexemes.getValueUString(position);
        if where.findEntry(entryName, false) <> nil then begin
            raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
        end;
        inc(position);
        case lexemes.getType(position) of
        TranslatorLexer.SEMICOLON: begin
            if not entryType.isMatchForVariable() or (codeType <> 0) then begin
                raise CompileError.create(msgExpectedOpenedParenthesis, lexemes, position);
            end;
            inc(position);
            varResult := where.addVariable(epublic, entryName, entryType);
            varResult.declarePosition := declarePosition;
        end;
        TranslatorLexer.OPENED_PARENTHESIS: begin
            if not entryType.isMatchForReturnType() then begin
                raise CompileError.create(msgTypeNotApplicableToFunc, lexemes, position - 1);
            end;
            funcResult := where.addFunction(epublic, entryName, codeType, entryType);
            position := parseArguments(where, lexemes, position + 1, funcResult.functionType);
            if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
                raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
                raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
            end;
            funcResult.startPosition := position;
            funcResult.declarePosition := declarePosition;
            position := skipCurlyBrackets(lexemes, position);
        end;
        else
            if entryType.isMatchForVariable() and (codeType = 0) then begin
                raise CompileError.create(msgExpectedSemicolon, lexemes, position);
            end else begin
                raise CompileError.create(msgExpectedOpenedParenthesis, lexemes, position);
            end;
        end;
    end;
    TranslatorLexer.KW_DISPOSE: begin
        if where <> systemNamespace then begin
            raise CompileError.create(msgSpecialFunctionMustInSystem, lexemes, position);
        end;
        if (codeType and TranslatorGlobalFunction.CODE_TYPE_INTERRUPT) <> 0 then begin
            raise CompileError.create(msgSpecialFunctionMustNoInterrupt, lexemes, position);
        end;
        inc(position);
        if lexemes.getType(position) <> TranslatorLexer.OPENED_PARENTHESIS then begin
            raise CompileError.create(msgExpectedOpenedParenthesis, lexemes, position);
        end;
        newFunc := TranslatorTypeFunction.create(operandSize, entryType);
        position := parseArguments(where, lexemes, position + 1, newFunc);
        if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
            raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
        end;
        inc(position);
        if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
            raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
        end;
        if newFunc.getArgumentsCount() <> 1 then begin
            raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
        end;
        if where.findEntry(FUNCTION_DISPOSE, false) <> nil then begin
            raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, declarePosition);
        end;
        if entryType.kind <> TranslatorType.KIND_VOID then begin
            raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
        end;
        funcResult := where.addFunction(epublic, FUNCTION_DISPOSE, codeType, entryType);
        resFunc := funcResult.functionType;
        with newFunc.getArgument(0) do begin
            tempType := dataType;
            if tempType.kind <> retKind then begin
                raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
            end;
            resFunc.addArgument(tempType, name);
        end;
        funcResult.startPosition := position;
        funcResult.declarePosition := declarePosition;
        position := skipCurlyBrackets(lexemes, position);
    end;
    TranslatorLexer.KW_NEW: begin
        if where <> systemNamespace then begin
            raise CompileError.create(msgSpecialFunctionMustInSystem, lexemes, position);
        end;
        if (codeType and TranslatorGlobalFunction.CODE_TYPE_INTERRUPT) <> 0 then begin
            raise CompileError.create(msgSpecialFunctionMustNoInterrupt, lexemes, position);
        end;
        inc(position);
        if lexemes.getType(position) <> TranslatorLexer.OPENED_PARENTHESIS then begin
            raise CompileError.create(msgExpectedOpenedParenthesis, lexemes, position);
        end;
        newFunc := TranslatorTypeFunction.create(operandSize, entryType);
        position := parseArguments(where, lexemes, position + 1, newFunc);
        if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
            raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
        end;
        inc(position);
        if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
            raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
        end;
        case newFunc.getArgumentsCount() of
        1: begin
            if where.findEntry(FUNCTION_NEW_STRUCT, false) <> nil then begin
                raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, declarePosition);
            end;
            if entryType.kind <> retKind then begin
                raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
            end;
            funcResult := where.addFunction(epublic, FUNCTION_NEW_STRUCT, codeType, entryType);
            resFunc := funcResult.functionType;
            with newFunc.getArgument(0) do begin
                tempType := dataType;
                if tempType.kind <> argKind then begin
                    raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
                end;
                resFunc.addArgument(tempType, name);
            end;
        end;
        2: begin
            if where.findEntry(FUNCTION_NEW_ARRAY, false) <> nil then begin
                raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, declarePosition);
            end;
            if entryType.kind <> retKind then begin
                raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
            end;
            funcResult := where.addFunction(epublic, FUNCTION_NEW_ARRAY, codeType, entryType);
            resFunc := funcResult.functionType;
            for i := 0 to 1 do with newFunc.getArgument(i) do begin
                tempType := dataType;
                if tempType.kind <> argKind then begin
                    raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
                end;
                resFunc.addArgument(tempType, name);
            end;
        end;
        else
            raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
        end;
        funcResult.startPosition := position;
        funcResult.declarePosition := declarePosition;
        position := skipCurlyBrackets(lexemes, position);
    end;
    else
        if entryType.isMatchForVariable() and (codeType = 0) then begin
            raise CompileError.create(msgExpectedIdentifierOfVariable, lexemes, position);
        end else begin
            raise CompileError.create(msgExpectedIdentifierOfFunction, lexemes, position);
        end;
    end;
    result := position;
end;

function TranslatorNamespacesBuilder.parseArguments(where: Namespace; lexemes: Lexer;
        position: int; destination: TypeFunction): int;
var
    argument: FunctionArgument;
    argType: TypeDescriptor;
    argName: UnicodeString;
begin
    if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
        repeat
            argType := parseType(where, position);
            position := stayPosition;
            if not argType.isMatchForVariable() then begin
                raise CompileError.create(msgTypeNotApplicableToVar, lexemes, position);
            end;
            if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
                raise CompileError.create(msgExpectedIdentifierOfArgument,
                        lexemes, position);
            end;
            argName := lexemes.getValueUString(position);
            if destination.findArgument(argName) <> nil then begin
                raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
            end;
            argument := destination.addArgument(argType, argName);
            argument.declarePosition := position;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.COMMA then begin
                break;
            end;
            inc(position);
        until false;
    end;
    result := position;
end;

function TranslatorNamespacesBuilder.parseConstElem(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    i: int;
    kind: int;
    value: int;
    compound: GlobalConstant_Array1d;
    index: GlobalConstant;
    place: Namespace;
    entry: NamespaceEntry;
    ident: UnicodeString;
begin
    case lexemes.getType(position) of
    TranslatorLexer.OPENED_PARENTHESIS: begin
        result := parseConstCond(where, lexemes, position + 1);
        position := stayPosition;
        if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
            raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
        end;
    end;
    TranslatorLexer.IDENTIFIER: begin
        ident := lexemes.getValueUString(position);
        entry := where.findEntry(ident, true);
        if entry = nil then begin
            place := findNamespace(ident);
            if place = nil then begin
                raise CompileError.create(msgExpectedConstant, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.PERIOD then begin
                raise CompileError.create(msgExpectedPeriod, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
                raise CompileError.create(msgExpectedIdentifierOfConstant, lexemes, position);
            end;
            ident := lexemes.getValueUString(position);
            entry := place.findEntry(ident, false);
            if not (entry is GlobalConstant) or not where.isVisible(entry) then begin
                raise CompileError.create(msgExpectedIdentifierOfConstant, lexemes, position);
            end;
            result := entry as GlobalConstant;
        end else
        if entry is GlobalConstant then begin
            result := entry as GlobalConstant;
        end else begin
            raise CompileError.create(msgExpectedIdentifierOfConstant, lexemes, position);
        end;
    end;
    TranslatorLexer.KW_FALSE: begin
        result := TranslatorLocalConstantInt.create(typeBoolean, false);
    end;
    TranslatorLexer.KW_TRUE: begin
        result := TranslatorLocalConstantInt.create(typeBoolean, true);
    end;
    TranslatorLexer.KW_NEW: begin
        inc(position);
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgTypeNotSupported, lexemes, position);
        end;
        case lexemes.getType(position) of
        TranslatorLexer.KW_ULTRA: begin
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
                raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
            end;
            inc(position);
            compound := GlobalConstant_Array1d(Interface_Array1d_create(4));
            for i := 0 to 3 do begin
                compound[i] := parseConstCond(where, lexemes, position);
                position := stayPosition;
                if not possibleAssign(TranslatorType.KIND_INT, compound[i]) then begin
                    raise CompileError.create(msgCannotAssignDataType, lexemes, position);
                end;
                if i < 3 then begin
                    if lexemes.getType(position) <> TranslatorLexer.COMMA then begin
                        raise CompileError.create(msgExpectedComma, lexemes, position);
                    end;
                    inc(position);
                end;
            end;
            result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(
                    compound[3].intValue, compound[2].intValue,
                    compound[1].intValue, compound[0].intValue));
        end;
        TranslatorLexer.KW_XVECTOR: begin
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
                raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
            end;
            inc(position);
            compound := GlobalConstant_Array1d(Interface_Array1d_create(4));
            for i := 0 to 3 do begin
                compound[i] := parseConstCond(where, lexemes, position);
                position := stayPosition;
                if not possibleAssign(TranslatorType.KIND_FLOAT, compound[i]) then begin
                    raise CompileError.create(msgCannotAssignDataType, lexemes, position);
                end;
                if i < 3 then begin
                    if lexemes.getType(position) <> TranslatorLexer.COMMA then begin
                        raise CompileError.create(msgExpectedComma, lexemes, position);
                    end;
                    inc(position);
                end;
            end;
            result := TranslatorLocalConstantXVector.create(typeXVector, xvectorBuild(
                    compound[3].realValue, compound[2].realValue,
                    compound[1].realValue, compound[0].realValue));
        end;
        TranslatorLexer.KW_YVECTOR, TranslatorLexer.KW_ULTRA32,
        TranslatorLexer.KW_ZVECTOR, TranslatorLexer.KW_ULTRA64,
        TranslatorLexer.KW_FVECTOR: begin
            raise CompileError.create(msgTypeReserved, lexemes, position);
        end;
        else
            raise CompileError.create(msgExpectedDataTypeCompound, lexemes, position);
        end;
        if lexemes.getType(position) <> TranslatorLexer.CLOSED_CURLY_BRACKET then begin
            raise CompileError.create(msgExpectedClosedCurlyBracket, lexemes, position);
        end;
    end;
    TranslatorLexer.NUM_INT: begin
        value := lexemes.getValueInt(position);
        if operandSize < TranslatorType.SIZE_32_BIT then begin
            if (value < -$8000) or (value > $ffff) then begin
                raise CompileError.create(msgTypeNotSupported, lexemes, position);
            end;
            if value < $8000 then begin
                result := TranslatorLocalConstantInt.create(typeShort, value);
            end else begin
                result := TranslatorLocalConstantInt.create(typeChar, value);
            end;
        end else begin
            result := TranslatorLocalConstantInt.create(typeInt, value);
        end;
    end;
    TranslatorLexer.NUM_LONG: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgTypeNotSupported, lexemes, position);
        end;
        result := TranslatorLocalConstantLong.create(typeLong, lexemes.getValueLong(position));
    end;
    TranslatorLexer.NUM_FLOAT: begin
        result := TranslatorLocalConstantReal.create(typeFloat, lexemes.getValueReal(position));
    end;
    TranslatorLexer.NUM_DOUBLE: begin
        result := TranslatorLocalConstantReal.create(typeDouble, lexemes.getValueReal(position));
    end;
    TranslatorLexer.NUM_REAL: begin
        result := TranslatorLocalConstantReal.create(typeReal, lexemes.getValueReal(position));
    end;
    else
        raise CompileError.create(msgExpressionError, lexemes, position);
    end;
    inc(position);
    if lexemes.getType(position) = TranslatorLexer.OPENED_SQUARE_BRACKET then begin
        kind := result.dataType.kind;
        case kind of
        TranslatorType.KIND_ULTRA, TranslatorType.KIND_XVECTOR: ;
        else
            raise CompileError.create(msgTypeMustBeCompound, lexemes, position);
        end;
        index := parseConstCond(where, lexemes, position + 1);
        position := stayPosition;
        if not possibleAssign(TranslatorType.KIND_INT, index) then begin
            raise CompileError.create(msgTypeMustBeInt, lexemes, position);
        end;
        i := index.intValue;
        if (i < 0) or (i >= 4) then begin
            raise CompileError.create(msgCompoundIndexOutOfBounds, lexemes, position);
        end;
        if lexemes.getType(position) <> TranslatorLexer.CLOSED_SQUARE_BRACKET then begin
            raise CompileError.create(msgExpectedClosedSquareBracket, lexemes, position);
        end;
        case kind of
        TranslatorType.KIND_ULTRA:
            result := TranslatorLocalConstantInt.create(typeInt,
                    result.getUltraValue().ints[i]);
        TranslatorType.KIND_XVECTOR:
            result := TranslatorLocalConstantReal.create(typeFloat,
                    result.getXVectorValue().floats[i]);
        end;
        inc(position);
    end;
    stayPosition := position;
end;

function TranslatorNamespacesBuilder.parseConstPref(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    endPosition: int;
    typeForCast: TypeDescriptor;
begin
    case lexemes.getType(position) of
    TranslatorLexer.OPENED_PARENTHESIS: begin
        inc(position);
        typeForCast := tryParseType(where, position);
        endPosition := stayPosition;
        if (typeForCast <> nil) and
                (lexemes.getType(endPosition) = TranslatorLexer.CLOSED_PARENTHESIS) then begin
            if not typeForCast.isMatchForConstant() then begin
                raise CompileError.create(msgTypeNotApplicableToConst, lexemes, position);
            end;
            result := parseConstPref(where, lexemes, endPosition + 1);
            if not result.dataType.possibleCastTo(typeForCast) then begin
                raise CompileError.create(msgCannotCastToType, lexemes, position);
            end;
            result := castConstTo(typeForCast.kind, result);
        end else begin
            result := parseConstElem(where, lexemes, position - 1);
        end;
    end;
    TranslatorLexer.SNOTB: begin
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
            if operandSize < TranslatorType.SIZE_32_BIT then begin
                result := TranslatorLocalConstantInt.create(typeShort,
                        short(result.shortValue xor (-1)));
            end else begin
                result := TranslatorLocalConstantInt.create(typeInt,
                        result.intValue xor (-1));
            end;
        TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantLong.create(typeLong,
                    result.longValue xor (-1));
        TranslatorType.KIND_ULTRA:
            result := TranslatorLocalConstantUltra.create(typeUltra,
                    result.getUltraValue() xor ultraBuild(-1, -1));
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.SNOTL: begin
        result := parseConstPref(where, lexemes, position + 1);
        if result.dataType.kind = TranslatorType.KIND_BOOLEAN then begin
            result := TranslatorLocalConstantInt.create(typeBoolean,
                    not result.booleanValue);
        end else begin
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.SPLUS: begin
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
            if operandSize < TranslatorType.SIZE_32_BIT then begin
                result := TranslatorLocalConstantInt.create(typeShort,
                        result.shortValue);
            end else begin
                result := TranslatorLocalConstantInt.create(typeInt,
                        result.intValue);
            end;
        TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantLong.create(typeLong,
                    result.longValue);
        TranslatorType.KIND_FLOAT:
            result := TranslatorLocalConstantReal.create(typeFloat,
                    result.realValue);
        TranslatorType.KIND_DOUBLE:
            result := TranslatorLocalConstantReal.create(typeDouble,
                    result.realValue);
        TranslatorType.KIND_REAL:
            result := TranslatorLocalConstantReal.create(typeReal,
                    result.realValue);
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.SMINUS: begin
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
            if operandSize < TranslatorType.SIZE_32_BIT then begin
                result := TranslatorLocalConstantInt.create(typeShort,
                        short(-result.shortValue));
            end else begin
                result := TranslatorLocalConstantInt.create(typeInt,
                        -result.intValue);
            end;
        TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantLong.create(typeLong,
                    -result.longValue);
        TranslatorType.KIND_FLOAT:
            result := TranslatorLocalConstantReal.create(typeFloat,
                    -result.realValue);
        TranslatorType.KIND_DOUBLE:
            result := TranslatorLocalConstantReal.create(typeDouble,
                    -result.realValue);
        TranslatorType.KIND_REAL:
            result := TranslatorLocalConstantReal.create(typeReal,
                    -result.realValue);
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.QPACKUS: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
        end;
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
        TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantInt.create(typeInt,
                    mmxPack(result.longValue));
        TranslatorType.KIND_ULTRA: begin
            if extension < EXTENSION_SSE4_1 then begin
                raise CompileError.create(msgOperationNotSupportedEX, lexemes, position);
            end;
            result := TranslatorLocalConstantLong.create(typeLong,
                    pack4IntUS(result.getUltraValue()));
        end;
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.QUNPCKL: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
        end;
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
            result := TranslatorLocalConstantLong.create(typeLong,
                    mmxUnpackLo(result.intValue));
        TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantUltra.create(typeUltra,
                    sseiUnpackLo(result.longValue));
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.QUNPCKH: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
        end;
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
            result := TranslatorLocalConstantLong.create(typeLong,
                    mmxUnpackHi(result.intValue));
        TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantUltra.create(typeUltra,
                    sseiUnpackHi(result.longValue));
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.QADD: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
        end;
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
            result := TranslatorLocalConstantLong.create(typeLong, result.longValue);
        TranslatorType.KIND_FLOAT:
            result := TranslatorLocalConstantXVector.create(typeXVector, result.getXVectorValue());
        TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA, TranslatorType.KIND_XVECTOR: ;
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.QSUB: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
        end;
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
        TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantLong.create(typeLong,
                    mmxSub(0, result.longValue));
        TranslatorType.KIND_ULTRA:
            result := TranslatorLocalConstantUltra.create(typeUltra,
                    sseiSub(ultraBuild(0, 0, 0, 0), result.getUltraValue()));
        TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
            result := TranslatorLocalConstantXVector.create(typeXVector,
                    ssefSub(xvectorBuild(0, 0, 0, 0), result.getXVectorValue()));
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.OPACKUS: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
        end;
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
        TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA: begin
            result := TranslatorLocalConstantLong.create(typeLong,
                    ssesPack(result.getUltraValue()));
        end;
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.OUNPCKL: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
        end;
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
        TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantUltra.create(typeUltra,
                    ssesUnpackLo(result.longValue));
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.OUNPCKH: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
        end;
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
        TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantUltra.create(typeUltra,
                    ssesUnpackHi(result.longValue));
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.OADD: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
        end;
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
        TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantUltra.create(typeUltra, result.getUltraValue());
        TranslatorType.KIND_ULTRA: ;
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    TranslatorLexer.OSUB: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
        end;
        result := parseConstPref(where, lexemes, position + 1);
        case result.dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
        TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
            result := TranslatorLocalConstantUltra.create(typeUltra,
                    ssesSub(ultraBuild(0, 0, 0, 0), result.getUltraValue()));
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    end;
    else
        result := parseConstElem(where, lexemes, position);
    end;
end;

function TranslatorNamespacesBuilder.parseConstMult(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    ival: int;
    lval: long;
    second: GlobalConstant;
begin
    result := parseConstPref(where, lexemes, position);
    repeat
        position := stayPosition;
        case lexemes.getType(position) of
        TranslatorLexer.SMULL: begin
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_SHORT:
                result := TranslatorLocalConstantInt.create(typeShort,
                        short(result.shortValue * second.shortValue));
            TranslatorType.KIND_INT:
                result := TranslatorLocalConstantInt.create(typeInt,
                        result.intValue * second.intValue);
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        long(result.longValue) * long(second.longValue));
            TranslatorType.KIND_FLOAT:
                result := TranslatorLocalConstantReal.create(typeFloat,
                        result.realValue * second.realValue);
            TranslatorType.KIND_DOUBLE:
                result := TranslatorLocalConstantReal.create(typeDouble,
                        result.realValue * second.realValue);
            TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantReal.create(typeReal,
                        result.realValue * second.realValue);
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.SDIVS: begin
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_SHORT: begin
                ival := second.shortValue;
                if ival = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantInt.create(typeShort,
                        short(result.shortValue div ival));
            end;
            TranslatorType.KIND_INT: begin
                ival := second.intValue;
                if ival = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantInt.create(typeInt,
                        result.intValue div ival);
            end;
            TranslatorType.KIND_LONG: begin
                lval := second.longValue;
                if lval = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantLong.create(typeLong,
                        long(result.longValue) div lval);
            end;
            TranslatorType.KIND_FLOAT:
                result := TranslatorLocalConstantReal.create(typeFloat,
                        result.realValue / second.realValue);
            TranslatorType.KIND_DOUBLE:
                result := TranslatorLocalConstantReal.create(typeDouble,
                        result.realValue / second.realValue);
            TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantReal.create(typeReal,
                        result.realValue / second.realValue);
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.SREMS: begin
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_SHORT: begin
                ival := second.shortValue;
                if ival = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantInt.create(typeShort,
                        short(result.shortValue mod ival));
            end;
            TranslatorType.KIND_INT: begin
                ival := second.intValue;
                if ival = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantInt.create(typeInt,
                        result.intValue mod ival);
            end;
            TranslatorType.KIND_LONG: begin
                lval := second.longValue;
                if lval = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantLong.create(typeLong,
                        long(result.longValue) mod lval);
            end;
            TranslatorType.KIND_FLOAT:
                result := TranslatorLocalConstantReal.create(typeFloat,
                        realMod(result.realValue, second.realValue));
            TranslatorType.KIND_DOUBLE:
                result := TranslatorLocalConstantReal.create(typeDouble,
                        realMod(result.realValue, second.realValue));
            TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantReal.create(typeReal,
                        realMod(result.realValue, second.realValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.SDIVU: begin
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_SHORT: begin
                ival := second.charValue;
                if ival = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantInt.create(typeShort,
                        short(result.charValue div ival));
            end;
            TranslatorType.KIND_INT: begin
                ival := second.intValue;
                if ival = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantInt.create(typeInt,
                        intUDiv(result.intValue, ival));
            end;
            TranslatorType.KIND_LONG: begin
                lval := second.longValue;
                if lval = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantLong.create(typeLong,
                        longUDiv(result.longValue, lval));
            end;
            TranslatorType.KIND_FLOAT:
                result := TranslatorLocalConstantReal.create(typeFloat,
                        result.realValue / second.realValue);
            TranslatorType.KIND_DOUBLE:
                result := TranslatorLocalConstantReal.create(typeDouble,
                        result.realValue / second.realValue);
            TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantReal.create(typeReal,
                        result.realValue / second.realValue);
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.SREMU: begin
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_SHORT: begin
                ival := second.charValue;
                if ival = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantInt.create(typeShort,
                        short(result.charValue mod ival));
            end;
            TranslatorType.KIND_INT: begin
                ival := second.intValue;
                if ival = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantInt.create(typeInt,
                        intUMod(result.intValue, ival));
            end;
            TranslatorType.KIND_LONG: begin
                lval := second.longValue;
                if lval = 0 then begin
                    raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
                end;
                result := TranslatorLocalConstantLong.create(typeLong,
                        longUMod(result.longValue, lval));
            end;
            TranslatorType.KIND_FLOAT:
                result := TranslatorLocalConstantReal.create(typeFloat,
                        realMod(result.realValue, second.realValue));
            TranslatorType.KIND_DOUBLE:
                result := TranslatorLocalConstantReal.create(typeDouble,
                        realMod(result.realValue, second.realValue));
            TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantReal.create(typeReal,
                        realMod(result.realValue, second.realValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QMULL: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxMulLo(result.longValue, second.longValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        sseiMulLo(result.getUltraValue(), second.getUltraValue()));
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantXVector.create(typeXVector,
                        ssefMul(result.getXVectorValue(), second.getXVectorValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QMULH: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxMulHi(result.longValue, second.longValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        sseiMulHi(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QMULHS: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxMulHiS(result.longValue, second.longValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QDIV: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantXVector.create(typeXVector,
                        ssefDiv(result.getXVectorValue(), second.getXVectorValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OMULL: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesMulLo(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OMULH: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesMulHi(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OMULHS: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstPref(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesMulHiS(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        else
            break;
        end;
    until false;
end;

function TranslatorNamespacesBuilder.parseConstAdd(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    second: GlobalConstant;
begin
    result := parseConstMult(where, lexemes, position);
    repeat
        position := stayPosition;
        case lexemes.getType(position) of
        TranslatorLexer.SPLUS: begin
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_SHORT:
                result := TranslatorLocalConstantInt.create(typeShort,
                        short(result.shortValue + second.shortValue));
            TranslatorType.KIND_INT:
                result := TranslatorLocalConstantInt.create(typeInt,
                        result.intValue + second.intValue);
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        result.longValue + second.longValue);
            TranslatorType.KIND_FLOAT:
                result := TranslatorLocalConstantReal.create(typeFloat,
                        result.realValue + second.realValue);
            TranslatorType.KIND_DOUBLE:
                result := TranslatorLocalConstantReal.create(typeDouble,
                        result.realValue + second.realValue);
            TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantReal.create(typeReal,
                        result.realValue + second.realValue);
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.SMINUS: begin
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_SHORT:
                result := TranslatorLocalConstantInt.create(typeShort,
                        short(result.shortValue - second.shortValue));
            TranslatorType.KIND_INT:
                result := TranslatorLocalConstantInt.create(typeInt,
                        result.intValue - second.intValue);
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        result.longValue - second.longValue);
            TranslatorType.KIND_FLOAT:
                result := TranslatorLocalConstantReal.create(typeFloat,
                        result.realValue - second.realValue);
            TranslatorType.KIND_DOUBLE:
                result := TranslatorLocalConstantReal.create(typeDouble,
                        result.realValue - second.realValue);
            TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantReal.create(typeReal,
                        result.realValue - second.realValue);
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QADD: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxAdd(result.longValue, second.longValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        sseiAdd(result.getUltraValue(), second.getUltraValue()));
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantXVector.create(typeXVector,
                        ssefAdd(result.getXVectorValue(), second.getXVectorValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QADDS: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxAddS(result.longValue, second.longValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QADDUS: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxAddUS(result.longValue, second.longValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QSUB: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxSub(result.longValue, second.longValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        sseiSub(result.getUltraValue(), second.getUltraValue()));
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantXVector.create(typeXVector,
                        ssefSub(result.getXVectorValue(), second.getXVectorValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QSUBS: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxSubS(result.longValue, second.longValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QSUBUS: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxSubUS(result.longValue, second.longValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OADD: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesAdd(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OADDS: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesAddS(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OADDUS: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesAddUS(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OSUB: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesSub(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OSUBS: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesSubS(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OSUBUS: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstMult(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesSubUS(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        else
            break;
        end;
    until false;
end;

function TranslatorNamespacesBuilder.parseConstShift(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    second: GlobalConstant;
begin
    result := parseConstAdd(where, lexemes, position);
    repeat
        position := stayPosition;
        case lexemes.getType(position) of
        TranslatorLexer.SSLL: begin
            second := parseConstAdd(where, lexemes, position + 1);
            if not possibleAssign(TranslatorType.KIND_INT, second) then begin
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
            case result.dataType.kind of
            TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
            TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
                if operandSize < TranslatorType.SIZE_32_BIT then begin
                    result := TranslatorLocalConstantInt.create(typeShort,
                            short(result.shortValue shl second.intValue));
                end else begin
                    result := TranslatorLocalConstantInt.create(typeInt,
                            result.intValue shl second.intValue);
                end;
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        long(result.longValue) shl second.intValue);
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.SSRA: begin
            second := parseConstAdd(where, lexemes, position + 1);
            if not possibleAssign(TranslatorType.KIND_INT, second) then begin
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
            case result.dataType.kind of
            TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
            TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
                if operandSize < TranslatorType.SIZE_32_BIT then begin
                    result := TranslatorLocalConstantInt.create(typeShort,
                            short(intSar(result.shortValue, second.intValue)));
                end else begin
                    result := TranslatorLocalConstantInt.create(typeInt,
                            intSar(result.intValue, second.intValue));
                end;
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        longSar(result.longValue, second.intValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.SSRL: begin
            second := parseConstAdd(where, lexemes, position + 1);
            if not possibleAssign(TranslatorType.KIND_INT, second) then begin
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
            case result.dataType.kind of
            TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
            TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
                if operandSize < TranslatorType.SIZE_32_BIT then begin
                    result := TranslatorLocalConstantInt.create(typeShort,
                            short((result.shortValue and $ffff) shr second.intValue));
                end else begin
                    result := TranslatorLocalConstantInt.create(typeInt,
                            result.intValue shr second.intValue);
                end;
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        long(result.longValue) shr second.intValue);
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QSLL: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstAdd(where, lexemes, position + 1);
            if not possibleAssign(TranslatorType.KIND_INT, second) then begin
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
            case result.dataType.kind of
            TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxShl(result.longValue, second.intValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        sseiShl(result.getUltraValue(), second.intValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QSRA: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstAdd(where, lexemes, position + 1);
            if not possibleAssign(TranslatorType.KIND_INT, second) then begin
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
            case result.dataType.kind of
            TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxSar(result.longValue, second.intValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        sseiSar(result.getUltraValue(), second.intValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QSRL: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstAdd(where, lexemes, position + 1);
            if not possibleAssign(TranslatorType.KIND_INT, second) then begin
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
            case result.dataType.kind of
            TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxShr(result.longValue, second.intValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        sseiShr(result.getUltraValue(), second.intValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OSLL: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstAdd(where, lexemes, position + 1);
            if not possibleAssign(TranslatorType.KIND_INT, second) then begin
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
            case result.dataType.kind of
            TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesShl(result.getUltraValue(), second.intValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OSRA: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstAdd(where, lexemes, position + 1);
            if not possibleAssign(TranslatorType.KIND_INT, second) then begin
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
            case result.dataType.kind of
            TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesSar(result.getUltraValue(), second.intValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OSRL: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstAdd(where, lexemes, position + 1);
            if not possibleAssign(TranslatorType.KIND_INT, second) then begin
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
            case result.dataType.kind of
            TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesShr(result.getUltraValue(), second.intValue));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        else
            break;
        end;
    until false;
end;

function TranslatorNamespacesBuilder.parseConstRel(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    second: GlobalConstant;
begin
    result := parseConstShift(where, lexemes, position);
    repeat
        position := stayPosition;
        case lexemes.getType(position) of
        TranslatorLexer.SGT: begin
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_SHORT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.shortValue > second.shortValue);
            TranslatorType.KIND_INT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.intValue > second.intValue);
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.longValue > second.longValue);
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        realCmpl(result.realValue, second.realValue) > 0);
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.SGE: begin
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_SHORT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.shortValue >= second.shortValue);
            TranslatorType.KIND_INT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.intValue >= second.intValue);
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.longValue >= second.longValue);
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        realCmpl(result.realValue, second.realValue) >= 0);
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.SLT: begin
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_SHORT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.shortValue < second.shortValue);
            TranslatorType.KIND_INT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.intValue < second.intValue);
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.longValue < second.longValue);
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        realCmpg(result.realValue, second.realValue) < 0);
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.SLE: begin
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_SHORT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.shortValue <= second.shortValue);
            TranslatorType.KIND_INT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.intValue <= second.intValue);
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.longValue <= second.longValue);
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        realCmpg(result.realValue, second.realValue) <= 0);
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QGT: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxGreate(result.longValue, second.longValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        sseiGreate(result.getUltraValue(), second.getUltraValue()));
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssefCmpg(result.getXVectorValue(), second.getXVectorValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QGE: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong, (-1) xor
                        mmxGreate(second.longValue, result.longValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
                        sseiGreate(second.getUltraValue(), result.getUltraValue()));
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssefCmpge(result.getXVectorValue(), second.getXVectorValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QLT: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxGreate(second.longValue, result.longValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        sseiGreate(second.getUltraValue(), result.getUltraValue()));
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssefCmpl(result.getXVectorValue(), second.getXVectorValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QLE: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong, (-1) xor
                        mmxGreate(result.longValue, second.longValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
                        sseiGreate(result.getUltraValue(), second.getUltraValue()));
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssefCmple(result.getXVectorValue(), second.getXVectorValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OGT: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesGreate(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OGE: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
                        ssesGreate(second.getUltraValue(), result.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OLT: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesGreate(second.getUltraValue(), result.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OLE: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstShift(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
                        ssesGreate(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        else
            break;
        end;
    until false;
end;

function TranslatorNamespacesBuilder.parseConstEqual(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    second: GlobalConstant;
begin
    result := parseConstRel(where, lexemes, position);
    repeat
        position := stayPosition;
        case lexemes.getType(position) of
        TranslatorLexer.SEQ: begin
            { a == b  ≡  @@..@@((a ==|| b) >>..>>> 8) == -1L }
            second := parseConstRel(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_BOOLEAN:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.booleanValue = second.booleanValue);
            TranslatorType.KIND_SHORT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.shortValue = second.shortValue);
            TranslatorType.KIND_INT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.intValue = second.intValue);
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.longValue = second.longValue);
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        ssesPack(ssesShr(sseiEquals(
                        result.getUltraValue(), second.getUltraValue()), $08)) = (-1));
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        realCmpl(result.realValue, second.realValue) = 0);
            TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        ssesPack(ssesShr(ssefCmpe(
                        result.getXVectorValue(), second.getXVectorValue()), $08)) = (-1));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.SNE: begin
            { a != b  ≡  @@..@@((a ==|| b) >>..>>> 8) != -1L }
            second := parseConstRel(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_BOOLEAN:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.booleanValue <> second.booleanValue);
            TranslatorType.KIND_SHORT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.shortValue <> second.shortValue);
            TranslatorType.KIND_INT:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.intValue <> second.intValue);
            TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        result.longValue <> second.longValue);
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        ssesPack(ssesShr(sseiEquals(
                        result.getUltraValue(), second.getUltraValue()), $08)) <> (-1));
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        realCmpl(result.realValue, second.realValue) <> 0);
            TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantInt.create(typeBoolean,
                        ssesPack(ssesShr(ssefCmpe(
                        result.getXVectorValue(), second.getXVectorValue()), $08)) <> (-1));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QEQ: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstRel(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong,
                        mmxEquals(result.longValue, second.longValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        sseiEquals(result.getUltraValue(), second.getUltraValue()));
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssefCmpe(result.getXVectorValue(), second.getXVectorValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.QNE: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstRel(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
                result := TranslatorLocalConstantLong.create(typeLong, (-1) xor
                        mmxEquals(result.longValue, second.longValue));
            TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
                        sseiEquals(result.getUltraValue(), second.getUltraValue()));
            TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssefCmpne(result.getXVectorValue(), second.getXVectorValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.OEQ: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstRel(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra,
                        ssesEquals(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        TranslatorLexer.ONE: begin
            if operandSize < TranslatorType.SIZE_64_BIT then begin
                raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
            end;
            second := parseConstRel(where, lexemes, position + 1);
            case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
            TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
                result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
                        ssesEquals(result.getUltraValue(), second.getUltraValue()));
            else
                raise CompileError.create(msgCannotApplyOperation, lexemes, position);
            end;
        end;
        else
            break;
        end;
    until false;
end;

function TranslatorNamespacesBuilder.parseConstBAnd(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    second: GlobalConstant;
begin
    result := parseConstEqual(where, lexemes, position);
    repeat
        position := stayPosition;
        if lexemes.getType(position) <> TranslatorLexer.SANDB then begin
            break;
        end;
        second := parseConstEqual(where, lexemes, position + 1);
        case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
        TranslatorType.KIND_BOOLEAN:
            {$BOOLEVAL ON}
            result := TranslatorLocalConstantInt.create(typeBoolean,
                    result.booleanValue and second.booleanValue);
            {$BOOLEVAL OFF}
        TranslatorType.KIND_SHORT:
            result := TranslatorLocalConstantInt.create(typeShort,
                    short(result.shortValue and second.shortValue));
        TranslatorType.KIND_INT:
            result := TranslatorLocalConstantInt.create(typeInt,
                    result.intValue and second.intValue);
        TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantLong.create(typeLong,
                    result.longValue and second.longValue);
        TranslatorType.KIND_ULTRA:
            result := TranslatorLocalConstantUltra.create(typeUltra,
                    result.getUltraValue() and second.getUltraValue());
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    until false;
end;

function TranslatorNamespacesBuilder.parseConstBXor(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    second: GlobalConstant;
begin
    result := parseConstBAnd(where, lexemes, position);
    repeat
        position := stayPosition;
        if lexemes.getType(position) <> TranslatorLexer.SXORB then begin
            break;
        end;
        second := parseConstBAnd(where, lexemes, position + 1);
        case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
        TranslatorType.KIND_BOOLEAN:
            {$BOOLEVAL ON}
            result := TranslatorLocalConstantInt.create(typeBoolean,
                    result.booleanValue xor second.booleanValue);
            {$BOOLEVAL OFF}
        TranslatorType.KIND_SHORT:
            result := TranslatorLocalConstantInt.create(typeShort,
                    short(result.shortValue xor second.shortValue));
        TranslatorType.KIND_INT:
            result := TranslatorLocalConstantInt.create(typeInt,
                    result.intValue xor second.intValue);
        TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantLong.create(typeLong,
                    result.longValue xor second.longValue);
        TranslatorType.KIND_ULTRA:
            result := TranslatorLocalConstantUltra.create(typeUltra,
                    result.getUltraValue() xor second.getUltraValue());
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    until false;
end;

function TranslatorNamespacesBuilder.parseConstBOr(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    second: GlobalConstant;
begin
    result := parseConstBXor(where, lexemes, position);
    repeat
        position := stayPosition;
        if lexemes.getType(position) <> TranslatorLexer.SORB then begin
            break;
        end;
        second := parseConstBXor(where, lexemes, position + 1);
        case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
        TranslatorType.KIND_BOOLEAN:
            {$BOOLEVAL ON}
            result := TranslatorLocalConstantInt.create(typeBoolean,
                    result.booleanValue or second.booleanValue);
            {$BOOLEVAL OFF}
        TranslatorType.KIND_SHORT:
            result := TranslatorLocalConstantInt.create(typeShort,
                    short(result.shortValue or second.shortValue));
        TranslatorType.KIND_INT:
            result := TranslatorLocalConstantInt.create(typeInt,
                    result.intValue or second.intValue);
        TranslatorType.KIND_LONG:
            result := TranslatorLocalConstantLong.create(typeLong,
                    result.longValue or second.longValue);
        TranslatorType.KIND_ULTRA:
            result := TranslatorLocalConstantUltra.create(typeUltra,
                    result.getUltraValue() or second.getUltraValue());
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    until false;
end;

function TranslatorNamespacesBuilder.parseConstLAnd(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    second: GlobalConstant;
begin
    result := parseConstBOr(where, lexemes, position);
    repeat
        position := stayPosition;
        if lexemes.getType(position) <> TranslatorLexer.SANDL then begin
            break;
        end;
        second := parseConstBOr(where, lexemes, position + 1);
        case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
        TranslatorType.KIND_BOOLEAN:
            {$BOOLEVAL ON}
            result := TranslatorLocalConstantInt.create(typeBoolean,
                    result.booleanValue and second.booleanValue);
            {$BOOLEVAL OFF}
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    until false;
end;

function TranslatorNamespacesBuilder.parseConstLOr(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    second: GlobalConstant;
begin
    result := parseConstLAnd(where, lexemes, position);
    repeat
        position := stayPosition;
        if lexemes.getType(position) <> TranslatorLexer.SORL then begin
            break;
        end;
        second := parseConstLAnd(where, lexemes, position + 1);
        case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
        TranslatorType.KIND_BOOLEAN:
            {$BOOLEVAL ON}
            result := TranslatorLocalConstantInt.create(typeBoolean,
                    result.booleanValue or second.booleanValue);
            {$BOOLEVAL OFF}
        else
            raise CompileError.create(msgCannotApplyOperation, lexemes, position);
        end;
    until false;
end;

function TranslatorNamespacesBuilder.parseConstCond(where: Namespace; lexemes: Lexer;
        position: int): GlobalConstant;
var
    vtrue: GlobalConstant;
    vfalse: GlobalConstant;
begin
    result := parseConstLOr(where, lexemes, position);
    position := stayPosition;
    if lexemes.getType(position) <> TranslatorLexer.QUESTION_MARK then begin
        exit;
    end;
    if result.dataType.kind <> TranslatorType.KIND_BOOLEAN then begin
        raise CompileError.create(msgTypeMustBeBoolean, lexemes, position);
    end;
    vtrue := parseConstCond(where, lexemes, position + 1);
    position := stayPosition;
    if lexemes.getType(position) <> TranslatorLexer.COLON then begin
        raise CompileError.create(msgExpectedColon, lexemes, position);
    end;
    vfalse := parseConstCond(where, lexemes, position + 1);
    case getCommonTypeKind(vtrue.dataType.kind, vfalse.dataType.kind) of
    TranslatorType.KIND_BOOLEAN:
        if result.booleanValue = true then begin
            result := vtrue;
        end else begin
            result := vfalse;
        end;
    TranslatorType.KIND_SHORT:
        if result.booleanValue = true then begin
            result := TranslatorLocalConstantInt.create(typeShort, vtrue.shortValue);
        end else begin
            result := TranslatorLocalConstantInt.create(typeShort, vfalse.shortValue);
        end;
    TranslatorType.KIND_INT:
        if result.booleanValue = true then begin
            result := TranslatorLocalConstantInt.create(typeInt, vtrue.intValue);
        end else begin
            result := TranslatorLocalConstantInt.create(typeInt, vfalse.intValue);
        end;
    TranslatorType.KIND_LONG:
        if result.booleanValue = true then begin
            result := TranslatorLocalConstantLong.create(typeLong, vtrue.longValue);
        end else begin
            result := TranslatorLocalConstantLong.create(typeLong, vfalse.longValue);
        end;
    TranslatorType.KIND_ULTRA:
        if result.booleanValue = true then begin
            result := TranslatorLocalConstantUltra.create(typeUltra, vtrue.getUltraValue());
        end else begin
            result := TranslatorLocalConstantUltra.create(typeUltra, vfalse.getUltraValue());
        end;
    TranslatorType.KIND_FLOAT:
        if result.booleanValue = true then begin
            result := TranslatorLocalConstantReal.create(typeFloat, vtrue.realValue);
        end else begin
            result := TranslatorLocalConstantReal.create(typeFloat, vfalse.realValue);
        end;
    TranslatorType.KIND_DOUBLE:
        if result.booleanValue = true then begin
            result := TranslatorLocalConstantReal.create(typeDouble, vtrue.realValue);
        end else begin
            result := TranslatorLocalConstantReal.create(typeDouble, vfalse.realValue);
        end;
    TranslatorType.KIND_REAL:
        if result.booleanValue = true then begin
            result := TranslatorLocalConstantReal.create(typeReal, vtrue.realValue);
        end else begin
            result := TranslatorLocalConstantReal.create(typeReal, vfalse.realValue);
        end;
    TranslatorType.KIND_XVECTOR:
        if result.booleanValue = true then begin
            result := TranslatorLocalConstantXVector.create(typeXVector, vtrue.getXVectorValue());
        end else begin
            result := TranslatorLocalConstantXVector.create(typeXVector, vfalse.getXVectorValue());
        end;
    else
        raise CompileError.create(msgCannotApplyOperation, lexemes, position);
    end;
end;

function TranslatorNamespacesBuilder.possibleAssign(dstTypeKind: int;
        constant: GlobalConstant): boolean;
var
    srcTypeKindIsLong: boolean;
    srcTypeKind: int;
    srcType: TypeDescriptor;
begin
    srcType := constant.dataType;
    srcTypeKind := srcType.kind;
    srcTypeKindIsLong :=
            (srcTypeKind = TranslatorType.KIND_CHAR) or
            (srcTypeKind = TranslatorType.KIND_BYTE) or
            (srcTypeKind = TranslatorType.KIND_SHORT) or
            (srcTypeKind = TranslatorType.KIND_INT) or
            (srcTypeKind = TranslatorType.KIND_LONG);
    case dstTypeKind of
    TranslatorType.KIND_BOOLEAN:
        result := srcType.possibleAssignTo(typeBoolean);
    TranslatorType.KIND_CHAR:
        result := srcTypeKindIsLong and typeChar.possibleAssignLong(constant.longValue);
    TranslatorType.KIND_BYTE:
        result := srcTypeKindIsLong and typeByte.possibleAssignLong(constant.longValue);
    TranslatorType.KIND_SHORT:
        result := srcTypeKindIsLong and typeShort.possibleAssignLong(constant.longValue);
    TranslatorType.KIND_INT:
        result := srcTypeKindIsLong and typeInt.possibleAssignLong(constant.longValue);
    TranslatorType.KIND_LONG:
        result := srcTypeKindIsLong and typeLong.possibleAssignLong(constant.longValue);
    TranslatorType.KIND_ULTRA:
        result := srcTypeKindIsLong and typeUltra.possibleAssignLong(constant.longValue) or
                srcType.possibleAssignTo(typeUltra);
    TranslatorType.KIND_FLOAT:
        result := srcTypeKindIsLong and typeFloat.possibleAssignLong(constant.longValue) or
                srcType.possibleAssignTo(typeFloat);
    TranslatorType.KIND_DOUBLE:
        result := srcTypeKindIsLong and typeDouble.possibleAssignLong(constant.longValue) or
                srcType.possibleAssignTo(typeDouble);
    TranslatorType.KIND_REAL:
        result := srcTypeKindIsLong and typeReal.possibleAssignLong(constant.longValue) or
                srcType.possibleAssignTo(typeReal);
    TranslatorType.KIND_XVECTOR:
        result := srcTypeKindIsLong and typeXVector.possibleAssignLong(constant.longValue) or
                srcType.possibleAssignTo(typeXVector);
    else
        result := false;
    end;
end;

function TranslatorNamespacesBuilder.skipCurlyBrackets(lexemes: Lexer; position: int): int;
var
    count: int;
begin
    count := 0;
    repeat
        case lexemes.getType(position) of
        TranslatorLexer.OPENED_CURLY_BRACKET: begin
            inc(count);
        end;
        TranslatorLexer.CLOSED_CURLY_BRACKET: begin
            dec(count);
            if count <= 0 then begin
                break;
            end;
        end;
        TranslatorLexer.NULL: begin
            dec(position);
            break;
        end;
        end;
        inc(position);
    until false;
    result := position + 1;
end;

function TranslatorNamespacesBuilder.skipParenthesis(lexemes: Lexer; position: int): int;
var
    count: int;
begin
    count := 0;
    repeat
        case lexemes.getType(position) of
        TranslatorLexer.OPENED_PARENTHESIS: begin
            inc(count);
        end;
        TranslatorLexer.CLOSED_PARENTHESIS: begin
            dec(count);
            if count <= 0 then begin
                break;
            end;
        end;
        TranslatorLexer.NULL: begin
            dec(position);
            break;
        end;
        end;
        inc(position);
    until false;
    result := position + 1;
end;

function TranslatorNamespacesBuilder.getCommonTypeKind(kind1, kind2: int): int;
begin
    case operandSize of
    TranslatorType.SIZE_16_BIT: begin
        {
Общие типы данных для двух операндов при 16-битной разрядности:
────────╥────────┬────────┬────────┬────────┬────────┬────────┐
 ↓1  2→ ║ char   │ byte   │ short  │ float  │ double │ real   │
════════╬════════╪════════╪════════╪════════╪════════╪════════╡
 char   ║ short  │ short  │ short  │ real   │ real   │ real   │
────────╫────────┼────────┼────────┼────────┼────────┼────────┤
 byte   ║ short  │ short  │ short  │ real   │ real   │ real   │
────────╫────────┼────────┼────────┼────────┼────────┼────────┤
 short  ║ short  │ short  │ short  │ real   │ real   │ real   │
────────╫────────┼────────┼────────┼────────┼────────┼────────┤
 float  ║ real   │ real   │ real   │ float  │ double │ real   │
────────╫────────┼────────┼────────┼────────┼────────┼────────┤
 double ║ real   │ real   │ real   │ double │ double │ real   │
────────╫────────┼────────┼────────┼────────┼────────┼────────┤
 real   ║ real   │ real   │ real   │ real   │ real   │ real   │
────────╨────────┴────────┴────────┴────────┴────────┴────────┘
        }
        case ((kind1 and $ffff) shl 16) + (kind2 and $ffff) of
        (TranslatorType.KIND_BOOLEAN shl 16) + TranslatorType.KIND_BOOLEAN:
            result := TranslatorType.KIND_BOOLEAN;
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_SHORT:
            result := TranslatorType.KIND_SHORT;
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_FLOAT:
            result := TranslatorType.KIND_FLOAT;
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_DOUBLE:
            result := TranslatorType.KIND_DOUBLE;
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_REAL:
            result := TranslatorType.KIND_REAL;
        else
            result := -1;
        end;
    end;
    TranslatorType.SIZE_32_BIT: begin
        {
Общие типы данных для двух операндов при 32-битной разрядности:
────────╥────────┬────────┬────────┬────────┬────────┬────────┬────────┐
 ↓1  2→ ║ char   │ byte   │ short  │ int    │ float  │ double │ real   │
════════╬════════╪════════╪════════╪════════╪════════╪════════╪════════╡
 char   ║ int    │ int    │ int    │ int    │ real   │ real   │ real   │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 byte   ║ int    │ int    │ int    │ int    │ real   │ real   │ real   │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 short  ║ int    │ int    │ int    │ int    │ real   │ real   │ real   │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 int    ║ int    │ int    │ int    │ int    │ real   │ real   │ real   │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 float  ║ real   │ real   │ real   │ real   │ float  │ double │ real   │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 double ║ real   │ real   │ real   │ real   │ double │ double │ real   │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 real   ║ real   │ real   │ real   │ real   │ real   │ real   │ real   │
────────╨────────┴────────┴────────┴────────┴────────┴────────┴────────┘
        }
        case ((kind1 and $ffff) shl 16) + (kind2 and $ffff) of
        (TranslatorType.KIND_BOOLEAN shl 16) + TranslatorType.KIND_BOOLEAN:
            result := TranslatorType.KIND_BOOLEAN;
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_INT:
            result := TranslatorType.KIND_INT;
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_FLOAT:
            result := TranslatorType.KIND_FLOAT;
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_DOUBLE:
            result := TranslatorType.KIND_DOUBLE;
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_REAL:
            result := TranslatorType.KIND_REAL;
        else
            result := -1;
        end;
    end;
    TranslatorType.SIZE_64_BIT: begin
        {
Общие типы данных для двух операндов при 64-битной разрядности:
────────╥────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
 ↓1  2→ ║ char   │ byte   │ short  │ int    │ long   │ ultra  │ float  │ double │ real   │ xvector│
════════╬════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╡
 char   ║ int    │ int    │ int    │ int    │ long   │ ultra  │ real   │ real   │ real   │        │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 byte   ║ int    │ int    │ int    │ int    │ long   │ ultra  │ real   │ real   │ real   │        │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 short  ║ int    │ int    │ int    │ int    │ long   │ ultra  │ real   │ real   │ real   │        │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 int    ║ int    │ int    │ int    │ int    │ long   │ ultra  │ real   │ real   │ real   │        │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 long   ║ long   │ long   │ long   │ long   │ long   │ ultra  │ real   │ real   │ real   │        │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 ultra  ║ ultra  │ ultra  │ ultra  │ ultra  │ ultra  │ ultra  │        │        │        │        │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 float  ║ real   │ real   │ real   │ real   │ real   │        │ float  │ double │ real   │ xvector│
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 double ║ real   │ real   │ real   │ real   │ real   │        │ double │ double │ real   │        │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 real   ║ real   │ real   │ real   │ real   │ real   │        │ real   │ real   │ real   │        │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
 xvector║        │        │        │        │        │        │ xvector│        │        │ xvector│
────────╨────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
Пустые ячейки означают несовместимость типов.
В случае обнаружения несовместимости типов (например, в выражении ((float) x) **** ((ultra) y) )
будет генерироваться ошибка компиляции.
        }
        case ((kind1 and $ffff) shl 16) + (kind2 and $ffff) of
        (TranslatorType.KIND_BOOLEAN shl 16) + TranslatorType.KIND_BOOLEAN:
            result := TranslatorType.KIND_BOOLEAN;
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_INT:
            result := TranslatorType.KIND_INT;
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_LONG,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_LONG,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_LONG,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_LONG,
        (TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_LONG:
            result := TranslatorType.KIND_LONG;
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_ULTRA,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_ULTRA,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_ULTRA,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_ULTRA,
        (TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_ULTRA,
        (TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_LONG,
        (TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_ULTRA:
            result := TranslatorType.KIND_ULTRA;
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_FLOAT:
            result := TranslatorType.KIND_FLOAT;
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_DOUBLE:
            result := TranslatorType.KIND_DOUBLE;
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_LONG,
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_LONG,
        (TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_REAL,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_CHAR,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_BYTE,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_SHORT,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_INT,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_LONG,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_DOUBLE,
        (TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_REAL:
            result := TranslatorType.KIND_REAL;
        (TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_XVECTOR,
        (TranslatorType.KIND_XVECTOR shl 16) + TranslatorType.KIND_FLOAT,
        (TranslatorType.KIND_XVECTOR shl 16) + TranslatorType.KIND_XVECTOR:
            result := TranslatorType.KIND_XVECTOR;
        else
            result := -1;
        end;
    end;
    else
        result := -1;
    end;
end;

function TranslatorNamespacesBuilder.castConstTo(newTypeKind: int;
        constant: GlobalConstant): GlobalConstant;
begin
    case newTypeKind of
    TranslatorType.KIND_BOOLEAN:
        result := TranslatorLocalConstantInt.create(typeBoolean, constant.booleanValue);
    TranslatorType.KIND_CHAR:
        result := TranslatorLocalConstantInt.create(typeChar, constant.charValue);
    TranslatorType.KIND_BYTE:
        result := TranslatorLocalConstantInt.create(typeByte, constant.byteValue);
    TranslatorType.KIND_SHORT:
        result := TranslatorLocalConstantInt.create(typeShort, constant.shortValue);
    TranslatorType.KIND_INT:
        result := TranslatorLocalConstantInt.create(typeInt, constant.intValue);
    TranslatorType.KIND_LONG:
        result := TranslatorLocalConstantLong.create(typeLong, constant.longValue);
    TranslatorType.KIND_ULTRA:
        result := TranslatorLocalConstantUltra.create(typeUltra, constant.getUltraValue());
    TranslatorType.KIND_FLOAT:
        result := TranslatorLocalConstantReal.create(typeFloat, constant.realValue);
    TranslatorType.KIND_DOUBLE:
        result := TranslatorLocalConstantReal.create(typeDouble, constant.realValue);
    TranslatorType.KIND_REAL:
        result := TranslatorLocalConstantReal.create(typeReal, constant.realValue);
    TranslatorType.KIND_XVECTOR:
        result := TranslatorLocalConstantXVector.create(typeXVector, constant.getXVectorValue());
    else
        result := nil;
    end;
end;

function TranslatorNamespacesBuilder.tryParseType(where: Namespace; position: int): TypeDescriptor;
var
    lexemes: Lexer;
    argType: TypeDescriptor;
    place: Namespace;
    entry: NamespaceEntry;
    ident: UnicodeString;
begin
    lexemes := where.lexemes;
    case lexemes.getType(position) of
    TranslatorLexer.KW_VOID: begin
        result := typeVoid;
    end;
    TranslatorLexer.KW_BOOLEAN: begin
        result := typeBoolean;
    end;
    TranslatorLexer.KW_CHAR: begin
        result := typeChar;
    end;
    TranslatorLexer.KW_BYTE: begin
        result := typeByte;
    end;
    TranslatorLexer.KW_SHORT: begin
        result := typeShort;
    end;
    TranslatorLexer.KW_INT: begin
        if operandSize < TranslatorType.SIZE_32_BIT then begin
            result := nil;
            exit;
        end;
        result := typeInt;
    end;
    TranslatorLexer.KW_LONG: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            result := nil;
            exit;
        end;
        result := typeLong;
    end;
    TranslatorLexer.KW_ULTRA: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            result := nil;
            exit;
        end;
        result := typeUltra;
    end;
    TranslatorLexer.KW_FLOAT: begin
        result := typeFloat;
    end;
    TranslatorLexer.KW_DOUBLE: begin
        result := typeDouble;
    end;
    TranslatorLexer.KW_REAL: begin
        result := typeReal;
    end;
    TranslatorLexer.KW_XVECTOR: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            result := nil;
            exit;
        end;
        result := typeXVector;
    end;
    TranslatorLexer.KW_YVECTOR, TranslatorLexer.KW_ULTRA32,
    TranslatorLexer.KW_ZVECTOR, TranslatorLexer.KW_ULTRA64,
    TranslatorLexer.KW_FVECTOR: begin
        result := nil;
        exit;
    end;
    TranslatorLexer.IDENTIFIER: begin
        ident := lexemes.getValueUString(position);
        entry := where.findEntry(ident, true);
        if entry = nil then begin
            place := findNamespace(ident);
            if place = nil then begin
                result := nil;
                exit;
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.PERIOD then begin
                result := nil;
                exit;
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
                result := nil;
                exit;
            end;
            ident := lexemes.getValueUString(position);
            entry := place.findEntry(ident, false);
            if not (entry is TypeDescriptor) or not where.isVisible(entry) then begin
                result := nil;
                exit;
            end;
            result := entry as TypeDescriptor;
        end else
        if entry is TypeDescriptor then begin
            result := entry as TypeDescriptor;
        end else begin
            result := nil;
            exit;
        end;
    end;
    else
        result := nil;
        exit;
    end;
    inc(position);
    repeat
        case lexemes.getType(position) of
        TranslatorLexer.OPENED_PARENTHESIS: begin
            if not result.isMatchForReturnType() then begin
                result := nil;
                exit;
            end;
            inc(position);
            result := TranslatorTypeFunction.create(operandSize, result);
            if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
                repeat
                    argType := tryParseType(where, position);
                    if argType = nil then begin
                        result := nil;
                        exit;
                    end;
                    position := stayPosition;
                    if not argType.isMatchForVariable() then begin
                        result := nil;
                        exit;
                    end;
                    (result as TypeFunction).addArgument(argType, '');
                    if lexemes.getType(position) <> TranslatorLexer.COMMA then begin
                        break;
                    end;
                    inc(position);
                until false;
                if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
                    result := nil;
                    exit;
                end;
            end;
            inc(position);
            result := getCanonicalType(result);
        end;
        TranslatorLexer.OPENED_SQUARE_BRACKET: begin
            if not result.isMatchForVariable() then begin
                result := nil;
                exit;
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.CLOSED_SQUARE_BRACKET then begin
                dec(position);
                break;
            end;
            inc(position);
            result := getCanonicalType(TranslatorTypeArray.create(operandSize, result));
        end;
        else
            break;
        end;
    until false;
    stayPosition := position;
end;

function TranslatorNamespacesBuilder.parseConst(where: Namespace; position: int): GlobalConstant;
begin
    result := parseConstCond(where, where.lexemes, position);
end;

function TranslatorNamespacesBuilder.parseType(where: Namespace; position: int): TypeDescriptor;
var
    lexemes: Lexer;
    argType: TypeDescriptor;
    place: Namespace;
    entry: NamespaceEntry;
    ident: UnicodeString;
begin
    lexemes := where.lexemes;
    case lexemes.getType(position) of
    TranslatorLexer.KW_VOID: begin
        result := typeVoid;
    end;
    TranslatorLexer.KW_BOOLEAN: begin
        result := typeBoolean;
    end;
    TranslatorLexer.KW_CHAR: begin
        result := typeChar;
    end;
    TranslatorLexer.KW_BYTE: begin
        result := typeByte;
    end;
    TranslatorLexer.KW_SHORT: begin
        result := typeShort;
    end;
    TranslatorLexer.KW_INT: begin
        if operandSize < TranslatorType.SIZE_32_BIT then begin
            raise CompileError.create(msgTypeNotSupported, lexemes, position);
        end;
        result := typeInt;
    end;
    TranslatorLexer.KW_LONG: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgTypeNotSupported, lexemes, position);
        end;
        result := typeLong;
    end;
    TranslatorLexer.KW_ULTRA: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgTypeNotSupported, lexemes, position);
        end;
        result := typeUltra;
    end;
    TranslatorLexer.KW_FLOAT: begin
        result := typeFloat;
    end;
    TranslatorLexer.KW_DOUBLE: begin
        result := typeDouble;
    end;
    TranslatorLexer.KW_REAL: begin
        result := typeReal;
    end;
    TranslatorLexer.KW_XVECTOR: begin
        if operandSize < TranslatorType.SIZE_64_BIT then begin
            raise CompileError.create(msgTypeNotSupported, lexemes, position);
        end;
        result := typeXVector;
    end;
    TranslatorLexer.KW_YVECTOR, TranslatorLexer.KW_ULTRA32,
    TranslatorLexer.KW_ZVECTOR, TranslatorLexer.KW_ULTRA64,
    TranslatorLexer.KW_FVECTOR: begin
        raise CompileError.create(msgTypeReserved, lexemes, position);
    end;
    TranslatorLexer.IDENTIFIER: begin
        ident := lexemes.getValueUString(position);
        entry := where.findEntry(ident, true);
        if entry = nil then begin
            place := findNamespace(ident);
            if place = nil then begin
                raise CompileError.create(msgExpectedDataType, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.PERIOD then begin
                raise CompileError.create(msgExpectedPeriod, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
                raise CompileError.create(msgExpectedIdentifierOfDataType, lexemes, position);
            end;
            ident := lexemes.getValueUString(position);
            entry := place.findEntry(ident, false);
            if not (entry is TypeDescriptor) or not where.isVisible(entry) then begin
                raise CompileError.create(msgExpectedIdentifierOfDataType, lexemes, position);
            end;
            result := entry as TypeDescriptor;
        end else
        if entry is TypeDescriptor then begin
            result := entry as TypeDescriptor;
        end else begin
            raise CompileError.create(msgExpectedIdentifierOfDataType, lexemes, position);
        end;
    end;
    else
        raise CompileError.create(msgExpectedDataType, lexemes, position);
    end;
    inc(position);
    repeat
        case lexemes.getType(position) of
        TranslatorLexer.OPENED_PARENTHESIS: begin
            if not result.isMatchForReturnType() then begin
                raise CompileError.create(msgTypeNotApplicableToFunc, lexemes, position);
            end;
            inc(position);
            result := TranslatorTypeFunction.create(operandSize, result);
            if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
                repeat
                    argType := parseType(where, position);
                    position := stayPosition;
                    if not argType.isMatchForVariable() then begin
                        raise CompileError.create(msgTypeNotApplicableToVar, lexemes, position);
                    end;
                    (result as TypeFunction).addArgument(argType, '');
                    if lexemes.getType(position) <> TranslatorLexer.COMMA then begin
                        break;
                    end;
                    inc(position);
                until false;
                if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
                    raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
                end;
            end;
            inc(position);
            result := getCanonicalType(result);
        end;
        TranslatorLexer.OPENED_SQUARE_BRACKET: begin
            if not result.isMatchForVariable() then begin
                raise CompileError.create(msgTypeNotApplicableToVar, lexemes, position);
            end;
            inc(position);
            if lexemes.getType(position) <> TranslatorLexer.CLOSED_SQUARE_BRACKET then begin
                raise CompileError.create(msgExpectedClosedSquareBracket, lexemes, position);
            end;
            inc(position);
            result := getCanonicalType(TranslatorTypeArray.create(operandSize, result));
        end;
        else
            break;
        end;
    until false;
    stayPosition := position;
end;

function TranslatorNamespacesBuilder.getCanonicalType(theType: TypeDescriptor): TypeDescriptor;
var
    i: int;
    c: int;
    current: TypeDescriptor;
    typeAsObject: TObject;
    types: TypeDescriptor_Array1d;
    newtypes: TypeDescriptor_Array1d;
begin
    c := self.typesCount;
    types := self.types;
    typeAsObject := theType as TObject;
    for i := c - 1 downto 0 do begin
        current := types[i];
        if current.equals(typeAsObject) then begin
            result := current;
            exit;
        end;
    end;
    if length(types) = c then begin
        newtypes := TypeDescriptor_Array1d(Interface_Array1d_create((c shl 1) + 1));
        arraycopyInterfaces(types, 0, newtypes, 0, c);
        self.types := newtypes;
        types := newtypes;
    end;
    self.typesCount := c + 1;
    types[c] := theType;
    result := theType;
end;

{ TranslatorLocalConstantInt }

constructor TranslatorLocalConstantInt.create(constType: TypeDescriptor;
        const constValue: boolean);
begin
    inherited create(nil, false, '', constType, int(constValue));
end;

constructor TranslatorLocalConstantInt.create(constType: TypeDescriptor;
        const constValue: int);
begin
    inherited create(nil, false, '', constType, constValue);
end;

{ TranslatorLocalConstantLong }

constructor TranslatorLocalConstantLong.create(constType: TypeDescriptor;
        const constValue: int64);
begin
    inherited create(nil, false, '', constType, constValue);
end;

{ TranslatorLocalConstantReal }

constructor TranslatorLocalConstantReal.create(constType: TypeDescriptor;
        const constValue: real);
begin
    inherited create(nil, false, '', constType, constValue);
end;

{ TranslatorLocalConstantUltra }

constructor TranslatorLocalConstantUltra.create(constType: TypeDescriptor;
        const constValue: ultra);
begin
    inherited create(nil, false, '', constType, constValue);
end;

{ TranslatorLocalConstantXVector }

constructor TranslatorLocalConstantXVector.create(constType: TypeDescriptor;
        const constValue: xvector);
begin
    inherited create(nil, false, '', constType, constValue);
end;

end.