about summary refs log tree commit diff stats
path: root/032array.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-08-14 16:58:59 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-08-14 16:58:59 -0700
commitc6520d9694d3cee265833b9e857f5f693645caba (patch)
tree46b832bf1921d6f4687aab7a1ded3488c8ff8c5b /032array.cc
parentcc835be2510ecea40a2382014d2e943cddb4ec29 (diff)
downloadmu-c6520d9694d3cee265833b9e857f5f693645caba.tar.gz
1994 - new primitive: 'create-array'
Not strictly necessary, but it might help me stage the introduction of
arrays and 'new'.
Diffstat (limited to '032array.cc')
-rw-r--r--032array.cc102
1 files changed, 78 insertions, 24 deletions
diff --git a/032array.cc b/032array.cc
index 412f6878..173b773b 100644
--- a/032array.cc
+++ b/032array.cc
@@ -5,18 +5,72 @@
 //: elements of a fixed size, so you can't create containers containing arrays.
 //: Create containers containing addresses to arrays instead.
 
-//: Tests in this layer often explicitly setup memory before reading it as an
-//: array. Don't do this in general. I'm tagging exceptions with /raw to
-//: avoid warnings.
+//: You can create arrays using 'create-array'.
+:(scenario create_array)
+recipe main [
+  # create an array occupying locations 1 (for the size) and 2-4 (for the elements)
+  1:array:number:3 <- create-array
+  # write to it
+  2:number <- copy 34
+  3:number <- copy 35
+  4:number <- copy 36
+  reply 1:array:number:3
+]
++run: creating array of size 4
+
+:(before "End Primitive Recipe Declarations")
+CREATE_ARRAY,
+:(before "End Primitive Recipe Numbers")
+Recipe_ordinal["create-array"] = CREATE_ARRAY;
+:(before "End Primitive Recipe Implementations")
+case CREATE_ARRAY: {
+  if (current_instruction().products.empty()) {
+    raise << current_recipe_name () << ": 'create-array' needs one product and no ingredients but got '" << current_instruction().to_string() << '\n' << end();
+    break;
+  }
+  reagent product = canonize(current_instruction().products.at(0));
+  if (!is_mu_array(product)) {
+    raise << current_recipe_name () << ": 'create-array' cannot create non-array " << product.original_string << '\n' << end();
+    break;
+  }
+  long long int base_address = product.value;
+  if (SIZE(product.types) == 1) {
+    raise << current_recipe_name () << ": create array of what? " << current_instruction().to_string() << '\n' << end();
+    break;
+  }
+  // 'create-array' will need to check properties rather than types
+  if (SIZE(product.properties.at(0).second) <= 2) {
+    raise << current_recipe_name () << ": create array of what size? " << current_instruction().to_string() << '\n' << end();
+    break;
+  }
+  if (!is_integer(product.properties.at(0).second.at(2))) {
+    raise << current_recipe_name () << ": 'create-array' product should specify size of array after its element type, but got " << product.properties.at(0).second.at(2) << '\n' << end();
+    break;
+  }
+  long long int array_size= to_integer(product.properties.at(0).second.at(2));
+  // initialize array size, so that size_of will work
+  Memory[base_address] = array_size;  // in array elements
+  long long int size = size_of(product);  // in locations
+  trace("run") << "creating array of size " << size << '\n' << end();
+  // initialize array
+  for (long long int i = 1; i <= size_of(product); ++i) {
+    Memory[base_address+i] = 0;
+  }
+  // dummy product; doesn't actually do anything
+  products.resize(1);
+  products.at(0).push_back(array_size);
+  break;
+}
+
 :(scenario copy_array)
 # Arrays can be copied around with a single instruction just like numbers,
 # no matter how large they are.
 recipe main [
-  1:number <- copy 3  # length
+  1:array:number:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
-  5:array:number <- copy 1:array:number/raw  # unsafe
+  5:array:number <- copy 1:array:number:3
 ]
 +mem: storing 3 in location 5
 +mem: storing 14 in location 6
