about summary refs log tree commit diff stats
path: root/022arithmetic.cc
diff options
context:
space:
mode:
Diffstat (limited to '022arithmetic.cc')
-rw-r--r--022arithmetic.cc805
1 files changed, 529 insertions, 276 deletions
diff --git a/022arithmetic.cc b/022arithmetic.cc
index ce8cf1b9..05e79e3b 100644
--- a/022arithmetic.cc
+++ b/022arithmetic.cc
@@ -34,39 +34,65 @@ case ADD: {
   break;
 }
 
-:(scenario add_literal)
-def main [
-  1:num <- add 23, 34
-]
-+mem: storing 57 in location 1
-
-:(scenario add)
-def main [
-  1:num <- copy 23
-  2:num <- copy 34
-  3:num <- add 1:num, 2:num
-]
-+mem: storing 57 in location 3
-
-:(scenario add_multiple)
-def main [
-  1:num <- add 3, 4, 5
-]
-+mem: storing 12 in location 1
-
-:(scenario add_checks_type)
-% Hide_errors = true;
-def main [
-  1:num <- add 2:bool, 1
-]
-+error: main: 'add' requires number ingredients, but got '2:bool'
-
-:(scenario add_checks_return_type)
-% Hide_errors = true;
-def main [
-  1:&:num <- add 2, 2
-]
-+error: main: 'add' should yield a number, but got '1:&:num'
+:(code)
+void test_add_literal() {
+  run(
+      "def main [\n"
+      "  1:num <- add 23, 34\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 57 in location 1\n"
+  );
+}
+
+void test_add() {
+  run(
+      "def main [\n"
+      "  1:num <- copy 23\n"
+      "  2:num <- copy 34\n"
+      "  3:num <- add 1:num, 2:num\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 57 in location 3\n"
+  );
+}
+
+void test_add_multiple() {
+  run(
+      "def main [\n"
+      "  1:num <- add 3, 4, 5\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 12 in location 1\n"
+  );
+}
+
+void test_add_checks_type() {
+  Hide_errors = true;
+  run(
+      "def main [\n"
+      "  1:num <- add 2:bool, 1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "error: main: 'add' requires number ingredients, but got '2:bool'\n"
+  );
+}
+
+void test_add_checks_return_type() {
+  Hide_errors = true;
+  run(
+      "def main [\n"
+      "  1:&:num <- add 2, 2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "error: main: 'add' should yield a number, but got '1:&:num'\n"
+  );
+}
 
 :(before "End Primitive Recipe Declarations")
 SUBTRACT,
@@ -104,25 +130,41 @@ case SUBTRACT: {
   break;
 }
 
-:(scenario subtract_literal)
-def main [
-  1:num <- subtract 5, 2
-]
-+mem: storing 3 in location 1
+:(code)
+void test_subtract_literal() {
+  run(
+      "def main [\n"
+      "  1:num <- subtract 5, 2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 3 in location 1\n"
+  );
+}
 
-:(scenario subtract)
-def main [
-  1:num <- copy 23
-  2:num <- copy 34
-  3:num <- subtract 1:num, 2:num
-]
-+mem: storing -11 in location 3
+void test_subtract() {
+  run(
+      "def main [\n"
+      "  1:num <- copy 23\n"
+      "  2:num <- copy 34\n"
+      "  3:num <- subtract 1:num, 2:num\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing -11 in location 3\n"
+  );
+}
 
-:(scenario subtract_multiple)
-def main [
-  1:num <- subtract 6, 3, 2
-]
-+mem: storing 1 in location 1
+void test_subtract_multiple() {
+  run(
+      "def main [\n"
+      "  1:num <- subtract 6, 3, 2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 1 in location 1\n"
+  );
+}
 
 :(before "End Primitive Recipe Declarations")
 MULTIPLY,
@@ -157,25 +199,41 @@ case MULTIPLY: {
   break;
 }
 
