From 4c07271aaf25efa58c926fa2d85d2ab42fbea83a Mon Sep 17 00:00:00 2001 From: Kyler Date: Thu, 27 Nov 2025 18:02:17 -0700 Subject: [PATCH] Added sls test cases --- SLS_Tests/interpreter_tester/README.md | 124 +++ .../python_tests.yaml | 0 .../test_runner.py | 0 SLS_Tests/interpreter_tester/tests.yaml | 706 ++++++++++++++++++ 4 files changed, 830 insertions(+) create mode 100644 SLS_Tests/interpreter_tester/README.md rename SLS_Tests/{interperater_tester => interpreter_tester}/python_tests.yaml (100%) rename SLS_Tests/{interperater_tester => interpreter_tester}/test_runner.py (100%) create mode 100644 SLS_Tests/interpreter_tester/tests.yaml diff --git a/SLS_Tests/interpreter_tester/README.md b/SLS_Tests/interpreter_tester/README.md new file mode 100644 index 0000000..77e41c9 --- /dev/null +++ b/SLS_Tests/interpreter_tester/README.md @@ -0,0 +1,124 @@ +# Interpreter Test Runner + +Requires `pip install pyyaml` + +Test SLS (UNIX): +`python3 test_runner.py ../../SLS_C/bin/sls tests.yaml` +`python3 test_runner.py "python3 -m ../../SLS_Python/sls" tests.yaml` +`python3 test_runner.py ../../SLS_Rust/target/debug/sls tests.yaml` + +Test SLS (Windows): +`python test_runner.py ..\..\SLS_C\bin\sls.exe tests.yaml` +`python test_runner.py "python -m ..\..\SLS_Python\sls" tests.yaml` +`python test_runner.py ..\..\SLS_Rust\target\debug\sls.exe tests.yaml` + +Python Examples: +`python test_runner.py python python_tests.yaml` +`python test_runner.py pypy python_tests.yaml` + +``` +>python test_runner.py python python_tests.yaml +✓ PASS: Simple print statement + +✓ PASS: Basic arithmetic + +✓ PASS: Variable assignment and usage + +✗ FAIL: Syntax error detection + Reason: stderr mismatch +Expected: +SyntaxError: unterminated string literal (detected at line 1) + +Got: + File "", line 1 + print("missing closing quote) + ^ +SyntaxError: unterminated string literal (detected at line 1) + + +✓ PASS: Import and use module + +✓ PASS: List operations + +✓ PASS: Execute Python file with args + +✓ PASS: Division by zero error + +✗ FAIL: Check Python version (using args instead of stdin) + Reason: stdout mismatch +Expected: +Python 3 +Got: +Python 3.14.0 + + +✓ PASS: Multi-line function definition + +✓ PASS: Long running operation with custom timeout + +============================================================ +TEST SUMMARY +============================================================ +Total tests: 11 +Passed: 9 +Failed: 2 + +Failed tests: + - Syntax error detection + - Check Python version (using args instead of stdin) +============================================================ +``` + +``` +>python test_runner.py pypy python_tests.yaml +✓ PASS: Simple print statement + +✓ PASS: Basic arithmetic + +✓ PASS: Variable assignment and usage + +✗ FAIL: Syntax error detection + Reason: stderr mismatch +Expected: +SyntaxError: unterminated string literal (detected at line 1) + +Got: + File "", line 1 + print("missing closing quote) + ^^^^^^^^^^^^^^^^^^^^^^^ +SyntaxError: unterminated string literal (detected at line 1) + + +✓ PASS: Import and use module + +✓ PASS: List operations + +✓ PASS: Execute Python file with args + +✓ PASS: Division by zero error + +✗ FAIL: Check Python version (using args instead of stdin) + Reason: stdout mismatch +Expected: +Python 3 +Got: +Python 3.10.13 (f1607341da97ff5a1e93430b6e8c4af0ad1aa019, Sep 28 2023, 05:42:24) +[PyPy 7.3.13 with MSC v.1929 64 bit (AMD64)] + + +✓ PASS: Multi-line function definition + +✓ PASS: Long running operation with custom timeout + +============================================================ +TEST SUMMARY +============================================================ +Total tests: 11 +Passed: 9 +Failed: 2 + +Failed tests: + - Syntax error detection + - Check Python version (using args instead of stdin) +============================================================ +``` diff --git a/SLS_Tests/interperater_tester/python_tests.yaml b/SLS_Tests/interpreter_tester/python_tests.yaml similarity index 100% rename from SLS_Tests/interperater_tester/python_tests.yaml rename to SLS_Tests/interpreter_tester/python_tests.yaml diff --git a/SLS_Tests/interperater_tester/test_runner.py b/SLS_Tests/interpreter_tester/test_runner.py similarity index 100% rename from SLS_Tests/interperater_tester/test_runner.py rename to SLS_Tests/interpreter_tester/test_runner.py diff --git a/SLS_Tests/interpreter_tester/tests.yaml b/SLS_Tests/interpreter_tester/tests.yaml new file mode 100644 index 0000000..5d126e4 --- /dev/null +++ b/SLS_Tests/interpreter_tester/tests.yaml @@ -0,0 +1,706 @@ +tests: + # Basic Stack Operations + - name: "Simple value push" + stdin: | + 42 print + stdout: | + 42 + exit: success + + - name: "Multiple values and operations" + stdin: | + 3 4 + print + 10 5 - print + stdout: | + 7 + 5 + exit: success + + - name: "Stack manipulation - dup" + stdin: | + 5 dup print print + stdout: | + 5 + 5 + exit: success + + - name: "Stack manipulation - swap" + stdin: | + 10 20 swap print print + stdout: | + 10 + 20 + exit: success + + - name: "Stack manipulation - over" + stdin: | + 5 10 over print print print + stdout: | + 5 + 10 + 5 + exit: success + + - name: "Stack manipulation - rot" + stdin: | + 1 2 3 rot print print print + stdout: | + 1 + 2 + 3 + exit: success + + - name: "Stack depth" + stdin: | + 1 2 3 depth print + stdout: | + 3 + exit: success + + # Arithmetic Operations + - name: "Basic arithmetic - all operators" + stdin: | + 10 3 + print + 10 3 - print + 10 3 * print + 10 3 / print + 10 3 % print + stdout: | + 13 + 7 + 30 + 3 + 1 + exit: success + + - name: "Exponentiation" + stdin: | + 2 8 ^ print + 3 3 ^ print + stdout: | + 256 + 27 + exit: success + + - name: "Floating point arithmetic" + stdin: | + 3.14 2.0 + print + 10.5 2.5 * print + stdout: | + 5.14 + 26.25 + exit: success + + - name: "Mathematical functions" + stdin: | + 16 sqrt print + -42 abs print + 3.7 round print + 3.14 floor print + 3.14 ceil print + stdout: | + 4.0 + 42 + 4.0 + 3.0 + 4.0 + exit: success + + - name: "Min and max" + stdin: | + 3 5 min print + 3 5 max print + stdout: | + 3 + 5 + exit: success + + # Comparison Operations + - name: "Comparison operators" + stdin: | + 5 3 > print + 5 3 < print + 5 5 == print + 5 3 != print + 5 5 >= print + 3 5 <= print + stdout: | + true + false + true + true + true + true + exit: success + + # Logical Operations + - name: "Logical operators" + stdin: | + true false and print + true false or print + false not print + stdout: | + false + true + true + exit: success + + # Bitwise Operations + - name: "Bitwise operations" + stdin: | + 0xFF 0x0F bitand print + 0xF0 0x0F bitor print + 0xFF 0x0F bitxor print + 4 2 shl print + 16 2 shr print + stdout: | + 15 + 255 + 240 + 16 + 4 + exit: success + + # String Operations + - name: "String concatenation" + stdin: | + "hello" " world" concat print + stdout: | + hello world + exit: success + + - name: "String length and substring" + stdin: | + "hello" length print + "hello" 1 3 substr print + stdout: | + 5 + el + exit: success + + - name: "String split and join" + stdin: | + "a,b,c" "," split print + stdout: | + ["a" "b" "c"] + exit: success + + - name: "String searching" + stdin: | + "hello" "hel" starts_with print + "hello" "lo" ends_with print + stdout: | + true + true + exit: success + + - name: "String trimming and replacement" + stdin: | + " hello " trim print + "hello world" "world" "Stack" replace print + stdout: | + hello + hello Stack + exit: success + + # Array Operations + - name: "Array literals and access" + stdin: | + [1 2 3 4 5] print + [1 2 3 4 5] 2 at print + [1 2 3 4 5] length print + stdout: | + [1 2 3 4 5] + 3 + 5 + exit: success + + - name: "Array slice" + stdin: | + [10 20 30 40 50] 1 3 slice print + stdout: | + [20 30] + exit: success + + - name: "Array map" + stdin: | + [1 2 3 4] { 2 * } map print + stdout: | + [2 4 6 8] + exit: success + + - name: "Array filter" + stdin: | + [1 2 3 4 5] { 2 % 0 == } filter print + stdout: | + [2 4] + exit: success + + - name: "Array reduce" + stdin: | + [1 2 3 4] 0 { + } reduce print + stdout: | + 10 + exit: success + + - name: "Array sum and mean" + stdin: | + [1 2 3 4 5] sum print + [1 2 3 4 5] mean print + stdout: | + 15 + 3.0 + exit: success + + - name: "Array zip and enumerate" + stdin: | + [1 2 3] [4 5 6] zip print + ["a" "b" "c"] enumerate print + stdout: | + [[1 4] [2 5] [3 6]] + [[0 "a"] [1 "b"] [2 "c"]] + exit: success + + - name: "Array reverse and transpose" + stdin: | + [1 2 3] reverse print + [[1 2] [3 4]] transpose print + stdout: | + [3 2 1] + [[1 3] [2 4]] + exit: success + + # Function Definition and Calling + - name: "Simple function definition" + stdin: | + (Number -- Number) { dup * } ::square fn + 5 square print + stdout: | + 25 + exit: success + + - name: "Function with multiple operations" + stdin: | + (Number Number -- Number Number) { + over over / swap % + } ::divmod fn + 10 3 divmod print print + stdout: | + 3 + 1 + exit: success + + - name: "Recursive factorial" + stdin: | + (Number -- Number) { + dup 1 <= + { drop 1 } + { dup 1 - factorial * } + if + } ::factorial fn + 5 factorial print + stdout: | + 120 + exit: success + + # Control Flow - Conditionals + - name: "Simple if statement" + stdin: | + 5 0 > { "positive" print } { "negative" print } if + stdout: | + positive + exit: success + + - name: "If with else branch" + stdin: | + -3 0 > { "positive" print } { "non-positive" print } if + stdout: | + non-positive + exit: success + + - name: "Nested conditionals" + stdin: | + 5 0 > + { + 5 10 + { "between 0 and 10" print } + { "greater than 10" print } + if + } + { "negative or zero" print } + if + stdout: | + between 0 and 10 + exit: success + + # Control Flow - Loops + - name: "For loop" + stdin: | + 1 5 { dup print } for + stdout: | + 1 + 2 + 3 + 4 + 5 + exit: success + + - name: "While loop" + stdin: | + 0 + { dup 3 < } + { + dup print + 1 + + } + while + drop + stdout: | + 0 + 1 + 2 + exit: success + + - name: "Loop with break" + stdin: | + 1 10 { + dup 5 == + { break } + { dup print } + if + } for + stdout: | + 1 + 2 + 3 + 4 + exit: success + + - name: "Loop with continue" + stdin: | + 1 5 { + dup 2 % 0 == + { continue } + { dup print } + if + } for + stdout: | + 1 + 3 + 5 + exit: success + + # Structs + - name: "Struct definition and creation" + stdin: | + (Number Number --) { x: y: } ::Point struct + 3.0 4.0 Point print + stdout: | + Point { x: 3.0, y: 4.0 } + exit: success + + - name: "Struct field access" + stdin: | + (Number Number --) { x: y: } ::Point struct + 3.0 4.0 Point + dup ::x get print + ::y get print + stdout: | + 3.0 + 4.0 + exit: success + + - name: "Struct field modification" + stdin: | + (Number Number --) { x: y: } ::Point struct + 3.0 4.0 Point + 10.0 ::x set + ::x get print + stdout: | + 10.0 + exit: success + + # Unions + - name: "Union creation - Option type" + stdin: | + (T --) { Some(T) None } ::Option union + 42 Option::Some print + Option::None print + stdout: | + Option::Some(42) + Option::None + exit: success + + - name: "Pattern matching with Option" + stdin: | + (T --) { Some(T) None } ::Option union + 42 Option::Some { + Some(x) => { x print } + None => { "Nothing" print } + } match + stdout: | + 42 + exit: success + + - name: "Result type pattern matching" + stdin: | + (T E --) { Ok(T) Err(E) } ::Result union + "success" Result::Ok { + Ok(val) => { val print } + Err(e) => { "Error: " e concat print } + } match + stdout: | + success + exit: success + + # Enums + - name: "Enum definition and usage" + stdin: | + { Pending: Active: Complete: } ::Status enum + Status::Active print + stdout: | + Status::Active + exit: success + + # Traits + - name: "Trait implementation for struct" + stdin: | + (Number Number --) { x: y: } ::Point struct + ::Addable { + (Self Self -- Self) { + over ::x get over ::x get + + swap ::y get swap ::y get + + Point + } +: + } ::Point impl + 1.0 2.0 Point 3.0 4.0 Point + print + stdout: | + Point { x: 4.0, y: 6.0 } + exit: success + + # Type Conversions + - name: "Type conversions" + stdin: | + 42 to_f64 print + 3.14 to_i32 print + 42 to_str print + stdout: | + 42.0 + 3 + "42" + exit: success + + - name: "String parsing" + stdin: | + "123" parse print + stdout: | + 123 + exit: success + + # Constants + - name: "Constant definition and usage" + stdin: | + 3.1415926535 ::pi const + 5 dup * pi * print + stdout: | + 78.53981633975 + exit: success + + # Lambda and Eval + - name: "Lambda function" + stdin: | + { dup * } lambda ::square swap + 5 square eval print + stdout: | + 25 + exit: success + + - name: "Eval operator" + stdin: | + "2 3 +" eval print + stdout: | + 5 + exit: success + + # Reflection + - name: "Type checking with type_of" + stdin: | + 42 type_of print + "hello" type_of print + stdout: | + ::i64 + ::String + exit: success + + - name: "Trait checking with implements" + stdin: | + 42 ::Addable implements print + 42 ::Drawable implements print + stdout: | + true + false + exit: success + + # Assertions + - name: "Passing assertion" + stdin: | + { 2 3 + } { 5 == } assert + "Test passed" print + stdout: | + Test passed + exit: success + + - name: "Failing assertion" + stdin: | + { 2 3 + } { 6 == } assert + stderr: | + Assertion failed + exit: error + + # Randomness + - name: "Random number generation with seed" + stdin: | + 12345 seed + rand 0.0 >= print + rand 1.0 < print + stdout: | + true + true + exit: success + + # Complex Examples + - name: "FizzBuzz (1-15)" + stdin: | + (Number -- ) { + dup 15 % 0 == + { drop "FizzBuzz" print } + { + dup 3 % 0 == + { drop "Fizz" print } + { + dup 5 % 0 == + { drop "Buzz" print } + { print } + if + } + if + } + if + } ::fizzbuzz fn + 1 15 { fizzbuzz } for + stdout: | + 1 + 2 + Fizz + 4 + Buzz + Fizz + 7 + 8 + Fizz + Buzz + 11 + Fizz + 13 + 14 + FizzBuzz + exit: success + + - name: "Sum of squares of even numbers" + stdin: | + [1 2 3 4 5 6 7 8 9 10] + { 2 % 0 == } filter + { dup * } map + 0 { + } reduce + print + stdout: | + 220 + exit: success + + # Error Cases + - name: "Type mismatch error" + stdin: | + "hello" 5 + + stderr: | + Type error + exit: error + + - name: "Stack underflow" + stdin: | + + + stderr: | + Stack underflow + exit: error + + - name: "Undefined identifier" + stdin: | + undefined_function + stderr: | + Undefined identifier: undefined_function + exit: error + + - name: "Division by zero" + stdin: | + 10 0 / + stderr: | + Division by zero + exit: error + + # Character Literals + - name: "Character literals" + stdin: | + 'A' print + '\n' print + '\u{1F600}' print + stdout: | + 'A' + '\n' + '😀' + exit: success + + # Multiple test with timeout + - name: "Complex computation with timeout" + stdin: | + 1 100 { dup * } map 0 { + } reduce print + stdout: | + 338350 + exit: success + timeout: 2.0 + + # Comments + - name: "Comments ignored" + stdin: | + // This is a comment + 5 // inline comment + 3 + // another comment + print + stdout: | + 8 + exit: success + + # Array of structs + - name: "Array of structs" + stdin: | + (Number Number --) { x: y: } ::Point struct + [1 2 Point 3 4 Point] print + stdout: | + [Point { x: 1, y: 2 }, Point { x: 3, y: 4 }] + exit: success + + # Format strings + - name: "String formatting" + stdin: | + "x=%d, y=%d" [5 10] format print + stdout: | + x=5, y=10 + exit: success + + # Underscore separators in literals + - name: "Underscore separators in numbers" + stdin: | + 1_000_000 print + 3_1415.92_65 print + stdout: | + 1000000 + 3141.9265 + exit: success