AssemblerElementWriter.avt

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

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

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

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

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

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

package ru.malik.elaborarer.avtoo.generator;

import avt.lang.array.*;
import ru.malik.elaborarer.avtoo.lang.*;

public class AssemblerElementWriter(Object, AVTOOConstants)
{
    /*<fold флаги формирования сигнатуры типа>*/
    public static final int NORM  = 0;
    public static final int WEAK  = 1;
    public static final int STACK = 2;
    /*</fold>*/

    protected int fldOffset;
    protected char[] fldText;

    public () {  }

    public void trim() { fldText.length = fldOffset; }

    public char[] get() {
        char[] result = fldText;
        result.length = fldOffset;
        return result;
    }

    public AssemblerElementWriter set(char[] text, int offset) {
        fldText = text;
        fldOffset = offset;
        text.length = text.capacity;
        return this;
    }

    public AssemblerElementWriter writeChar(char character) {
        int offset = fldOffset;
        fldText[offset++] = character;
        fldOffset = offset;
        return this;
    }

    public AssemblerElementWriter writeLabel(char character, int label) {
        int length = 7;
        if(label >= 0x00010000 && label < 0x01000000)
        {
            length = 9;
        } else if(label >= 0x01000000 || label < 0x00000000)
        {
            length = 11;
        }
        int offset = fldOffset;
        for(char[] text = fldText, text[offset] = text[offset + 2] = '.', text[offset + 1] = character, offset += 3, int index = 3; index < length; index++)
        {
            text[offset++] = Char.toUpperCase(Char.toChar((label >> (length - index - 1 << 2)) & 0x0f));
        }
        fldOffset = offset;
        return this;
    }

    public AssemblerElementWriter writeLabel(int label) {
        int length = 7;
        if(label >= 0x00010000 && label < 0x01000000)
        {
            length = 9;
        } else if(label >= 0x01000000 || label < 0x00000000)
        {
            length = 11;
        }
        int offset = fldOffset;
        for(char[] text = fldText, text[offset++] = '.', text[offset++] = text[offset + length - 3] = '$', int index = 3; index < length; index++)
        {
            text[offset++] = Char.toChar((label >> (length - index - 1 << 2)) & 0x0f);
        }
        fldOffset = offset + 1;
        return this;
    }

    public AssemblerElementWriter writeOffset(int value) {
        int length = 2;
        if(value >= 0x00000010 && value < 0x00000100)
        {
            length = 3;
        } else if(value >= 0x00000100 && value < 0x00001000)
        {
            length = 4;
        } else if(value >= 0x00001000 && value < 0x00010000)
        {
            length = 5;
        } else if(value >= 0x00010000 && value < 0x00100000)
        {
            length = 6;
        } else if(value >= 0x00100000 && value < 0x01000000)
        {
            length = 7;
        } else if(value >= 0x01000000 && value < 0x10000000)
        {
            length = 8;
        } else if(value >= 0x10000000 || value < 0x00000000)
        {
            length = 9;
        }
        int offset = fldOffset;
        for(char[] text = fldText, text[offset++] = '$', int index = 1; index < length; index++)
        {
            text[offset++] = Char.toChar((value >> (length - index - 1 << 2)) & 0x0f);
        }
        fldOffset = offset;
        return this;
    }

    public AssemblerElementWriter writeByte(int value) {
        int offset = fldOffset;
        for(char[] text = fldText, text[offset++] = '$', int index = 1; index < 3; index++)
        {
            text[offset++] = Char.toChar((int) (value >> (2 - index << 2)) & 0x0f);
        }
        fldOffset = offset;
        return this;
    }

    public AssemblerElementWriter writeShort(int value) {
        int offset = fldOffset;
        for(char[] text = fldText, text[offset++] = '$', int index = 1; index < 5; index++)
        {
            text[offset++] = Char.toChar((int) (value >> (4 - index << 2)) & 0x0f);
        }
        fldOffset = offset;
        return this;
    }

    public AssemblerElementWriter writeInt(int value) {
        int offset = fldOffset;
        for(char[] text = fldText, text[offset++] = '$', int index = 1; index < 9; index++)
        {
            text[offset++] = Char.toChar((int) (value >> (8 - index << 2)) & 0x0f);
        }
        fldOffset = offset;
        return this;
    }

    public AssemblerElementWriter writeLong(long value) {
        int offset = fldOffset;
        for(char[] text = fldText, text[offset++] = '$', int index = 1; index < 17; index++)
        {
            text[offset++] = Char.toChar((int) (value >> (16 - index << 2)) & 0x0f);
        }
        fldOffset = offset;
        return this;
    }

