AssemblerSourcePrintStream.avt

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

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

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

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

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

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

package ru.malik.elaborarer.avtoo.generator;

import avt.io.*;
import avt.io.charset.*;
import avt.lang.array.*;
import platform.independent.streamformat.*;
import ru.malik.elaborarer.avtoo.lang.*;

public class AssemblerSourcePrintStream(Object, DataEncoder, CharsetOutputAdapter, OutputAdapter, MutableDataHolder, DataHolder)
{
    private static final CharEncoder defaultEncoder = Charset.getDefault().newEncoder();

    private int fldState;
    private int fldMargin;
    private char[] fldSpaces;
    private final StringBuilder fldText;
    private final CharEncoder fldEncoder;
    private final String fldEmptyString;
    private final String fldLineSeparator;

    public (): this(null) {  }

    public (CharEncoder encoder) {
        Array.fill(fldSpaces = new char[0xff], 0, 0xff, '\u0020');
        fldText = new StringBuilder(0x1000);
        fldEncoder = encoder != null ? encoder : defaultEncoder;
        fldEmptyString = "";
        fldLineSeparator = Platform.instance.lineSeparator;
    }

    public void saveToDataStream(DataOutputStream stream, CharEncoder encoder) throws IOException { saveToOutputStream(stream == null ? null : stream.writer, encoder); }

    public void saveToDataStream(DataOutputStream stream, String charsetName) throws IOException { saveToOutputStream(stream == null ? null : stream.writer, Charset.get(charsetName).newEncoder()); }

    public void saveToOutputStream(ByteWriter stream, CharEncoder encoder) throws IOException { (encoder != null ? encoder : fldEncoder).encodeToWriter(stream, fldText.toCharArray()); }

    public void saveToOutputStream(ByteWriter stream, String charsetName) throws IOException { saveToOutputStream(stream, Charset.get(charsetName).newEncoder()); }

    public void saveToDataStream(DataOutputStream stream) throws IOException { saveToOutputStream(stream == null ? null : stream.writer, (CharEncoder) null); }

    public void saveToOutputStream(ByteWriter stream) throws IOException { saveToOutputStream(stream, (CharEncoder) null); }

    public void clear() {
        fldState = fldMargin = 0;
        fldText.clear();
    }

    public boolean isEmpty() { return fldState == 0 && fldMargin == 0 && fldText.isEmpty(); }

    public void increaseMargin() { fldMargin++; }

    public void decreaseMargin() { fldMargin--; }

    public void print(CharArray src) {
        write(src);
        fldState = 1;
    }

    public void printHeader(CharArray header) {
        write(fldState > 0 ? fldLineSeparator : fldEmptyString);
        write(spaces(Int.max(fldMargin, 0) << 2));
        write(header);
        fldState = 1;
    }

    public void printLabel(CharArray label) {
        if(label == null || label.length <= 0) label = "\u0020\u0020\u0020\u0020\u0020@@";
        write(fldState > 0 ? fldLineSeparator : fldEmptyString);
        write(spaces(Int.max(fldMargin, 0) << 2));
        write(label);
        write(':');
        fldState = label.length + 1;
    }

    public void printInstruction(CharArray mnemonic) {
        if(mnemonic == null || mnemonic.length <= 0)
        {
            mnemonic = "nop";
        }
        int state = fldState;
        switch(state)
        {
        default:
            if(state < 12)
            {
                write(spaces(Int.max(12 - state, 1)));
                break;
            }
            /* падение через */
        case 0:
        case 1:
            write(state > 0 ? fldLineSeparator : fldEmptyString);
            write(spaces(Int.max(fldMargin, 0) + 3 << 2));
        }
        write(mnemonic);
        fldState = 1;
    }

    public void printInstruction(CharArray mnemonic, CharArray operand) {
        if(mnemonic == null || mnemonic.length <= 0)
        {
            mnemonic = "nop";
        }
        int state = fldState;
        switch(state)
        {
        default:
            if(state < 12)
            {
                write(spaces(Int.max(12 - state, 1)));
                break;
            }
            /* падение через */
        case 0:
        case 1:
            write(state > 0 ? fldLineSeparator : fldEmptyString);
            write(spaces(Int.max(fldMargin, 0) + 3 << 2));
        }
        write(mnemonic);
        write(spaces(Int.max(12 - mnemonic.length, 1)));
        write(operand);
        fldState = 1;
    }

    public void printInstruction(CharArray mnemonic, CharArray[] operands, int offset, int length) {
        if(mnemonic == null || mnemonic.length <= 0)
        {
            mnemonic = "nop";
        }
        if(operands == null)
        {
            offset = length = 0;
        } else
        {
            int2 bounds = Array.intersectBounds(operands, offset, length);
            offset = bounds[0];
            length = bounds[1];
        }
        int state = fldState;
        switch(state)
        {
        default:
            if(state < 12)
            {
                write(spaces(Int.max(12 - state, 1)));
                break;
            }
            /* падение через */
        case 0:
        case 1:
            write(state > 0 ? fldLineSeparator : fldEmptyString);
            write(spaces(Int.max(fldMargin, 0) + 3 << 2));
        }
        write(mnemonic);
        if(length > 0)
        {
            write(spaces(Int.max(12 - mnemonic.length, 1)));
        }
        for(int limit = offset + length - 1; offset <= limit; offset++)
        {
            write(operands[offset]);
            if(offset < limit) write(",\u0020");
        }
        fldState = 1;
    }

