about summary refs log tree commit diff stats
path: root/038new_text.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-06-24 09:16:17 -0700
committerKartik Agaram <vc@akkartik.com>2018-06-24 09:18:20 -0700
commit23d3a02226973f80188e84fa5dcedb14413c5b7f (patch)
tree3c73284cb795e74d78e53b72df470cafca4c70cf /038new_text.cc
parent377b00b045289a3fa8e88d4b2f129d797c687e2f (diff)
downloadmu-23d3a02226973f80188e84fa5dcedb14413c5b7f.tar.gz
4266 - space for alloc-id in heap allocations
This has taken me almost 6 weeks :(
Diffstat (limited to '038new_text.cc')
-rw-r--r--038new_text.cc73
1 files changed, 41 insertions, 32 deletions
diff --git a/038new_text.cc b/038new_text.cc
index f0616c54..7e3c02f6 100644
--- a/038new_text.cc
+++ b/038new_text.cc
@@ -6,21 +6,21 @@ put(Type_abbreviations, "text", new_type_tree("&:@:character"));
 
 :(scenario new_string)
 def main [
-  1:text <- new [abc def]
-  2:char <- index *1:text, 5
+  10:text <- new [abc def]
+  20:char <- index *10:text, 5
 ]
 # number code for 'e'
-+mem: storing 101 in location 2
++mem: storing 101 in location 20
 
 :(scenario new_string_handles_unicode)
 def main [
-  1:text <- new [a«c]
-  2:num <- length *1:text
-  3:char <- index *1:text, 1
+  10:text <- new [a«c]
+  20:num <- length *10:text
+  21:char <- index *10:text, 1
 ]
-+mem: storing 3 in location 2
++mem: storing 3 in location 20
 # unicode for '«'
-+mem: storing 171 in location 3
++mem: storing 171 in location 21
 
 :(before "End NEW Check Special-cases")
 if (is_literal_text(inst.ingredients.at(0))) break;
@@ -29,6 +29,7 @@ if (inst.name == "new" && !inst.ingredients.empty() && is_literal_text(inst.ingr
 :(after "case NEW" following "Primitive Recipe Implementations")
   if (is_literal_text(current_instruction().ingredients.at(0))) {
     products.resize(1);
+    products.at(0).push_back(/*alloc id*/0);
     products.at(0).push_back(new_mu_text(current_instruction().ingredients.at(0).name));
     trace("mem") << "new string alloc: " << products.at(0).at(0) << end();
     break;
@@ -40,8 +41,9 @@ int new_mu_text(const string& contents) {
   int string_length = unicode_length(contents);
 //?   Total_alloc += string_length+1;
 //?   ++Num_alloc;
-  int result = allocate(string_length+/*array length*/1);
+  int result = allocate(/*array length*/1 + string_length);
   int curr_address = result;
+  ++curr_address;  // skip alloc id
   trace("mem") << "storing string length " << string_length << " in location " << curr_address << end();
   put(Memory, curr_address, string_length);
   ++curr_address;  // skip length
@@ -62,16 +64,16 @@ int new_mu_text(const string& contents) {
 
 //: a new kind of typo
 
-:(scenario string_literal_without_instruction)
+:(scenario literal_text_without_instruction)
 % Hide_errors = true;
 def main [
   [abc]
 ]
 +error: main: instruction '[abc]' has no recipe in '[abc]'
 
-//: stash recognizes strings
+//: stash recognizes texts
 
-:(scenario stash_string)
+:(scenario stash_text)
 def main [
   1:text <- new [abc]
   stash [foo:], 1:text
@@ -80,30 +82,29 @@ def main [
 
 :(before "End inspect Special-cases(r, data)")
 if (is_mu_text(r)) {
-  assert(scalar(data));
-  return read_mu_text(data.at(0));
+  return read_mu_text(data.at(/*skip alloc id*/1));
 }
 
 :(before "End $print Special-cases")
 else if (is_mu_text(current_instruction().ingredients.at(i))) {
-  cout << read_mu_text(ingredients.at(i).at(0));
+  cout << read_mu_text(ingredients.at(i).at(/*skip alloc id*/1));
 }
 
-:(scenario unicode_string)
+:(scenario unicode_text)
 def main [
   1:text <- new [♠]
   stash [foo:], 1:text
 ]
 +app: foo: ♠
 
-:(scenario stash_space_after_string)
+:(scenario stash_space_after_text)
 def main [
   1:text <- new [abc]
   stash 1:text, [foo]
 ]
 +app: abc foo
 
-:(scenario stash_string_as_array)
+:(scenario stash_text_as_array)
 def main [
   1:text <- new [abc]
   stash *1:text
@@ -114,15 +115,15 @@ def main [
 :(before "End Preprocess is_mu_text(reagent x)")
 if (!canonize_type(x)) return false;
 
-//: Allocate more to routine when initializing a literal string
-:(scenario new_string_overflow)
-% Initial_memory_per_routine = 2;
+//: Allocate more to routine when initializing a literal text
+:(scenario new_text_overflow)
+% Initial_memory_per_routine = 3;
 def main [
-  1:&:num/raw <- new number:type
-  2:text/raw <- new [a]  # not enough room in initial page, if you take the array length into account
+  10:&:num/raw <- new number:type
+  20:text/raw <- new [a]  # not enough room in initial page, if you take the array length into account
 ]
-+new: routine allocated memory from 1000 to 1002
-+new: routine allocated memory from 1002 to 1004
++new: routine allocated memory from 1000 to 1003
++new: routine allocated memory from 1003 to 1006
 
 //: helpers
 :(code)
@@ -140,9 +141,9 @@ int unicode_length(const string& s) {
 
 string read_mu_text(int address) {
   if (address == 0) return "";
-  int length = get_or_insert(Memory, address);
+  int length = get_or_insert(Memory, address+/*alloc id*/1);
   if (length == 0) return "";
-  return read_mu_characters(address+1, length);
+  return read_mu_characters(address+/*alloc id*/1+/*length*/1, length);
 }
 
 string read_mu_characters(int start, int length) {
@@ -156,13 +157,21 @@ string read_mu_characters(int start, int length) {
 
 //: assert: perform sanity checks at runtime
 
-:(scenario assert)
+:(scenario assert_literal)
 % Hide_errors = true;  // '%' lines insert arbitrary C code into tests before calling 'run' with the lines below. Must be immediately after :(scenario) line.
 def main [
   assert 0, [this is an assert in Mu]
 ]
 +error: this is an assert in Mu
 
+:(scenario assert)
+% Hide_errors = true;  // '%' lines insert arbitrary C code into tests before calling 'run' with the lines below. Must be immediately after :(scenario) line.
+def main [
+  1:text <- new [this is an assert in Mu]
+  assert 0, 1:text
+]
++error: this is an assert in Mu
+
 :(before "End Primitive Recipe Declarations")
 ASSERT,
 :(before "End Primitive Recipe Numbers")
@@ -173,8 +182,8 @@ case ASSERT: {
     raise << maybe(get(Recipe, r).name) << "'assert' takes exactly two ingredients rather than '" << to_original_string(inst) << "'\n" << end();
     break;
   }
-  if (!is_mu_scalar(inst.ingredients.at(0))) {
-    raise << maybe(get(Recipe, r).name) << "'assert' requires a boolean for its first ingredient, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
+  if (!is_mu_address(inst.ingredients.at(0)) && !is_mu_scalar(inst.ingredients.at(0))) {
+    raise << maybe(get(Recipe, r).name) << "'assert' requires a scalar or address for its first ingredient, but got '" << inst.ingredients.at(0).original_string << "'\n" << end();
     break;
   }
   if (!is_literal_text(inst.ingredients.at(1)) && !is_mu_text(inst.ingredients.at(1))) {
@@ -185,11 +194,11 @@ case ASSERT: {
 }
 :(before "End Primitive Recipe Implementations")
 case ASSERT: {
-  if (!ingredients.at(0).at(0)) {
+  if (!scalar_ingredient(ingredients, 0)) {
     if (is_literal_text(current_instruction().ingredients.at(1)))
       raise << current_instruction().ingredients.at(1).name << '\n' << end();
     else
-      raise << read_mu_text(ingredients.at(1).at(0)) << '\n' << end();
+      raise << read_mu_text(ingredients.at(1).at(/*skip alloc id*/1)) << '\n' << end();
     if (!Hide_errors) exit(1);
   }
   break;