Changed lexer from iterator to buffer based code

This commit is contained in:
Willem Cazander 2025-01-16 22:08:56 +01:00
parent c2371ebaa3
commit 4454a4d322
2 changed files with 232 additions and 238 deletions

View file

@ -159,13 +159,13 @@ public enum FCDotDEC0127DashPX0 implements FourCornerX06BaklavaPoints, FourCorne
/// A = 1, first P6 is terminator select, than next P6 _A++ select pie part 1-27, until other P6 stops it. /// A = 1, first P6 is terminator select, than next P6 _A++ select pie part 1-27, until other P6 stops it.
/// Example ascii "012" is /// Example ascii "012" is
/// 012 = __PIE NX10_J NX01_A NX02_B NX02_C /// 012 = __PIE NX10_J NX01_A NX02_B NX02_C
/// TODO: Add negative A for -1 to -27 as P6 symbols to select PIE9D + map in __RESERVED_PIE_SYMBOLS /// TODO: Add negative AT for -1 to -27 as P6 symbols to select PIE9D + map in __RESERVED_PIE_SYMBOLS
ESC68_PIE, ESC68_PIE,
/// _ESC6_X3 _ESC6_X3 _ESC6_X2 /// _ESC6_X3 _ESC6_X3 _ESC6_X2
/// Select packed pie terminator number for 6 and 8 bit systems. /// Select packed pie terminator number for 6 and 8 bit systems.
/// First NXX P6 is terminator select, than next NXX P6 are values, until out of range. /// First NXX P6 is terminator select, than next NXX P6 are values, until out of range.
/// TODO: Double range to 54 with the negative A (= symbols) for -1=AT=28 -2=BAR_V_RIGHT=29 /// TODO: Double range to 54 with the negative AT (= symbols) for -1=AT=28 -2=BAR_V_RIGHT=29
ESC68_NCR, ESC68_NCR,
/// _ESC6_X3 _ESC6_X3 _ESC6_X3 /// _ESC6_X3 _ESC6_X3 _ESC6_X3

View file

