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