-:(scenario multiply_literal)
-def main [
-  1:num <- multiply 2, 3
-]
-+mem: storing 6 in location 1
+:(code)
+void test_multiply_literal() {
+  run(
+      "def main [\n"
+      "  1:num <- multiply 2, 3\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 6 in location 1\n"
+  );
+}
 
-:(scenario multiply)
-def main [
-  1:num <- copy 4
-  2:num <- copy 6
-  3:num <- multiply 1:num, 2:num
-]
-+mem: storing 24 in location 3
+void test_multiply() {
+  run(
+      "def main [\n"
+      "  1:num <- copy 4\n"
+      "  2:num <- copy 6\n"
+      "  3:num <- multiply 1:num, 2:num\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 24 in location 3\n"
+  );
+}
 
-:(scenario multiply_multiple)
-def main [
-  1:num <- multiply 2, 3, 4
-]
-+mem: storing 24 in location 1
+void test_multiply_multiple() {
+  run(
+      "def main [\n"
+      "  1:num <- multiply 2, 3, 4\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 24 in location 1\n"
+  );
+}
 
 :(before "End Primitive Recipe Declarations")
 DIVIDE,
@@ -213,25 +271,41 @@ case DIVIDE: {
   break;
 }
 
-:(scenario divide_literal)
-def main [
-  1:num <- divide 8, 2
-]
-+mem: storing 4 in location 1
+:(code)
+void test_divide_literal() {
+  run(
+      "def main [\n"
+      "  1:num <- divide 8, 2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 4 in location 1\n"
+  );
+}
 
-:(scenario divide)
-def main [
-  1:num <- copy 27
-  2:num <- copy 3
-  3:num <- divide 1:num, 2:num
-]
-+mem: storing 9 in location 3
+void test_divide() {
+  run(
+      "def main [\n"
+      "  1:num <- copy 27\n"
+      "  2:num <- copy 3\n"
+      "  3:num <- divide 1:num, 2:num\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 9 in location 3\n"
+  );
+}
 
-:(scenario divide_multiple)
-def main [
-  1:num <- divide 12, 3, 2
-]
-+mem: storing 2 in location 1
+void test_divide_multiple() {
+  run(
+      "def main [\n"
+      "  1:num <- divide 12, 3, 2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 2 in location 1\n"
+  );
+}
 
 //: Integer division
 
@@ -281,41 +355,67 @@ case DIVIDE_WITH_REMAINDER: {
   break;
 }
 
-:(scenario divide_with_remainder_literal)
-def main [
-  1:num, 2:num <- divide-with-remainder 9, 2
-]
-+mem: storing 4 in location 1
-+mem: storing 1 in location 2
-
-:(scenario divide_with_remainder)
-def main [
-  1:num <- copy 27
-  2:num <- copy 11
-  3:num, 4:num <- divide-with-remainder 1:num, 2:num
-]
-+mem: storing 2 in location 3
-+mem: storing 5 in location 4
-
-:(scenario divide_with_decimal_point)
-def main [
-  1:num <- divide 5, 2
-]
-+mem: storing 2.5 in location 1
-
-:(scenario divide_by_zero)
-def main [
-  1:num <- divide 4, 0
-]
-+mem: storing inf in location 1
-
-:(scenario divide_by_zero_2)
-% Hide_errors = true;
-def main [
-  1:num <- divide-with-remainder 4, 0
-]
-# integer division can't return floating-point infinity
-+error: main: divide by zero in '1:num <- divide-with-remainder 4, 0'
+:(code)
+void test_divide_with_remainder_literal() {
+  run(
+      "def main [\n"
+      "  1:num, 2:num <- divide-with-remainder 9, 2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 4 in location 1\n"
+      "mem: storing 1 in location 2\n"
+  );
+}
+
+void test_divide_with_remainder() {
+  run(
+      "def main [\n"
+      "  1:num <- copy 27\n"
+      "  2:num <- copy 11\n"
+      "  3:num, 4:num <- divide-with-remainder 1:num, 2:num\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 2 in location 3\n"
+      "mem: storing 5 in location 4\n"
+  );
+}
+
+void test_divide_with_decimal_point() {
+  run(
+      "def main [\n"
+      "  1:num <- divide 5, 2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 2.5 in location 1\n"
+  );
+}
+
+void test_divide_by_zero() {
+  run(
+      "def main [\n"
+      "  1:num <- divide 4, 0\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing inf in location 1\n"
+  );
+}
+
+void test_divide_by_zero_2() {
+  Hide_errors = true;
+  run(
+      "def main [\n"
+      "  1:num <- divide-with-remainder 4, 0\n"
+      "]\n"
+  );
+  // integer division can't return floating-point infinity
+  CHECK_TRACE_CONTENTS(
+      "error: main: divide by zero in '1:num <- divide-with-remainder 4, 0'\n"
+  );
+}
 
 //: Bitwise shifts
 
