FC18: Moved untested sand walker octals to escape sequence

This commit is contained in:
Willem Cazander 2025-08-13 22:07:53 +02:00
parent 2dc62e8f25
commit d176710f16
7 changed files with 145 additions and 79 deletions

View file

@ -25,6 +25,7 @@ package org.x4o.fc18;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.PrimitiveIterator;
import org.x4o.fc18.cake2.FourCornerDotCake;
@ -35,6 +36,8 @@ import org.x4o.fc18.cake2.pie9c.FCDotPIE9CDash10;
import org.x4o.fc18.cake2.pie9c.FCDotPIE9CDash11;
import org.x4o.fc18.cake2.pie9c.FCDotPIE9CDash20;
import org.x4o.fc18.cake2.zero33.FCDotCDC1604DashP6;
import org.x4o.fc18.cake2.zero33.dec1.FCDotDEC2701DashPX0;
import org.x4o.fc18.octal8.PrimordialOctal;
/// Holds different lookup and conversion maps towards four corner int18 cake points.
///
@ -42,12 +45,50 @@ import org.x4o.fc18.cake2.zero33.FCDotCDC1604DashP6;
/// @version 1.0 Jan 09, 2025
final public class FourCornerRecipe {
static final private BigInteger NCR1632_MASK_PAGE = BigInteger.valueOf(0x1FF);
static final private BigInteger NCR1632_VALUE_MAX = new BigInteger("FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF", 16);
public static final BigInteger NCR1632_MASK_PAGE = BigInteger.valueOf(0x1FF);
public static final BigInteger NCR1632_VALUE_MAX = new BigInteger("FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF"+"FFFFFFFFFFFFFFFFFF", 16);
public static final List<Integer> SAND_WORM_SIGN = List.of(24,48,72,96,120,144,168,192);
private FourCornerRecipe() {
}
static public List<Integer> embedSandWalker(List<PrimordialOctal> rhythm) {
return embedSandWalker(new ArrayList<>(), rhythm);
}
static public List<Integer> embedSandWalker(List<Integer> out, List<PrimordialOctal> rhythm) {
Objects.requireNonNull(rhythm);
if (!FourCornerRecipe.SAND_WORM_SIGN.contains(rhythm.size())) {
throw new IllegalArgumentException("Sand walker rhythm is not 72 bit aligned: " + rhythm.size());
}
out.add(FCDotDEC2701DashPX0.ESC_SAND_WALKER.cakePointDotIndex());
for (int i = 192 - 1; i >= 0; i--) {
if (rhythm.size() <= i) {
continue;
}
PrimordialOctal octal = rhythm.get(i);
out.add(FCDotCDC1604DashP6.NX01_A.cakePointDotIndex() + octal.ordinal());
}
out.add(FCDotCDC1604DashP6._SALAH_EXCLAMATION.cakePointDotIndex());
return out;
}
static public List<Integer> embedSandWorm(List<PrimordialOctal> spice) {
return embedSandWorm(new ArrayList<>(), spice);
}
static public List<Integer> embedSandWorm(List<Integer> out, List<PrimordialOctal> spice) {
Objects.requireNonNull(spice);
// TODO: redo for 18 bit FC this is 6 bit
out.add(FCDotDEC2701DashPX0.ESC68_SAND_WORM.cakePointDotIndex());
for (int i = spice.size(); i >= 0; i--) {
PrimordialOctal octal = spice.get(i);
out.add(FCDotCDC1604DashP6.NX01_A.cakePointDotIndex() + octal.ordinal());
}
out.add(FCDotCDC1604DashP6._SALAH_EXCLAMATION.cakePointDotIndex());
return out;
}
static public List<Integer> embedNCR1632Denominator(BigInteger value) {
return embedNCR1632Value(new ArrayList<>(), value, FourCornerDotCake.FC_NCR1632_XD.getStart());
}

View file

@ -232,10 +232,13 @@ public class FourCornerUnicodeDisplay {
@Override
public void strobeSandWalker(List<PrimordialOctal> rhythm) {
// todo; select plugin for renderer
rhythm.forEach(v -> output.append(v.name()));
}
@Override
public void strobeSandWorm(List<PrimordialOctal> spice) {
spice.forEach(v -> output.append(v.name()));
}
@Override

View file

@ -330,15 +330,14 @@ public enum FourCornerDotCake {
/// See: https://www.ibm.com/docs/en/db2/11.5?topic=uce-code-page-coded-character-set-identifier-ccsid-numbers-unicode-graphic-data
FC_F4TXT0001_SP(0x026DBF, 1, FCDotF4TXT0001DashSP.values(), "Flag4 TXT00 zero one Spanish Peace"),
/// Preamble of a sand worm body as a identifiable type header or an Número2 Lingua tree key.
/// Octal worm encoding are 192 unique octals in ordered sequence and have allowed length of 24/48/96 or 192.
/// This mime-type like information and decoders can be fetched from the the nether DB.
FC_SAND_OLGOI(0x026DC0, 576, "Large head of logoi worm"),
/// free
__RESERVED_F4C(0x026DC0, 576, "free"),
/// To escape the question of undefined behavior, we define it as dark nether space, so we can see it in C++
/// Undefined octal data which are packed big indian octals per 5, which is a 15 bit data gram in one 18 bit cake point.
/// This can encode sand worm text data like icons, bitmap images or vector images and unicode4D/etc like HolyC of TempleOS.
FC_SAND_KHORKHOI(0x27000, 32768, "Sand octals of large khorkhoi"),
/// With the ESC_SAND_WALKER preamble the binary octal mime-type information must be send first.
FC_SAND_WORM(0x27000, 32768, "Sand octals of olgoi khorkhoi"),
/// free
__RESERVED_F4A(0x30000 - 4096, 2048, "free"),

View file

@ -141,10 +141,12 @@ public enum FCDotDEC2701DashPX0 implements FourCornerX06BaklavaPointSequence, Fo
__ESC_RESERVED_C5,
/// _ESC6_X3 _ESC6_X2 _ESC6_X3 = 24
__ESC_RESERVED_C6,
/// Command for octal mime-type information sequence of sand walker.
ESC_SAND_WALKER,
/// _ESC6_X3 _ESC6_X3 _ESC6_X1 = 25
__ESC_RESERVED_C7,
/// Command for embedded octal sand worm for 6 or 8 bit systems.
ESC68_SAND_WORM,
/// _ESC6_X3 _ESC6_X3 _ESC6_X2 = 26
/// Virtual Typewriter 0ctal Six bit control sequences with argumented commands which MUST end with !

View file

@ -70,10 +70,12 @@ public class FourCornerZionStenoGrapher {
@Override
public void strobeSandWalker(List<PrimordialOctal> rhythm) {
FourCornerRecipe.embedSandWalker(out, rhythm);
}
@Override
public void strobeSandWorm(List<PrimordialOctal> spice) {
FourCornerRecipe.embedSandWorm(out, spice);
}
@Override

View file

@ -31,6 +31,7 @@ import java.util.Objects;
import java.util.Optional;
import java.util.PrimitiveIterator;
import org.x4o.fc18.FourCornerRecipe;
import org.x4o.fc18.cake2.FourCornerDotCake;
import org.x4o.fc18.cake2.flag4.FCDotF4TTY0001DashNL;
import org.x4o.fc18.cake2.flag4.FCDotF4TXT0001DashSP;
@ -85,16 +86,7 @@ public class FourCornerZionStenoLexer {
if (FourCornerDotCake.FC_DEC2701_PX0.equals(cakeSlice)) {
continue; // handle DEC manually
}
// if (FourCornerDotCake.FC_UNI2K_11.equals(cakeSlice)) {
// continue; // parse block manually
// }
// if (FourCornerDotCake.FC_UNI2K_22.equals(cakeSlice)) {
// continue; // parse block manually
// }
if (FourCornerDotCake.FC_SAND_OLGOI.equals(cakeSlice)) {
continue; // parse nether head manually
}
if (FourCornerDotCake.FC_SAND_KHORKHOI.equals(cakeSlice)) {
if (FourCornerDotCake.FC_SAND_WORM.equals(cakeSlice)) {
continue; // parse nether body manually
}
if (FourCornerDotCake.FC_NCR1632_XD.equals(cakeSlice)) {
@ -107,8 +99,7 @@ public class FourCornerZionStenoLexer {
}
CAKE_SLICE_EATERS.add(new StenoScannerCDCDEC());
CAKE_SLICE_EATERS.add(new StenoScannerNCR18());
CAKE_SLICE_EATERS.add(new StenoScannerSandOlgoi());
CAKE_SLICE_EATERS.add(new StenoScannerSandKhorkhoi());
CAKE_SLICE_EATERS.add(new StenoScannerSandWorm());
ArrayList.class.cast(CAKE_SLICE_EATERS).trimToSize();
}
@ -260,6 +251,9 @@ public class FourCornerZionStenoLexer {
}
final public ScanResult scan(FourCornerZionStenoLexer lexer) {
if (lexer.inputIndex >= lexer.input.size()) {
return ScanResult.EOF; // only for empty input with size zero
}
int matchPoint = lexer.input.get(lexer.inputIndex);
if (matchPoint < blockStart || matchPoint > blockStop) {
return ScanResult.NEXT;
@ -307,64 +301,10 @@ public class FourCornerZionStenoLexer {
}
}
static class StenoScannerSandOlgoi extends StenoScanner {
static class StenoScannerSandWorm extends StenoScanner {
private static final List<Integer> WORM_SIGN = List.of(24,48,96,192);// TODO: add missing here + cake doc as it grows per 72 bit slug
public StenoScannerSandOlgoi() {
super(FourCornerDotCake.FC_SAND_OLGOI);
}
@Override
public void process(FourCornerZionStenoLexer lexer, int idxFirst, int idxLast) {
int bitSize = 0;
int bitIdxLast = 0;
int[] sandWalking = new int[576];
for (int i = idxFirst; i <= idxLast; i++) {
int bitIdx = lexer.input.get(i);
if (bitIdx != 0 && bitIdx < bitIdxLast) {
lexer.smokeSignals.burnSandWalkerOutOfRhythm(lexer.currLine, lexer.currCol);
return;
}
bitIdxLast = bitIdx;
int bitOff = bitIdx - FourCornerDotCake.FC_SAND_OLGOI.getStart();
sandWalking[bitOff] = 1;
bitSize = bitOff;
}
List<PrimordialOctal> sandwormHead = new ArrayList<>();
PrimitiveIterator.OfInt i = Arrays.stream(sandWalking).iterator();
int octalIdx = 2;
int octalValue = 0;
int bitSizeCounter = 0;
while (i.hasNext()) {
if (bitSizeCounter > bitSize) {
break; // the sand walk bit pulses are always full size
}
bitSizeCounter++;
int bitValue = i.nextInt();
octalValue += bitValue << octalIdx;
if (octalIdx > 0) {
octalIdx--;
continue;
}
sandwormHead.add(PrimordialOctal.valueOf(octalValue));
octalIdx = 2;
octalValue = 0;
}
int wormHeadSize = sandwormHead.size();
if (!WORM_SIGN.contains(wormHeadSize)) {
lexer.smokeSignals.burnSandWalkerStepUnaligned(lexer.currLine, lexer.currCol, wormHeadSize);
return;
}
// Sand walking signal pulses have been stamped correctly to call the worm
lexer.handler.strobeSandWalker(sandwormHead);
}
}
static class StenoScannerSandKhorkhoi extends StenoScanner {
public StenoScannerSandKhorkhoi() {
super(FourCornerDotCake.FC_SAND_KHORKHOI);
public StenoScannerSandWorm() {
super(FourCornerDotCake.FC_SAND_WORM);
}
@Override
@ -588,6 +528,12 @@ public class FourCornerZionStenoLexer {
if (FCDotDEC2701DashPX0.ESC68_INC0801_P8.equals(cdcDECMode)) {
return handleINC(lexer);
}
if (FCDotDEC2701DashPX0.ESC_SAND_WALKER.equals(cdcDECMode)) {
return handleSandWalker(lexer);
}
if (FCDotDEC2701DashPX0.ESC68_SAND_WORM.equals(cdcDECMode)) {
return handleSandWorm68(lexer);
}
return false;
}
@ -714,7 +660,7 @@ public class FourCornerZionStenoLexer {
if (lexer.cdcDECModePieAlt) {
sliceBase = FourCornerDotCake.FC_PIE9D_01.ordinal();
}
FourCornerDotCake slice = FourCornerDotCake.valueOf(terminatorOffZero + sliceBase);
FourCornerDotCake slice = FourCornerDotCake.valueOf(terminatorOffZero + sliceBase); // TODO: remove slice here
//lexer.handler.strobeWord(slice, numberIdxOffZero);
lexer.handler.strobeWord(slice.getStart() + numberIdxOffZero);
return true;
@ -782,5 +728,62 @@ public class FourCornerZionStenoLexer {
result.clear();
return false;
}
// TODO: make better
private boolean handleSandWalker(FourCornerZionStenoLexer lexer) {
List<PrimordialOctal> rhythm = new ArrayList<>();
while (lexer.cdcDECScanIndex <= lexer.cdcDECScanIndexEnd) {
int cdcPoint = lexer.input.get(lexer.cdcDECScanIndex);
if (cdcPoint == FCDotCDC1604DashP6._NUL.ordinal()) {
lexer.smokeSignals.burnSalahInvalidCakePoint(lexer.currLine, lexer.currCol, cdcPoint);
lexer.cdcDECScanIndex--;
return false; // _NUL not allowed here
}
if (FCDotCDC1604DashP6.isEscape6(cdcPoint)) {
lexer.cdcDECScanIndex--;
return true;
}
if (FCDotCDC1604DashP6._SALAH_EXCLAMATION.ordinal() == cdcPoint) {
if (!FourCornerRecipe.SAND_WORM_SIGN.contains(rhythm.size())) {
lexer.smokeSignals.burnSandWalkerStepUnaligned(lexer.currLine, lexer.currCol, cdcPoint);
} else {
lexer.handler.strobeSandWalker(rhythm);
}
return true;
}
lexer.cdcDECScanIndex++;
if (cdcPoint < FCDotCDC1604DashP6.NX01_A.ordinal()) {
break;
}
if (cdcPoint > FCDotCDC1604DashP6.NX08_H.ordinal()) {
break;
}
rhythm.add(PrimordialOctal.valueOf(cdcPoint - FCDotCDC1604DashP6.NX01_A.cakePointDotIndex()));
}
lexer.cdcDECScanIndex--;
lexer.smokeSignals.burnSandWalkerOutOfRhythm(lexer.currLine, lexer.currCol);
return false;
}
private boolean handleSandWorm68(FourCornerZionStenoLexer lexer) {
List<PrimordialOctal> sandWorm = new ArrayList<>();
while (lexer.cdcDECScanIndex <= lexer.cdcDECScanIndexEnd) {
int cdcPoint = lexer.input.get(lexer.cdcDECScanIndex);
if (cdcPoint == FCDotCDC1604DashP6._SALAH_EXCLAMATION.ordinal()) {
lexer.handler.strobeSandWorm(sandWorm);
return true;
}
lexer.cdcDECScanIndex++;
if (cdcPoint < FCDotCDC1604DashP6.NX01_A.ordinal()) {
break;
}
if (cdcPoint > FCDotCDC1604DashP6.NX08_H.ordinal()) {
break;
}
sandWorm.add(PrimordialOctal.valueOf(cdcPoint - FCDotCDC1604DashP6.NX01_A.cakePointDotIndex()));
}
lexer.cdcDECScanIndex--;
return false;
}
}
}

View file

@ -28,6 +28,7 @@ import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.x4o.fc18.octal8.PrimordialOctal;
/**
* Tests FourCornerRecipe methods.
@ -37,6 +38,21 @@ import org.junit.jupiter.api.Test;
*/
public class FourCornerRecipeTest {
@Test
public void testSandWalker() throws Exception {
List<Integer> cdc = new ArrayList<>();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
FourCornerRecipe.embedSandWalker(cdc, List.of(PrimordialOctal.PART_1));
});
List<PrimordialOctal> octalMine = new ArrayList<>();
for (int i=0;i<24;i++) {
octalMine.add(PrimordialOctal.PART_1);
}
FourCornerRecipe.embedSandWalker(cdc, octalMine);
String res = FourCornerUnicodeDisplay.text().renderFromInt18(cdc);
Assertions.assertTrue(res.endsWith("PART_1PART_1"), "missing " + res);
}
@Test
public void testNCRCount1024() throws Exception {
List<Integer> cdc = new ArrayList<>();