about summary refs log tree commit diff stats
path: root/034address.cc
diff options
context:
space:
mode:
Diffstat (limited to '034address.cc')
-rw-r--r--034address.cc342
1 files changed, 208 insertions, 134 deletions
diff --git a/034address.cc b/034address.cc
index af98fc14..bafde7b4 100644
--- a/034address.cc
+++ b/034address.cc
@@ -52,37 +52,54 @@ Next_alloc_id = 0;
 
 //: todo: give 'new' a custodian ingredient. Following malloc/free is a temporary hack.
 
-:(scenario new)
-# call 'new' two times with identical types without modifying the results; you
-# should get back different results
-def main [
-  10:&:num <- new num:type
-  12:&:num <- new num:type
-  20:bool <- equal 10:&:num, 12:&:num
-]
-+mem: storing 1000 in location 11
-+mem: storing 0 in location 20
-
-:(scenario new_array)
-# call 'new' with a second ingredient to allocate an array of some type rather than a single copy
-def main [
-  10:&:@:num <- new num:type, 5
-  12:&:num <- new num:type
-  20:num/alloc2, 21:num/alloc1 <- deaddress 10:&:@:num, 12:&:num
-  30:num <- subtract 21:num/alloc2, 20:num/alloc1
-]
-+run: {10: ("address" "array" "number")} <- new {num: "type"}, {5: "literal"}
-+mem: array length is 5
-# skip alloc id in allocation
-+mem: storing 1000 in location 11
-# don't forget the extra locations for alloc id and array length
-+mem: storing 7 in location 30
-
-:(scenario dilated_reagent_with_new)
-def main [
-  10:&:&:num <- new {(& num): type}
-]
-+new: size of '(& num)' is 2
+:(code)
+void test_new() {
+  run(
+      // call 'new' two times with identical types without modifying the
+      // results; you should get back different results
+      "def main [\n"
+      "  10:&:num <- new num:type\n"
+      "  12:&:num <- new num:type\n"
+      "  20:bool <- equal 10:&:num, 12:&:num\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 1000 in location 11\n"
+      "mem: storing 0 in location 20\n"
+  );
+}
+
+void test_new_array() {
+  run(
+      // call 'new' with a second ingredient to allocate an array of some type
+      // rather than a single copy
+      "def main [\n"
+      "  10:&:@:num <- new num:type, 5\n"
+      "  12:&:num <- new num:type\n"
+      "  20:num/alloc2, 21:num/alloc1 <- deaddress 10:&:@:num, 12:&:num\n"
+      "  30:num <- subtract 21:num/alloc2, 20:num/alloc1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: {10: (\"address\" \"array\" \"number\")} <- new {num: \"type\"}, {5: \"literal\"}\n"
+      "mem: array length is 5\n"
+      // skip alloc id in allocation
+      "mem: storing 1000 in location 11\n"
+      // don't forget the extra locations for alloc id and array length
+      "mem: storing 7 in location 30\n"
+  );
+}
+
+void test_dilated_reagent_with_new() {
+  run(
+      "def main [\n"
+      "  10:&:&:num <- new {(& num): type}\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "new: size of '(& num)' is 2\n"
+  );
+}
 
 //: 'new' takes a weird 'type' as its first ingredient; don't error on it
 :(before "End Mu Types Initialization")
@@ -123,6 +140,7 @@ case NEW: {
   }
   break;
 }
