From 0112928b2f1f6a6f3d322e1d06e9538695420c66 Mon Sep 17 00:00:00 2001 From: JebediahS Date: Fri, 5 Sep 2025 21:20:15 +0200 Subject: [PATCH 1/4] Update expr.c Filling the stack should start from element with index 0. --- chapter_5/exercise_5_10/expr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chapter_5/exercise_5_10/expr.c b/chapter_5/exercise_5_10/expr.c index a8de7e1..5f82c87 100644 --- a/chapter_5/exercise_5_10/expr.c +++ b/chapter_5/exercise_5_10/expr.c @@ -95,7 +95,7 @@ int main(int argc, char *argv[]) { float pop(void) { if (stack_pointer > 0) { - return stack[stack_pointer--]; + return stack[--stack_pointer]; } printf("Error: the stack is empty.\n"); @@ -104,7 +104,7 @@ float pop(void) { void push(float element) { if (stack_pointer < STACK_SIZE) { - stack[++stack_pointer] = element; + stack[stack_pointer++] = element; } else { printf("Error: the stack is full.\n"); } From 218cece634ea4754aa739f3ef062ac87ac56b2f5 Mon Sep 17 00:00:00 2001 From: JebediahS Date: Thu, 18 Dec 2025 11:05:25 +0100 Subject: [PATCH 2/4] added test-script for expr --- chapter_5/exercise_5_10/expr_test.sh | 87 ++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100755 chapter_5/exercise_5_10/expr_test.sh diff --git a/chapter_5/exercise_5_10/expr_test.sh b/chapter_5/exercise_5_10/expr_test.sh new file mode 100755 index 0000000..dc15e28 --- /dev/null +++ b/chapter_5/exercise_5_10/expr_test.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +# check if file is present and executable +if [ ! -f expr ]; then + echo "File 'expr' found!" + exit 1 +fi + +if [ ! -x expr ]; then + echo "File 'expr' not executable!" + exit 1 +fi + +echo "=== Testing expr calculator ===" + +# Test 1: Simple addition +T=1 +result=$(./expr 2 3 +) +expected="result: 5.000" +if [[ "$result" == "$expected" ]]; then + echo "Test $T PASS: 2 + 3 = 5" +else + echo "Test $T FAIL: Expected '$expected', got '$result'" +fi + +# Test 2: Commutativity of addition +T=2 +result=$(./expr 3 2 +) +expected="result: 5.000" +if [[ "$result" == "$expected" ]]; then + echo "Test $T PASS: 3 + 2 = 5" +else + echo "Test $T FAIL: Expected '$expected', got '$result'" +fi + +# Test 3: Subtraction +T=3 +result=$(./expr 10 3 -) +expected="result: 7.000" +if [[ "$result" == "$expected" ]]; then + echo "Test $T PASS: 10 - 3 = 7" +else + echo "Test $T FAIL: Expected '$expected', got '$result'" +fi + +# Test 4: Complex expression +T=4 +# ------------------------------------ +# Expected: +# 5 --> [5] +# 1 --> [5, 1] +# 2 --> [5, 1, 2] +# + --> (1 + 2 = 3) --> [5, 3] +# 4 --> [5, 3, 4] +# * --> (3 * 4 = 12) --> [5, 12] +# + --> (5 + 12 = 17) --> [17] +# 3 --> [17, 3] +# - --> (17 - 3 = 14) --> [14] +# ------------------------------------ +result=$(./expr 5 1 2 + 4 \* + 3 -) +expected="result: 14.000" +if [[ "$result" == "$expected" ]]; then + echo "Test $T PASS: Complex RPN expression" +else + echo "Test $T FAIL: Expected '$expected', got '$result'" +fi + +# Test 5: Division by zero +T=5 +result=$(./expr 5 0 / 2>&1) +if [[ "$result" == *"division by zero"* ]]; then + echo "Test $T PASS: Division by zero detected" +else + echo "Test $T FAIL: Should detect division by zero" +fi + +# Test 6: Missing operator +T=6 +result=$(./expr 5 1) +expected="Error: Operator is missing!" +if [[ "$result" == "$expected" ]]; then + echo "Test $T PASS: Missing operator" +else + echo "Test $T FAIL: Expected '$expected', got '$result'" +fi + +echo "=== Tests Complete ===" \ No newline at end of file From 68fe0cb76e1d0c4ac8aeba25b24b3215c0ef96a4 Mon Sep 17 00:00:00 2001 From: JebediahS Date: Thu, 18 Dec 2025 12:25:58 +0100 Subject: [PATCH 3/4] fixed case without operators --- chapter_5/exercise_5_10/expr.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/chapter_5/exercise_5_10/expr.c b/chapter_5/exercise_5_10/expr.c index 5f82c87..9cbb598 100644 --- a/chapter_5/exercise_5_10/expr.c +++ b/chapter_5/exercise_5_10/expr.c @@ -13,6 +13,7 @@ void push(float element); int main(int argc, char *argv[]) { char Error = 0; + int op_count = 0; // Using int instead of size_t for loop variable to match signed argc // This prevents sign comparison warnings @@ -29,19 +30,23 @@ int main(int argc, char *argv[]) { char op = *argv[i]; switch (op) { case '+': + op_count++; push(number1 + number2); break; case '-': + op_count++; push(number1 - number2); break; case '*': // This char might require to be escaped when passed // as an argument. + op_count++; push(number1 * number2); break; case '/': + op_count++; if (number2 == 0) { Error = 4; } else { @@ -87,8 +92,13 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - - printf("result: %.3f", pop()); + + if (op_count == 0 && argc > 2) { + printf("Error: Operator is missing!"); + return EXIT_FAILURE; + } else { + printf("result: %.3f", pop()); + } return EXIT_SUCCESS; } From 415836318b02894c54dcd584c697ba70aa4b61d1 Mon Sep 17 00:00:00 2001 From: JebediahS Date: Thu, 18 Dec 2025 12:25:58 +0100 Subject: [PATCH 4/4] fixed case without operators --- chapter_5/exercise_5_10/expr.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/chapter_5/exercise_5_10/expr.c b/chapter_5/exercise_5_10/expr.c index 5f82c87..3e1eed5 100644 --- a/chapter_5/exercise_5_10/expr.c +++ b/chapter_5/exercise_5_10/expr.c @@ -13,6 +13,7 @@ void push(float element); int main(int argc, char *argv[]) { char Error = 0; + int op_count = 0; // Using int instead of size_t for loop variable to match signed argc // This prevents sign comparison warnings @@ -29,19 +30,23 @@ int main(int argc, char *argv[]) { char op = *argv[i]; switch (op) { case '+': + op_count++; push(number1 + number2); break; case '-': + op_count++; push(number1 - number2); break; case '*': // This char might require to be escaped when passed // as an argument. + op_count++; push(number1 * number2); break; case '/': + op_count++; if (number2 == 0) { Error = 4; } else { @@ -87,8 +92,13 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - - printf("result: %.3f", pop()); + + if (op_count == 0 && argc > 2) { + printf("Error: Operator is missing!\n"); + return EXIT_FAILURE; + } else { + printf("result: %.3f", pop()); + } return EXIT_SUCCESS; }