From 7e7ccc23ab09c1e9bd6fa8a8456c76db9295ee1f Mon Sep 17 00:00:00 2001 From: c272 Date: Mon, 20 May 2024 11:55:04 +0100 Subject: [PATCH] ci(feat): Add additional testing for intrinsics. --- crates/compiler/src/tests/data.rs | 10 +- crates/compiler/src/tests/intrinsics.rs | 161 ++++++++++++++++++++++++ crates/compiler/src/tests/io.rs | 44 ++++++- crates/compiler/src/tests/memory.rs | 134 +++++++++++++++++++- crates/compiler/src/tests/mod.rs | 3 +- 5 files changed, 342 insertions(+), 10 deletions(-) create mode 100644 crates/compiler/src/tests/intrinsics.rs diff --git a/crates/compiler/src/tests/data.rs b/crates/compiler/src/tests/data.rs index 36e35ea..fd99b93 100644 --- a/crates/compiler/src/tests/data.rs +++ b/crates/compiler/src/tests/data.rs @@ -6,7 +6,7 @@ fn str_initial_value() { CommonTestRunner::new("str_initial_val") .source(r#" IDENTIFICATION DIVISION. -PROGRAM-ID. INITIAL-VALUE-TEST. +PROGRAM-ID. STR-INITIAL-VALUE-TEST. DATA DIVISION. WORKING-STORAGE SECTION. @@ -26,7 +26,7 @@ fn invalid_str_initial_value() { CommonTestRunner::new("invalid_str_initial_val") .source(r#" IDENTIFICATION DIVISION. -PROGRAM-ID. INITIAL-VALUE-TEST. +PROGRAM-ID. INV-STR-INITIAL-VALUE-TEST. DATA DIVISION. WORKING-STORAGE SECTION. @@ -46,7 +46,7 @@ fn int_initial_value() { CommonTestRunner::new("int_initial_val") .source(r#" IDENTIFICATION DIVISION. -PROGRAM-ID. INITIAL-VALUE-TEST. +PROGRAM-ID. INT-INITIAL-VALUE-TEST. DATA DIVISION. WORKING-STORAGE SECTION. @@ -66,7 +66,7 @@ fn invalid_int_initial_value() { CommonTestRunner::new("invalid_int_initial_val") .source(r#" IDENTIFICATION DIVISION. -PROGRAM-ID. INITIAL-VALUE-TEST. +PROGRAM-ID. INV-INT-INITIAL-VALUE-TEST. DATA DIVISION. WORKING-STORAGE SECTION. @@ -86,7 +86,7 @@ fn float_initial_value() { CommonTestRunner::new("float_initial_val") .source(r#" IDENTIFICATION DIVISION. -PROGRAM-ID. INITIAL-VALUE-TEST. +PROGRAM-ID. FLT-INITIAL-VALUE-TEST. DATA DIVISION. WORKING-STORAGE SECTION. diff --git a/crates/compiler/src/tests/intrinsics.rs b/crates/compiler/src/tests/intrinsics.rs new file mode 100644 index 0000000..acdb863 --- /dev/null +++ b/crates/compiler/src/tests/intrinsics.rs @@ -0,0 +1,161 @@ +use super::common::CommonTestRunner; + +/// Tests that the "MOD" intrinsic functions correctly on an exact +/// divisor. +#[test] +fn mod_exact() { + CommonTestRunner::new("mod_exact") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. MOD-EXACT. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 OUT-VAL PIC 9(4) COMP. + +PROCEDURE DIVISION. + MOVE FUNCTION MOD(4, 2) TO OUT-VAL. + DISPLAY OUT-VAL. +STOP RUN. + "#) + .expect_output("0\n") + .run(); +} + +/// Tests that the "MOD" intrinsic functions correctly on an exact +/// divisor. +#[test] +fn mod_non_divisor() { + CommonTestRunner::new("mod_non_divisor") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. MOD-NON-DIV. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 OUT-VAL PIC 9(4) COMP. + +PROCEDURE DIVISION. + MOVE FUNCTION MOD(5, 3) TO OUT-VAL. + DISPLAY OUT-VAL. +STOP RUN. + "#) + .expect_output("2\n") + .run(); +} + +/// Tests that the "LENGTH" intrinsic functions correctly on a zero +/// length string. +#[test] +fn str_length_zero() { + CommonTestRunner::new("str_length_zero") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. STR-LEN-ZERO. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 OUT-VAL PIC 9(4) COMP. + +PROCEDURE DIVISION. + MOVE FUNCTION LENGTH("") TO OUT-VAL. + DISPLAY OUT-VAL. +STOP RUN. + "#) + .expect_output("0\n") + .run(); +} + +/// Tests that the "LENGTH" intrinsic functions correctly on a +/// non-zero length string. +#[test] +fn str_length_non_zero() { + CommonTestRunner::new("str_length_non_zero") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. STR-LEN-NON-ZERO. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 OUT-VAL PIC 9(4) COMP. + +PROCEDURE DIVISION. + MOVE FUNCTION LENGTH("SomeLitVal") TO OUT-VAL. + DISPLAY OUT-VAL. +STOP RUN. + "#) + .expect_output("10\n") + .run(); +} + +/// Tests that the "RANDOM" intrinsic generates different +/// values on subsequent executions. +#[test] +fn random_differs() { + CommonTestRunner::new("random_differs") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. RANDOM-DIFFERS. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 A-VAL PIC S9(4)P9(4) COMP. + 01 B-VAL PIC S9(4)P9(4) COMP. + +PROCEDURE DIVISION. + MOVE FUNCTION RANDOM() TO A-VAL. + MOVE FUNCTION RANDOM() TO B-VAL. + IF A-VAL = B-VAL THEN + DISPLAY "fail" + ELSE + DISPLAY "pass" + END-IF. +STOP RUN. + "#) + .expect_output("pass\n") + .run(); +} + +/// Tests that the "INTEGER" intrinsic correctly rounds up a given +/// floating point value. +#[test] +fn integer_rounds_up() { + CommonTestRunner::new("integer_rounds_up") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. INT-ROUNDS-UP. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 OUT-VAL PIC 9(4) COMP. + +PROCEDURE DIVISION. + MOVE FUNCTION INTEGER(2.398282) TO OUT-VAL. + DISPLAY OUT-VAL. +STOP RUN. + "#) + .expect_output("3\n") + .run(); +} + +/// Tests that the "INTEGER" intrinsic correctly converts an exact +/// floating point value to the equivalent integer. +#[test] +fn integer_translates_exact() { + CommonTestRunner::new("integer_translates_exact") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. INT-TRANS-EXACT. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 OUT-VAL PIC 9(4) COMP. + +PROCEDURE DIVISION. + MOVE FUNCTION INTEGER(214.0) TO OUT-VAL. + DISPLAY OUT-VAL. +STOP RUN. + "#) + .expect_output("214\n") + .run(); +} \ No newline at end of file diff --git a/crates/compiler/src/tests/io.rs b/crates/compiler/src/tests/io.rs index 1826e95..2088cc5 100644 --- a/crates/compiler/src/tests/io.rs +++ b/crates/compiler/src/tests/io.rs @@ -83,7 +83,7 @@ fn accept_str() { CommonTestRunner::new("accept_str") .source(r#" IDENTIFICATION DIVISION. -PROGRAM-ID. DISPLAY-DATA-TEST. +PROGRAM-ID. ACCEPT-STR-TEST. DATA DIVISION. WORKING-STORAGE SECTION. @@ -96,4 +96,46 @@ STOP RUN. "#) .expect_output_with_input("InitialVal\n", "InitialVal\n") .run(); +} + +/// Tests that accepting an integer via. stdin works as expected. +#[test] +fn accept_int() { + CommonTestRunner::new("accept_int") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. ACCEPT-INT-TEST. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 INT-VAL PIC 9(4) COMP. + +PROCEDURE DIVISION. + ACCEPT INT-VAL. + DISPLAY INT-VAL. +STOP RUN. + "#) + .expect_output_with_input("2024\n", "2024\n") + .run(); +} + +/// Tests that accepting a floating point value via. stdin works as expected. +#[test] +fn accept_float() { + CommonTestRunner::new("accept_float") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. ACCEPT-FLT-TEST. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 FLT-VAL PIC S9(4)P9(5) COMP. + +PROCEDURE DIVISION. + ACCEPT FLT-VAL. + DISPLAY FLT-VAL. +STOP RUN. + "#) + .expect_output_with_input("-1234.5678\n", "-1234.5678\n") + .run(); } \ No newline at end of file diff --git a/crates/compiler/src/tests/memory.rs b/crates/compiler/src/tests/memory.rs index 7bc0c63..c221053 100644 --- a/crates/compiler/src/tests/memory.rs +++ b/crates/compiler/src/tests/memory.rs @@ -2,11 +2,11 @@ use super::common::CommonTestRunner; /// Tests that a simple integer MOVE instruction compiles. #[test] -fn int_move() { - CommonTestRunner::new("int_move") +fn int_lit_move() { + CommonTestRunner::new("int_lit_move") .source(r#" IDENTIFICATION DIVISION. -PROGRAM-ID. INITIAL-VALUE-TEST. +PROGRAM-ID. INT-LIT-MOV. DATA DIVISION. WORKING-STORAGE SECTION. @@ -18,4 +18,132 @@ STOP RUN. "#) .expect_pass() .run(); +} + + +/// Tests that a simple floating point MOVE instruction compiles. +#[test] +fn float_lit_move() { + CommonTestRunner::new("float_lit_move") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. FLT-LIT-MOV. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 FLT-VAL PIC S9(4)P9(4) COMP. + +PROCEDURE DIVISION. + MOVE -1234.5678 TO FLT-VAL. +STOP RUN. + "#) + .expect_pass() + .run(); +} + +/// Tests that a simple string literal MOVE instruction compiles. +#[test] +fn str_lit_move() { + CommonTestRunner::new("str_lit_move") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. STR-LIT-MOV. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 STR-VAL PIC X(10). + +PROCEDURE DIVISION. + MOVE "SomeString" TO STR-VAL. +STOP RUN. + "#) + .expect_pass() + .run(); +} + +/// Tests that an OOB string literal MOVE instruction fails to compile. +#[test] +fn str_inv_lit_move() { + CommonTestRunner::new("str_inv_lit_move") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. STR-INV-LIT-MOV. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 STR-VAL PIC X(10). + +PROCEDURE DIVISION. + MOVE "SomeTooLargeString" TO STR-VAL. +STOP RUN. + "#) + .expect_fail(Some("move incompatible literal")) + .run(); +} + +/// Tests that a spanned source string MOVE instruction behaves as expected. +#[test] +fn str_spanned_src_move() { + CommonTestRunner::new("str_spanned_src_move") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. STR-SPANNED-SRC-MOV. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 SRC-VAL PIC X(10) VALUE "SomeString". + 01 DEST-VAL PIC X(10). + +PROCEDURE DIVISION. + MOVE SRC-VAL(1:4) TO DEST-VAL. + DISPLAY DEST-VAL. +STOP RUN. + "#) + .expect_output("Some\n") + .run(); +} + +/// Tests that a spanned destination MOVE instruction behaves as expected. +#[test] +fn str_spanned_dest_move() { + CommonTestRunner::new("str_spanned_dest_move") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. STR-SPANNED-DEST-MOV. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 SRC-VAL PIC X(10) VALUE "SomeString". + 01 DEST-VAL PIC X(10). + +PROCEDURE DIVISION. + MOVE SRC-VAL TO DEST-VAL(4:4). + DISPLAY DEST-VAL. +STOP RUN. + "#) + .expect_output(" Some\n") + .run(); +} + +/// Tests that a spanned source and destination MOVE instruction +/// behaves as expected. +#[test] +fn str_spanned_src_dest_move() { + CommonTestRunner::new("str_spanned_src_dest_move") + .source(r#" +IDENTIFICATION DIVISION. +PROGRAM-ID. STR-SPANNED-SRC-DEST-MOV. + +DATA DIVISION. + WORKING-STORAGE SECTION. + 01 SRC-VAL PIC X(10) VALUE "SomeString". + 01 DEST-VAL PIC X(10). + +PROCEDURE DIVISION. + MOVE SRC-VAL(5:6) TO DEST-VAL(2:3). + DISPLAY DEST-VAL. +STOP RUN. + "#) + .expect_output(" Str\n") + .run(); } \ No newline at end of file diff --git a/crates/compiler/src/tests/mod.rs b/crates/compiler/src/tests/mod.rs index 10f6a00..a50dcd0 100644 --- a/crates/compiler/src/tests/mod.rs +++ b/crates/compiler/src/tests/mod.rs @@ -2,6 +2,7 @@ mod common; // Individual conformance test modules. -mod io; mod data; +mod intrinsics; +mod io; mod memory; \ No newline at end of file