@@ -358,37 +458,63 @@ case SHIFT_LEFT: {
   break;
 }
 
-:(scenario shift_left_by_zero)
-def main [
-  1:num <- shift-left 1, 0
-]
-+mem: storing 1 in location 1
-
-:(scenario shift_left_1)
-def main [
-  1:num <- shift-left 1, 4
-]
-+mem: storing 16 in location 1
-
-:(scenario shift_left_2)
-def main [
-  1:num <- shift-left 3, 2
-]
-+mem: storing 12 in location 1
-
-:(scenario shift_left_by_negative)
-% Hide_errors = true;
-def main [
-  1:num <- shift-left 3, -1
-]
-+error: main: second ingredient can't be negative in '1:num <- shift-left 3, -1'
-
-:(scenario shift_left_ignores_fractional_part)
-def main [
-  1:num <- divide 3, 2
-  2:num <- shift-left 1:num, 1
-]
-+mem: storing 2 in location 2
+:(code)
+void test_shift_left_by_zero() {
+  run(
+      "def main [\n"
+      "  1:num <- shift-left 1, 0\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 1 in location 1\n"
+  );
+}
+
+void test_shift_left_1() {
+  run(
+      "def main [\n"
+      "  1:num <- shift-left 1, 4\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 16 in location 1\n"
+  );
+}
+
+void test_shift_left_2() {
+  run(
+      "def main [\n"
+      "  1:num <- shift-left 3, 2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 12 in location 1\n"
+  );
+}
+
+void test_shift_left_by_negative() {
+  Hide_errors = true;
+  run(
+      "def main [\n"
+      "  1:num <- shift-left 3, -1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "error: main: second ingredient can't be negative in '1:num <- shift-left 3, -1'\n"
+  );
+}
+
+void test_shift_left_ignores_fractional_part() {
+  run(
+      "def main [\n"
+      "  1:num <- divide 3, 2\n"
+      "  2:num <- shift-left 1:num, 1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 2 in location 2\n"
+  );
+}
 
 :(before "End Primitive Recipe Declarations")
 SHIFT_RIGHT,
@@ -429,37 +555,63 @@ case SHIFT_RIGHT: {
   break;
 }
 