+
 :(code)
 bool product_of_new_is_valid(const instruction& inst) {
   reagent/*copy*/ product = inst.products.at(0);
@@ -160,38 +178,59 @@ void drop_from_type(reagent& r, string expected_type) {
   delete tmp;
 }
 
-:(scenario new_returns_incorrect_type)
-% Hide_errors = true;
-def main [
-  1:bool <- new num:type
-]
-+error: main: product of 'new' has incorrect type: '1:bool <- new num:type'
-
-:(scenario new_discerns_singleton_list_from_atom_container)
-% Hide_errors = true;
-def main [
-  1:&:num <- new {(num): type}  # should be '{num: type}'
-]
-+error: main: product of 'new' has incorrect type: '1:&:num <- new {(num): type}'
-
-:(scenario new_with_type_abbreviation)
-def main [
-  1:&:num <- new num:type
-]
-$error: 0
-
-:(scenario new_with_type_abbreviation_inside_compound)
-def main [
-  {1: (address address number), raw: ()} <- new {(& num): type}
-]
-$error: 0
-
-:(scenario equal_result_of_new_with_null)
-def main [
-  1:&:num <- new num:type
-  10:bool <- equal 1:&:num, null
-]
-+mem: storing 0 in location 10
+void test_new_returns_incorrect_type() {
+  Hide_errors = true;
+  run(
+      "def main [\n"
+      "  1:bool <- new num:type\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "error: main: product of 'new' has incorrect type: '1:bool <- new num:type'\n"
+  );
+}
+
+void test_new_discerns_singleton_list_from_atom_container() {
+  Hide_errors = true;
+  run(
+      "def main [\n"
+      "  1:&:num <- new {(num): type}\n"  // should be '{num: type}'
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "error: main: product of 'new' has incorrect type: '1:&:num <- new {(num): type}'\n"
+  );
+}
+
+void test_new_with_type_abbreviation() {
+  run(
+      "def main [\n"
+      "  1:&:num <- new num:type\n"
+      "]\n"
+  );
+  CHECK_TRACE_COUNT("error", 0);
+}
+
+void test_new_with_type_abbreviation_inside_compound() {
+  run(
+      "def main [\n"
+      "  {1: (address address number), raw: ()} <- new {(& num): type}\n"
+      "]\n"
+  );
+  CHECK_TRACE_COUNT("error", 0);
+}
+
+void test_equal_result_of_new_with_null() {
+  run(
+      "def main [\n"
+      "  1:&:num <- new num:type\n"
+      "  10:bool <- equal 1:&:num, null\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 0 in location 10\n"
+  );
+}
 
 //: To implement 'new', a Mu transform turns all 'new' instructions into
 //: 'allocate' instructions that precompute the amount of memory they want to
@@ -329,79 +368,114 @@ void ensure_space(int size) {
   }
 }
 
