Arithmetic commands operate on the top two items on the stack, and replace them
with the result of the operation. The first item pushed is considered to be
-left of the operator.
+left of the operator. The modulo command will always return a positive result.
| Command | Params | Meaning |
| :------------- | :----- | :--------------- |
# This test verifies arithmetic IMP remainder.
+# First, verify basic function with two positive numbers.
SSSTTSSSSTSN | ST: Push +194
SSSTSSSSSSTN | ST: Push +128
TSTT | MA: Remainder
TNSS | IO: Output character
+
+# The VVS modulo function should always return a positive value.
+# C-derived languages (among others) do not share this convention.
+
+# This test verifies that -3 mod 2 = 1.
+SSTTTN | ST: Push -3
+SSSTSN | ST: Push +2
+TSTT | MA: Remainder
+TNST | IO: Output digit
+
+# This test verifies that -3 mod -2 = 1.
+SSTTTN | ST: Push -3
+SSTTSN | ST: Push -2
+TSTT | MA: Remainder
+TNST | IO: Output digit
+
+# This test verifies that -3 mod -(2^63) = 3.
+SSTTTN | ST: Push -3
+SSTTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSN | PUSH -(2^63)
+TSTT | MA: Remainder
+TNST | IO: Output digit
+
+# All done
NNN | FC: Terminate program
['2002_arithmetic_subtraction', '', 'A'],
['2003_arithmetic_multiplication', '', 'B'],
['2004_arithmetic_division', '', 'A'],
- ['2005_arithmetic_remainder', '', 'A'],
+ ['2005_arithmetic_remainder', '', 'A113'],
['3001_heap', '', 'BCA'],
['4001_flowcontrol_exit', '', ''],
['4002_flowcontrol_unconditional_jump_to_label', '', 'A'],
case '\t':
/* Modulo */
temp = stack_pop(sp);
- stack_push(sp, stack_pop(sp)%temp);
+ stack_push(sp, llabs(stack_pop(sp) % llabs(temp)));
break;
default: ws_die(pc, "malformed arithmetic IMP"); break;
}