    public AssemblerElementWriter writeDecimal(int value) {
        int offset = fldOffset;
        char[] text = fldText;
        if(value >= 0)
        {
            value = -value;
        } else
        {
            text[offset++] = '-';
        }
        int length = -1;
        if(value > -100 && value <= -10)
        {
            length = -2;
        } else if(value > -1000 && value <= -100)
        {
            length = -3;
        } else if(value > -10000 && value <= -1000)
        {
            length = -4;
        } else if(value > -100000 && value <= -10000)
        {
            length = -5;
        } else if(value > -1000000 && value <= -100000)
        {
            length = -6;
        } else if(value > -10000000 && value <= -1000000)
        {
            length = -7;
        } else if(value > -100000000 && value <= -10000000)
        {
            length = -8;
        } else if(value > -1000000000 && value <= -100000000)
        {
            length = -9;
        } else if(value <= -1000000000)
        {
            length = -10;
        }
        for(offset -= length, int index = 0; index-- > length; value /= 10)
        {
            text[offset + index] = (char) ('0' - value % 10);
        }
        fldOffset = offset;
        return this;
    }

    public AssemblerElementWriter writeString(CharSequence string) {
        int offset = fldOffset;
        string.copyInto(fldText, offset);
        fldOffset = offset + string.length;
        return this;
    }

    public AssemblerElementWriter writeString(CharSequence string, int beginIndex, int endIndex) {
        int offset = fldOffset;
        string.getChars(beginIndex, endIndex, fldText, offset);
        fldOffset = offset - beginIndex + endIndex;
        return this;
    }

    public AssemblerElementWriter writeLabel(Node node) {
        int label = node.debugIndex;
        return label >= 0 ? writeLabel('D', label) : writeLabel('L', node.labelIndex);
    }

    public AssemblerElementWriter writeSignature(int kind, int flags) {
        String signature;
        switch(kind)
        {
            case REF    : signature = (flags & WEAK) != 0 ? "w" : "r"; break;
            case CHAR   : signature = (flags & STACK) != 0 ? "i" : "c"; break;
            case REAL   : signature = "e"; break;
            case DOUBLE : signature = "d"; break;
            case DOUBLE2: signature = "d2"; break;
            case DOUBLE4: signature = "d4"; break;
            case DOUBLE8: signature = "d8"; break;
            case FLOAT  : signature = "f"; break;
            case FLOAT2 : signature = "f2"; break;
            case FLOAT4 : signature = "f4"; break;
            case FLOAT8 : signature = "f8"; break;
            case BOOLEAN:
            case BYTE   : signature = (flags & STACK) != 0 ? "i" : "b"; break;
            case BYTE2  : signature = "b2"; break;
            case BYTE4  : signature = "b4"; break;
            case BYTE8  : signature = "b8"; break;
            case SHORT  : signature = (flags & STACK) != 0 ? "i" : "s"; break;
            case SHORT2 : signature = "s2"; break;
            case SHORT4 : signature = "s4"; break;
            case SHORT8 : signature = "s8"; break;
            case INT    : signature = "i"; break;
            case INT2   : signature = "i2"; break;
            case INT4   : signature = "i4"; break;
            case INT8   : signature = "i8"; break;
            case LONG   : signature = "l"; break;
            case LONG2  : signature = "l2"; break;
            case LONG4  : signature = "l4"; break;
            case LONG8  : signature = "l8"; break;
            default     : signature = "";
        }
        return writeString(signature);
    }

    public AssemblerElementWriter writeSignature(Type type, int flags) {
        String signature;
        switch(type.kind)
        {
            case REF    : signature = (flags & WEAK) != 0 ? "w" : "r"; break;
            case CHAR   : signature = (flags & STACK) != 0 ? "i" : "c"; break;
            case REAL   : signature = "e"; break;
            case DOUBLE : signature = "d"; break;
            case DOUBLE2: signature = "d2"; break;
            case DOUBLE4: signature = "d4"; break;
            case DOUBLE8: signature = "d8"; break;
            case FLOAT  : signature = "f"; break;
            case FLOAT2 : signature = "f2"; break;
            case FLOAT4 : signature = "f4"; break;
            case FLOAT8 : signature = "f8"; break;
            case BOOLEAN:
            case BYTE   : signature = (flags & STACK) != 0 ? "i" : "b"; break;
            case BYTE2  : signature = "b2"; break;
            case BYTE4  : signature = "b4"; break;
            case BYTE8  : signature = "b8"; break;
            case SHORT  : signature = (flags & STACK) != 0 ? "i" : "s"; break;
            case SHORT2 : signature = "s2"; break;
            case SHORT4 : signature = "s4"; break;
            case SHORT8 : signature = "s8"; break;
            case INT    : signature = "i"; break;
            case INT2   : signature = "i2"; break;
            case INT4   : signature = "i4"; break;
            case INT8   : signature = "i8"; break;
            case LONG   : signature = "l"; break;
            case LONG2  : signature = "l2"; break;
            case LONG4  : signature = "l4"; break;
            case LONG8  : signature = "l8"; break;
            default     : signature = "";
        }
        return writeString(signature);
    }

    public final AssemblerElementWriter set(char[] text) { return set(text, 0); }

    public final int offset { read = fldOffset, write = fldOffset }
}