From d176710f1632c5d26607513d978bc1b0284034cb Mon Sep 17 00:00:00 2001 From: Willem Date: Wed, 13 Aug 2025 22:07:53 +0200 Subject: [PATCH] FC18: Moved untested sand walker octals to escape sequence --- .../java/org/x4o/fc18/FourCornerRecipe.java | 45 +++++- .../x4o/fc18/FourCornerUnicodeDisplay.java | 3 + .../org/x4o/fc18/cake2/FourCornerDotCake.java | 9 +- .../zero33/dec1/FCDotDEC2701DashPX0.java | 6 +- .../zion7/FourCornerZionStenoGrapher.java | 2 + .../fc18/zion7/FourCornerZionStenoLexer.java | 143 +++++++++--------- .../org/x4o/fc18/FourCornerRecipeTest.java | 16 ++ 7 files changed, 145 insertions(+), 79 deletions(-) diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerRecipe.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerRecipe.java index 03fc2ac..1940a8b 100644 --- a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerRecipe.java +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerRecipe.java @@ -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 SAND_WORM_SIGN = List.of(24,48,72,96,120,144,168,192); private FourCornerRecipe() { } + static public List embedSandWalker(List rhythm) { + return embedSandWalker(new ArrayList<>(), rhythm); + } + + static public List embedSandWalker(List out, List 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 embedSandWorm(List spice) { + return embedSandWorm(new ArrayList<>(), spice); + } + + static public List embedSandWorm(List out, List 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 embedNCR1632Denominator(BigInteger value) { return embedNCR1632Value(new ArrayList<>(), value, FourCornerDotCake.FC_NCR1632_XD.getStart()); } diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerUnicodeDisplay.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerUnicodeDisplay.java index eebc579..cc5c17c 100644 --- a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerUnicodeDisplay.java +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/FourCornerUnicodeDisplay.java @@ -232,10 +232,13 @@ public class FourCornerUnicodeDisplay { @Override public void strobeSandWalker(List rhythm) { + // todo; select plugin for renderer + rhythm.forEach(v -> output.append(v.name())); } @Override public void strobeSandWorm(List spice) { + spice.forEach(v -> output.append(v.name())); } @Override diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/FourCornerDotCake.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/FourCornerDotCake.java index 3594bb7..460a0aa 100644 --- a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/FourCornerDotCake.java +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/FourCornerDotCake.java @@ -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"), diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/zero33/dec1/FCDotDEC2701DashPX0.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/zero33/dec1/FCDotDEC2701DashPX0.java index 9c7529e..2b6615e 100644 --- a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/zero33/dec1/FCDotDEC2701DashPX0.java +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/zero33/dec1/FCDotDEC2701DashPX0.java @@ -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 ! diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java index ff953f2..ad86640 100644 --- a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java @@ -70,10 +70,12 @@ public class FourCornerZionStenoGrapher { @Override public void strobeSandWalker(List rhythm) { + FourCornerRecipe.embedSandWalker(out, rhythm); } @Override public void strobeSandWorm(List spice) { + FourCornerRecipe.embedSandWorm(out, spice); } @Override diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoLexer.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoLexer.java index 9f56351..0acd5b1 100644 --- a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoLexer.java +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoLexer.java @@ -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 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 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 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 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; + } } } diff --git a/nx01-x4o-fc18/src/test/java/org/x4o/fc18/FourCornerRecipeTest.java b/nx01-x4o-fc18/src/test/java/org/x4o/fc18/FourCornerRecipeTest.java index 4431555..b1db32c 100644 --- a/nx01-x4o-fc18/src/test/java/org/x4o/fc18/FourCornerRecipeTest.java +++ b/nx01-x4o-fc18/src/test/java/org/x4o/fc18/FourCornerRecipeTest.java @@ -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 cdc = new ArrayList<>(); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + FourCornerRecipe.embedSandWalker(cdc, List.of(PrimordialOctal.PART_1)); + }); + List 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 cdc = new ArrayList<>();