From c6520d9694d3cee265833b9e857f5f693645caba Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Fri, 14 Aug 2015 16:58:59 -0700 Subject: 1994 - new primitive: 'create-array' Not strictly necessary, but it might help me stage the introduction of arrays and 'new'. --- 010vm.cc | 4 ++- 030container.cc | 4 ++- 032array.cc | 102 +++++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 84 insertions(+), 26 deletions(-) diff --git a/010vm.cc b/010vm.cc index 41a63e2c..c9bfaa5d 100644 --- a/010vm.cc +++ b/010vm.cc @@ -196,7 +196,9 @@ reagent::reagent(string s) :original_string(s), value(0), initialized(false) { name = properties.at(0).first; for (long long int i = 0; i < SIZE(properties.at(0).second); ++i) { string type = properties.at(0).second.at(i); - if (Type_ordinal.find(type) == Type_ordinal.end()) { + if (Type_ordinal.find(type) == Type_ordinal.end() + // types can contain integers, like for array sizes + && !is_integer(type)) { //? cerr << type << " is " << Next_type_ordinal << '\n'; //? 1 Type_ordinal[type] = Next_type_ordinal++; } diff --git a/030container.cc b/030container.cc index ac198929..808b64fe 100644 --- a/030container.cc +++ b/030container.cc @@ -325,7 +325,9 @@ void insert_container(const string& command, kind_of_type kind, istream& in) { vector types; while (!inner.eof()) { string type_name = slurp_until(inner, ':'); - if (Type_ordinal.find(type_name) == Type_ordinal.end()) { + if (Type_ordinal.find(type_name) == Type_ordinal.end() + // types can contain integers, like for array sizes + && !is_integer(type_name)) { //? cerr << type_name << " is " << Next_type_ordinal << '\n'; //? 1 Type_ordinal[type_name] = Next_type_ordinal++; } 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 array_element(const vector& 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 -- cgit 1.4.1-2-gfad0