Skip to content

Commit

Permalink
Adding detection of COMP-1 data type
Browse files Browse the repository at this point in the history
  • Loading branch information
avishek-sen-gupta committed Nov 9, 2024
1 parent 4d1c42c commit 8d059df
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,22 @@ private Pair<DataTypeSpec, Integer> 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);
return ImmutablePair.of(new GroupDataTypeSpec(groupSize), groupSize);
}
}

private Pair<DataTypeSpec, Integer> 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<CobolDataStructure> primaryDefinitions() {
return structures.stream().filter(s -> !s.isRedefinition()).toList();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
54 changes: 27 additions & 27 deletions smojol-core/src/test/java/org/smojol/common/DataTypesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -381,58 +381,58 @@ 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());
}

@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());
}

@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());
}

@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();
Expand All @@ -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());
Expand Down
11 changes: 11 additions & 0 deletions smojol-test-code/test-comp-1.cbl
Original file line number Diff line number Diff line change
@@ -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.

Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit 8d059df

Please sign in to comment.