-:(scenario shift_right_by_zero)
-def main [
-  1:num <- shift-right 1, 0
-]
-+mem: storing 1 in location 1
-
-:(scenario shift_right_1)
-def main [
-  1:num <- shift-right 1024, 1
-]
-+mem: storing 512 in location 1
-
-:(scenario shift_right_2)
-def main [
-  1:num <- shift-right 3, 1
-]
-+mem: storing 1 in location 1
-
-:(scenario shift_right_by_negative)
-% Hide_errors = true;
-def main [
-  1:num <- shift-right 4, -1
-]
-+error: main: second ingredient can't be negative in '1:num <- shift-right 4, -1'
-
-:(scenario shift_right_ignores_fractional_part)
-def main [
-  1:num <- divide 3, 2
-  2:num <- shift-right 1:num, 1
-]
-+mem: storing 0 in location 2
+:(code)
+void test_shift_right_by_zero() {
+  run(
+      "def main [\n"
+      "  1:num <- shift-right 1, 0\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 1 in location 1\n"
+  );
+}
+
+void test_shift_right_1() {
+  run(
+      "def main [\n"
+      "  1:num <- shift-right 1024, 1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 512 in location 1\n"
+  );
+}
+
+void test_shift_right_2() {
+  run(
+      "def main [\n"
+      "  1:num <- shift-right 3, 1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 1 in location 1\n"
+  );
+}
+
+void test_shift_right_by_negative() {
+  Hide_errors = true;
+  run(
+      "def main [\n"
+      "  1:num <- shift-right 4, -1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "error: main: second ingredient can't be negative in '1:num <- shift-right 4, -1'\n"
+  );
+}
+
+void test_shift_right_ignores_fractional_part() {
+  run(
+      "def main [\n"
+      "  1:num <- divide 3, 2\n"
+      "  2:num <- shift-right 1:num, 1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 0 in location 2\n"
+  );
+}
 
 :(before "End Primitive Recipe Declarations")
 AND_BITS,
@@ -495,29 +647,50 @@ case AND_BITS: {
   break;
 }
 
-:(scenario and_bits_1)
-def main [
-  1:num <- and-bits 8, 3
-]
-+mem: storing 0 in location 1
+:(code)
+void test_and_bits_1() {
+  run(
+      "def main [\n"
+      "  1:num <- and-bits 8, 3\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 0 in location 1\n"
+  );
+}
 
-:(scenario and_bits_2)
-def main [
-  1:num <- and-bits 3, 2
-]
-+mem: storing 2 in location 1
+void test_and_bits_2() {
+  run(
+      "def main [\n"
+      "  1:num <- and-bits 3, 2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 2 in location 1\n"
+  );
+}
 
-:(scenario and_bits_3)
-def main [
-  1:num <- and-bits 14, 3
-]
-+mem: storing 2 in location 1
+void test_and_bits_3() {
+  run(
+      "def main [\n"
+      "  1:num <- and-bits 14, 3\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 2 in location 1\n"
+  );
+}
 
-:(scenario and_bits_negative)
-def main [
-  1:num <- and-bits -3, 4
-]
-+mem: storing 4 in location 1
+void test_and_bits_negative() {
+  run(
+      "def main [\n"
+      "  1:num <- and-bits -3, 4\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 4 in location 1\n"
+  );
+}
 
 :(before "End Primitive Recipe Declarations")
 OR_BITS,
@@ -553,23 +726,39 @@ case OR_BITS: {
   break;
 }
 
-:(scenario or_bits_1)
-def main [
-  1:num <- or-bits 3, 8
-]
-+mem: storing 11 in location 1
+:(code)
+void test_or_bits_1() {
+  run(
+      "def main [\n"
+      "  1:num <- or-bits 3, 8\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 11 in location 1\n"
+  );
+}
 
-:(scenario or_bits_2)
-def main [
-  1:num <- or-bits 3, 10
-]
-+mem: storing 11 in location 1
+void test_or_bits_2() {
+  run(
+      "def main [\n"
+      "  1:num <- or-bits 3, 10\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 11 in location 1\n"
+  );
+}
 
-:(scenario or_bits_3)
-def main [
-  1:num <- or-bits 4, 6
-]
-+mem: storing 6 in location 1
+void test_or_bits_3() {
+  run(
+      "def main [\n"
+      "  1:num <- or-bits 4, 6\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 6 in location 1\n"
+  );
+}
 
 :(before "End Primitive Recipe Declarations")
 XOR_BITS,
@@ -605,23 +794,39 @@ case XOR_BITS: {
   break;
 }
 
-:(scenario xor_bits_1)
-def main [
-  1:num <- xor-bits 3, 8
-]
-+mem: storing 11 in location 1
+:(code)
+void test_xor_bits_1() {
+  run(
+      "def main [\n"
+      "  1:num <- xor-bits 3, 8\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 11 in location 1\n"
+  );
+}
 
