ArrayType.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 ArrayType(ClassType, Cloneable, Measureable, ObjectArray, AllocatableFactory, AVTOOConstants)
{
    private static Type check(Type componentType) {
        if(componentType == null)
        {
            throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "componentType" }));
        }
        return componentType;
    }

    private boolean fldCompilable;
    private final int fldDimensionsCount;
    private final Type fldComponentType;
    private final Type fldCellType;

    public (Type componentType):
        super(check(componentType).parentPackage, componentType.visibility, componentType.specialSimpleName + "[]", null, -1, -1, null) {
        if(!(componentType instanceof ArrayType))
        {
            fldDimensionsCount = 1;
            fldCellType = componentType;
        } else
        {
            ArrayType array = (ArrayType) componentType;
            fldDimensionsCount = array.fldDimensionsCount + 1;
            fldCellType = array.fldCellType;
        }
        fldComponentType = componentType;
    }

    public void makeCompilable() {
        if(!fldCompilable)
        {
            fldCompilable = true;
            for(Type componentType = fldComponentType; componentType instanceof ArrayType; )
            {
                ArrayType array = (ArrayType) componentType;
                array.fldCompilable = true;
                componentType = array.fldComponentType;
            }
        }
    }

    public boolean isCompilable() { return fldCompilable; }

    public boolean isAssignableFrom(Type anot) {
        if(anot == null)
        {
            throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "anot" }));
        }
        if(anot == this || anot.isNull()) return true;
        if(!(anot instanceof ArrayType)) return false;
        ArrayType array = (ArrayType) anot;
        int thisDimensionsCount = fldDimensionsCount;
        int anotDimensionsCount = array.fldDimensionsCount;
        if(thisDimensionsCount > anotDimensionsCount) return false;
        Type cell = array.fldComponentType;
        for(int dimCount = thisDimensionsCount; dimCount-- > 1; ) cell = ((ArrayType) cell).fldComponentType;
        return fldCellType.isAssignableFrom(cell);
    }

    public boolean isCompatibleWith(Type anot) {
        if(!(anot instanceof ArrayType)) return super.isCompatibleWith(anot);
        ArrayType array = (ArrayType) anot;
        int thisDimensionsCount = fldDimensionsCount;
        int anotDimensionsCount = array.fldDimensionsCount;
        Type typeA;
        Type typeB;
        if(thisDimensionsCount > anotDimensionsCount)
        {
            typeA = array.fldCellType;
            typeB = fldComponentType;
            for(int dimCount = anotDimensionsCount; dimCount-- > 1; ) typeB = ((ArrayType) typeB).fldComponentType;
        } else
        {
            typeA = fldCellType;
            typeB = array.fldComponentType;
            for(int dimCount = thisDimensionsCount; dimCount-- > 1; ) typeB = ((ArrayType) typeB).fldComponentType;
        }
        return typeA.isCompatibleWith(typeB);
    }

    public boolean isArray() { return true; }

    public final int dimensionsCount { read = fldDimensionsCount }

    public final Type componentType { read = fldComponentType }

    public final Type cellType { read = fldCellType }

    protected String composeRecompilableName() { return "[" + fldComponentType.recompilableName; }

    protected String composeFasmSimpleName() { return fldCellType.fasmSimpleName + composeFasmDimensionsCount(); }

    protected String composeFasmFullName() { return fasmSimpleName; }

    protected String composeFasmFileName() { return fldCellType.fasmFileName + composeFasmDimensionsCount(); }

    private String composeFasmDimensionsCount() {
        int dimensions = fldDimensionsCount;
        return new String(new char[] { '.', (char) ('0' + dimensions / 10), (char) ('0' + dimensions % 10), 'd' });
    }
}