@@ -25,11 +79,11 @@ recipe main [
 
 :(scenario copy_array_indirect)
 recipe main [
-  1:number <- copy 3  # length
+  1:array:number:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
-  5:address:array:number <- copy 1
+  5:address:array:number <- copy 1  # unsafe
   6:array:number <- copy *5:address:array:number
 ]
 +mem: storing 3 in location 6
@@ -39,11 +93,11 @@ recipe main [
 
 :(scenario stash_array)
 recipe main [
-  1:number <- copy 3  # length
+  1:array:number:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
-  stash [foo: ], 1:array:number
+  stash [foo: ], 1:array:number:3
 ]
 +app: foo: 3 14 15 16
 
@@ -64,22 +118,22 @@ if (r.types.at(0) == Type_ordinal["array"]) {
 
 :(scenario index)
 recipe main [
-  1:number <- copy 3  # length
+  1:array:number:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
-  5:number <- index 1:array:number/raw, 0  # unsafe
+  5:number <- index 1:array:number:3, 0
 ]
 +mem: storing 14 in location 5
 
 :(scenario index_direct_offset)
 recipe main [
-  1:number <- copy 3  # length
+  1:array:number:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
   5:number <- copy 0
-  6:number <- index 1:array:number/raw, 5:number  # unsafe
+  6:number <- index 1:array:number, 5:number
 ]
 +mem: storing 14 in location 6
 
@@ -127,7 +181,7 @@ vector<type_ordinal> array_element(const vector<type_ordinal>& types) {
 
 :(scenario index_indirect)
 recipe main [
-  1:number <- copy 3  # length
+  1:array:number:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
@@ -139,7 +193,7 @@ recipe main [
 :(scenario index_out_of_bounds)
 % Hide_warnings = true;
 recipe main [
-  1:number <- copy 3  # 3 points
+  1:array:number:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
@@ -154,7 +208,7 @@ recipe main [
 :(scenario index_out_of_bounds_2)
 % Hide_warnings = true;
 recipe main [
-  1:number <- copy 3  # 3 points
+  1:array:point:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
@@ -170,11 +224,11 @@ recipe main [
 
 :(scenario index_address)
 recipe main [
-  1:number <- copy 3  # length
+  1:array:number:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
-  5:number <- index-address 1:array:number/raw, 0  # unsafe
+  5:number <- index-address 1:array:number, 0
 ]
 +mem: storing 2 in location 5
 
@@ -214,14 +268,14 @@ case INDEX_ADDRESS: {
 :(scenario index_address_out_of_bounds)
 % Hide_warnings = true;
 recipe main [
-  1:number <- copy 3  # 3 points
+  1:array:point:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
   5:number <- copy 14
   6:number <- copy 15
   7:number <- copy 16
-  8:address:array:point <- copy 1
+  8:address:array:point <- copy 1  # unsafe
   index-address *8:address:array:point, 4  # less than size of array in locations, but larger than its length in elements
 ]
 +warn: main: invalid index 4
@@ -229,14 +283,14 @@ recipe main [
 :(scenario index_address_out_of_bounds_2)
 % Hide_warnings = true;
 recipe main [
-  1:number <- copy 3  # 3 points
+  1:array:point:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
   5:number <- copy 14
   6:number <- copy 15
   7:number <- copy 16
-  8:address:array:point <- copy 1
+  8:address:array:point <- copy 1  # unsafe
   index-address *8:address:array:point, -1
 ]
 +warn: main: invalid index -1
@@ -245,11 +299,11 @@ recipe main [
 
 :(scenario array_length)
 recipe main [
-  1:number <- copy 3  # length
+  1:array:number:3 <- create-array
   2:number <- copy 14
   3:number <- copy 15
   4:number <- copy 16
-  5:number <- length 1:array:number/raw  # unsafe
+  5:number <- length 1:array:number:3
 ]
 +mem: storing 3 in location 5