diff --git a/cobj/codegen.c b/cobj/codegen.c index cd217577..cbafab1b 100644 --- a/cobj/codegen.c +++ b/cobj/codegen.c @@ -3549,6 +3549,47 @@ static void joutput_ferror_stmt(struct cb_statement *p, int code) { // joutput_line("// %s:%d: %s", p->file, p->line, p->comment); // } +static void joutput_switch(struct cb_switch *sw, + enum joutput_stmt_type output_type) { + joutput_prefix(); + joutput("switch("); + joutput_param(sw->test, -1); + joutput(".getInt()) {"); + joutput_newline(); + joutput_indent_level += 2; + cb_tree case_tree; + for (case_tree = sw->case_list; case_tree; case_tree = CB_CHAIN(case_tree)) { + cb_tree whens = CB_VALUE(case_tree); + cb_tree stmt = CB_VALUE(whens); + int flag_other_exists = 1; + for (; whens; whens = CB_CHAIN(whens)) { + cb_tree objs = CB_VALUE(whens); + for (; objs; objs = CB_CHAIN(objs)) { + cb_tree obj = CB_VALUE(objs); + if (obj && CB_LIST_P(obj)) { + flag_other_exists = 0; + } + if (obj && CB_PAIR_P(obj)) { + cb_tree when_target = CB_PAIR_Y(obj); + struct cb_literal *primary_target = + CB_LITERAL(CB_PAIR_X(when_target)); + int dummy; + int label = + cb_literal_to_int_for_switch_label(primary_target, &dummy); + joutput_line("case %d:", label); + } + } + } + if (flag_other_exists) { + joutput_line("default:"); + } + joutput_stmt(stmt, output_type); + joutput_line("break;"); + } + joutput_indent_level -= 2; + joutput_line("}"); +} + static void joutput_stmt(cb_tree x, enum joutput_stmt_type output_type) { struct cb_statement *p; struct cb_label *lp; @@ -3948,6 +3989,9 @@ static void joutput_stmt(cb_tree x, enum joutput_stmt_type output_type) { joutput_prefix(); joutput(";\n"); break; + case CB_TAG_SWITCH: + joutput_switch(CB_SWITCH(x), output_type); + break; case CB_TAG_LIST: if (x && CB_TREE_TAG(CB_VALUE(x)) == CB_TAG_PERFORM) { putParen = 0; diff --git a/cobj/tree.c b/cobj/tree.c index a7298644..16f0b64d 100644 --- a/cobj/tree.c +++ b/cobj/tree.c @@ -2511,6 +2511,19 @@ cb_tree cb_build_continue(void) { return CB_TREE(p); } +/* + * SWITCH + */ + +cb_tree cb_build_switch(cb_tree test, cb_tree case_list) { + struct cb_switch *p; + + p = make_tree(CB_TAG_SWITCH, CB_CATEGORY_UNKNOWN, sizeof(struct cb_switch)); + p->test = test; + p->case_list = case_list; + return CB_TREE(p); +} + /* * FUNCTION */ diff --git a/cobj/tree.h b/cobj/tree.h index 4e79b45a..1f124408 100644 --- a/cobj/tree.h +++ b/cobj/tree.h @@ -85,6 +85,8 @@ enum cb_tag { CB_TAG_JAVA_CONTINUE, CB_TAG_JAVA_BREAK, + + CB_TAG_SWITCH, }; enum cb_alphabet_name_type { @@ -1118,6 +1120,24 @@ extern cb_tree cb_build_perform(int type); extern cb_tree cb_build_perform_varying(cb_tree name, cb_tree from, cb_tree step, cb_tree until); +/* + * switch (evaluate) + */ + +struct cb_switch { + struct cb_tree_common common; + cb_tree test; + cb_tree case_list; +}; + +#define CB_SWITCH(x) (CB_TREE_CAST(CB_TAG_SWITCH, struct cb_switch, x)) +#define CB_SWITCH_P(x) (CB_TREE_TAG(x) == CB_TAG_SWITCH) + +extern cb_tree cb_build_switch(cb_tree test, cb_tree case_tree); + +extern int cb_literal_to_int_for_switch_label(struct cb_literal *lit, + int *result); + /* * SORT */ diff --git a/cobj/typeck.c b/cobj/typeck.c index 95db7b33..e94577ea 100644 --- a/cobj/typeck.c +++ b/cobj/typeck.c @@ -3673,8 +3673,154 @@ static cb_tree build_evaluate(cb_tree subject_list, cb_tree case_list) { } } +int cb_literal_to_int_for_switch_label(struct cb_literal *lit, int *result) { + const char *min_num_abs = + "2147483648"; // -1 * (the minimum value of int of Java) + const char *max_num = "2147483647"; // the maximum value of int of Java + const int len_boundary = + 10; // string length of min_num_abs (== string length of max_num) + if (lit->size > len_boundary) { + // the value of the literal is out of range + *result = 0; + return 0; + } + + size_t i; + const char *boundary = lit->sign < 0 ? min_num_abs : max_num; + if (lit->size == len_boundary) { + for (i = 0; i < len_boundary; ++i) { + if (boundary[i] < lit->data[i]) { + // the value of the literal is out of range + *result = 0; + return 0; + } + } + } + + int ret = 0; + for (i = 0; i < lit->size; ++i) { + ret = ret * 10 + lit->data[i] - '0'; + } + *result = 1; + return lit->sign < 0 ? -ret : ret; +} + +// Determine a given label exists in the list of existing labels +// If a given label exists in the list, return 1. Otherwise return 0; +static int is_switch_label_duplicate(int label, const int *existing_label_list, + int list_len) { + int i = 0; + for (; i < list_len; ++i) { + if (existing_label_list[i] == label) { + return 1; + } + } + return 0; +} + +static cb_tree convert_evaluate_stmt_to_switch_stmt(cb_tree subject_list, + cb_tree case_list) { + cb_tree subjs; + cb_tree whens; + cb_tree objs; + + cb_tree case_tree = case_list; + int when_count = 0; + int other_exists = 0; + + // The length of subject_list must be 1 + if (subject_list == NULL || CB_CHAIN(subject_list)) { + return NULL; + } + + // Determine if a given evaluate statement can be converted to a switch + // statement + int case_count = 0; + for (; case_tree; case_tree = CB_CHAIN(case_tree), ++case_count) { + whens = CB_VALUE(case_tree); + /* for each WHEN sequence */ + int flag_other_exists = 1; + for (; whens; whens = CB_CHAIN(whens)) { + for (subjs = subject_list, objs = CB_VALUE(whens); subjs && objs; + subjs = CB_CHAIN(subjs), objs = CB_CHAIN(objs)) { + cb_tree subj = CB_VALUE(subjs); + cb_tree obj = CB_VALUE(objs); + if (!subj || CB_TREE_CATEGORY(subj) != CB_CATEGORY_NUMERIC) { + return NULL; + } + if (obj) { + if (CB_LIST_P(obj)) { + flag_other_exists = 0; + } + if (CB_STATEMENT_P(obj)) { + continue; + } + if (CB_PAIR_P(obj)) { + // WHEN NOT + if (CB_PURPOSE_INT(obj)) { + return NULL; + } + cb_tree when_target = CB_PAIR_Y(obj); + if (CB_PAIR_P(when_target)) { + cb_tree primary_target = CB_PAIR_X(when_target); + cb_tree thru_target = CB_PAIR_Y(when_target); + if (!CB_LITERAL_P(primary_target) || thru_target) { + return NULL; + } + struct cb_literal *lit = CB_LITERAL(primary_target); + if (lit->data == NULL || lit->scale != 0) { + return NULL; + } + ++when_count; + } + } + } + } + } + other_exists |= flag_other_exists; + } + // Build Switch statement + int *cases = malloc(when_count * sizeof(int)); + int case_index = 0; + for (case_tree = case_list; case_tree; case_tree = CB_CHAIN(case_tree)) { + whens = CB_VALUE(case_tree); + /* for each WHEN sequence */ + for (; whens; whens = CB_CHAIN(whens)) { + for (objs = CB_VALUE(whens); objs; objs = CB_CHAIN(objs)) { + cb_tree obj = CB_VALUE(objs); + if (obj && CB_PAIR_P(obj)) { + cb_tree when_target = CB_PAIR_Y(obj); + struct cb_literal *primary_target = + CB_LITERAL(CB_PAIR_X(when_target)); + int result; + int label = + cb_literal_to_int_for_switch_label(primary_target, &result); + // If calculating a switch label fails, the evaluate statement cannot + // be converted to switch statement + if (!result) { + return NULL; + } + // If a duplicate label is found, the evaluate statement cannot be + // converted to switch statement + if (is_switch_label_duplicate(label, cases, case_index)) { + return NULL; + } + cases[case_index++] = label; + } + } + } + } + return cb_build_switch(CB_VALUE(subject_list), case_list); +} + void cb_emit_evaluate(cb_tree subject_list, cb_tree case_list) { - cb_emit(build_evaluate(subject_list, case_list)); + cb_tree switch_stmt = + convert_evaluate_stmt_to_switch_stmt(subject_list, case_list); + if (switch_stmt) { + cb_emit(switch_stmt); + } else { + cb_emit(build_evaluate(subject_list, case_list)); + } } /* diff --git a/tests/Makefile.am b/tests/Makefile.am index 88ea25ed..fcc50f85 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -217,7 +217,8 @@ misc_DEPENDENCIES = \ misc.src/record-key-duplicates-error.at \ misc.src/copy-comments.at \ misc.src/read_prev_after_start.at \ - misc.src/japanese-char-section-var.at + misc.src/japanese-char-section-var.at \ + misc.src/evaluate-switch.at EXTRA_DIST = $(srcdir)/package.m4 \ $(TESTS) \ diff --git a/tests/Makefile.in b/tests/Makefile.in index 6f23695a..f5377a88 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -758,7 +758,8 @@ misc_DEPENDENCIES = \ misc.src/record-key-duplicates-error.at \ misc.src/copy-comments.at \ misc.src/read_prev_after_start.at \ - misc.src/japanese-char-section-var.at + misc.src/japanese-char-section-var.at \ + misc.src/evaluate-switch.at EXTRA_DIST = $(srcdir)/package.m4 \ $(TESTS) \ diff --git a/tests/misc.at b/tests/misc.at index 8012e6cc..2aba485d 100644 --- a/tests/misc.at +++ b/tests/misc.at @@ -47,3 +47,4 @@ m4_include([record-key-duplicates-error.at]) #m4_include([copy-comments.at]) m4_include([read_prev_after_start.at]) m4_include([japanese-char-section-var.at]) +m4_include([evaluate-switch.at]) diff --git a/tests/misc.src/evaluate-switch.at b/tests/misc.src/evaluate-switch.at new file mode 100644 index 00000000..ac57e172 --- /dev/null +++ b/tests/misc.src/evaluate-switch.at @@ -0,0 +1,1034 @@ +AT_SETUP([Convert EVALUATE to switch]) + +AT_DATA([prog.cbl], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + + DATA DIVISION. + WORKING-STORAGE SECTION. + 78 STATUS-1 VALUE 1. + 78 STATUS--1 VALUE -1. + 78 STATUS-2 VALUE 2. + + 01 TEST-9-1 PIC 9(3) VALUE 1. + 01 TEST-9-2 PIC 9(3) VALUE 2. + 01 TEST-S9-1 PIC S9(3) VALUE 1. + 01 TEST-S9-2 PIC S9(3) VALUE 2. + 01 TEST-9-1-COMP3 PIC 9(3) COMP-3 VALUE 1. + 01 TEST-9-2-COMP3 PIC 9(3) COMP-3 VALUE 2. + 01 TEST-S9-1-COMP3 PIC S9(3) COMP-3 VALUE 1. + 01 TEST-S9-2-COMP3 PIC S9(3) COMP-3 VALUE 2. + 01 TEST-9-1-COMP5 PIC 9(3) COMP-5 VALUE 1. + 01 TEST-9-2-COMP5 PIC 9(3) COMP-5 VALUE 2. + 01 TEST-S9-1-COMP5 PIC 9(3) COMP-5 VALUE 1. + 01 TEST-S9-2-COMP5 PIC 9(3) COMP-5 VALUE 2. + PROCEDURE DIVISION. + MAIN-PROC SECTION. + + EVALUATE 1 + WHEN 1 + DISPLAY "OK". + + EVALUATE 1 + WHEN STATUS-1 + DISPLAY "OK". + + EVALUATE 1 + WHEN 1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE 1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE 1 + WHEN -1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE 1 + WHEN STATUS--1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE 2 + WHEN 1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE 2 + WHEN STATUS-1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE 1 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE 1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE 1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG". + + EVALUATE 1 + WHEN 1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE 1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE 1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS--1 + DISPLAY "NG". + + EVALUATE 1 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE 1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE 1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + *************************** + + EVALUATE TEST-9-1 + WHEN 1 + DISPLAY "OK". + + EVALUATE TEST-9-1 + WHEN STATUS-1 + DISPLAY "OK". + + EVALUATE TEST-9-1 + WHEN 1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1 + WHEN -1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-9-1 + WHEN STATUS--1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-9-2 + WHEN 1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-9-2 + WHEN STATUS-1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-9-1 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE TEST-9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE TEST-9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG". + + EVALUATE TEST-9-1 + WHEN 1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS--1 + DISPLAY "NG". + + EVALUATE TEST-9-1 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + *************************** + + EVALUATE TEST-S9-1 + WHEN 1 + DISPLAY "OK". + + EVALUATE TEST-S9-1 + WHEN STATUS-1 + DISPLAY "OK". + + EVALUATE TEST-S9-1 + WHEN 1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1 + WHEN -1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-1 + WHEN STATUS--1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-2 + WHEN 1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-2 + WHEN STATUS-1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-1 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE TEST-S9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE TEST-S9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG". + + EVALUATE TEST-S9-1 + WHEN 1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-S9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-S9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS--1 + DISPLAY "NG". + + EVALUATE TEST-S9-1 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + *************************** + + EVALUATE TEST-9-1-COMP3 + WHEN 1 + DISPLAY "OK". + + EVALUATE TEST-9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK". + + EVALUATE TEST-9-1-COMP3 + WHEN 1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP3 + WHEN -1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-9-1-COMP3 + WHEN STATUS--1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-9-2-COMP3 + WHEN 1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-9-2-COMP3 + WHEN STATUS-1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-9-1-COMP3 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP3 + WHEN 1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS--1 + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP3 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + *************************** + + EVALUATE TEST-S9-1-COMP3 + WHEN 1 + DISPLAY "OK". + + EVALUATE TEST-S9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK". + + EVALUATE TEST-S9-1-COMP3 + WHEN 1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP3 + WHEN -1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-1-COMP3 + WHEN STATUS--1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-2-COMP3 + WHEN 1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-2-COMP3 + WHEN STATUS-1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-1-COMP3 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP3 + WHEN 1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS--1 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP3 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP3 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + *************************** + + EVALUATE TEST-9-1-COMP5 + WHEN 1 + DISPLAY "OK". + + EVALUATE TEST-9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK". + + EVALUATE TEST-9-1-COMP5 + WHEN 1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP5 + WHEN -1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-9-1-COMP5 + WHEN STATUS--1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-9-2-COMP5 + WHEN 1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK22222". + + EVALUATE TEST-9-2-COMP5 + WHEN STATUS-1 + DISPLAY "NG11111111" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-9-1-COMP5 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "N". + + EVALUATE TEST-9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP5 + WHEN 1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS--1 + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP5 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + *************************** + + EVALUATE TEST-S9-1-COMP5 + WHEN 1 + DISPLAY "OK". + + EVALUATE TEST-S9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK". + + EVALUATE TEST-S9-1-COMP5 + WHEN 1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP5 + WHEN -1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-1-COMP5 + WHEN STATUS--1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-2-COMP5 + WHEN 1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-2-COMP5 + WHEN STATUS-1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + EVALUATE TEST-S9-1-COMP5 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP5 + WHEN 1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN -1 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS--1 + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP5 + WHEN 1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN 2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + + EVALUATE TEST-S9-1-COMP5 + WHEN STATUS-1 + DISPLAY "OK" + WHEN STATUS-2 + DISPLAY "NG" + WHEN OTHER + DISPLAY "NG". + *************************** +]) + +AT_DATA([test.sh], +[#!/bin/bash +# Compile a COBOL source file +cobj prog.cbl +# The number of OK in the program output +OK_COUNT=$(java prog | tee result.txt | grep OK | wc -l) +# The number of EVALUATE statements in a COBOL source file +EVALUATE_COUNT=$(grep EVALUATE prog.cbl | wc -l) +# The number of switch statements corresponding to EVALUATE statements +SWITCH_COUNT=$(grep -A 2 '/\* prog.cbl:@<:@0-9@:>@*: EVALUATE \*/' prog.java | grep 'switch' | wc -l) +# Check the numbers +test "$OK_COUNT" = "$EVALUATE_COUNT" && test "$OK_COUNT" = "$SWITCH_COUNT" +]) + +AT_CHECK([chmod +x test.sh]) +AT_CHECK([./test.sh]) + +AT_DATA([prog2.cbl], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + MAIN-PROC SECTION. + + EVALUATE 1 + WHEN NOT 1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK". + + + EVALUATE 1 + WHEN 3 + DISPLAY "NG" + WHEN NOT 2 + DISPLAY "OK" + WHEN OTHER + DISPLAY "NG". +]) + +AT_DATA([test2.sh], +[#!/bin/bash +# Compile a COBOL source file +cobj prog2.cbl +# The number of OK in the program output +OK_COUNT=$(java prog2 | tee result.txt | grep OK | wc -l) +# The number of EVALUATE statements in a COBOL source file +EVALUATE_COUNT=$(grep EVALUATE prog2.cbl | wc -l) +# The number of switch statements corresponding to EVALUATE statements +SWITCH_COUNT=$(grep -A 2 '/\* prog2.cbl:@<:@0-9@:>@*: EVALUATE \*/' prog2.java | grep 'switch' | wc -l) +# Check the numbers +test "$OK_COUNT" = "$EVALUATE_COUNT" && test "$SWITCH_COUNT" = 0 +]) + +AT_CHECK([chmod +x test2.sh]) +AT_CHECK([./test2.sh]) + +AT_DATA([pp.cbl], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. pp. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 A PIC 9 VALUE 0. + PROCEDURE DIVISION. + EVALUATE A + WHEN 1 + WHEN 2 + DISPLAY "NG" + WHEN 3 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK" + END-EVALUATE. + EVALUATE A + WHEN 1 + WHEN 2 + WHEN 3 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK" + END-EVALUATE. + EVALUATE A + WHEN 1 + DISPLAY "NG" + WHEN 2 + WHEN 3 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK" + END-EVALUATE. + GOBACK. + +]) +AT_CHECK([cobj pp.cbl]) +AT_CHECK([java pp], [0], +[OK +OK +OK +]) + +AT_DATA([qq.cbl], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. qq. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 A PIC 9 VALUE 0. + PROCEDURE DIVISION. + EVALUATE A + WHEN 1 + WHEN 2 + DISPLAY "NG" + WHEN 3 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK" + END-EVALUATE. + EVALUATE A + WHEN 1 + WHEN 2 + WHEN 3 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK" + END-EVALUATE. + EVALUATE A + WHEN 1 + DISPLAY "NG" + WHEN 2 + WHEN 3 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK" + END-EVALUATE. + + EVALUATE A + WHEN 1 + WHEN 2 + WHEN 3 + WHEN OTHER + DISPLAY "OK" + END-EVALUATE. + + EVALUATE A + WHEN 1 + WHEN 2 + DISPLAY "NG" + WHEN 3 + WHEN OTHER + DISPLAY "OK" + END-EVALUATE. + + EVALUATE A + WHEN 1 + DISPLAY "NG" + WHEN 2 + WHEN 3 + WHEN OTHER + DISPLAY "OK" + END-EVALUATE. + + EVALUATE A + WHEN 1 + DISPLAY "NG" + WHEN 2 + DISPLAY "NG" + WHEN 3 + WHEN OTHER + DISPLAY "OK" + END-EVALUATE. + GOBACK. + +]) +AT_CHECK([cobj ${CONF_JP_COMPAT} qq.cbl]) +AT_CHECK([java qq], [0], +[OK +OK +OK +OK +OK +OK +OK +]) + +AT_DATA([rr.cbl], +[ IDENTIFICATION DIVISION. + PROGRAM-ID. rr. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT F ASSIGN TO 'sample-file' + ORGANIZATION IS SEQUENTIAL. + DATA DIVISION. + FILE SECTION. + FD F. + 01 REC PIC X. + WORKING-STORAGE SECTION. + 01 A PIC 9 VALUE 0. + 01 C PIC 9 VALUE 0. + PROCEDURE DIVISION. + EVALUATE A + WHEN 0 + DISPLAY "OK1" + IF 1 = 1 THEN + DISPLAY "OK2" + END-IF + PERFORM VARYING C FROM 3 BY 1 UNTIL C >= 4 + DISPLAY "OK" C + END-PERFORM + OPEN OUTPUT F + MOVE 'A' TO REC + WRITE REC + MOVE 'B' TO REC + WRITE REC + CLOSE F + OPEN INPUT F + PERFORM FOREVER + READ F + AT END + DISPLAY "READ END" + EXIT PERFORM + NOT AT END + DISPLAY "READ DATA:" REC + END-READ + END-PERFORM + CLOSE F + END-EVALUATE. + EVALUATE A + WHEN 1 + DISPLAY "NG" + WHEN OTHER + DISPLAY "OK1" + IF 1 = 1 THEN + DISPLAY "OK2" + END-IF + PERFORM VARYING C FROM 3 BY 1 UNTIL C >= 4 + DISPLAY "OK" C + END-PERFORM + OPEN INPUT F + PERFORM FOREVER + READ F + AT END + DISPLAY "READ END" + EXIT PERFORM + NOT AT END + DISPLAY "READ DATA:" REC + END-READ + END-PERFORM + CLOSE F + END-EVALUATE. + GOBACK. +]) + +AT_CHECK([cobj rr.cbl]) +AT_CHECK([java rr], [0], +[OK1 +OK2 +OK3 +READ DATA:A +READ DATA:B +READ END +OK1 +OK2 +OK3 +READ DATA:A +READ DATA:B +READ END +]) + +AT_CLEANUP