Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

276 Support ON EXCEPTION in CALLs #310

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,30 @@ public class Interpreter {

// Source tokens from Procedure Division that begin batch I/O statements
private static final List<String> batchFileIOVerbs = Arrays.asList(
"OPEN", "CLOSE", "READ", "WRITE", "REWRITE", "DELETE", "START"
);
"OPEN", "CLOSE", "READ", "WRITE", "REWRITE", "DELETE", "START");

// Used for handling source lines from copybooks that may not have the standard 80-byte length
// Used for handling source lines from copybooks that may not have the standard
// 80-byte length
private static final int minimumMeaningfulSourceLineLength = 7;
private static final int commentIndicatorOffset = 6;
private static final List<Character> commentIndicators = Arrays.asList('*', '/');

//Used to find areas
// Used to find areas
private static final int sequenceNumberAreaEnd = 6;
private static final int indicatorAreaEnd = 7;
private static final int A_AreaEnd = 11;
private static final int B_AreaEnd = 71;

public static int getSequenceNumberAreaIndex(){
public static int getSequenceNumberAreaIndex() {
return sequenceNumberAreaEnd;
}

//TODO: Speed up method by adding 'else if's and putting 'if's inside 'if's
// TODO: Speed up method by adding 'else if's and putting 'if's inside 'if's
/**
* Sets flags based on a line, to be able to know which kinds of source
* statements to look for when reading and interpreting lines.
*
* @param line - current source line being processed
* @param line - current source line being processed
* @param state - current state of flags
* @return - the part of the program just entered or null if no part was entered
*/
Expand Down Expand Up @@ -146,7 +146,7 @@ public static String setFlagsForCurrentLine(CobolLine line, CobolLine nextLine,
* (b) - previous line contains just a period
* (c) - first token on this line is a Cobol verb
*
* @param currentLine - current source line being processed
* @param currentLine - current source line being processed
* @param nextMeaningfulLine - next source line that is not empty
* @return - true if end of statement is recognized
*/
Expand All @@ -163,6 +163,27 @@ public static boolean isEndOfStatement(CobolLine currentLine, CobolLine nextMean
if (containsOnlyPeriod(nextMeaningfulLine)) {
return false;
}
if (currentLine.containsToken(Constants.CALL_TOKEN)) {
List<String> currentTokens = currentLine.getTokens();
int callTokenCount = 0, endCallTokenCount = 0;
for (String token : currentTokens) {
if (token.equals(Constants.CALL_TOKEN)) {
callTokenCount++;
}
if (token.equals(Constants.END_CALL_TOKEN)) {
endCallTokenCount++;
}
}
if (callTokenCount == endCallTokenCount) {
return true;
}
if (nextMeaningfulLine.containsToken("ON")) {
return false;
}
if (currentLine.containsToken("ON")) {
return false;
}
}
if (CobolVerbs.isStartOrEndCobolVerb(nextMeaningfulLine.getTokens().get(0))) {
return true;
}
Expand All @@ -185,7 +206,8 @@ public static boolean lineEndsParagraphOrSection(CobolLine currentLine, CobolLin
* This "shouldn't happen." Famous last words.
*
* @param line
* @return true if the source line is too short to be a meaningful line of code in Cobol.
* @return true if the source line is too short to be a meaningful line of code
* in Cobol.
*/
public static boolean isTooShortToBeMeaningful(CobolLine line) {
return line.getUnNumberedString() == null
Expand Down Expand Up @@ -254,7 +276,8 @@ public static boolean shouldLineBeStubbed(CobolLine line, State state) {
}
}
if (state.isFlagSetFor(Constants.WORKING_STORAGE_SECTION)) {
if (line.containsToken(Constants.EXEC_SQL_TOKEN) || line.containsToken(Constants.INCLUDE) || line.containsToken(Constants.END_EXEC_TOKEN))
if (line.containsToken(Constants.EXEC_SQL_TOKEN) || line.containsToken(Constants.INCLUDE)
|| line.containsToken(Constants.END_EXEC_TOKEN))
return true;
}
return false;
Expand Down Expand Up @@ -289,8 +312,8 @@ public static boolean shouldLineBeReadAsStatement(CobolLine line, State state) {
if (line.containsToken(Constants.REPLACE_TOKEN))
return true;
}
if (state.isFlagSetFor(Constants.DATA_DIVISION)){
if (!Interpreter.endsInPeriod(line)){
if (state.isFlagSetFor(Constants.DATA_DIVISION)) {
if (!Interpreter.endsInPeriod(line)) {
return true;
}
}
Expand All @@ -299,9 +322,9 @@ public static boolean shouldLineBeReadAsStatement(CobolLine line, State state) {

public static boolean lineContainsBinaryFieldDefinition(CobolLine line) {
return line.containsToken(Constants.COMP_VALUE)
|| line.containsToken(Constants.COMP_4_VALUE)
|| line.containsToken(Constants.COMP_5_VALUE)
|| line.containsToken(Constants.BINARY);
|| line.containsToken(Constants.COMP_4_VALUE)
|| line.containsToken(Constants.COMP_5_VALUE)
|| line.containsToken(Constants.BINARY);
}

public static boolean containsOnlyPeriod(CobolLine line) {
Expand Down Expand Up @@ -340,13 +363,15 @@ public static boolean isSectionHeader(CobolLine line, State state) {
}

/**
* As paragraph headers are not associated with any keyword, the method matches the
* As paragraph headers are not associated with any keyword, the method matches
* the
* source line against specific attributes that makes up a paragraph header.
*
* @param line - The line to check
* @param line - The line to check
* @param nextLine - The line after the line param
* @param state - current state of flags
* @return true if the source line have all the attributes of a paragraph header.
* @param state - current state of flags
* @return true if the source line have all the attributes of a paragraph
* header.
*/
public static boolean isParagraphHeader(CobolLine line, CobolLine nextLine, State state) {
return (state.isFlagSetFor(Constants.PROCEDURE_DIVISION)
Expand All @@ -361,7 +386,7 @@ && isParagraphHeaderFormat(line, nextLine)
* - It has only one token
* - The token is followed by a period on this or the next line.
*
* @param line - The line to check
* @param line - The line to check
* @param nextLine - The line after the line param
* @return true if sourceLine is of the format of a paragraph header
*/
Expand All @@ -370,7 +395,7 @@ private static boolean isParagraphHeaderFormat(CobolLine line, CobolLine nextLin
if (line.tokensSize() == 1) {
if (line.getTrimmedString().endsWith(Constants.PERIOD) ||
(nextLine != null &&
nextLine.getTrimmedString().equals(Constants.PERIOD)))
nextLine.getTrimmedString().equals(Constants.PERIOD)))
return true;
}
}
Expand Down Expand Up @@ -457,7 +482,8 @@ public static boolean endsInPeriod(CobolLine line) {
}

/**
* Checks if the last of these lines is ending the current component (SECTION, CALL, etc.)
* Checks if the last of these lines is ending the current component (SECTION,
* CALL, etc.)
* This should be called from inside the component, as it only checks, if
* the trimmed line ends with a period
*
Expand All @@ -469,29 +495,32 @@ public static boolean endsInPeriod(List<CobolLine> lines) {
}

/**
* Depending on the line that is being interpreted, we want to make sure that we update
* the current datastructure. This structure is based on the lines we have read so far in
* Depending on the line that is being interpreted, we want to make sure that we
* update
* the current datastructure. This structure is based on the lines we have read
* so far in
* working storage.
* This will make sure to add or remove any referenced field within the structure, based on
* This will make sure to add or remove any referenced field within the
* structure, based on
* the level of said field within the structure.
*/
public static TreeMap<Integer,String> updateCurrentDataStructure(List<CobolLine> currentStatement, TreeMap<Integer, String> currentHierarchy) {
public static TreeMap<Integer, String> updateCurrentDataStructure(List<CobolLine> currentStatement,
TreeMap<Integer, String> currentHierarchy) {

String[] statementWords = extractStatementWords(currentStatement);

if (currentHierarchy==null) {
if (currentHierarchy == null) {
currentHierarchy = new TreeMap<>();
}

int lastKeyOfCurrentHierarchy;
if (currentHierarchy.isEmpty()) {
lastKeyOfCurrentHierarchy=0;
}
else {
lastKeyOfCurrentHierarchy = 0;
} else {
lastKeyOfCurrentHierarchy = currentHierarchy.lastKey();
}

if (!isInteger(statementWords[0])){
if (!isInteger(statementWords[0])) {
return currentHierarchy;
}
int cobolLevelNumber = determineCobolLevelNumber(statementWords[0]);
Expand Down Expand Up @@ -527,24 +556,21 @@ private static boolean isInteger(String testString) {
}
}

private static Integer determineCobolLevelNumber(String levelNumberString){
private static Integer determineCobolLevelNumber(String levelNumberString) {
int cobolLevelNumber = Integer.parseInt(levelNumberString);
if (cobolLevelNumber == 77){
if (cobolLevelNumber == 77) {
cobolLevelNumber = 01;
}
return cobolLevelNumber;
}

private static String[] extractStatementWords(List<CobolLine> currentStatement){
String statementString = "";
for(CobolLine loopLine: currentStatement){
statementString += loopLine.getTrimmedString();
}
statementString = statementString.trim().replace(Constants.PERIOD, "");
String[] statementWords = statementString.split("\\s+");
return statementWords;
private static String[] extractStatementWords(List<CobolLine> currentStatement) {
String statementString = "";
for (CobolLine loopLine : currentStatement) {
statementString += loopLine.getTrimmedString();
}
statementString = statementString.trim().replace(Constants.PERIOD, "");
String[] statementWords = statementString.split("\\s+");
return statementWords;
}
}



Loading
Loading