/*
Компилятор языка программирования
Объектно-ориентированный продвинутый векторный транслятор
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();
}
}