    public void printContinuation(CharArray[] operands, int offset, int length) {
        if(operands == null)
        {
            offset = length = 0;
        } else
        {
            int2 bounds = Array.intersectBounds(operands, offset, length);
            offset = bounds[0];
            length = bounds[1];
        }
        write(fldState > 0 ? fldLineSeparator : fldEmptyString);
        write(spaces(Int.max(fldMargin, 0) + 6 << 2));
        for(int limit = offset + length - 1; offset <= limit; offset++)
        {
            write(operands[offset]);
            if(offset < limit) write(",\u0020");
        }
        fldState = 1;
    }

    public void println() {
        write(fldLineSeparator);
        fldState = 0;
    }

    public void println(CharArray src) {
        write(src);
        write(fldLineSeparator);
        fldState = 0;
    }

    public void printlnHeader(CharArray header) {
        String lineSeparator = fldLineSeparator;
        write(fldState > 0 ? lineSeparator : fldEmptyString);
        write(spaces(Int.max(fldMargin, 0) << 2));
        write(header);
        write(lineSeparator);
        fldState = 0;
    }

    public void printlnLabel(CharArray label) {
        String lineSeparator = fldLineSeparator;
        if(label == null || label.length <= 0) label = "\u0020\u0020\u0020\u0020\u0020@@";
        write(fldState > 0 ? lineSeparator : fldEmptyString);
        write(spaces(Int.max(fldMargin, 0) << 2));
        write(label);
        write(':');
        write(lineSeparator);
        fldState = 0;
    }

    public void printlnInstruction(CharArray mnemonic) {
        if(mnemonic == null || mnemonic.length <= 0)
        {
            mnemonic = "nop";
        }
        int state = fldState;
        String lineSeparator = fldLineSeparator;
        switch(state)
        {
        default:
            if(state < 12)
            {
                write(spaces(Int.max(12 - state, 1)));
                break;
            }
            /* падение через */
        case 0:
        case 1:
            write(state > 0 ? lineSeparator : fldEmptyString);
            write(spaces(Int.max(fldMargin, 0) + 3 << 2));
        }
        write(mnemonic);
        write(lineSeparator);
        fldState = 0;
    }

    public void printlnInstruction(CharArray mnemonic, CharArray operand) {
        if(mnemonic == null || mnemonic.length <= 0)
        {
            mnemonic = "nop";
        }
        int state = fldState;
        String lineSeparator = fldLineSeparator;
        switch(state)
        {
        default:
            if(state < 12)
            {
                write(spaces(Int.max(12 - state, 1)));
                break;
            }
            /* падение через */
        case 0:
        case 1:
            write(state > 0 ? lineSeparator : fldEmptyString);
            write(spaces(Int.max(fldMargin, 0) + 3 << 2));
        }
        write(mnemonic);
        write(spaces(Int.max(12 - mnemonic.length, 1)));
        write(operand);
        write(lineSeparator);
        fldState = 0;
    }

    public void printlnInstruction(CharArray mnemonic, CharArray[] operands, int offset, int length) {
        if(mnemonic == null || mnemonic.length <= 0)
        {
            mnemonic = "nop";
        }
        if(operands == null)
        {
            offset = length = 0;
        } else
        {
            int2 bounds = Array.intersectBounds(operands, offset, length);
            offset = bounds[0];
            length = bounds[1];
        }
        int state = fldState;
        String lineSeparator = fldLineSeparator;
        switch(state)
        {
        default:
            if(state < 12)
            {
                write(spaces(Int.max(12 - state, 1)));
                break;
            }
            /* падение через */
        case 0:
        case 1:
            write(state > 0 ? lineSeparator : fldEmptyString);
            write(spaces(Int.max(fldMargin, 0) + 3 << 2));
        }
        write(mnemonic);
        if(length > 0)
        {
            write(spaces(Int.max(12 - mnemonic.length, 1)));
        }
        for(int limit = offset + length - 1; offset <= limit; offset++)
        {
            write(operands[offset]);
            if(offset < limit) write(",\u0020");
        }
        write(lineSeparator);
        fldState = 0;
    }

    public void printlnContinuation(CharArray[] operands, int offset, int length) {
        if(operands == null)
        {
            offset = length = 0;
        } else
        {
            int2 bounds = Array.intersectBounds(operands, offset, length);
            offset = bounds[0];
            length = bounds[1];
        }
        String lineSeparator = fldLineSeparator;
        write(fldState > 0 ? lineSeparator : fldEmptyString);
        write(spaces(Int.max(fldMargin, 0) + 6 << 2));
        for(int limit = offset + length - 1; offset <= limit; offset++)
        {
            write(operands[offset]);
            if(offset < limit) write(",\u0020");
        }
        write(lineSeparator);
        fldState = 0;
    }

    private void write(char src) { fldText.append(src); }

    private void write(CharArray src) {
        int length = src == null ? 0 : src.length;
        if(length > 0) fldText.append(src, 0, length);
    }

    private char[] spaces(int count) {
        char[] result = fldSpaces;
        if(count > result.length)
        {
            int capacity = AVTOOService.getBestArrayCapacity(count);
            Array.fill(result = fldSpaces = new char[capacity], 0, capacity, '\u0020');
        }
        result.length = count;
        return result;
    }
}