ru.malik.elaborarer.avtoo.avtc.pas

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

{
    Компилятор языка программирования
    Объектно-ориентированный продвинутый векторный транслятор

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

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

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

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

unit ru.malik.elaborarer.avtoo.avtc;

    {$MODE OBJFPC}

interface

    {%region} uses
        pascalx.lang,
        pascalx.lang.math.avo,
        pascalx.io,
        platform.independent.filesystem,
        platform.independent.osservices,
        ru.malik.elaborarer.avtoo.lang;
    {%endregion}

    {$TYPEINFO ON}
    {$CALLING REGISTER}

    const UNIT_NAME = 'ru.malik.elaborarer.avtoo.avtc';

    {%region} type
        PrintThread        = class;
        PrintCodeThread    = class;
        PrintLexemesThread = class;

        PrintThread = class(Thread)
        strict private
            fldTerminated: boolean;
            fldMonitor: Monitor;
        protected
            fldFileName: UnicodeString;
            fldFileSystem: FileSystem;
            procedure terminate();
        public
            constructor create(monitor: Monitor; fileSystem: FileSystem; const fileName: UnicodeString);
            function isTerminated(): boolean;
        end;

        PrintCodeThread = class(PrintThread)
        strict private
            class procedure print(fileSystem: FileSystem; const fileName: UnicodeString; programme: Programme); static;
            class function attributesToString(item: ReflectItem): AnsiString; static;
            class function namesToString(item: ReflectItem): AnsiString; static;
            class function supertypesToString(__type: ClassType): AnsiString; static;
        strict private
            fldProgramme: Programme;
        public
            constructor create(monitor: Monitor; fileSystem: FileSystem; const fileName: UnicodeString; programme: Programme);
            procedure run(); override;
        end;

        PrintLexemesThread = class(PrintThread)
        strict private
            class procedure print(fileSystem: FileSystem; const fileName: UnicodeString; project: &Library); static;
            class procedure printDocumentLexemes(sequence: LexemeSequence; printer: PrintStream); static;
            class procedure printLanguageLexemes(sequence: LexemeSequence; printer: PrintStream); static;
        strict private
            fldProject: &Library;
        public
            constructor create(monitor: Monitor; fileSystem: FileSystem; const fileName: UnicodeString; project: &Library);
            procedure run(); override;
        end;
    {endregion}

implementation

    {$TYPEINFO OFF}
    {$CALLING REGISTER}

    {%region  PrintThread }
        procedure PrintThread.terminate();
        begin
            with fldMonitor do begin
                beginSynchronized();
                try
                    if not fldTerminated then begin
                        fldTerminated := true;
                        notify();
                    end;
                finally
                    endSynchronized();
                end;
            end;
        end;

        constructor PrintThread.create(monitor: Monitor; fileSystem: FileSystem; const fileName: UnicodeString);
        begin
            inherited create();
            if fileSystem = nil then fileSystem := FileSystemRoot.get(Process.current().workingDirectory).fileSystem;
            fldMonitor := monitor;
            fldFileName := fileName;
            fldFileSystem := fileSystem;
        end;

        function PrintThread.isTerminated(): boolean;
        begin
            result := fldTerminated;
        end;
    {%endregion}

    {%region  PrintCodeThread }
        class procedure PrintCodeThread.print(fileSystem: FileSystem; const fileName: UnicodeString; programme: Programme);
        label
            break_label0;
        var
            order: int;
            cindex: int;
            eindex: int;
            jindex: int;
            lindex: int;
            mindex: int;
            pindex: int;
            tindex: int;
            jlength: int;
            __debug: int;
            __label: int;
            instruction: int;
            location: int2;
            message: AnsiString;
            debugBuilder: AnsiString;
            typeAsString: AnsiString;
            instructionAsString: AnsiString;
            root: Node;
            target: Node;
            __node: Node;
            __code: Code;
            read: Method;
            write: Method;
            index: Method;
            __type: &Type;
            stored: Method;
            typeRef: &Type;
            svalue: Constant;
            __member: Member;
            __value: Constant;
            operand: TableItem;
            reference: TObject;
            __package: Package;
            __library: &Library;
            smember: TypedMember;
            libraries: LibraryArray;
            debugOutput: PrintStream;
            __class: ru.malik.elaborarer.avtoo.lang.ClassType;
        begin
            debugOutput := PrintStream.create(fileSystem.rewriteFile(fileName));
            try
                debugBuilder := '';
                libraries := programme.libraries;
                for lindex := 0 to libraries.getLength() - 1 do begin
                    __library := libraries.readComponent(lindex);
                    debugOutput.println(__library.specialSimpleName);
                    for pindex := 0 to __library.getLength() - 1 do begin
                        __package := __library.readComponent(pindex);
                        debugOutput.println(#$09 + attributesToString(__package) + namesToString(__package));
                        for tindex := 0 to __package.getLength() - 1 do begin
                            __type := __package.readComponent(tindex);
                            if __type is ru.malik.elaborarer.avtoo.lang.ClassType then begin
                                debugOutput.println(#$09#$09 + attributesToString(__type) + supertypesToString(ru.malik.elaborarer.avtoo.lang.ClassType(__type)) + namesToString(__type));
                            end else begin
                                debugOutput.println(#$09#$09 + attributesToString(__type) + namesToString(__type));
                                continue;
                            end;
                            __class := ru.malik.elaborarer.avtoo.lang.ClassType(__type);
                            for mindex := 0 to __class.getLength() - 1 do begin
                                __member := __class.readComponent(mindex);
                                root := nil;
                                debugBuilder := #$09#$09#$09 + attributesToString(__member);
                                if __member is Callable then with Callable(__member) do begin
                                    debugBuilder := debugBuilder + arguments.toFullString();
                                    if __member is Method then with Method(__member) do for eindex := 0 to getThrowablesLength() - 1 do begin
                                        if eindex < 1 then begin
                                            message := ' throws ';
                                        end else begin
                                            message := ', ';
                                        end;
                                        debugBuilder := debugBuilder + message + getThrowableTypeAt(eindex).specialCanonicalName;
                                    end;
                                    __code := code;
                                    if __code <> nil then root := __code.root;
                                end else
                                if __member is Field then with Field(__member) do begin
                                    __value := value;
                                    if __value <> nil then begin
                                        debugBuilder := debugBuilder + ' = ' + __value.toString();
                                    end;
                                end else
                                if __member is &Property then with &Property(__member) do begin
                                    index := indexSynthetic;
                                    read := readSynthetic;
                                    write := writeSynthetic;
                                    stored := storedSynthetic;
                                    debugBuilder := debugBuilder + ' { ';
                                    if index <> nil then begin
                                        smember := indexMember;
                                        svalue := indexConstant;
                                        if smember <> nil then begin
                                            message := smember.specialSimpleName;
                                        end else
                                        if svalue = nil then begin
                                            message := index.specialSimpleName;
                                        end else begin
                                            message := svalue.toString();
                                        end;
                                        debugBuilder := debugBuilder + 'index = ' + message + ', ';
                                    end;
                                    if read = nil then begin
                                        smember := writeMember;
                                        if smember <> nil then begin
                                            message := smember.specialSimpleName;
                                        end else begin
                                            message := write.specialSimpleName;
                                        end;
                                        debugBuilder := debugBuilder + 'write = ' + message;
                                    end else
                                    if write = nil then begin
                                        smember := readMember;
                                        svalue := readConstant;
                                        if smember <> nil then begin
                                            message := smember.specialSimpleName;
                                        end else
                                        if svalue = nil then begin
                                            message := read.specialSimpleName;
                                        end else begin
                                            message := svalue.toString();
                                        end;
                                        debugBuilder := debugBuilder + 'read = ' + message;
                                    end else begin
                                        smember := readMember;
                                        svalue := readConstant;
                                        if smember <> nil then begin
                                            message := smember.specialSimpleName;
                                        end else
                                        if svalue = nil then begin
                                            message := read.specialSimpleName;
                                        end else begin
                                            message := svalue.toString();
                                        end;
                                        debugBuilder := debugBuilder + 'read = ' + message + ', ';
                                        smember := writeMember;
                                        if smember <> nil then begin
                                            message := smember.specialSimpleName;
                                        end else begin
                                            message := write.specialSimpleName;
                                        end;
                                        debugBuilder := debugBuilder + 'write = ' + message;
                                    end;
                                    if stored <> nil then begin
                                        smember := storedMember;
                                        svalue := storedConstant;
                                        if smember <> nil then begin
                                            message := smember.specialSimpleName;
                                        end else
                                        if svalue = nil then begin
                                            message := stored.specialSimpleName;
                                        end else begin
                                            message := svalue.toString();
                                        end;
                                        debugBuilder := debugBuilder + ', stored = ' + message;
                                    end;
                                    debugBuilder := debugBuilder + ' }';
                                end;
                                debugOutput.println(debugBuilder + namesToString(__member));
                                if root <> nil then for cindex := 0 to __code.getLength() - 1 do begin
                                    __node := __code.readComponent(cindex);
                                    instruction := __node.instruction;
                                    typeRef := __node.&type;
                                    if typeRef = nil then begin
                                        typeAsString := '-';
                                    end else begin
                                        typeAsString := typeRef.toString();
                                    end;
                                    case instruction of
                                    AVTOOConstants.DCL_CLASS          : instructionAsString := 'CLASS';
                                    AVTOOConstants.EXP_INSTANCEOF     : instructionAsString := 'INSTANCEOF';
                                    AVTOOConstants.FCT_IF             : instructionAsString := 'IF';
                                    AVTOOConstants.FCT_SWITCH         : instructionAsString := 'SWITCH';
                                    AVTOOConstants.FCT_BRANCH         : instructionAsString := 'BRANCH';
                                    AVTOOConstants.FCT_CASE           : instructionAsString := 'CASE';
                                    AVTOOConstants.FCT_DEFAULT        : instructionAsString := 'DEFAULT';
                                    AVTOOConstants.FCT_LABEL          : instructionAsString := 'LABEL';
                                    AVTOOConstants.FCT_DO             : instructionAsString := 'DO';
                                    AVTOOConstants.FCT_FOR            : instructionAsString := 'FOR';
                                    AVTOOConstants.FCT_WHILE          : instructionAsString := 'WHILE';
                                    AVTOOConstants.FCT_BLOCK          : instructionAsString := 'BLOCK';
                                    AVTOOConstants.FCT_JUMP           : instructionAsString := 'JUMP';
                                    AVTOOConstants.FCT_BREAK          : instructionAsString := 'BREAK';
                                    AVTOOConstants.FCT_CONTINUE       : instructionAsString := 'CONTINUE';
                                    AVTOOConstants.FCT_RETURN         : instructionAsString := 'RETURN';
                                    AVTOOConstants.FCT_THROW          : instructionAsString := 'THROW';
                                    AVTOOConstants.FCT_BOUND          : instructionAsString := 'BOUND';
                                    AVTOOConstants.FCT_BEGIN          : instructionAsString := 'BEGIN';
                                    AVTOOConstants.FCT_END            : instructionAsString := 'END';
                                    AVTOOConstants.FCT_TRY            : instructionAsString := 'TRY';
                                    AVTOOConstants.FCT_CATCH          : instructionAsString := 'CATCH';
                                    AVTOOConstants.INVOKE_FINALLY     : instructionAsString := 'INVOKE_FINALLY';
                                    AVTOOConstants.CLINIT_TRY_LOCK    : instructionAsString := 'CLINIT_TRY_LOCK';
                                    AVTOOConstants.CLINIT_UNLOCK      : instructionAsString := 'CLINIT_UNLOCK';
                                    AVTOOConstants.FINALLY_ENTER      : instructionAsString := 'FINALLY_ENTER';
                                    AVTOOConstants.FINALLY_LEAVE      : instructionAsString := 'FINALLY_LEAVE';
                                    AVTOOConstants.MONITOR_ENTER      : instructionAsString := 'MONITOR_ENTER';
                                    AVTOOConstants.MONITOR_LEAVE      : instructionAsString := 'MONITOR_LEAVE';
                                    AVTOOConstants.METHOD_ENTER       : instructionAsString := 'METHOD_ENTER';
                                    AVTOOConstants.METHOD_LEAVE       : instructionAsString := 'METHOD_LEAVE';
                                    AVTOOConstants.LOAD_CONST         : instructionAsString := 'LOAD_CONST';
                                    AVTOOConstants.LOAD_LOCAL         : instructionAsString := 'LOAD_LOCAL';
                                    AVTOOConstants.LOAD_INTERRUPT     : instructionAsString := 'LOAD_INTERRUPT';
                                    AVTOOConstants.LOAD_STATIC        : instructionAsString := 'LOAD_STATIC';
                                    AVTOOConstants.READ_ELEMENT       : instructionAsString := 'READ_ELEMENT';
                                    AVTOOConstants.READ_COMPONENT     : instructionAsString := 'READ_COMPONENT';
                                    AVTOOConstants.READ_FIELD         : instructionAsString := 'READ_FIELD';
                                    AVTOOConstants.READ_SPECIAL       : instructionAsString := 'READ_SPECIAL';
                                    AVTOOConstants.READ_PROPERTY      : instructionAsString := 'READ_PROPERTY';
                                    AVTOOConstants.SWAP               : instructionAsString := 'SWAP';
                                    AVTOOConstants.DUP1               : instructionAsString := 'DUP1';
                                    AVTOOConstants.DUP1X1             : instructionAsString := 'DUP1X1';
                                    AVTOOConstants.DUP1X2             : instructionAsString := 'DUP1X2';
                                    AVTOOConstants.DUP2               : instructionAsString := 'DUP2';
                                    AVTOOConstants.INVOKE_STATIC      : instructionAsString := 'INVOKE_STATIC';
                                    AVTOOConstants.INVOKE_SPECIAL     : instructionAsString := 'INVOKE_SPECIAL';
                                    AVTOOConstants.INVOKE_VIRTUAL     : instructionAsString := 'INVOKE_VIRTUAL';
                                    AVTOOConstants.INVOKE_SERVICE     : instructionAsString := 'INVOKE_SERVICE';
                                    AVTOOConstants.NEW_VECTOR         : instructionAsString := 'NEW_VECTOR';
                                    AVTOOConstants.NEW_ARRAY          : instructionAsString := 'NEW_ARRAY';
                                    AVTOOConstants.NEW_ARRAY_MONO     : instructionAsString := 'NEW_ARRAY_MONO';
                                    AVTOOConstants.NEW_ARRAY_MULTI    : instructionAsString := 'NEW_ARRAY_MULTI';
                                    AVTOOConstants.NEW_INSTANCE       : instructionAsString := 'NEW_INSTANCE';
                                    AVTOOConstants.CAST_TO            : instructionAsString := 'CAST_TO';
                                    AVTOOConstants.INC_LOCAL          : instructionAsString := 'INC_LOCAL';
                                    AVTOOConstants.DEC_LOCAL          : instructionAsString := 'DEC_LOCAL';
                                    AVTOOConstants.INC_PRED_LOAD_LOCAL: instructionAsString := 'INC_PRED_LOAD_LOCAL';
                                    AVTOOConstants.DEC_PRED_LOAD_LOCAL: instructionAsString := 'DEC_PRED_LOAD_LOCAL';
                                    AVTOOConstants.INC_POST_LOAD_LOCAL: instructionAsString := 'INC_POST_LOAD_LOCAL';
                                    AVTOOConstants.DEC_POST_LOAD_LOCAL: instructionAsString := 'DEC_POST_LOAD_LOCAL';
                                    AVTOOConstants.BOOL_NOT           : instructionAsString := 'BOOL_NOT';
                                    AVTOOConstants.BOOL_AND           : instructionAsString := 'BOOL_AND';
                                    AVTOOConstants.BOOL_OR            : instructionAsString := 'BOOL_OR';
                                    AVTOOConstants.BOOL_COND          : instructionAsString := 'BOOL_COND';
                                    AVTOOConstants.REF_EQ             : instructionAsString := 'REF_EQ';
                                    AVTOOConstants.REF_NE             : instructionAsString := 'REF_NE';
                                    AVTOOConstants.REF_IS_NULL        : instructionAsString := 'REF_IS_NULL';
                                    AVTOOConstants.REF_IS_OBJECT      : instructionAsString := 'REF_IS_OBJECT';
                                    AVTOOConstants.TEST_EQZ           : instructionAsString := 'TEST_EQZ';
                                    AVTOOConstants.TEST_NEZ           : instructionAsString := 'TEST_NEZ';
                                    AVTOOConstants.O_BIT_NOT          : instructionAsString := 'O_BIT_NOT';
                                    AVTOOConstants.O_BIT_AND          : instructionAsString := 'O_BIT_AND';
                                    AVTOOConstants.O_BIT_OR           : instructionAsString := 'O_BIT_OR';
                                    AVTOOConstants.O_BIT_XOR          : instructionAsString := 'O_BIT_XOR';
                                    AVTOOConstants.O_SCAL_NEG         : instructionAsString := 'O_SCAL_NEG';
                                    AVTOOConstants.O_SCAL_MUL         : instructionAsString := 'O_SCAL_MUL';
                                    AVTOOConstants.O_SCAL_DIV         : instructionAsString := 'O_SCAL_DIV';
                                    AVTOOConstants.O_SCAL_DIVU        : instructionAsString := 'O_SCAL_DIVU';
                                    AVTOOConstants.O_SCAL_REM         : instructionAsString := 'O_SCAL_REM';
                                    AVTOOConstants.O_SCAL_REMU        : instructionAsString := 'O_SCAL_REMU';
                                    AVTOOConstants.O_SCAL_ADD         : instructionAsString := 'O_SCAL_ADD';
                                    AVTOOConstants.O_SCAL_SUB         : instructionAsString := 'O_SCAL_SUB';
                                    AVTOOConstants.O_SCAL_SHR         : instructionAsString := 'O_SCAL_SHR';
                                    AVTOOConstants.O_SCAL_SHRU        : instructionAsString := 'O_SCAL_SHRU';
                                    AVTOOConstants.O_SCAL_SHL         : instructionAsString := 'O_SCAL_SHL';
                                    AVTOOConstants.O_SCAL_GT          : instructionAsString := 'O_SCAL_GT';
                                    AVTOOConstants.O_SCAL_GE          : instructionAsString := 'O_SCAL_GE';
                                    AVTOOConstants.O_SCAL_LT          : instructionAsString := 'O_SCAL_LT';
                                    AVTOOConstants.O_SCAL_LE          : instructionAsString := 'O_SCAL_LE';
                                    AVTOOConstants.O_SCAL_EQ          : instructionAsString := 'O_SCAL_EQ';
                                    AVTOOConstants.O_SCAL_NE          : instructionAsString := 'O_SCAL_NE';
                                    AVTOOConstants.O_VECT_LUP         : instructionAsString := 'O_VECT_LUP';
                                    AVTOOConstants.O_VECT_UUP         : instructionAsString := 'O_VECT_UUP';
                                    AVTOOConstants.O_VECT_PCK         : instructionAsString := 'O_VECT_PCK';
                                    AVTOOConstants.O_VECT_NEG         : instructionAsString := 'O_VECT_NEG';
                                    AVTOOConstants.O_VECT_MUL         : instructionAsString := 'O_VECT_MUL';
                                    AVTOOConstants.O_VECT_DIV         : instructionAsString := 'O_VECT_DIV';
                                    AVTOOConstants.O_VECT_ADD         : instructionAsString := 'O_VECT_ADD';
                                    AVTOOConstants.O_VECT_SUB         : instructionAsString := 'O_VECT_SUB';
                                    AVTOOConstants.O_VECT_SHR         : instructionAsString := 'O_VECT_SHR';
                                    AVTOOConstants.O_VECT_SHRU        : instructionAsString := 'O_VECT_SHRU';
                                    AVTOOConstants.O_VECT_SHL         : instructionAsString := 'O_VECT_SHL';
                                    AVTOOConstants.O_VECT_GT          : instructionAsString := 'O_VECT_GT';
                                    AVTOOConstants.O_VECT_GE          : instructionAsString := 'O_VECT_GE';
                                    AVTOOConstants.O_VECT_LT          : instructionAsString := 'O_VECT_LT';
                                    AVTOOConstants.O_VECT_LE          : instructionAsString := 'O_VECT_LE';
                                    AVTOOConstants.O_VECT_EQ          : instructionAsString := 'O_VECT_EQ';
                                    AVTOOConstants.O_VECT_NE          : instructionAsString := 'O_VECT_NE';
                                    AVTOOConstants.O_VECT_HMUL        : instructionAsString := 'O_VECT_HMUL';
                                    AVTOOConstants.O_VECT_HMULU       : instructionAsString := 'O_VECT_HMULU';
                                    AVTOOConstants.O_VECT_SADD        : instructionAsString := 'O_VECT_SADD';
                                    AVTOOConstants.O_VECT_SADDU       : instructionAsString := 'O_VECT_SADDU';
                                    AVTOOConstants.O_VECT_SSUB        : instructionAsString := 'O_VECT_SSUB';
                                    AVTOOConstants.O_VECT_SSUBU       : instructionAsString := 'O_VECT_SSUBU';
                                    AVTOOConstants.STORE_LOCAL        : instructionAsString := 'STORE_LOCAL';
                                    AVTOOConstants.DECLARE_WITH       : instructionAsString := 'DECLARE_WITH';
                                    AVTOOConstants.DECLARE_LOCAL      : instructionAsString := 'DECLARE_LOCAL';
                                    AVTOOConstants.STORE_STATIC       : instructionAsString := 'STORE_STATIC';
                                    AVTOOConstants.WRITE_COMPONENT    : instructionAsString := 'WRITE_COMPONENT';
                                    AVTOOConstants.WRITE_FIELD        : instructionAsString := 'WRITE_FIELD';
                                    AVTOOConstants.WRITE_SPECIAL      : instructionAsString := 'WRITE_SPECIAL';
                                    AVTOOConstants.WRITE_PROPERTY     : instructionAsString := 'WRITE_PROPERTY';
                                    AVTOOConstants.EXCEPT_ENTER       : instructionAsString := 'EXCEPT_ENTER';
                                    AVTOOConstants.EXCEPT_TRY         : instructionAsString := 'EXCEPT_TRY';
                                    AVTOOConstants.EXCEPT_CATCH       : instructionAsString := 'EXCEPT_CATCH';
                                    AVTOOConstants.EXCEPT_FINALLY     : instructionAsString := 'EXCEPT_FINALLY';
                                    AVTOOConstants.EXCEPT_LEAVE       : instructionAsString := 'EXCEPT_LEAVE';
                                    else                                instructionAsString := '<UNKNOWN>';
                                    end;
                                    if __node.weak then instructionAsString := '(w)' + instructionAsString;
                                    order := __node.order;
                                    location := __node.location + Vector.newByte2(1, 1);
                                    debugBuilder := #$09#$09#$09#$09'0x' + CoLong.toHexString(long(__node));
                                    if order >= 0 then begin
                                        __debug := __node.debugIndex;
                                        __label := __node.labelIndex;
                                        debugBuilder := debugBuilder + '(' + CoInt.toString(order);
                                        if __debug >= 0 then begin
                                            debugBuilder := debugBuilder + ', D.' + CoInt.toString(__debug);
                                        end else
                                        if __label >= 0 then begin
                                            debugBuilder := debugBuilder + ', L.' + CoInt.toString(__label);
                                        end;
                                        debugBuilder := debugBuilder + ')';
                                    end;
                                    debugBuilder := debugBuilder + AnsiString.format('[%0:5%:%1:3%] %2% %3%', [
                                        CoAnsiString.create(CoInt.toString(location[0])), CoAnsiString.create(CoInt.toString(location[1])),
                                        CoAnsiString.create(typeAsString), CoAnsiString.create(instructionAsString)
                                    ]);
                                    begin
                                        operand := __node.operand1;
                                        if operand <> nil then begin
                                            debugBuilder := debugBuilder + '(';
                                            if ((instruction = AVTOOConstants.DECLARE_LOCAL) or (instruction = AVTOOConstants.DECLARE_WITH)) and (operand is TypedItem) then begin
                                                debugBuilder := debugBuilder + (operand as TypedItem).&type.toString() + ' ';
                                            end;
                                            debugBuilder := debugBuilder + operand.toString();
                                            operand := __node.operand2;
                                            if operand <> nil then begin
                                                debugBuilder := debugBuilder + ', ' + operand.toString();
                                            end;
                                            svalue := __node.operandC;
                                            if svalue <> nil then begin
                                                debugBuilder := debugBuilder + ', ' + svalue.toString();
                                            end;
                                            debugBuilder := debugBuilder + ')';
                                            goto break_label0;
                                        end;
                                        svalue := __node.operandC;
                                        if svalue <> nil then begin
                                            debugBuilder := debugBuilder + '(' + svalue.toString() + ')';
                                        end;
                                        reference := __node.reference1;
                                        if reference <> nil then begin
                                            debugBuilder := debugBuilder + '(';
                                            if reference is Node then begin
                                                debugBuilder := debugBuilder + '0x' + CoLong.toHexString(long(reference));
                                            end else begin
                                                debugBuilder := debugBuilder + reference.toString();
                                            end;
                                            reference := __node.reference2;
                                            if reference <> nil then begin
                                                debugBuilder := debugBuilder + ', ';
                                                if reference is Node then begin
                                                    debugBuilder := debugBuilder + '0x' + CoLong.toHexString(long(reference));
                                                end else begin
                                                    debugBuilder := debugBuilder + reference.toString();
                                                end;
                                            end;
                                            debugBuilder := debugBuilder + ')';
                                        end;
                                    end;
                                    break_label0:
                                    jlength := __node.getJumpCasesLength();
                                    if (jlength > 0) or (instruction = AVTOOConstants.FCT_JUMP) or (instruction = AVTOOConstants.FCT_RETURN) then begin
                                        target := __node.jumpDefault;
                                        debugBuilder := debugBuilder + '[default';
                                        if target = nil then begin
                                            debugBuilder := debugBuilder + '>null';
                                        end else begin
                                            debugBuilder := debugBuilder + '>0x' + CoLong.toHexString(long(target));
                                        end;
                                        for jindex := 0 to jlength - 1 do begin
                                            target := __node.getJumpCaseNodeAt(jindex);
                                            debugBuilder := debugBuilder + ', ' + CoInt.toString(__node.getJumpCaseValueAt(jindex));
                                            if target = nil then begin
                                                debugBuilder := debugBuilder + '>null';
                                            end else begin
                                                debugBuilder := debugBuilder + '>0x' + CoLong.toHexString(long(target));
                                            end;
                                        end;
                                        debugBuilder := debugBuilder + ']';
                                    end;
                                    debugOutput.println(debugBuilder);
                                end;
                            end;
                        end;
                    end;
                end;
            finally
                debugOutput.close();
            end;
        end;

        class function PrintCodeThread.attributesToString(item: ReflectItem): AnsiString;
        var
            attributesAsNumber: int;
            attributesAsString: AnsiString;
        begin
            attributesAsNumber := item.attributes;
            attributesAsString := '';
            case attributesAsNumber and AVTOOConstants.MASK_VISIBILITY of
            AVTOOConstants.VIS_PRIVATE:
                attributesAsString := attributesAsString + 'private ';
            AVTOOConstants.RESERVED_PACKAGE,
            AVTOOConstants.VIS_PACKAGE:
                attributesAsString := attributesAsString + 'package ';
            AVTOOConstants.VIS_PROTECTED:
                attributesAsString := attributesAsString + 'protected ';
            AVTOOConstants.VIS_PUBLIC:
                attributesAsString := attributesAsString + 'public ';
            AVTOOConstants.VIS_PUBLISHED:
                attributesAsString := attributesAsString + 'published ';
            end;
            if (attributesAsNumber and AVTOOConstants.ATTR_SYNTHETIC) <> 0 then begin
                attributesAsString := attributesAsString + 'synthetic ';
            end;
            if (attributesAsNumber and AVTOOConstants.ATTR_ABSTRACT) <> 0 then begin
                attributesAsString := attributesAsString + 'abstract ';
            end;
            if (attributesAsNumber and AVTOOConstants.ATTR_STATIC) <> 0 then begin
                attributesAsString := attributesAsString + 'static ';
            end;
            if (attributesAsNumber and AVTOOConstants.ATTR_FINAL) <> 0 then begin
                attributesAsString := attributesAsString + 'final ';
            end;
            if item is Package then begin
                attributesAsString := attributesAsString + 'package ';
            end else
            if item is &Type then case (attributesAsNumber and AVTOOConstants.MASK_TYPE) shr 5 of
            AVTOOConstants.ATTR_PRIMITIVE shr 5:
                attributesAsString := attributesAsString + 'primitive ';
            AVTOOConstants.ATTR_SERVICE shr 5:
                attributesAsString := attributesAsString + 'service ';
            AVTOOConstants.ATTR_STRUCT shr 5:
                attributesAsString := attributesAsString + 'struct ';
            AVTOOConstants.ATTR_INTERFACE shr 5:
                attributesAsString := attributesAsString + 'interface ';
            else
                attributesAsString := attributesAsString + 'class ';
            end;
            if (attributesAsNumber and AVTOOConstants.ATTR_NATIVE) <> 0 then begin
                attributesAsString := attributesAsString + 'native ';
            end;
            if (attributesAsNumber and AVTOOConstants.ATTR_INTERRUPT) <> 0 then begin
                attributesAsString := attributesAsString + 'interrupt ';
            end;
            if (attributesAsNumber and AVTOOConstants.ATTR_SYNCHRONIZED) <> 0 then begin
                attributesAsString := attributesAsString + 'synchronized ';
            end;
            if item is TypedItem then begin
                attributesAsString := attributesAsString + (item as TypedItem).&type.specialCanonicalName + ' ';
            end;
            result := attributesAsString + item.specialSimpleName;
        end;

        class function PrintCodeThread.namesToString(item: ReflectItem): AnsiString;
        var
            __field: Field;
        begin
            result := ' { ';
            if item is RequiredReflectItem then begin
                result := result + 'spec canonical = ' + RequiredReflectItem(item).specialCanonicalName + ', ';
            end;
            result := result + 'recompilable = ' + item.recompilableName + ', fasm simple = ' + item.fasmSimpleName + ', fasm full = ' + item.fasmFullName;
            if item is Field then begin
                __field := Field(item);
                result := result + ', fasm struct = ' + __field.fasmStructName + ', capacity = ' + CoInt.toString(__field.capacity);
            end;
            result := result + ' }';
        end;

        class function PrintCodeThread.supertypesToString(__type: ClassType): AnsiString;
        var
            index: int;
            supertype: ru.malik.elaborarer.avtoo.lang.ClassType;
        begin
            supertype := __type.getSuperclassType();
            if supertype = nil then begin
                result := '';
                exit;
            end;
            result := '(' + supertype.specialCanonicalName;
            for index := 0 to __type.getSuperservicesLength() - 1 do begin
                result := result + ', ' + __type.getSuperserviceTypeAt(index).specialCanonicalName;
            end;
            result := result + ')';
        end;

        constructor PrintCodeThread.create(monitor: Monitor; fileSystem: FileSystem; const fileName: UnicodeString; programme: Programme);
        begin
            inherited create(monitor, fileSystem, fileName);
            fldProgramme := programme;
        end;

        procedure PrintCodeThread.run();
        begin
            try
                try
                    print(fldFileSystem, fldFileName, fldProgramme);
                except
                    on exception: IOException do begin
                        exception.printStackTrace();
                    end;
                end;
            finally
                terminate();
            end;
        end;
    {%endregion}

    {%region  PrintLexemesThread }
        class procedure PrintLexemesThread.print(fileSystem: FileSystem; const fileName: UnicodeString; project: &Library);
        var
            index: int;
            sources: Source_Array1d;
            source: TextSource;
            debugOutput: PrintStream;
        begin
            debugOutput := PrintStream.create(fileSystem.rewriteFile(fileName));
            try
                sources := project.sources.clone();
                for index := 0 to system.length(sources) - 1 do begin
                    source := TextSource(Lang.cast(sources[index], TextSource));
                    debugOutput.println(source.textSourcePath);
                    printLanguageLexemes(source, debugOutput);
                end;
            finally
                debugOutput.close();
            end;
        end;

        class procedure PrintLexemesThread.printDocumentLexemes(sequence: LexemeSequence; printer: PrintStream);
        var
            position: int;
            location: int2;
            kindAsString: AnsiString;
        begin
            for position := 0 to sequence.getLength() - 1 do begin
                location := sequence.getLexemeLocation(position) + Vector.newByte2(1, 1);
                case sequence.getLexemeKind(position) of
                AVTOOConstants.D_TEXT          : kindAsString := 'D_TEXT          ';
                AVTOOConstants.D_NAME          : kindAsString := 'D_NAME          ';
                AVTOOConstants.D_ALINK         : kindAsString := 'D_ALINK         ';
                AVTOOConstants.D_APARAM        : kindAsString := 'D_APARAM        ';
                AVTOOConstants.D_ARETURN       : kindAsString := 'D_ARETURN       ';
                AVTOOConstants.D_ATHROWS       : kindAsString := 'D_ATHROWS       ';
                AVTOOConstants.D_ASINCE        : kindAsString := 'D_ASINCE        ';
                AVTOOConstants.D_ASEE          : kindAsString := 'D_ASEE          ';
                AVTOOConstants.D_SCAL_DIVU     : kindAsString := 'D_SCAL_DIVU     ';
                AVTOOConstants.D_SCAL_REMU     : kindAsString := 'D_SCAL_REMU     ';
                AVTOOConstants.D_SCAL_SHR      : kindAsString := 'D_SCAL_SHR      ';
                AVTOOConstants.D_SCAL_SHRU     : kindAsString := 'D_SCAL_SHRU     ';
                AVTOOConstants.D_SCAL_SHL      : kindAsString := 'D_SCAL_SHL      ';
                AVTOOConstants.D_SCAL_GE       : kindAsString := 'D_SCAL_GE       ';
                AVTOOConstants.D_SCAL_LE       : kindAsString := 'D_SCAL_LE       ';
                AVTOOConstants.D_SCAL_EQ       : kindAsString := 'D_SCAL_EQ       ';
                AVTOOConstants.D_SCAL_NE       : kindAsString := 'D_SCAL_NE       ';
                AVTOOConstants.D_VECT_LUP      : kindAsString := 'D_VECT_LUP      ';
                AVTOOConstants.D_VECT_UUP      : kindAsString := 'D_VECT_UUP      ';
                AVTOOConstants.D_VECT_PCK      : kindAsString := 'D_VECT_PCK      ';
                AVTOOConstants.D_VECT_MUL      : kindAsString := 'D_VECT_MUL      ';
                AVTOOConstants.D_VECT_DIV      : kindAsString := 'D_VECT_DIV      ';
                AVTOOConstants.D_VECT_ADD      : kindAsString := 'D_VECT_ADD      ';
                AVTOOConstants.D_VECT_SUB      : kindAsString := 'D_VECT_SUB      ';
                AVTOOConstants.D_VECT_SHR      : kindAsString := 'D_VECT_SHR      ';
                AVTOOConstants.D_VECT_SHRU     : kindAsString := 'D_VECT_SHRU     ';
                AVTOOConstants.D_VECT_SHL      : kindAsString := 'D_VECT_SHL      ';
                AVTOOConstants.D_VECT_GT       : kindAsString := 'D_VECT_GT       ';
                AVTOOConstants.D_VECT_GE       : kindAsString := 'D_VECT_GE       ';
                AVTOOConstants.D_VECT_LT       : kindAsString := 'D_VECT_LT       ';
                AVTOOConstants.D_VECT_LE       : kindAsString := 'D_VECT_LE       ';
                AVTOOConstants.D_VECT_EQ       : kindAsString := 'D_VECT_EQ       ';
                AVTOOConstants.D_VECT_NE       : kindAsString := 'D_VECT_NE       ';
                AVTOOConstants.D_VECT_HMUL     : kindAsString := 'D_VECT_HMUL     ';
                AVTOOConstants.D_VECT_HMULU    : kindAsString := 'D_VECT_HMULU    ';
                AVTOOConstants.D_VECT_SADD     : kindAsString := 'D_VECT_SADD     ';
                AVTOOConstants.D_VECT_SADDU    : kindAsString := 'D_VECT_SADDU    ';
                AVTOOConstants.D_VECT_SSUB     : kindAsString := 'D_VECT_SSUB     ';
                AVTOOConstants.D_VECT_SSUBU    : kindAsString := 'D_VECT_SSUBU    ';
                AVTOOConstants.D_PARENTH_OPENED: kindAsString := 'D_PARENTH_OPENED';
                AVTOOConstants.D_PARENTH_CLOSED: kindAsString := 'D_PARENTH_CLOSED';
                AVTOOConstants.D_BRACKET_OPENED: kindAsString := 'D_BRACKET_OPENED';
                AVTOOConstants.D_BRACKET_CLOSED: kindAsString := 'D_BRACKET_CLOSED';
                AVTOOConstants.D_CURLY_OPENED  : kindAsString := 'D_CURLY_OPENED  ';
                AVTOOConstants.D_CURLY_CLOSED  : kindAsString := 'D_CURLY_CLOSED  ';
                AVTOOConstants.D_TAG_OPENED    : kindAsString := 'D_TAG_OPENED    ';
                AVTOOConstants.D_TAG_CLOSED    : kindAsString := 'D_TAG_CLOSED    ';
                AVTOOConstants.D_EQUAL         : kindAsString := 'D_EQUALS        ';
                AVTOOConstants.D_PERIOD        : kindAsString := 'D_PERIOD        ';
                AVTOOConstants.D_COMMA         : kindAsString := 'D_COMMA         ';
                AVTOOConstants.D_EXCLAM_MARK   : kindAsString := 'D_EXCLAM_MARK   ';
                AVTOOConstants.D_VERTICAL_LINE : kindAsString := 'D_VERTICAL_LINE ';
                AVTOOConstants.D_AMPERSAND     : kindAsString := 'D_AMPERSAND     ';
                AVTOOConstants.D_TILDE         : kindAsString := 'D_TILDE         ';
                AVTOOConstants.D_POUND_SIGN    : kindAsString := 'D_POUND_SIGN    ';
                AVTOOConstants.D_CIRCUMFLEX_ACC: kindAsString := 'D_CIRCUMFLEX_ACC';
                AVTOOConstants.D_ASTERISK      : kindAsString := 'D_ASTERISK      ';
                AVTOOConstants.D_SOLIDUS       : kindAsString := 'D_SOLIDUS       ';
                AVTOOConstants.D_PERCENT       : kindAsString := 'D_PERCENT       ';
                AVTOOConstants.D_PLUS          : kindAsString := 'D_PLUS          ';
                AVTOOConstants.D_MINUS         : kindAsString := 'D_MINUS         ';
                AVTOOConstants.D_AT            : kindAsString := 'D_AT            ';
                AVTOOConstants.D_EOL           : kindAsString := 'D_EOL           ';
                AVTOOConstants.D_EOP           : kindAsString := 'D_EOP           ';
                AVTOOConstants.D_END           : kindAsString := 'D_END           ';
                else                             kindAsString := '<unknown>       ';
                end;
                if sequence.getLexemeType(position) <> AVTOOConstants.LT_STRING then begin
                    printer.printlnf(#$09#$09'[%0:5%] %1:4%:%2:3% %3%', [
                        CoAnsiString.create(CoInt.toString(position)), CoAnsiString.create(CoInt.toString(location[0])),
                        CoAnsiString.create(CoInt.toString(location[1])), CoAnsiString.create(kindAsString)
                    ]);
                end else begin
                    printer.printlnf(#$09#$09'[%0:5%] %1:4%:%2:3% %3% ("%4%")', [
                        CoAnsiString.create(CoInt.toString(position)), CoAnsiString.create(CoInt.toString(location[0])),
                        CoAnsiString.create(CoInt.toString(location[1])), CoAnsiString.create(kindAsString),
                        CoUnicodeString.create(sequence.getLexemeString(position))
                    ]);
                end;
            end;
        end;

        class procedure PrintLexemesThread.printLanguageLexemes(sequence: LexemeSequence; printer: PrintStream);
        var
            position: int;
            location: int2;
            kindAsString: AnsiString;
            component: TObject;
        begin
            for position := 0 to sequence.getLength() - 1 do begin
                location := sequence.getLexemeLocation(position) + Vector.newByte2(1, 1);
                case sequence.getLexemeKind(position) of
                AVTOOConstants.VIS_PRIVATE     : kindAsString := 'PRIVATE       ';
                AVTOOConstants.VIS_PACKAGE     : kindAsString := 'PACKAGE       ';
                AVTOOConstants.VIS_PROTECTED   : kindAsString := 'PROTECTED     ';
                AVTOOConstants.VIS_PUBLIC      : kindAsString := 'PUBLIC        ';
                AVTOOConstants.VIS_PUBLISHED   : kindAsString := 'PUBLISHED     ';
                AVTOOConstants.DCL_IMPORT      : kindAsString := 'IMPORT        ';
                AVTOOConstants.DCL_UNION       : kindAsString := 'UNION         ';
                AVTOOConstants.DCL_ABSTRACT    : kindAsString := 'ABSTRACT      ';
                AVTOOConstants.DCL_FINAL       : kindAsString := 'FINAL         ';
                AVTOOConstants.DCL_CLASS       : kindAsString := 'CLASS         ';
                AVTOOConstants.DCL_STRUCT      : kindAsString := 'STRUCT        ';
                AVTOOConstants.DCL_SERVICE     : kindAsString := 'SERVICE       ';
                AVTOOConstants.DCL_INTERFACE   : kindAsString := 'INTERFACE     ';
                AVTOOConstants.DCL_HELPER      : kindAsString := 'HELPER        ';
                AVTOOConstants.DCL_STATIC      : kindAsString := 'STATIC        ';
                AVTOOConstants.DCL_NATIVE      : kindAsString := 'NATIVE        ';
                AVTOOConstants.DCL_INTERRUPT   : kindAsString := 'INTERRUPT     ';
                AVTOOConstants.DCL_SYNCHRONIZED: kindAsString := 'SYNCHRONIZED  ';
                AVTOOConstants.DCL_OPERATOR    : kindAsString := 'OPERATOR      ';
                AVTOOConstants.DCL_THROWS      : kindAsString := 'THROWS        ';
                AVTOOConstants.EXP_FALSE       : kindAsString := 'FALSE         ';
                AVTOOConstants.EXP_TRUE        : kindAsString := 'TRUE          ';
                AVTOOConstants.EXP_NULL        : kindAsString := 'NULL          ';
                AVTOOConstants.EXP_NEW         : kindAsString := 'NEW           ';
                AVTOOConstants.EXP_SUPER       : kindAsString := 'SUPER         ';
                AVTOOConstants.EXP_THIS        : kindAsString := 'THIS          ';
                AVTOOConstants.EXP_INSTANCEOF  : kindAsString := 'INSTANCEOF    ';
                AVTOOConstants.TYP_VOID        : kindAsString := 'VOID          ';
                AVTOOConstants.TYP_BOOLEAN     : kindAsString := 'BOOLEAN       ';
                AVTOOConstants.TYP_CHAR        : kindAsString := 'CHAR          ';
                AVTOOConstants.TYP_REAL        : kindAsString := 'REAL          ';
                AVTOOConstants.TYP_DOUBLE      : kindAsString := 'DOUBLE        ';
                AVTOOConstants.TYP_DOUBLE2     : kindAsString := 'DOUBLE2       ';
                AVTOOConstants.TYP_DOUBLE4     : kindAsString := 'DOUBLE4       ';
                AVTOOConstants.TYP_DOUBLE8     : kindAsString := 'DOUBLE8       ';
                AVTOOConstants.TYP_FLOAT       : kindAsString := 'FLOAT         ';
                AVTOOConstants.TYP_FLOAT2      : kindAsString := 'FLOAT2        ';
                AVTOOConstants.TYP_FLOAT4      : kindAsString := 'FLOAT4        ';
                AVTOOConstants.TYP_FLOAT8      : kindAsString := 'FLOAT8        ';
                AVTOOConstants.TYP_BYTE        : kindAsString := 'BYTE          ';
                AVTOOConstants.TYP_BYTE2       : kindAsString := 'BYTE2         ';
                AVTOOConstants.TYP_BYTE4       : kindAsString := 'BYTE4         ';
                AVTOOConstants.TYP_BYTE8       : kindAsString := 'BYTE8         ';
                AVTOOConstants.TYP_SHORT       : kindAsString := 'SHORT         ';
                AVTOOConstants.TYP_SHORT2      : kindAsString := 'SHORT2        ';
                AVTOOConstants.TYP_SHORT4      : kindAsString := 'SHORT4        ';
                AVTOOConstants.TYP_SHORT8      : kindAsString := 'SHORT8        ';
                AVTOOConstants.TYP_INT         : kindAsString := 'INT           ';
                AVTOOConstants.TYP_INT2        : kindAsString := 'INT2          ';
                AVTOOConstants.TYP_INT4        : kindAsString := 'INT4          ';
                AVTOOConstants.TYP_INT8        : kindAsString := 'INT8          ';
                AVTOOConstants.TYP_LONG        : kindAsString := 'LONG          ';
                AVTOOConstants.TYP_LONG2       : kindAsString := 'LONG2         ';
                AVTOOConstants.TYP_LONG4       : kindAsString := 'LONG4         ';
                AVTOOConstants.TYP_LONG8       : kindAsString := 'LONG8         ';
                AVTOOConstants.FCT_WITH        : kindAsString := 'WITH          ';
                AVTOOConstants.FCT_IF          : kindAsString := 'IF            ';
                AVTOOConstants.FCT_ELSE        : kindAsString := 'ELSE          ';
                AVTOOConstants.FCT_SWITCH      : kindAsString := 'SWITCH        ';
                AVTOOConstants.FCT_CASE        : kindAsString := 'CASE          ';
                AVTOOConstants.FCT_DEFAULT     : kindAsString := 'DEFAULT       ';
                AVTOOConstants.FCT_DO          : kindAsString := 'DO            ';
                AVTOOConstants.FCT_FOR         : kindAsString := 'FOR           ';
                AVTOOConstants.FCT_WHILE       : kindAsString := 'WHILE         ';
                AVTOOConstants.FCT_BREAK       : kindAsString := 'BREAK         ';
                AVTOOConstants.FCT_CONTINUE    : kindAsString := 'CONTINUE      ';
                AVTOOConstants.FCT_RETURN      : kindAsString := 'RETURN        ';
                AVTOOConstants.FCT_THROW       : kindAsString := 'THROW         ';
                AVTOOConstants.FCT_TRY         : kindAsString := 'TRY           ';
                AVTOOConstants.FCT_CATCH       : kindAsString := 'CATCH         ';
                AVTOOConstants.FCT_FINALLY     : kindAsString := 'FINALLY       ';
                AVTOOConstants.INC_LOCAL       : kindAsString := 'INC_LOCAL     ';
                AVTOOConstants.DEC_LOCAL       : kindAsString := 'DEC_LOCAL     ';
                AVTOOConstants.BOOL_NOT        : kindAsString := 'BOOL_NOT      ';
                AVTOOConstants.BOOL_AND        : kindAsString := 'BOOL_AND      ';
                AVTOOConstants.BOOL_OR         : kindAsString := 'BOOL_OR       ';
                AVTOOConstants.O_BIT_NOT       : kindAsString := 'O_BIT_NOT     ';
                AVTOOConstants.O_BIT_AND       : kindAsString := 'O_BIT_AND     ';
                AVTOOConstants.O_BIT_OR        : kindAsString := 'O_BIT_OR      ';
                AVTOOConstants.O_BIT_XOR       : kindAsString := 'O_BIT_XOR     ';
                AVTOOConstants.O_SCAL_MUL      : kindAsString := 'O_SCAL_MUL    ';
                AVTOOConstants.O_SCAL_DIV      : kindAsString := 'O_SCAL_DIV    ';
                AVTOOConstants.O_SCAL_DIVU     : kindAsString := 'O_SCAL_DIVU   ';
                AVTOOConstants.O_SCAL_REM      : kindAsString := 'O_SCAL_REM    ';
                AVTOOConstants.O_SCAL_REMU     : kindAsString := 'O_SCAL_REMU   ';
                AVTOOConstants.O_SCAL_ADD      : kindAsString := 'O_SCAL_ADD    ';
                AVTOOConstants.O_SCAL_SUB      : kindAsString := 'O_SCAL_SUB    ';
                AVTOOConstants.O_SCAL_SHR      : kindAsString := 'O_SCAL_SHR    ';
                AVTOOConstants.O_SCAL_SHRU     : kindAsString := 'O_SCAL_SHRU   ';
                AVTOOConstants.O_SCAL_SHL      : kindAsString := 'O_SCAL_SHL    ';
                AVTOOConstants.O_SCAL_GT       : kindAsString := 'O_SCAL_GT     ';
                AVTOOConstants.O_SCAL_GE       : kindAsString := 'O_SCAL_GE     ';
                AVTOOConstants.O_SCAL_LT       : kindAsString := 'O_SCAL_LT     ';
                AVTOOConstants.O_SCAL_LE       : kindAsString := 'O_SCAL_LE     ';
                AVTOOConstants.O_SCAL_EQ       : kindAsString := 'O_SCAL_EQ     ';
                AVTOOConstants.O_SCAL_NE       : kindAsString := 'O_SCAL_NE     ';
                AVTOOConstants.O_VECT_LUP      : kindAsString := 'O_VECT_LUP    ';
                AVTOOConstants.O_VECT_UUP      : kindAsString := 'O_VECT_UUP    ';
                AVTOOConstants.O_VECT_PCK      : kindAsString := 'O_VECT_PCK    ';
                AVTOOConstants.O_VECT_MUL      : kindAsString := 'O_VECT_MUL    ';
                AVTOOConstants.O_VECT_DIV      : kindAsString := 'O_VECT_DIV    ';
                AVTOOConstants.O_VECT_ADD      : kindAsString := 'O_VECT_ADD    ';
                AVTOOConstants.O_VECT_SUB      : kindAsString := 'O_VECT_SUB    ';
                AVTOOConstants.O_VECT_SHR      : kindAsString := 'O_VECT_SHR    ';
                AVTOOConstants.O_VECT_SHRU     : kindAsString := 'O_VECT_SHRU   ';
                AVTOOConstants.O_VECT_SHL      : kindAsString := 'O_VECT_SHL    ';
                AVTOOConstants.O_VECT_GT       : kindAsString := 'O_VECT_GT     ';
                AVTOOConstants.O_VECT_GE       : kindAsString := 'O_VECT_GE     ';
                AVTOOConstants.O_VECT_LT       : kindAsString := 'O_VECT_LT     ';
                AVTOOConstants.O_VECT_LE       : kindAsString := 'O_VECT_LE     ';
                AVTOOConstants.O_VECT_EQ       : kindAsString := 'O_VECT_EQ     ';
                AVTOOConstants.O_VECT_NE       : kindAsString := 'O_VECT_NE     ';
                AVTOOConstants.O_VECT_HMUL     : kindAsString := 'O_VECT_HMUL   ';
                AVTOOConstants.O_VECT_HMULU    : kindAsString := 'O_VECT_HMULU  ';
                AVTOOConstants.O_VECT_SADD     : kindAsString := 'O_VECT_SADD   ';
                AVTOOConstants.O_VECT_SADDU    : kindAsString := 'O_VECT_SADDU  ';
                AVTOOConstants.O_VECT_SSUB     : kindAsString := 'O_VECT_SSUB   ';
                AVTOOConstants.O_VECT_SSUBU    : kindAsString := 'O_VECT_SSUBU  ';
                AVTOOConstants.A_BIT_AND       : kindAsString := 'A_BIT_AND     ';
                AVTOOConstants.A_BIT_OR        : kindAsString := 'A_BIT_OR      ';
                AVTOOConstants.A_BIT_XOR       : kindAsString := 'A_BIT_XOR     ';
                AVTOOConstants.A_SCAL_MUL      : kindAsString := 'A_SCAL_MUL    ';
                AVTOOConstants.A_SCAL_DIV      : kindAsString := 'A_SCAL_DIV    ';
                AVTOOConstants.A_SCAL_DIVU     : kindAsString := 'A_SCAL_DIVU   ';
                AVTOOConstants.A_SCAL_REM      : kindAsString := 'A_SCAL_REM    ';
                AVTOOConstants.A_SCAL_REMU     : kindAsString := 'A_SCAL_REMU   ';
                AVTOOConstants.A_SCAL_ADD      : kindAsString := 'A_SCAL_ADD    ';
                AVTOOConstants.A_SCAL_SUB      : kindAsString := 'A_SCAL_SUB    ';
                AVTOOConstants.A_SCAL_SHR      : kindAsString := 'A_SCAL_SHR    ';
                AVTOOConstants.A_SCAL_SHRU     : kindAsString := 'A_SCAL_SHRU   ';
                AVTOOConstants.A_SCAL_SHL      : kindAsString := 'A_SCAL_SHL    ';
                AVTOOConstants.A_VECT_MUL      : kindAsString := 'A_VECT_MUL    ';
                AVTOOConstants.A_VECT_DIV      : kindAsString := 'A_VECT_DIV    ';
                AVTOOConstants.A_VECT_ADD      : kindAsString := 'A_VECT_ADD    ';
                AVTOOConstants.A_VECT_SUB      : kindAsString := 'A_VECT_SUB    ';
                AVTOOConstants.A_VECT_SHR      : kindAsString := 'A_VECT_SHR    ';
                AVTOOConstants.A_VECT_SHRU     : kindAsString := 'A_VECT_SHRU   ';
                AVTOOConstants.A_VECT_SHL      : kindAsString := 'A_VECT_SHL    ';
                AVTOOConstants.A_VECT_GT       : kindAsString := 'A_VECT_GT     ';
                AVTOOConstants.A_VECT_GE       : kindAsString := 'A_VECT_GE     ';
                AVTOOConstants.A_VECT_LT       : kindAsString := 'A_VECT_LT     ';
                AVTOOConstants.A_VECT_LE       : kindAsString := 'A_VECT_LE     ';
                AVTOOConstants.A_VECT_EQ       : kindAsString := 'A_VECT_EQ     ';
                AVTOOConstants.A_VECT_NE       : kindAsString := 'A_VECT_NE     ';
                AVTOOConstants.A_VECT_HMUL     : kindAsString := 'A_VECT_HMUL   ';
                AVTOOConstants.A_VECT_HMULU    : kindAsString := 'A_VECT_HMULU  ';
                AVTOOConstants.A_VECT_SADD     : kindAsString := 'A_VECT_SADD   ';
                AVTOOConstants.A_VECT_SADDU    : kindAsString := 'A_VECT_SADDU  ';
                AVTOOConstants.A_VECT_SSUB     : kindAsString := 'A_VECT_SSUB   ';
                AVTOOConstants.A_VECT_SSUBU    : kindAsString := 'A_VECT_SSUBU  ';
                AVTOOConstants.PARENTH_OPENED  : kindAsString := 'PARENTH_OPENED';
                AVTOOConstants.PARENTH_CLOSED  : kindAsString := 'PARENTH_CLOSED';
                AVTOOConstants.BRACKET_OPENED  : kindAsString := 'BRACKET_OPENED';
                AVTOOConstants.BRACKET_CLOSED  : kindAsString := 'BRACKET_CLOSED';
                AVTOOConstants.CURLY_OPENED    : kindAsString := 'CURLY_OPENED  ';
                AVTOOConstants.CURLY_CLOSED    : kindAsString := 'CURLY_CLOSED  ';
                AVTOOConstants.EQUAL           : kindAsString := 'EQUALS        ';
                AVTOOConstants.QUESTION        : kindAsString := 'QUESTION      ';
                AVTOOConstants.REVERSE         : kindAsString := 'REVERSE       ';
                AVTOOConstants.PERIOD          : kindAsString := 'PERIOD        ';
                AVTOOConstants.COMMA           : kindAsString := 'COMMA         ';
                AVTOOConstants.COLON           : kindAsString := 'COLON         ';
                AVTOOConstants.SEMICOLON       : kindAsString := 'SEMICOLON     ';
                AVTOOConstants.L_NAME          : kindAsString := 'L_NAME        ';
                AVTOOConstants.L_STRING        : kindAsString := 'L_STRING      ';
                AVTOOConstants.L_DOC           : kindAsString := 'L_DOC         ';
                AVTOOConstants.L_BOOLEAN       : kindAsString := 'L_BOOLEAN     ';
                AVTOOConstants.L_CHAR          : kindAsString := 'L_CHAR        ';
                AVTOOConstants.L_REAL          : kindAsString := 'L_REAL        ';
                AVTOOConstants.L_DOUBLE        : kindAsString := 'L_DOUBLE      ';
                AVTOOConstants.L_FLOAT         : kindAsString := 'L_FLOAT       ';
                AVTOOConstants.L_BYTE          : kindAsString := 'L_BYTE        ';
                AVTOOConstants.L_SHORT         : kindAsString := 'L_SHORT       ';
                AVTOOConstants.L_INT           : kindAsString := 'L_INT         ';
                AVTOOConstants.L_LONG          : kindAsString := 'L_LONG        ';
                AVTOOConstants.L_END           : kindAsString := 'L_END         ';
                else                             kindAsString := '<unknown>     ';
                end;
                case sequence.getLexemeType(position) of
                AVTOOConstants.LT_BOOLEAN:
                    printer.printlnf(#$09'[%0:5%] %1:4%:%2:3% %3% %4%', [
                        CoAnsiString.create(CoInt.toString(position)), CoAnsiString.create(CoInt.toString(location[0])),
                        CoAnsiString.create(CoInt.toString(location[1])), CoAnsiString.create(kindAsString),
                        CoBoolean.create(sequence.getLexemeBoolean(position))
                    ]);
                AVTOOConstants.LT_CHAR:
                    printer.printlnf(#$09'[%0:5%] %1:4%:%2:3% %3% ''%4%''', [
                        CoAnsiString.create(CoInt.toString(position)), CoAnsiString.create(CoInt.toString(location[0])),
                        CoAnsiString.create(CoInt.toString(location[1])), CoAnsiString.create(kindAsString),
                        CoUnicodeString.create(sequence.getLexemeChar(position))
                    ]);
                AVTOOConstants.LT_BYTE,
                AVTOOConstants.LT_SHORT,
                AVTOOConstants.LT_INT:
                    printer.printlnf(#$09'[%0:5%] %1:4%:%2:3% %3% %4%', [
                        CoAnsiString.create(CoInt.toString(position)), CoAnsiString.create(CoInt.toString(location[0])),
                        CoAnsiString.create(CoInt.toString(location[1])), CoAnsiString.create(kindAsString),
                        CoInt.create(sequence.getLexemeInt(position))
                    ]);
                AVTOOConstants.LT_LONG:
                    printer.printlnf(#$09'[%0:5%] %1:4%:%2:3% %3% %4%', [
                        CoAnsiString.create(CoInt.toString(position)), CoAnsiString.create(CoInt.toString(location[0])),
                        CoAnsiString.create(CoInt.toString(location[1])), CoAnsiString.create(kindAsString),
                        CoLong.create(sequence.getLexemeLong(position))
                    ]);
                AVTOOConstants.LT_FLOAT:
                    printer.printlnf(#$09'[%0:5%] %1:4%:%2:3% %3% %4%', [
                        CoAnsiString.create(CoInt.toString(position)), CoAnsiString.create(CoInt.toString(location[0])),
                        CoAnsiString.create(CoInt.toString(location[1])), CoAnsiString.create(kindAsString),
                        CoFloat.create(sequence.getLexemeFloat(position))
                    ]);
                AVTOOConstants.LT_DOUBLE:
                    printer.printlnf(#$09'[%0:5%] %1:4%:%2:3% %3% %4%', [
                        CoAnsiString.create(CoInt.toString(position)), CoAnsiString.create(CoInt.toString(location[0])),
                        CoAnsiString.create(CoInt.toString(location[1])), CoAnsiString.create(kindAsString),
                        CoDouble.create(sequence.getLexemeDouble(position))
                    ]);
                AVTOOConstants.LT_REAL:
                    printer.printlnf(#$09'[%0:5%] %1:4%:%2:3% %3% %4%', [
                        CoAnsiString.create(CoInt.toString(position)), CoAnsiString.create(CoInt.toString(location[0])),
                        CoAnsiString.create(CoInt.toString(location[1])), CoAnsiString.create(kindAsString),
                        CoReal.create(sequence.getLexemeReal(position))
                    ]);
                AVTOOConstants.LT_STRING:
                    printer.printlnf(#$09'[%0:5%] %1:4%:%2:3% %3% "%4%"', [
                        CoAnsiString.create(CoInt.toString(position)), CoAnsiString.create(CoInt.toString(location[0])),
                        CoAnsiString.create(CoInt.toString(location[1])), CoAnsiString.create(kindAsString),
                        CoUnicodeString.create(sequence.getLexemeString(position))
                    ]);
                else
                    printer.printlnf(#$09'[%0:5%] %1:4%:%2:3% %3%', [
                        CoAnsiString.create(CoInt.toString(position)), CoAnsiString.create(CoInt.toString(location[0])),
                        CoAnsiString.create(CoInt.toString(location[1])), CoAnsiString.create(kindAsString)
                    ]);
                    component := sequence.readComponent(position);
                    if component is LexemeSequence then printDocumentLexemes(LexemeSequence(component), printer);
                end;
            end;
        end;

        constructor PrintLexemesThread.create(monitor: Monitor; fileSystem: FileSystem; const fileName: UnicodeString; project: &Library);
        begin
            inherited create(monitor, fileSystem, fileName);
            fldProject := project;
        end;

        procedure PrintLexemesThread.run();
        begin
            try
                try
                    print(fldFileSystem, fldFileName, fldProject);
                except
                    on exception: IOException do begin
                        exception.printStackTrace();
                    end;
                end;
            finally
                terminate();
            end;
        end;
    {%endregion}

end.