LexemeSequence.avt

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

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

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

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

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

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

package ru.malik.elaborarer.avtoo.lang;

import avt.lang.array.*;

public class LexemeSequence(Object, Cloneable, Measureable, MutableObjectArray, ObjectArray, AVTOOConstants)
{
    private int4[] fldLexemes;
    private Object[] fldObjects;
    private LongStorage fldLongs;
    private RealStorage fldReals;
    private FloatStorage fldFloats;
    private DoubleStorage fldDoubles;
    private StringStorage fldStrings;

    public () {
        (fldLexemes = new int4[0x3f]).length = 0;
        (fldObjects = new Object[0x3f]).length = 0;
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_NONE, 0);
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind, boolean lexemeValue) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_BOOLEAN, lexemeValue ? -1 : 0);
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind, char lexemeValue) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_CHAR, lexemeValue);
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind, byte lexemeValue) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_BYTE, lexemeValue);
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind, short lexemeValue) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_SHORT, lexemeValue);
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind, int lexemeValue) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_INT, lexemeValue);
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind, long lexemeValue) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_LONG, getLongs().indexAcquire(lexemeValue));
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind, float lexemeValue) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_FLOAT, getFloats().indexAcquire(lexemeValue));
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind, double lexemeValue) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_DOUBLE, getDoubles().indexAcquire(lexemeValue));
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind, real lexemeValue) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_REAL, getReals().indexAcquire(lexemeValue));
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind, String lexemeValue) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_STRING, getStrings().indexAcquire(lexemeValue));
    }

    public void appendLexeme(int lineIndex, int charIndex, int lexemeKind, Object component) {
        appendLexemeInternal(lineIndex, charIndex, lexemeKind, LT_NONE, 0, component);
    }

    public void insertLexeme(int position, int lineIndex, int charIndex, int lexemeKind) {
        int4[] lexemes = fldLexemes;
        Object[] objects = fldObjects;
        int length = lexemes.length;
        if(length == lexemes.capacity)
        {
            if(length == Int.MAX_VALUE)
            {
                throw new BufferTooLargeError(avt.lang.package.getResourceString("!error.buffer-too-large"));
            }
            int capacity = length << 1 | 1;
            Array.copy(lexemes, 0, fldLexemes = lexemes = new int4[capacity], 0, length);
            Array.copy(objects, 0, fldObjects = objects = new Object[capacity], 0, length);
        }
        if(position < 0) position = 0;
        if(position > length) position = length;
        int positionPlus1 = position + 1;
        int lengthForCopy = length++ - position;
        lexemes.length = objects.length = length;
        Array.copy(lexemes, position, lexemes, positionPlus1, lengthForCopy);
        Array.copy(objects, position, objects, positionPlus1, lengthForCopy);
        lexemes[position] = new int4 { lineIndex, charIndex, lexemeKind << 4, 0 };
        objects[position] = null;
    }

    public void setLexeme(int position, int lineIndex, int charIndex, int lexemeKind) { fldLexemes[position] = new int4 { lineIndex, charIndex, lexemeKind << 4, 0 }; }

    public void removeLexeme(int position) {
        int4[] lexemes = fldLexemes;
        Object[] objects = fldObjects;
        int length = lexemes.length;
        if(position < 0 || position >= length)
        {
            throw new IndexOutOfBoundsException(avt.lang.package.getResourceString("out-of-bounds.index"));
        }
        int positionPlus1 = position + 1;
        int lengthForCopy = length-- - positionPlus1;
        Array.copy(lexemes, positionPlus1, lexemes, position, lengthForCopy);
        Array.copy(objects, positionPlus1, objects, position, lengthForCopy);
        lexemes[length] = 0;
        objects[length] = null;
        lexemes.length = objects.length = length;
    }

    public int getLineIndex(int position) { return fldLexemes[position][0]; }

    public int getCharIndex(int position) { return fldLexemes[position][1]; }

    public int getLexemeKind(int position) { return fldLexemes[position][2] >> 4; }

    public int getLexemeType(int position) { return fldLexemes[position][2] & 0x0f; }

    public int2 getLexemeLocation(int position) { return (int2) fldLexemes[position]; }

    public int4 getLexemeInfo(int position) {
        int4 info = fldLexemes[position];
        int kind = info[2];
        return Int4.create((int2) info, new int2 { kind >> 4, kind & 0x0f });
    }

    public boolean getLexemeBoolean(int position) {
        int4 info = fldLexemes[position];
        switch(info[2] & 0x0f)
        {
        case LT_BOOLEAN:
            return info[3] != 0;
        default:
            throw new IllegalLexemeTypeException(package.getResourceString("illegal-type.lexeme"));
        }
    }

    public char getLexemeChar(int position) {
        int4 info = fldLexemes[position];
        switch(info[2] & 0x0f)
        {
        case LT_CHAR:
            return (char) info[3];
        default:
            throw new IllegalLexemeTypeException(package.getResourceString("illegal-type.lexeme"));
        }
    }

    public int getLexemeInt(int position) {
        int4 info = fldLexemes[position];
        switch(info[2] & 0x0f)
        {
        case LT_BYTE:
        case LT_SHORT:
        case LT_INT:
            return info[3];
        default:
            throw new IllegalLexemeTypeException(package.getResourceString("illegal-type.lexeme"));
        }
    }

    public long getLexemeLong(int position) {
        int4 info = fldLexemes[position];
        switch(info[2] & 0x0f)
        {
        case LT_BYTE:
        case LT_SHORT:
        case LT_INT:
            return info[3];
        case LT_LONG:
            return fldLongs[info[3]];
        default:
            throw new IllegalLexemeTypeException(package.getResourceString("illegal-type.lexeme"));
        }
    }

    public float getLexemeFloat(int position) {
        int4 info = fldLexemes[position];
        switch(info[2] & 0x0f)
        {
        case LT_FLOAT:
            return fldFloats[info[3]];
        default:
            throw new IllegalLexemeTypeException(package.getResourceString("illegal-type.lexeme"));
        }
    }

    public double getLexemeDouble(int position) {
        int4 info = fldLexemes[position];
        switch(info[2] & 0x0f)
        {
        case LT_FLOAT:
            return fldFloats[info[3]];
        case LT_DOUBLE:
            return fldDoubles[info[3]];
        default:
            throw new IllegalLexemeTypeException(package.getResourceString("illegal-type.lexeme"));
        }
    }

    public real getLexemeReal(int position) {
        int4 info = fldLexemes[position];
        switch(info[2] & 0x0f)
        {
        case LT_FLOAT:
            return fldFloats[info[3]];
        case LT_DOUBLE:
            return fldDoubles[info[3]];
        case LT_REAL:
            return fldReals[info[3]];
        default:
            throw new IllegalLexemeTypeException(package.getResourceString("illegal-type.lexeme"));
        }
    }

    public String getLexemeString(int position) {
        int4 info = fldLexemes[position];
        switch(info[2] & 0x0f)
        {
        case LT_STRING:
            return fldStrings[info[3]];
        default:
            throw new IllegalLexemeTypeException(package.getResourceString("illegal-type.lexeme"));
        }
    }

    public int length { read = fldLexemes.length }

    public void operator []=(int position, Object component) { fldObjects[position] = component; }

    public Object operator [](int position) { return fldObjects[position]; }

    private void appendLexemeInternal(int lineIndex, int charIndex, int lexemeKind, int lexemeType, int lexemeValue) {
        int4[] lexemes = fldLexemes;
        Object[] objects = fldObjects;
        int length = lexemes.length;
        if(length == lexemes.capacity)
        {
            if(length == Int.MAX_VALUE)
            {
                throw new BufferTooLargeError(avt.lang.package.getResourceString("!error.buffer-too-large"));
            }
            int capacity = length << 1 | 1;
            Array.copy(lexemes, 0, fldLexemes = lexemes = new int4[capacity], 0, length);
            Array.copy(objects, 0, fldObjects = objects = new Object[capacity], 0, length);
        }
        lexemes.length = objects.length = length + 1;
        lexemes[length] = new int4 { lineIndex, charIndex, lexemeKind << 4 | lexemeType, lexemeValue };
    }

    private void appendLexemeInternal(int lineIndex, int charIndex, int lexemeKind, int lexemeType, int lexemeValue, Object component) {
        int4[] lexemes = fldLexemes;
        Object[] objects = fldObjects;
        int length = lexemes.length;
        if(length == lexemes.capacity)
        {
            if(length == Int.MAX_VALUE)
            {
                throw new BufferTooLargeError(avt.lang.package.getResourceString("!error.buffer-too-large"));
            }
            int capacity = length << 1 | 1;
            Array.copy(lexemes, 0, fldLexemes = lexemes = new int4[capacity], 0, length);
            Array.copy(objects, 0, fldObjects = objects = new Object[capacity], 0, length);
        }
        lexemes.length = objects.length = length + 1;
        lexemes[length] = new int4 { lineIndex, charIndex, lexemeKind << 4 | lexemeType, lexemeValue };
        objects[length] = component;
    }

    private LongStorage getLongs() {
        LongStorage result = fldLongs;
        return result != null ? result : fldLongs = new LongStorage();
    }

    private RealStorage getReals() {
        RealStorage result = fldReals;
        return result != null ? result : fldReals = new RealStorage();
    }

    private FloatStorage getFloats() {
        FloatStorage result = fldFloats;
        return result != null ? result : fldFloats = new FloatStorage();
    }

    private DoubleStorage getDoubles() {
        DoubleStorage result = fldDoubles;
        return result != null ? result : fldDoubles = new DoubleStorage();
    }

    private StringStorage getStrings() {
        StringStorage result = fldStrings;
        return result != null ? result : fldStrings = new StringStorage();
    }
}