diff --git a/smojol-core/src/main/java/org/smojol/common/vm/structure/Format1DataStructure.java b/smojol-core/src/main/java/org/smojol/common/vm/structure/Format1DataStructure.java index e90c2a1d..c60e5132 100644 --- a/smojol-core/src/main/java/org/smojol/common/vm/structure/Format1DataStructure.java +++ b/smojol-core/src/main/java/org/smojol/common/vm/structure/Format1DataStructure.java @@ -205,7 +205,7 @@ private Pair typeSpecForSingle() { return ImmutablePair.of(new ZonedDecimalDataTypeSpec(8, 0), 8); else if (!isComposite) { LOGGER.info("Calculating type spec for single data structure: " + dataDescription.getText()); - return new DataLayoutBuilder().size(dataDescription.dataPictureClause().getFirst().pictureString().getFirst().getText()); + return spec(dataDescription); } else { structures.forEach(CobolDataStructure::calculateMemoryRequirements); Integer groupSize = primaryDefinitions().stream().map(CobolDataStructure::size).reduce(0, Integer::sum); @@ -213,6 +213,14 @@ else if (!isComposite) { } } + private Pair spec(CobolParser.DataDescriptionEntryFormat1Context dataDescription) { + if (!dataDescription.dataUsageClause().isEmpty() + && (dataDescription.dataUsageClause(0).usageFormat().COMP_1() != null + || dataDescription.dataUsageClause(0).usageFormat().COMPUTATIONAL_1() != null)) + return ImmutablePair.of(new Comp1DataTypeSpec(), 4); + return new DataLayoutBuilder().size(dataDescription.dataPictureClause().getFirst().pictureString().getFirst().getText()); + } + protected List primaryDefinitions() { return structures.stream().filter(s -> !s.isRedefinition()).toList(); } diff --git a/smojol-core/src/main/java/org/smojol/common/vm/type/Comp1DataTypeSpec.java b/smojol-core/src/main/java/org/smojol/common/vm/type/Comp1DataTypeSpec.java new file mode 100644 index 00000000..67f995ab --- /dev/null +++ b/smojol-core/src/main/java/org/smojol/common/vm/type/Comp1DataTypeSpec.java @@ -0,0 +1,40 @@ +package org.smojol.common.vm.type; + +import org.smojol.common.vm.memory.MemoryAccess; +import org.smojol.common.vm.memory.MemoryLayout; + +public class Comp1DataTypeSpec extends DataTypeSpec { + public Comp1DataTypeSpec() { + super(DataFilter.NO_FILTER); + } + + @Override + public String readRaw(String v) { + throw new UnsupportedOperationException("COMP-1 operations not supported yet!"); + } + + @Override + public Object readPublic(MemoryAccess access) { + throw new UnsupportedOperationException("COMP-1 operations not supported yet!"); + } + + @Override + public Object readFormatted(MemoryAccess access) { + throw new UnsupportedOperationException("COMP-1 operations not supported yet!"); + } + + @Override + public void refresh(MemoryAccess access) { + throw new UnsupportedOperationException("COMP-1 operations not supported yet!"); + } + + @Override + public void set(String s, MemoryAccess access) { + throw new UnsupportedOperationException("COMP-1 operations not supported yet!"); + } + + @Override + public MemoryLayout index(int i, MemoryAccess access) { + return null; + } +} diff --git a/smojol-core/src/main/java/org/smojol/common/vm/type/Comp3lDataTypeSpec.java b/smojol-core/src/main/java/org/smojol/common/vm/type/Comp3DataTypeSpec.java similarity index 92% rename from smojol-core/src/main/java/org/smojol/common/vm/type/Comp3lDataTypeSpec.java rename to smojol-core/src/main/java/org/smojol/common/vm/type/Comp3DataTypeSpec.java index 19e120bf..f7e97622 100644 --- a/smojol-core/src/main/java/org/smojol/common/vm/type/Comp3lDataTypeSpec.java +++ b/smojol-core/src/main/java/org/smojol/common/vm/type/Comp3DataTypeSpec.java @@ -11,19 +11,18 @@ import java.util.ArrayList; import java.util.List; -public class Comp3lDataTypeSpec extends DataTypeSpec { +public class Comp3DataTypeSpec extends DataTypeSpec { public static final String BYTE_0X0 = Character.toString(0x00); - public static final String CHARACTER_ZERO = "0"; @Getter private final Comp3SignType signType; private final int leftSideDigits; private final int rightSideDigits; - public Comp3lDataTypeSpec(int leftSideDigits, int rightSideDigits) { + public Comp3DataTypeSpec(int leftSideDigits, int rightSideDigits) { this(leftSideDigits, rightSideDigits, Comp3SignType.UNSIGNED); } - public Comp3lDataTypeSpec(int leftSideDigits, int rightSideDigits, Comp3SignType signType) { + public Comp3DataTypeSpec(int leftSideDigits, int rightSideDigits, Comp3SignType signType) { super(new DecimalPointAligner(leftSideDigits, rightSideDigits)); this.signType = signType; this.leftSideDigits = leftSideDigits; diff --git a/smojol-core/src/main/java/org/smojol/common/vm/type/DataFilter.java b/smojol-core/src/main/java/org/smojol/common/vm/type/DataFilter.java index 52f295aa..3b124e9f 100644 --- a/smojol-core/src/main/java/org/smojol/common/vm/type/DataFilter.java +++ b/smojol-core/src/main/java/org/smojol/common/vm/type/DataFilter.java @@ -1,6 +1,18 @@ package org.smojol.common.vm.type; public interface DataFilter { + DataFilter NO_FILTER = new DataFilter() { + @Override + public String filter(String s) { + return s; + } + + @Override + public int sizeInBytes() { + return 0; + } + }; + String filter(String s); int sizeInBytes(); } diff --git a/smojol-core/src/test/java/org/smojol/common/DataTypesTest.java b/smojol-core/src/test/java/org/smojol/common/DataTypesTest.java index eb88daff..1ca08d4b 100644 --- a/smojol-core/src/test/java/org/smojol/common/DataTypesTest.java +++ b/smojol-core/src/test/java/org/smojol/common/DataTypesTest.java @@ -381,24 +381,24 @@ public void canErrorOnOutOfBoundsIndexAccess() { @Test public void canAllocateCorrectNumberOfBytesBasedOnNumberOfDigitsInComp3DataType() { - assertEquals(3, new Comp3lDataTypeSpec(3, 2, Comp3SignType.UNSIGNED).sizeInBytes()); - assertEquals(3, new Comp3lDataTypeSpec(2, 2, Comp3SignType.UNSIGNED).sizeInBytes()); + assertEquals(3, new Comp3DataTypeSpec(3, 2, Comp3SignType.UNSIGNED).sizeInBytes()); + assertEquals(3, new Comp3DataTypeSpec(2, 2, Comp3SignType.UNSIGNED).sizeInBytes()); } @Test public void canReadUnsignedComp3Item() { - Comp3lDataTypeSpec comp3lDataTypeSpec = new Comp3lDataTypeSpec(3, 2, Comp3SignType.UNSIGNED); - MemoryRegion memoryRegion = new MemoryRegion(comp3lDataTypeSpec.sizeInBytes()); - MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3lDataTypeSpec); + Comp3DataTypeSpec comp3DataTypeSpec = new Comp3DataTypeSpec(3, 2, Comp3SignType.UNSIGNED); + MemoryRegion memoryRegion = new MemoryRegion(comp3DataTypeSpec.sizeInBytes()); + MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3DataTypeSpec); memoryRegion.write(HexMapper.asBytes(ImmutableList.of(0x01, 0x23, 0x4F))); assertEquals(1234.0, layout.read()); } @Test public void canWriteUnsignedComp3Item() { - Comp3lDataTypeSpec comp3lDataTypeSpec = new Comp3lDataTypeSpec(2, 2, Comp3SignType.UNSIGNED); - MemoryRegion memoryRegion = new MemoryRegion(comp3lDataTypeSpec.sizeInBytes()); - MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3lDataTypeSpec); + Comp3DataTypeSpec comp3DataTypeSpec = new Comp3DataTypeSpec(2, 2, Comp3SignType.UNSIGNED); + MemoryRegion memoryRegion = new MemoryRegion(comp3DataTypeSpec.sizeInBytes()); + MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3DataTypeSpec); layout.set("12.34"); assertMemory(memoryRegion, "01:23:4F"); assertEquals("12.34", layout.readFormatted().toString()); @@ -406,9 +406,9 @@ public void canWriteUnsignedComp3Item() { @Test public void canTruncateLongerItemsUnsignedComp3Item() { - Comp3lDataTypeSpec comp3lDataTypeSpec = new Comp3lDataTypeSpec(2, 2, Comp3SignType.UNSIGNED); - MemoryRegion memoryRegion = new MemoryRegion(comp3lDataTypeSpec.sizeInBytes()); - MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3lDataTypeSpec); + Comp3DataTypeSpec comp3DataTypeSpec = new Comp3DataTypeSpec(2, 2, Comp3SignType.UNSIGNED); + MemoryRegion memoryRegion = new MemoryRegion(comp3DataTypeSpec.sizeInBytes()); + MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3DataTypeSpec); layout.set("1234.56"); assertMemory(memoryRegion, "03:45:6F"); assertEquals("34.56", layout.readFormatted().toString()); @@ -416,9 +416,9 @@ public void canTruncateLongerItemsUnsignedComp3Item() { @Test public void canTruncateIntegersUnsignedComp3Item() { - Comp3lDataTypeSpec comp3lDataTypeSpec = new Comp3lDataTypeSpec(2, 2, Comp3SignType.UNSIGNED); - MemoryRegion memoryRegion = new MemoryRegion(comp3lDataTypeSpec.sizeInBytes()); - MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3lDataTypeSpec); + Comp3DataTypeSpec comp3DataTypeSpec = new Comp3DataTypeSpec(2, 2, Comp3SignType.UNSIGNED); + MemoryRegion memoryRegion = new MemoryRegion(comp3DataTypeSpec.sizeInBytes()); + MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3DataTypeSpec); layout.set("1234"); assertMemory(memoryRegion, "03:40:0F"); assertEquals("34.0", layout.readFormatted().toString()); @@ -426,13 +426,13 @@ public void canTruncateIntegersUnsignedComp3Item() { @Test public void canPerformArithmeticOperationsWithUnsignedComp3Data() { - Comp3lDataTypeSpec comp3lDataTypeSpec = new Comp3lDataTypeSpec(2, 2, Comp3SignType.UNSIGNED); - MemoryRegion memoryRegion1 = new MemoryRegion(comp3lDataTypeSpec.sizeInBytes()); - MemoryRegion memoryRegion2 = new MemoryRegion(comp3lDataTypeSpec.sizeInBytes()); - MemoryRegion resultMemoryRegion = new MemoryRegion(comp3lDataTypeSpec.sizeInBytes()); - MemoryLayout layout1 = new MemoryLayout(memoryRegion1.fullAccess(), comp3lDataTypeSpec); - MemoryLayout layout2 = new MemoryLayout(memoryRegion2.fullAccess(), comp3lDataTypeSpec); - MemoryLayout resultLayout = new MemoryLayout(resultMemoryRegion.fullAccess(), comp3lDataTypeSpec); + Comp3DataTypeSpec comp3DataTypeSpec = new Comp3DataTypeSpec(2, 2, Comp3SignType.UNSIGNED); + MemoryRegion memoryRegion1 = new MemoryRegion(comp3DataTypeSpec.sizeInBytes()); + MemoryRegion memoryRegion2 = new MemoryRegion(comp3DataTypeSpec.sizeInBytes()); + MemoryRegion resultMemoryRegion = new MemoryRegion(comp3DataTypeSpec.sizeInBytes()); + MemoryLayout layout1 = new MemoryLayout(memoryRegion1.fullAccess(), comp3DataTypeSpec); + MemoryLayout layout2 = new MemoryLayout(memoryRegion2.fullAccess(), comp3DataTypeSpec); + MemoryLayout resultLayout = new MemoryLayout(resultMemoryRegion.fullAccess(), comp3DataTypeSpec); layout1.set("12.34"); layout2.set("12.34"); double sum = (Double) layout1.readFormatted() + (Double) layout2.readFormatted(); @@ -443,18 +443,18 @@ public void canPerformArithmeticOperationsWithUnsignedComp3Data() { @Test public void canReadSignedComp3Item() { - Comp3lDataTypeSpec comp3lDataTypeSpec = new Comp3lDataTypeSpec(3, 2, Comp3SignType.SIGNED); - MemoryRegion memoryRegion = new MemoryRegion(comp3lDataTypeSpec.sizeInBytes()); - MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3lDataTypeSpec); + Comp3DataTypeSpec comp3DataTypeSpec = new Comp3DataTypeSpec(3, 2, Comp3SignType.SIGNED); + MemoryRegion memoryRegion = new MemoryRegion(comp3DataTypeSpec.sizeInBytes()); + MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3DataTypeSpec); memoryRegion.write(HexMapper.asBytes(ImmutableList.of(0x01, 0x23, 0x4D))); assertEquals(-1234.0, layout.read()); } @Test public void canWritePositiveAndNegativeSignedComp3Item() { - Comp3lDataTypeSpec comp3lDataTypeSpec = new Comp3lDataTypeSpec(2, 2, Comp3SignType.SIGNED); - MemoryRegion memoryRegion = new MemoryRegion(comp3lDataTypeSpec.sizeInBytes()); - MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3lDataTypeSpec); + Comp3DataTypeSpec comp3DataTypeSpec = new Comp3DataTypeSpec(2, 2, Comp3SignType.SIGNED); + MemoryRegion memoryRegion = new MemoryRegion(comp3DataTypeSpec.sizeInBytes()); + MemoryLayout layout = new MemoryLayout(memoryRegion.fullAccess(), comp3DataTypeSpec); layout.set("-12.34"); assertMemory(memoryRegion, "01:23:4D"); assertEquals(-1234.0, layout.read()); diff --git a/smojol-test-code/test-comp-1.cbl b/smojol-test-code/test-comp-1.cbl new file mode 100644 index 00000000..7d8c538d --- /dev/null +++ b/smojol-test-code/test-comp-1.cbl @@ -0,0 +1,11 @@ + IDENTIFICATION DIVISION. + PROGRAM-ID. HELLO-WORLD. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 EXCHANGE-PART-01 PIC XXXX. + 10 LOADBUCKET-LAT-BEGN USAGE COMP-1. + PROCEDURE DIVISION. + SECTION-0 SECTION. + P1. + STOP RUN. + diff --git a/smojol-toolkit/src/main/java/org/smojol/toolkit/examples/DataStructureBuildMain_Issue59.java b/smojol-toolkit/src/main/java/org/smojol/toolkit/examples/DataStructureBuildMain_Issue59.java index 6546aa3e..1ff7ddc1 100644 --- a/smojol-toolkit/src/main/java/org/smojol/toolkit/examples/DataStructureBuildMain_Issue59.java +++ b/smojol-toolkit/src/main/java/org/smojol/toolkit/examples/DataStructureBuildMain_Issue59.java @@ -31,7 +31,7 @@ LanguageDialect.IDMS, new FullProgram(FlowchartOutputFormat.PNG, new UUIDProvide new OccursIgnoringFormat1DataStructureBuilder(), new ProgramSearch(), new LocalFilesystemOperations()) - .runForPrograms(ImmutableList.of(BUILD_BASE_ANALYSIS), ImmutableList.of("test-exp.cbl")); + .runForPrograms(ImmutableList.of(BUILD_BASE_ANALYSIS), ImmutableList.of("test-comp-1.cbl")); AnalysisTaskResultOK ok = (AnalysisTaskResultOK) result.values().stream().toList().getFirst().getFirst(); BaseAnalysisModel base = ok.getDetail(); System.out.println("DONE");