-:(scenario xor_bits_2)
-def main [
-  1:num <- xor-bits 3, 10
-]
-+mem: storing 9 in location 1
+void test_xor_bits_2() {
+  run(
+      "def main [\n"
+      "  1:num <- xor-bits 3, 10\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 9 in location 1\n"
+  );
+}
 
-:(scenario xor_bits_3)
-def main [
-  1:num <- xor-bits 4, 6
-]
-+mem: storing 2 in location 1
+void test_xor_bits_3() {
+  run(
+      "def main [\n"
+      "  1:num <- xor-bits 4, 6\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 2 in location 1\n"
+  );
+}
 
 :(before "End Primitive Recipe Declarations")
 FLIP_BITS,
@@ -656,29 +861,50 @@ case FLIP_BITS: {
   break;
 }
 
-:(scenario flip_bits_zero)
-def main [
-  1:num <- flip-bits 0
-]
-+mem: storing -1 in location 1
+:(code)
+void test_flip_bits_zero() {
+  run(
+      "def main [\n"
+      "  1:num <- flip-bits 0\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing -1 in location 1\n"
+  );
+}
 
-:(scenario flip_bits_negative)
-def main [
-  1:num <- flip-bits -1
-]
-+mem: storing 0 in location 1
+void test_flip_bits_negative() {
+  run(
+      "def main [\n"
+      "  1:num <- flip-bits -1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 0 in location 1\n"
+  );
+}
 
-:(scenario flip_bits_1)
-def main [
-  1:num <- flip-bits 3
-]
-+mem: storing -4 in location 1
+void test_flip_bits_1() {
+  run(
+      "def main [\n"
+      "  1:num <- flip-bits 3\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing -4 in location 1\n"
+  );
+}
 
-:(scenario flip_bits_2)
-def main [
-  1:num <- flip-bits 12
-]
-+mem: storing -13 in location 1
+void test_flip_bits_2() {
+  run(
+      "def main [\n"
+      "  1:num <- flip-bits 12\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing -13 in location 1\n"
+  );
+}
 
 :(before "End Primitive Recipe Declarations")
 ROUND,
@@ -703,23 +929,39 @@ case ROUND: {
   break;
 }
 
-:(scenario round_to_nearest_integer)
-def main [
-  1:num <- round 12.2
-]
-+mem: storing 12 in location 1
+:(code)
+void test_round_to_nearest_integer() {
+  run(
+      "def main [\n"
+      "  1:num <- round 12.2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 12 in location 1\n"
+  );
+}
 
-:(scenario round_halves_toward_zero)
-def main [
-  1:num <- round 12.5
-]
-+mem: storing 12 in location 1
+void test_round_halves_toward_zero() {
+  run(
+      "def main [\n"
+      "  1:num <- round 12.5\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 12 in location 1\n"
+  );
+}
 
-:(scenario round_halves_toward_zero_2)
-def main [
-  1:num <- round -12.5
-]
-+mem: storing -12 in location 1
+void test_round_halves_toward_zero_2() {
+  run(
+      "def main [\n"
+      "  1:num <- round -12.5\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing -12 in location 1\n"
+  );
+}
 
 :(before "End Primitive Recipe Declarations")
 TRUNCATE,
@@ -744,17 +986,28 @@ case TRUNCATE: {
   break;
 }
 
-:(scenario truncate_to_nearest_integer)
-def main [
-  1:num <- truncate 12.2
-]
-+mem: storing 12 in location 1
+:(code)
+void test_truncate_to_nearest_integer() {
+  run(
+      "def main [\n"
+      "  1:num <- truncate 12.2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 12 in location 1\n"
+  );
+}
 
-:(scenario truncate_negative)
-def main [
-  1:num <- truncate -12.2
-]
-+mem: storing -12 in location 1
+void test_truncate_negative() {
+  run(
+      "def main [\n"
+      "  1:num <- truncate -12.2\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing -12 in location 1\n"
+  );
+}
 
 :(before "End Primitive Recipe Declarations")
 SQUARE_ROOT,