@ -24,7 +24,6 @@ package org.x4o.fc18.zion7;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
@ -47,9 +46,12 @@ public class FourCornerZionStenoLexer {
private final FourCornerZion7AlphaOmega handlerDocument; private final FourCornerZion7AlphaOmega handlerDocument;
private final FourCornerZion7SalahSequence handlerSalahSequence; private final FourCornerZion7SalahSequence handlerSalahSequence;
private final FourCornerZion7TempleScrolls handlerTempleScrolls; private final FourCornerZion7TempleScrolls handlerTempleScrolls;
private final List<StenoScanner> scanners = new ArrayList<>(); private final List<StenoScanner> scanners = new ArrayList<>(); // TODO: make static is WIP
private final int denominatorBank[] = new int[64]; // <== is the terminator select per 9 bit group
private final int numeratorBank[] = new int[denominatorBank.length];
private List<Integer> input;
private int inputIndex = 0;
private int readLevel = 0; private int readLevel = 0;
private Integer cakePoint = null;
private int currLine = 0; private int currLine = 0;
private int currCol = 0; private int currCol = 0;
private FourCornerZionStenoLexerSmoke smokeSignals = CLEAN_SMOKE; private FourCornerZionStenoLexerSmoke smokeSignals = CLEAN_SMOKE;
@ -133,10 +135,79 @@ public class FourCornerZionStenoLexer {
} }
} }
abstract private class StenoScanner { public void read(List<Integer> points) {
input = Objects.requireNonNull(points);
readLevel++; // first puts on one, we allow level deep
if (readLevel > 2) {
smokeSignals.burnRecursive(currLine, currCol);
return;
}
if (readLevel == 1) {
inputIndex = 0;
currLine = 0;
currCol = 0; // allow reuse of lexer
handlerDocument.strobeDocumentAlpha();
}
while (true) {
ScanResult run = ScanResult.DONE;
while (run.isDone()) {
run = readTokens(); // FIXME: remove triple looper to ones here
if (run.isEOF()) {
break;
}
break;
}
if (run.isEOF()) {
break;
}
if (!run.isDone()) {
smokeSignals.burnUnsupported(currLine, currCol, input.get(inputIndex));
}
}
if (readLevel == 1) {
handlerDocument.strobeDocumentOmega();
}
readLevel--;
}
private ScanResult readTokens() {
ScanResult result = ScanResult.NEXT;
for (StenoScanner scanner : scanners) {
result = scanner.scan(this);
if (result.isEOF()) {
return result;
}
if (result.isDone()) {
return result;
}
}
if (!safeNext()) {
return ScanResult.EOF;
}
return result;
}
private boolean safeHasNext() {
if (inputIndex + 1 < input.size()) {
return true;
}
return false;
}
private boolean safeNext() {
if (!safeHasNext()) {
return false;
}
inputIndex++;
currCol++;
fireSignals.fireStateColumn(currCol);
return true;
}
abstract static private class StenoScanner {
private final int blockStart; protected final int blockStart;
private final int blockStop; protected final int blockStop;
public StenoScanner(int blockStart, int blockStop) { public StenoScanner(int blockStart, int blockStop) {
this.blockStart = blockStart; this.blockStart = blockStart;
@ -147,100 +218,37 @@ public class FourCornerZionStenoLexer {
this(cakeSlice.getStart(), cakeSlice.getStop()); this(cakeSlice.getStart(), cakeSlice.getStop());
} }
final public ScanResult scan(Iterator<Integer> input) { final public ScanResult scan(FourCornerZionStenoLexer lexer) {
int cakePoint = lexer.input.get(lexer.inputIndex);
if (cakePoint < blockStart || cakePoint > blockStop) { if (cakePoint < blockStart || cakePoint > blockStop) {
return ScanResult.NEXT; return ScanResult.NEXT;
} }
fireSignals.fireStateScanner(blockStart, blockStop, cakePoint); lexer.fireSignals.fireStateScanner(blockStart, blockStop, cakePoint); // TODO: move below and add idxStart/stop + next
return process(input); ScanResult result = ScanResult.DONE;
int idxStart = lexer.inputIndex;
int idxStop = lexer.inputIndex;
while (true) {
cakePoint = lexer.input.get(lexer.inputIndex);
if (cakePoint < blockStart || cakePoint > blockStop) {
break;
}
idxStop = lexer.inputIndex;
if (lexer.safeNext() == false) {
result = ScanResult.EOF;
break;
}
}
//System.out.println("PROCESS: " + lexer.input.size() + " start: " + idxStart + " stop: " + idxStop + " currenId: " + lexer.inputIndex);
process(lexer, idxStart, idxStop);
return result;
} }
abstract ScanResult process(Iterator<Integer> input); abstract void process(FourCornerZionStenoLexer lexer, int idxStart, int idxStop);
protected ScanResult safeReadCakePoints(Iterator<Integer> input, List<Integer> result) {
return safeReadRanged(input, blockStart, blockStop, result, false);
}
protected ScanResult safeReadSliceOffsets(Iterator<Integer> input, List<Integer> result) {
return safeReadRanged(input, blockStart, blockStop, result, true);
}
} }
public void read(List<Integer> points) { static class StenoScannerWordCakeSlice extends StenoScanner {
read(points.iterator());
}
public void read(Iterator<Integer> points) {
Iterator<Integer> input = Objects.requireNonNull(points);
readLevel++; // first puts on one, we allow level deep
if (readLevel > 2) {
smokeSignals.burnRecursive(currLine, currCol);
return;
}
if (readLevel == 1) {
cakePoint = null; // allow reuse of lexer
currLine = 0;
currCol = 0;
handlerDocument.strobeDocumentAlpha();
}
while (input.hasNext()) {
if (safeNext(input).isEOF()) {
break;
}
ScanResult run = ScanResult.DONE;
while (run.isDone()) {
run = readTokens(input);
}
if (run.isEOF()) {
break;
}
smokeSignals.burnUnsupported(currLine, currCol, cakePoint);
}
if (readLevel == 1) {
handlerDocument.strobeDocumentOmega();
}
readLevel--;
}
private ScanResult readTokens(Iterator<Integer> input) {
ScanResult result = ScanResult.NEXT;
for (StenoScanner scanner : scanners) {
result = scanner.scan(input);
if (result.isEOF()) {
return result;
}
if (result.isDone()) {
return result;
}
}
return result;
}
private ScanResult safeNext(Iterator<Integer> input) {
if (!input.hasNext()) {
return ScanResult.EOF;
}
cakePoint = input.next();
currCol++;
fireSignals.fireStateColumn(currCol);
return ScanResult.DONE;
}
private ScanResult safeReadRanged(Iterator<Integer> input, int start, int stop, List<Integer> result, boolean offset) {
while (cakePoint >= start && cakePoint <= stop) {
if (offset) {
result.add(cakePoint - start);
} else {
result.add(cakePoint);
}
if (safeNext(input).isEOF()) {
return ScanResult.EOF;
}
}
return ScanResult.DONE;
}
class StenoScannerWordCakeSlice extends StenoScanner {
private final FourCornerDotCake cakeSlice; private final FourCornerDotCake cakeSlice;
@ -250,78 +258,60 @@ public class FourCornerZionStenoLexer {
} }
@Override @Override
public ScanResult process(Iterator<Integer> input) { public void process(FourCornerZionStenoLexer lexer, int idxStart, int idxStop) {
List<Integer> result = new ArrayList<>(); List<Integer> offsets = lexer.input.subList(idxStart, idxStop + 1);
ScanResult status = safeReadSliceOffsets(input, result); for (int i = 0; i < offsets.size(); i++) {
if (!result.isEmpty()) { offsets.set(i, offsets.get(i) - blockStart);
handler.strobeWords(cakeSlice, result);
} }
return status; lexer.handler.strobeWords(cakeSlice, offsets);
} }
} }
class StenoScannerNether extends StenoScanner { static class StenoScannerNether extends StenoScanner {
public StenoScannerNether() { public StenoScannerNether() {
super(FourCornerDotCake.FC_NETHER); super(FourCornerDotCake.FC_NETHER);
} }
@Override @Override
public ScanResult process(Iterator<Integer> input) { public void process(FourCornerZionStenoLexer lexer, int idxStart, int idxStop) {
List<Integer> result = new ArrayList<>();
ScanResult status = safeReadCakePoints(input, result);
if (!result.isEmpty()) {
handlePoints(result);
}
return status;
} }
private void handlePoints(List<Integer> slicedPoints) { private void handlePoints(FourCornerZionStenoLexer lexer, List<Integer> slicedPoints) {
// TODO: convert from 15 bit to 3 bit // TODO: convert from 15 bit to 3 bit
handler.strobeNether(null, slicedPoints); lexer.handler.strobeNether(null, slicedPoints);
} }
} }
class StenoScannerNCR18 extends StenoScanner { static class StenoScannerNCR18 extends StenoScanner {
private final int denominatorBank[] = new int[64]; // <== is the terminator select per 9 bit group
private final int numeratorBank[] = new int[denominatorBank.length];
public StenoScannerNCR18() { public StenoScannerNCR18() {
super(FourCornerDotCake.FC_NCR1632_XD.getStart(), FourCornerDotCake.FC_NCR1632_XN.getStop()); super(FourCornerDotCake.FC_NCR1632_XD.getStart(), FourCornerDotCake.FC_NCR1632_XN.getStop());
} }
@Override @Override
public ScanResult process(Iterator<Integer> input) { public void process(FourCornerZionStenoLexer lexer, int idxStart, int idxStop) {
List<Integer> result = new ArrayList<>(); bankReset(lexer);
ScanResult status = safeReadCakePoints(input, result);
if (!result.isEmpty()) {
handlePoints(result); // mix of the two blocks
}
return status;
}
private void handlePoints(List<Integer> slicedPoints) {
bankReset();
boolean magicSparkler = true; boolean magicSparkler = true;
boolean requestBankReset = false; boolean requestBankReset = false;
for (Integer cakePoint : slicedPoints) { for (int i = idxStart; i <= idxStop; i++) {
int cakePoint = lexer.input.get(i);
if (cakePoint >= FourCornerDotCake.FC_NCR1632_XD.getStart() && cakePoint <= FourCornerDotCake.FC_NCR1632_XD.getStop()) { if (cakePoint >= FourCornerDotCake.FC_NCR1632_XD.getStart() && cakePoint <= FourCornerDotCake.FC_NCR1632_XD.getStop()) {
int denominatorX = cakePoint - FourCornerDotCake.FC_NCR1632_XD.getStart(); int denominatorX = cakePoint - FourCornerDotCake.FC_NCR1632_XD.getStart();
denominatorBank[denominatorX / 512] = denominatorX % 512; lexer.denominatorBank[denominatorX / 512] = denominatorX % 512;
magicSparkler = true; magicSparkler = true;
continue; continue;
} }
int numeratorX = cakePoint - FourCornerDotCake.FC_NCR1632_XN.getStart(); int numeratorX = cakePoint - FourCornerDotCake.FC_NCR1632_XN.getStart();
numeratorBank[numeratorX / 512] = numeratorX % 512; lexer.numeratorBank[numeratorX / 512] = numeratorX % 512;
// highest number, 1st select + enable request, if second than reset bank // highest number, 1st select + enable request, if second than reset bank
if (cakePoint == FourCornerDotCake.FC_NCR1632_XN.getStop()) { if (cakePoint == FourCornerDotCake.FC_NCR1632_XN.getStop()) {
if (requestBankReset) { if (requestBankReset) {
requestBankReset = false; requestBankReset = false;
magicSparkler = false; // if EOF ends with bank reset, ignore lexer.fireSignals.fireStateNCR1632BankReset();
fireSignals.fireStateNCR1632BankReset(); bankReset(lexer);
bankReset(); magicSparkler = false; // if block ends with bank reset, don't leak a sparkler
continue; continue;
} }
requestBankReset = true; requestBankReset = true;
@ -333,56 +323,48 @@ public class FourCornerZionStenoLexer {
magicSparkler = true; magicSparkler = true;
continue; // Only fire fraction on lowest value select continue; // Only fire fraction on lowest value select
} else } else
bankFire(); bankFire(lexer);
magicSparkler = false; magicSparkler = false;
} }
if (magicSparkler) { if (magicSparkler) {
fireSignals.fireStateNCR1632BankSparkler(); lexer.fireSignals.fireStateNCR1632BankSparkler();
bankFire(); bankFire(lexer);
} }
} }
private void bankReset() { private void bankReset(FourCornerZionStenoLexer lexer) {
for (int i = 0; i < denominatorBank.length; i++) { for (int i = 0; i < lexer.denominatorBank.length; i++) {
denominatorBank[i] = 0; lexer.denominatorBank[i] = 0;
numeratorBank[i] = 0; lexer.numeratorBank[i] = 0;
} }
} }
private void bankFire() { private void bankFire(FourCornerZionStenoLexer lexer) {
BigInteger denominator = BigInteger.ONE; BigInteger denominator = BigInteger.ONE;
for (int i = 0; i < denominatorBank.length; i++) { for (int i = 0; i < lexer.denominatorBank.length; i++) {
denominator = denominator.add(BigInteger.valueOf(denominatorBank[i]).shiftLeft(i * 9)); denominator = denominator.add(BigInteger.valueOf(lexer.denominatorBank[i]).shiftLeft(i * 9));
} }
BigInteger numerator = BigInteger.ONE; BigInteger numerator = BigInteger.ONE;
for (int i = 0; i < numeratorBank.length; i++) { for (int i = 0; i < lexer.numeratorBank.length; i++) {
numerator = numerator.add(BigInteger.valueOf(numeratorBank[i]).shiftLeft(i * 9)); numerator = numerator.add(BigInteger.valueOf(lexer.numeratorBank[i]).shiftLeft(i * 9));
} }
handler.strobeNCR1632(denominator, numerator); lexer.handler.strobeNCR1632(denominator, numerator);
} }
} }
class StenoScannerUNI21 extends StenoScanner { static class StenoScannerUNI21 extends StenoScanner {
public StenoScannerUNI21() { public StenoScannerUNI21() {
super(FourCornerDotCake.FC_UNI2K_11.getStart(), FourCornerDotCake.FC_UNI2K_22.getStop()); super(FourCornerDotCake.FC_UNI2K_11.getStart(), FourCornerDotCake.FC_UNI2K_22.getStop());
} }
@Override @Override
public ScanResult process(Iterator<Integer> input) { public void process(FourCornerZionStenoLexer lexer, int idxStart, int idxStop) {
List<Integer> result = new ArrayList<>();
ScanResult status = safeReadCakePoints(input, result);
if (!result.isEmpty()) {
handlePoints(result); // mix of the two unicode blocks pages
}
return status;
}
private void handlePoints(List<Integer> slicedPoints) {
boolean errorUnusedBigIndian = false; // are optional boolean errorUnusedBigIndian = false; // are optional
List<Integer> result = new ArrayList<>(); List<Integer> result = new ArrayList<>();
int codePoint22 = 0; int codePoint22 = 0;
for (Integer cakePoint : slicedPoints) { for (int i = idxStart; i <= idxStop; i++) {
int cakePoint = lexer.input.get(i);
if (cakePoint >= FourCornerDotCake.FC_UNI2K_22.getStart() && cakePoint <= FourCornerDotCake.FC_UNI2K_22.getStop()) { if (cakePoint >= FourCornerDotCake.FC_UNI2K_22.getStart() && cakePoint <= FourCornerDotCake.FC_UNI2K_22.getStop()) {
codePoint22 = cakePoint - FourCornerDotCake.FC_UNI2K_22.getStart(); codePoint22 = cakePoint - FourCornerDotCake.FC_UNI2K_22.getStart();
errorUnusedBigIndian = true; errorUnusedBigIndian = true;
@ -394,84 +376,84 @@ public class FourCornerZionStenoLexer {
errorUnusedBigIndian = false; errorUnusedBigIndian = false;
} }
if (errorUnusedBigIndian) { if (errorUnusedBigIndian) {
smokeSignals.burnUNI21UnusedBigIndian(currLine, currCol); lexer.smokeSignals.burnUNI21UnusedBigIndian(lexer.currLine, lexer.currCol);
} }
if (!result.isEmpty()) { if (!result.isEmpty()) {
handler.strobeUnicode(result); lexer.handler.strobeUnicode(result);
} }
} }
} }
class StenoScannerCDCDEC extends StenoScanner { static class StenoScannerCDCDEC extends StenoScanner {
// TODO: remove state here
private Integer numberMode = null; private Integer numberMode = null;
private boolean numberPIE = true; private boolean numberPIE = true;
private FCDotDEC0127DashPX0 decMode = null; private FCDotDEC0127DashPX0 decMode = null;
private int scanIndex = 0;
private int scanIndexEnd = 0;
public StenoScannerCDCDEC() { public StenoScannerCDCDEC() {
super(FourCornerDotCake.FC_CDC1604_P6.getStart(), FourCornerDotCake.FC_DEC0127_PX0.getStop()); super(FourCornerDotCake.FC_CDC1604_P6.getStart(), FourCornerDotCake.FC_DEC0127_PX0.getStop());
} }
@Override @Override
public ScanResult process(Iterator<Integer> input) { public void process(FourCornerZionStenoLexer lexer, int idxStart, int idxStop) {
List<Integer> result = new ArrayList<>();
ScanResult status = safeReadCakePoints(input, result);
if (!result.isEmpty()) {
handlePoints(result);
}
return status;
}
private void handlePoints(List<Integer> slicedPoints) {
Iterator<Integer> cdc = slicedPoints.iterator();
numberMode = null; numberMode = null;
numberPIE = true; numberPIE = true;
while (cdc.hasNext()) { scanIndex = idxStart;
Integer cdcDECPoint = cdc.next(); scanIndexEnd = idxStop;
for (scanIndex = idxStart; scanIndex <= idxStop; scanIndex++) {
int cdcDECPoint = lexer.input.get(scanIndex);
// Log state changes // Log state changes
if (FCDotCDC1604DashP6._NEWLINE.ordinal() == cdcDECPoint) { if (FCDotCDC1604DashP6._NEWLINE.ordinal() == cdcDECPoint) {
currLine++; lexer.currLine++;
currCol = 0; lexer.currCol = 0;
fireSignals.fireStateLine(currLine); lexer.fireSignals.fireStateLine(lexer.currLine);
fireSignals.fireStateColumn(currCol); lexer.fireSignals.fireStateColumn(lexer.currCol);
} }
if (handlerEscape) { // No escaping, print CDC or DEC code
// Handle 6 bit CDC and DEC codes if (!lexer.handlerEscape) {
handleCDCDEC(cdc, cdcDECPoint, null); if (FourCornerDotCake.FC_DEC0127_PX0.contains(cdcDECPoint)) {
} else if (FourCornerDotCake.FC_DEC0127_PX0.contains(cdcDECPoint)) { lexer.handler.strobeWords(FourCornerDotCake.FC_DEC0127_PX0, List.of(cdcDECPoint - FourCornerDotCake.FC_DEC0127_PX0.getStart()));
// No escaping, print DEC code for 8 and 18 bit } else {
handler.strobeWords(FourCornerDotCake.FC_DEC0127_PX0, List.of(cdcDECPoint - FourCornerDotCake.FC_DEC0127_PX0.getStart())); lexer.handler.strobeWords(FourCornerDotCake.FC_CDC1604_P6, List.of(cdcDECPoint));
} else { }
// No escaping, print CDC code continue;
handler.strobeWords(FourCornerDotCake.FC_CDC1604_P6, List.of(cdcDECPoint));
} }
// Handle 6 bit CDC and DEC codes
handleCDCDEC(lexer, cdcDECPoint, null);
} }
} }
private FCDotDEC0127DashPX0 readEscape6(Iterator<Integer> cdc, Integer cdcPoint) { private FCDotDEC0127DashPX0 readEscape6(FourCornerZionStenoLexer lexer, int cdcPoint1) {
// Read 8 or 18 bit Direct Escape Code // Read 8 or 18 bit Direct Escape Code
if (FourCornerDotCake.FC_DEC0127_PX0.contains(cdcPoint)) { if (FourCornerDotCake.FC_DEC0127_PX0.contains(cdcPoint1)) {
return FCDotDEC0127DashPX0.valueOfCakePoint(cdcPoint); System.out.println("readEscape6 upper : " + cdcPoint1);
return FCDotDEC0127DashPX0.valueOfCakePoint(cdcPoint1);
} }
// Read 6 bit escape code // Read 6 bit escape code
FCDotCDC1604DashP6 x1 = FCDotCDC1604DashP6.valueOf(cdcPoint); FCDotCDC1604DashP6 x1 = FCDotCDC1604DashP6.valueOf(cdcPoint1);
FCDotCDC1604DashP6 x2 = null; FCDotCDC1604DashP6 x2 = null;
FCDotCDC1604DashP6 x3 = null; FCDotCDC1604DashP6 x3 = null;
if (!cdc.hasNext()) { if (scanIndex >= scanIndexEnd) {
return null; return null;
} }
cdcPoint = cdc.next(); scanIndex++;
if (FCDotCDC1604DashP6.isEscape6(cdcPoint)) { int cdcPoint2 = lexer.input.get(scanIndex);
x2 = FCDotCDC1604DashP6.valueOf(cdcPoint); if (FCDotCDC1604DashP6.isEscape6(cdcPoint2)) {
x2 = FCDotCDC1604DashP6.valueOf(cdcPoint2);
} else { } else {
return null; return null;
} }
if (!cdc.hasNext()) { if (scanIndex >= scanIndexEnd) {
return null; return null;
} }
cdcPoint = cdc.next(); scanIndex++;
if (FCDotCDC1604DashP6.isEscape6(cdcPoint)) { int cdcPoint3 = lexer.input.get(scanIndex);
x3 = FCDotCDC1604DashP6.valueOf(cdcPoint); if (FCDotCDC1604DashP6.isEscape6(cdcPoint3)) {
x3 = FCDotCDC1604DashP6.valueOf(cdcPoint3);
} else { } else {
return null; return null;
} }
@ -479,7 +461,9 @@ public class FourCornerZionStenoLexer {
} }
/// note; cdcPoint is always CDC or direct DEC escape code /// note; cdcPoint is always CDC or direct DEC escape code
private void handleCDCDEC(Iterator<Integer> cdc, Integer cdcPoint, FCDotDEC0127DashPX0 startMode) { private void handleCDCDEC(FourCornerZionStenoLexer lexer, int cdcPoint, FCDotDEC0127DashPX0 startMode) {
// TODO: make simple
if (startMode != null) { if (startMode != null) {
numberMode = null; numberMode = null;
@ -488,70 +472,76 @@ public class FourCornerZionStenoLexer {
// Start of escape // Start of escape
if (FCDotCDC1604DashP6.isEscape6(cdcPoint) || FourCornerDotCake.FC_DEC0127_PX0.contains(cdcPoint)) { if (FCDotCDC1604DashP6.isEscape6(cdcPoint) || FourCornerDotCake.FC_DEC0127_PX0.contains(cdcPoint)) {
numberMode = null; // out of range, thus stop numberMode = null; // out of range, thus stop
decMode = readEscape6(cdc, cdcPoint); decMode = readEscape6(lexer, cdcPoint);
if (decMode == null) { if (decMode == null) {
smokeSignals.burnInvalidEscape(currLine, currCol, cdcPoint); lexer.smokeSignals.burnInvalidEscape(lexer.currLine, lexer.currCol, cdcPoint);
return; return;
} }
if (decMode == FCDotDEC0127DashPX0.ESC68_PIE || decMode == FCDotDEC0127DashPX0.ESC68_NCR) { if (decMode == FCDotDEC0127DashPX0.ESC68_PIE || decMode == FCDotDEC0127DashPX0.ESC68_NCR) {
if (!cdc.hasNext()) { if (scanIndex >= scanIndexEnd) {
return; return;
} }
numberMode = cdc.next(); scanIndex++;
numberMode = lexer.input.get(scanIndex);
numberPIE = decMode == FCDotDEC0127DashPX0.ESC68_PIE; // is false for NCR numberPIE = decMode == FCDotDEC0127DashPX0.ESC68_PIE; // is false for NCR
if (numberMode < FCDotCDC1604DashP6.NX01_A.ordinal()) { if (numberMode < FCDotCDC1604DashP6.NX01_A.ordinal()) {
cdcPoint = numberMode; // print char cdcPoint = numberMode; // print char
numberMode = null; // invalid selector, thus stop numberMode = null; // invalid selector, thus stop
} else { } else {
if (!cdc.hasNext()) { if (scanIndex >= scanIndexEnd) {
return; return;
} }
cdcPoint = cdc.next(); // fetch next letter, for number mode scanIndex++;
cdcPoint = lexer.input.get(scanIndex); // fetch next letter, for number mode
} }
} else { } else {
boolean modeDone = readDECMode(cdc); boolean modeDone = readDECMode(lexer);
if (modeDone) { if (modeDone) {
return; // fetch next return; // fetch next
} }
if (!cdc.hasNext()) { if (scanIndex >= scanIndexEnd) {
return; return;
} }
cdcPoint = cdc.next(); // is used by readEscape6, thus read again scanIndex++;
cdcPoint = lexer.input.get(scanIndex); // is used by readEscape6, thus read again
} }
} }
// Escape without body and new escape ... // Escape without body and new escape ...
if (FCDotCDC1604DashP6.isEscape6(cdcPoint) || FourCornerDotCake.FC_DEC0127_PX0.contains(cdcPoint)) { if (FCDotCDC1604DashP6.isEscape6(cdcPoint) || FourCornerDotCake.FC_DEC0127_PX0.contains(cdcPoint)) {
//goto next_escape; TODO: add extra loop to remove stack here... //goto next_escape; TODO: add extra loop to remove stack here...
handleCDCDEC(cdc, cdcPoint, startMode); handleCDCDEC(lexer, cdcPoint, startMode);
return; return;
} }
// FIXME: this pages need a stop on out of range too // FIXME: this pages need a stop on out of range too
if (decMode == FCDotDEC0127DashPX0.ESC6_APL0127_P7A) { if (decMode == FCDotDEC0127DashPX0.ESC6_APL0127_P7A) {
handler.strobeWords(FourCornerDotCake.FC_APL0127_P7A, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal())); lexer.handler.strobeWords(FourCornerDotCake.FC_APL0127_P7A, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal()));
return; return;
} }
if (decMode == FCDotDEC0127DashPX0.ESC6_APL0127_P7B) { if (decMode == FCDotDEC0127DashPX0.ESC6_APL0127_P7B) {
handler.strobeWords(FourCornerDotCake.FC_APL0127_P7B, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal())); lexer.handler.strobeWords(FourCornerDotCake.FC_APL0127_P7B, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal()));
return; return;
} }
if (decMode == FCDotDEC0127DashPX0.ESC6_APL0127_P7C) { if (decMode == FCDotDEC0127DashPX0.ESC6_APL0127_P7C) {
handler.strobeWords(FourCornerDotCake.FC_APL0127_P7C, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal())); lexer.handler.strobeWords(FourCornerDotCake.FC_APL0127_P7C, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal()));
return; return;
} }
if (decMode == FCDotDEC0127DashPX0.ESC6_BYD0127_P7D) { if (decMode == FCDotDEC0127DashPX0.ESC6_BYD0127_P7D) {
handler.strobeWords(FourCornerDotCake.FC_BYD0127_P7D, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal())); lexer.handler.strobeWords(FourCornerDotCake.FC_BYD0127_P7D, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal()));
return; return;
} }
if (decMode == FCDotDEC0127DashPX0.ESC6_BYD0127_P7E) { if (decMode == FCDotDEC0127DashPX0.ESC6_BYD0127_P7E) {
handler.strobeWords(FourCornerDotCake.FC_BYD0127_P7E, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal())); lexer.handler.strobeWords(FourCornerDotCake.FC_BYD0127_P7E, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal()));
return; return;
} }
if (decMode == FCDotDEC0127DashPX0.ESC6_BYD0127_P7F) { if (decMode == FCDotDEC0127DashPX0.ESC6_BYD0127_P7F) {
handler.strobeWords(FourCornerDotCake.FC_BYD0127_P7F, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal())); lexer.handler.strobeWords(FourCornerDotCake.FC_BYD0127_P7F, List.of(cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal()));
return; return;
} }
//System.out.println("decMode="+decMode + " cdcPoint: " + cdcPoint + " numnerMode: " + numberMode);
if (decMode == FCDotDEC0127DashPX0.ESC_STOP) { if (decMode == FCDotDEC0127DashPX0.ESC_STOP) {
//decMode = null; //decMode = null;
numberMode = null; // stop requested, print normal numberMode = null; // stop requested, print normal
@ -565,47 +555,48 @@ public class FourCornerZionStenoLexer {
if (numberMode == null) { if (numberMode == null) {
Optional<FourCornerDotCake> slice = FourCornerDotCake.valueFromCakePoint(cdcPoint); Optional<FourCornerDotCake> slice = FourCornerDotCake.valueFromCakePoint(cdcPoint);
if (slice.isEmpty()) { if (slice.isEmpty()) {
smokeSignals.burnUnsupported(currLine, currCol, cdcPoint); System.out.println("No slice for point: " + Integer.toHexString(cdcPoint));
lexer.smokeSignals.burnUnsupported(lexer.currLine, lexer.currCol, cdcPoint);
return; return;
} }
handler.strobeWords(slice.get(), List.of(cdcPoint)); lexer.handler.strobeWords(slice.get(), List.of(cdcPoint));
return; return;
} }
if (numberPIE) { if (numberPIE) {
int terminatorOffZero = numberMode - FCDotCDC1604DashP6.NX01_A.ordinal(); int terminatorOffZero = numberMode - FCDotCDC1604DashP6.NX01_A.ordinal();
int numberIdxOffZero = cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal(); int numberIdxOffZero = cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal();
FourCornerDotCake slice = FourCornerDotCake.values()[terminatorOffZero + FourCornerDotCake.FC_PIE9C_01.ordinal()]; FourCornerDotCake slice = FourCornerDotCake.values()[terminatorOffZero + FourCornerDotCake.FC_PIE9C_01.ordinal()];
handler.strobeWords(slice, List.of(numberIdxOffZero)); lexer.handler.strobeWords(slice, List.of(numberIdxOffZero));
} else { // _PIN = ² } else { // _PIN = ²
int terminatorOff = numberMode - FCDotCDC1604DashP6.NX01_A.ordinal() + 1; int terminatorOff = numberMode - FCDotCDC1604DashP6.NX01_A.ordinal() + 1;
int numberIdxOff = cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal() + 1; int numberIdxOff = cdcPoint - FCDotCDC1604DashP6.NX01_A.ordinal() + 1;
BigInteger denominator = BigInteger.valueOf(terminatorOff); BigInteger denominator = BigInteger.valueOf(terminatorOff);
BigInteger numerator = BigInteger.valueOf(numberIdxOff); BigInteger numerator = BigInteger.valueOf(numberIdxOff);
handler.strobeNCR1632(denominator, numerator); lexer.handler.strobeNCR1632(denominator, numerator);
} }
} }
private boolean readDECMode(Iterator<Integer> cdc) { private boolean readDECMode(FourCornerZionStenoLexer lexer) {
for (FCDotDEC0127DashPX0 salahMode : FCDotDEC0127DashPX0.values()) { for (FCDotDEC0127DashPX0 salahMode : FCDotDEC0127DashPX0.values()) {
if (!salahMode.isExternal()) { if (!salahMode.isExternal()) {
continue; continue;
} }
if (salahMode.equals(decMode)) { if (salahMode.equals(decMode)) {
if (salahMode.name().startsWith("__")) { if (salahMode.name().startsWith("__")) {
smokeSignals.burnSalahDECUnsupported(currLine, currCol, decMode); lexer.smokeSignals.burnSalahDECUnsupported(lexer.currLine, lexer.currCol, decMode);
return false; return false;
} }
List<List<Integer>> args = new ArrayList<>(); List<List<Integer>> args = new ArrayList<>();
scanSalahRakaAt(cdc, args); scanSalahRakaAt(lexer, args);
if (!args.isEmpty() && handlerSalahSequence != null) { if (!args.isEmpty() && lexer.handlerSalahSequence != null) {
handlerSalahSequence.strobeSalahSequence(salahMode, args); lexer.handlerSalahSequence.strobeSalahSequence(salahMode, args);
} }
return true; return true;
} }
} }
if (FCDotDEC0127DashPX0.ESC68_FC18.equals(decMode)) { if (FCDotDEC0127DashPX0.ESC68_FC18.equals(decMode)) {
List<List<Integer>> result = new ArrayList<>(); List<List<Integer>> result = new ArrayList<>();
scanSalahRakaAt(cdc, result); scanSalahRakaAt(lexer, result);
if (!result.isEmpty()) { if (!result.isEmpty()) {
List<Integer> renderCakePoints = new ArrayList<>(); List<Integer> renderCakePoints = new ArrayList<>();
for (List<Integer> argu : result) { for (List<Integer> argu : result) {
@ -628,26 +619,28 @@ public class FourCornerZionStenoLexer {
} }
} }
} }
read(renderCakePoints); FourCornerZionStenoLexer lexer2 = new FourCornerZionStenoLexer(lexer.handler);
lexer2.read(renderCakePoints);
return true; return true;
} }
} }
return false; return false;
} }
private ScanResult scanSalahRakaAt(Iterator<Integer> input, List<List<Integer>> result) { private ScanResult scanSalahRakaAt(FourCornerZionStenoLexer lexer, List<List<Integer>> result) {
List<Integer> argu = new ArrayList<>(); List<Integer> argu = new ArrayList<>();
while (input.hasNext()) { while (scanIndex <= scanIndexEnd) {
int cdcPoint = input.next(); scanIndex++;
int cdcPoint = lexer.input.get(scanIndex);
if (cdcPoint == FCDotCDC1604DashP6._NUL.ordinal()) { if (cdcPoint == FCDotCDC1604DashP6._NUL.ordinal()) {
smokeSignals.burnSalahInvalidCakePoint(currLine, currCol, cdcPoint); lexer.smokeSignals.burnSalahInvalidCakePoint(lexer.currLine, lexer.currCol, cdcPoint);
result.clear(); result.clear();
return ScanResult.NEXT; // _NUL not allowed salah return ScanResult.NEXT; // _NUL not allowed salah
} }
if (FCDotCDC1604DashP6.isEscape6(cdcPoint) || FourCornerDotCake.FC_DEC0127_PX0.contains(cdcPoint)) { if (FCDotCDC1604DashP6.isEscape6(cdcPoint) || FourCornerDotCake.FC_DEC0127_PX0.contains(cdcPoint)) {
FCDotDEC0127DashPX0 embedESC = readEscape6(input, cdcPoint); FCDotDEC0127DashPX0 embedESC = readEscape6(lexer, cdcPoint);
if (embedESC == null) { if (embedESC == null) {
smokeSignals.burnInvalidEscape(currLine, currCol, cdcPoint); lexer.smokeSignals.burnInvalidEscape(lexer.currLine, lexer.currCol, cdcPoint);
result.clear(); result.clear();
return ScanResult.NEXT; return ScanResult.NEXT;
} }
@ -658,23 +651,24 @@ public class FourCornerZionStenoLexer {
if (FCDotDEC0127DashPX0.ESC_SEQ_RAKA_AT.equals(embedESC)) { if (FCDotDEC0127DashPX0.ESC_SEQ_RAKA_AT.equals(embedESC)) {
result.add(argu); result.add(argu);
argu = new ArrayList<>(); argu = new ArrayList<>();
if (safeNext(input).isEOF()) { //if (safeNext(input).isEOF()) {
return ScanResult.EOF; // return ScanResult.EOF;
} //}
continue; // Next argument continue; // Next argument
} }
if (!embedESC.isEmbeddable()) { if (!embedESC.isEmbeddable()) {
smokeSignals.burnSalahDECIllegal(currLine, currCol, embedESC); lexer.smokeSignals.burnSalahDECIllegal(lexer.currLine, lexer.currCol, embedESC);
result.clear(); result.clear();
return ScanResult.NEXT; return ScanResult.NEXT;
} }
// FIXME: this is wrong // FIXME: this is wrong
handleCDCDEC(input, cdcPoint, embedESC); //handleCDCDEC(lexer, cdcPoint, embedESC);
result.add(argu);
continue; continue;
} }
argu.add(cdcPoint); argu.add(cdcPoint);
} }
smokeSignals.burnSalahMissingAmen(currLine, currCol); lexer.smokeSignals.burnSalahMissingAmen(lexer.currLine, lexer.currCol);
result.clear(); result.clear();
return ScanResult.NEXT; return ScanResult.NEXT;
} }