-:(scenario new_initializes)
-% Memory_allocated_until = 10;
-% put(Memory, Memory_allocated_until, 1);
-def main [
-  1:&:num <- new num:type
-]
-+mem: storing 0 in location 10
-+mem: storing 0 in location 11
-+mem: storing 10 in location 2
-
-:(scenario new_initializes_alloc_id)
-% Memory_allocated_until = 10;
-% put(Memory, Memory_allocated_until, 1);
-% Next_alloc_id = 23;
-def main [
-  1:&:num <- new num:type
-]
-# initialize memory
-+mem: storing 0 in location 10
-+mem: storing 0 in location 11
-# alloc-id in payload
-+mem: storing alloc-id 23 in location 10
-# alloc-id in address
-+mem: storing 23 in location 1
-
-:(scenario new_size)
-def main [
-  10:&:num <- new num:type
-  12:&:num <- new num:type
-  20:num/alloc1, 21:num/alloc2 <- deaddress 10:&:num, 12:&:num
-  30:num <- subtract 21:num/alloc2, 20:num/alloc1
-]
-# size of number + alloc id
-+mem: storing 2 in location 30
-
-:(scenario new_array_size)
-def main [
-  10:&:@:num <- new num:type, 5
-  12:&:num <- new num:type
-  20:num/alloc1, 21:num/alloc2 <- deaddress 10:&:num, 12:&:num
-  30:num <- subtract 21:num/alloc2, 20:num/alloc1
-]
-# 5 locations for array contents + array length + alloc id
-+mem: storing 7 in location 30
-
-:(scenario new_empty_array)
-def main [
-  10:&:@:num <- new num:type, 0
-  12:&:num <- new num:type
-  20:num/alloc1, 21:num/alloc2 <- deaddress 10:&:@:num, 12:&:num
-  30:num <- subtract 21:num/alloc2, 20:num/alloc1
-]
-+run: {10: ("address" "array" "number")} <- new {num: "type"}, {0: "literal"}
-+mem: array length is 0
-# one location for array length
-+mem: storing 2 in location 30
+void test_new_initializes() {
+  Memory_allocated_until = 10;
+  put(Memory, Memory_allocated_until, 1);
+  run(
+      "def main [\n"
+      "  1:&:num <- new num:type\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "mem: storing 0 in location 10\n"
+      "mem: storing 0 in location 11\n"
+      "mem: storing 10 in location 2\n"
+  );
+}
+
+void test_new_initializes_alloc_id() {
+  Memory_allocated_until = 10;
+  put(Memory, Memory_allocated_until, 1);
+  Next_alloc_id = 23;
+  run(
+      "def main [\n"
+      "  1:&:num <- new num:type\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      // initialize memory
+      "mem: storing 0 in location 10\n"
+      "mem: storing 0 in location 11\n"
+      // alloc-id in payload
+      "mem: storing alloc-id 23 in location 10\n"
+      // alloc-id in address
+      "mem: storing 23 in location 1\n"
+  );
+}
+
+void test_new_size() {
+  run(
+      "def main [\n"
+      "  10:&:num <- new num:type\n"
+      "  12:&:num <- new num:type\n"
+      "  20:num/alloc1, 21:num/alloc2 <- deaddress 10:&:num, 12:&:num\n"
+      "  30:num <- subtract 21:num/alloc2, 20:num/alloc1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      // size of number + alloc id
+      "mem: storing 2 in location 30\n"
+  );
+}
+
+void test_new_array_size() {
+  run(
+      "def main [\n"
+      "  10:&:@:num <- new num:type, 5\n"
+      "  12:&:num <- new num:type\n"
+      "  20:num/alloc1, 21:num/alloc2 <- deaddress 10:&:num, 12:&:num\n"
+      "  30:num <- subtract 21:num/alloc2, 20:num/alloc1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      // 5 locations for array contents + array length + alloc id
+      "mem: storing 7 in location 30\n"
+  );
+}
+
+void test_new_empty_array() {
+  run(
+      "def main [\n"
+      "  10:&:@:num <- new num:type, 0\n"
+      "  12:&:num <- new num:type\n"
+      "  20:num/alloc1, 21:num/alloc2 <- deaddress 10:&:@:num, 12:&:num\n"
+      "  30:num <- subtract 21:num/alloc2, 20:num/alloc1\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: {10: (\"address\" \"array\" \"number\")} <- new {num: \"type\"}, {0: \"literal\"}\n"
+      "mem: array length is 0\n"
+      // one location for array length and one for alloc id
+      "mem: storing 2 in location 30\n"
+  );
+}
 
 //: If a routine runs out of its initial allocation, it should allocate more.
-:(scenario new_overflow)
-% Initial_memory_per_routine = 3;  // barely enough room for point allocation below
-def main [
-  10:&:num <- new num:type
-  12:&:point <- new point:type  # not enough room in initial page
-]
-+new: routine allocated memory from 1000 to 1003
-+new: routine allocated memory from 1003 to 1006
-
-:(scenario new_without_ingredient)
-% Hide_errors = true;
-def main [
-  1:&:num <- new  # missing ingredient
-]
-+error: main: 'new' requires one or two ingredients, but got '1:&:num <- new'
+void test_new_overflow() {
+  Initial_memory_per_routine = 3;  // barely enough room for point allocation below
+  run(
+      "def main [\n"
+      "  10:&:num <- new num:type\n"
+      "  12:&:point <- new point:type\n"  // not enough room in initial page
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "new: routine allocated memory from 1000 to 1003\n"
+      "new: routine allocated memory from 1003 to 1006\n"
+  );
+}
+
+void test_new_without_ingredient() {
+  Hide_errors = true;
+  run(
+      "def main [\n"
+      "  1:&:num <- new\n"  // missing ingredient
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "error: main: 'new' requires one or two ingredients, but got '1:&:num <- new'\n"
+  );
+}
 
 //: a little helper: convert address to number