about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--cpp/.traces/check_string_in_memory29
-rw-r--r--cpp/041name8
-rw-r--r--cpp/050scenario33
-rw-r--r--cpp/051scenario_test.mu12
-rw-r--r--cpp/060string.mu58
5 files changed, 85 insertions, 55 deletions
diff --git a/cpp/.traces/check_string_in_memory b/cpp/.traces/check_string_in_memory
new file mode 100644
index 00000000..491c8944
--- /dev/null
+++ b/cpp/.traces/check_string_in_memory
@@ -0,0 +1,29 @@
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "3", value: 0, type: 0, properties: ["3": "literal"]}
+parse/0:   product: {name: "1", value: 0, type: 1, properties: ["1": "integer"]}
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "97", value: 0, type: 0, properties: ["97": "literal"]}
+parse/0:   product: {name: "2", value: 0, type: 4, properties: ["2": "character"]}
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "98", value: 0, type: 0, properties: ["98": "literal"]}
+parse/0:   product: {name: "3", value: 0, type: 4, properties: ["3": "character"]}
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "99", value: 0, type: 0, properties: ["99": "literal"]}
+parse/0:   product: {name: "4", value: 0, type: 4, properties: ["4": "character"]}
+after-brace/0: recipe test-check_string_in_memory
+after-brace/0: copy ...
+after-brace/0: copy ...
+after-brace/0: copy ...
+after-brace/0: copy ...
+run/0: instruction test-check_string_in_memory/0
+run/0: ingredient 0 is 3
+mem/0: storing 3 in location 1
+run/0: instruction test-check_string_in_memory/1
+run/0: ingredient 0 is 97
+mem/0: storing 97 in location 2
+run/0: instruction test-check_string_in_memory/2
+run/0: ingredient 0 is 98
+mem/0: storing 98 in location 3
+run/0: instruction test-check_string_in_memory/3
+run/0: ingredient 0 is 99
+mem/0: storing 99 in location 4
diff --git a/cpp/041name b/cpp/041name
index f4c1dffd..7aede15a 100644
--- a/cpp/041name
+++ b/cpp/041name
@@ -47,7 +47,7 @@ void transform_names(const recipe_number r) {
       assert(!inst.ingredients[in].types.empty());
       if (inst.ingredients[in].types[0]  // not a literal
           && !inst.ingredients[in].initialized
-          && inst.ingredients[in].name.find_first_not_of("0123456789-.") != string::npos) {
+          && !is_number(inst.ingredients[in].name)) {
         if (!already_transformed(inst.ingredients[in], names)) {
           raise << "use before set: " << inst.ingredients[in].name << " in " << Recipe[r].name << '\n';
         }
@@ -64,7 +64,7 @@ void transform_names(const recipe_number r) {
         inst.products[out].initialized = true;
       if (inst.products[out].types[0]  // not a literal
           && !inst.products[out].initialized
-          && inst.products[out].name.find_first_not_of("0123456789-.") != string::npos) {
+          && !is_number(inst.products[out].name)) {
         if (names.find(inst.products[out].name) == names.end()) {
           trace("name") << "assign " << inst.products[out].name << " " << curr_idx;
           names[inst.products[out].name] = curr_idx;
@@ -110,6 +110,10 @@ bool is_raw(const reagent& r) {
   return false;
 }
 
+bool is_number(const string& s) {
+  return s.find_first_not_of("0123456789-.") == string::npos;
+}
+
 :(scenario "convert_names_passes_dummy")
 # _ is just a dummy result that never gets consumed
 recipe main [
diff --git a/cpp/050scenario b/cpp/050scenario
index ff2a43dc..16949048 100644
--- a/cpp/050scenario
+++ b/cpp/050scenario
@@ -31,6 +31,7 @@ for (size_t i = 0; i < Scenarios.size(); ++i) {
        p != Scenarios[i].memory_expectations.end();
        ++p) {
     if (Memory[p->first] != p->second) {
+      // todo: unit tests for the test parsing infrastructure; use raise?
       cerr << Scenarios[i].name << ": Expected location " << p->first << " to contain " << p->second << " but saw " << Memory[p->first] << '\n';
       Passed = false;
     }
@@ -129,7 +130,12 @@ void handle_scenario_memory_directive(istream& in, scenario& out) {
     if (in.eof()) break;
 //?     cout << "a: " << in.peek() << '\n'; //? 1
     if (in.peek() == ']') break;
-    int address = 0;  in >> address;
+    string lhs = next_word(in);
+    if (!is_number(lhs)) {
+      handle_type(lhs, in, out);
+      continue;
+    }
+    int address = to_int(lhs);
 //?     cout << "address: " << address << '\n'; //? 2
 //?     cout << "b: " << in.peek() << '\n'; //? 1
     skip_whitespace_and_comments(in);
@@ -146,6 +152,31 @@ void handle_scenario_memory_directive(istream& in, scenario& out) {
   assert(in.get() == ']');
 }
 
+void handle_type(const string& lhs, istream& in, scenario& out) {
+  reagent x(lhs);
+  if (x.properties[0].second[0] == "string") {
+    x.set_value(to_int(x.name));
+//?     cerr << x.name << ' ' << x.value << '\n'; //? 1
+    skip_whitespace_and_comments(in);
+    string _assign = next_word(in);
+//?     cerr << _assign << '\n'; //? 1
+    assert(_assign == "<-");
+    skip_whitespace_and_comments(in);
+    string literal = next_word(in);
+//?     cerr << literal << '\n'; //? 1
+    size_t address = x.value;
+    out.memory_expectations[address] = literal.size()-2;  // exclude quoting brackets
+    ++address;
+    for (size_t i = 1; i < literal.size()-1; ++i) {
+//?       cerr << "checking " << address << ": " << literal[i] << '\n'; //? 1
+      out.memory_expectations[address] = literal[i];
+      ++address;
+    }
+    return;
+  }
+  raise << "scenario doesn't know how to parse memory expectation on " << lhs << '\n';
+}
+
 void slurp_until_matching_bracket(istream& in, ostream& out) {
   int brace_depth = 1;  // just scanned '['
   char c;
diff --git a/cpp/051scenario_test.mu b/cpp/051scenario_test.mu
index 024086a9..d401c62b 100644
--- a/cpp/051scenario_test.mu
+++ b/cpp/051scenario_test.mu
@@ -8,3 +8,15 @@ scenario first_scenario_in_mu [
     1 <- 4
   ]
 ]
+
+scenario check_string_in_memory [
+  run [
+    1:integer <- copy 3:literal
+    2:character <- copy 97:literal  # 'a'
+    3:character <- copy 98:literal  # 'b'
+    4:character <- copy 99:literal  # 'c'
+  ]
+  memory should contain [
+    1:string <- [abc]
+  ]
+]
diff --git a/cpp/060string.mu b/cpp/060string.mu
index a92d4637..5c17f91f 100644
--- a/cpp/060string.mu
+++ b/cpp/060string.mu
@@ -294,8 +294,7 @@ scenario integer-to-decimal-digit-zero [
     2:array:character/raw <- copy 1:address:array:character/deref/raw
   ]
   memory should contain [
-    2 <- 1
-    3 <- 48  # '0'
+    2:string <- [0]
   ]
 ]
 
@@ -305,10 +304,7 @@ scenario integer-to-decimal-digit-positive [
     2:array:character/raw <- copy 1:address:array:character/deref/raw
   ]
   memory should contain [
-    2 <- 3
-    3 <- 50  # '2'
-    4 <- 51  # '3'
-    5 <- 52  # '4'
+    2:string <- [234]
   ]
 ]
 
@@ -377,20 +373,7 @@ scenario string-append-1 [
     4:array:character/raw <- copy 3:address:array:character/raw/deref
   ]
   memory should contain [
-    4 <- 13
-    5 <- 104  # 'h'
-    6 <- 101  # 'e'
-    7 <- 108  # 'l'
-    8 <- 108  # 'l'
-    9 <- 111  # 'o'
-    10 <- 44  # ','
-    11 <- 32  # ' '
-    12 <- 119  # 'w'
-    13 <- 111  # 'o'
-    14 <- 114  # 'r'
-    15 <- 108  # 'l'
-    16 <- 100  # 'd'
-    17 <- 33  # '!'
+    4:string <- [hello, world!]
   ]
 ]
 
@@ -493,14 +476,7 @@ scenario interpolate-works [
     4:array:character/raw <- copy 3:address:array:character/raw/deref
   ]
   memory should contain [
-    4 <- 7  # length
-    5 <- 97  # 'a'
-    6 <- 98  # 'b'
-    7 <- 99  # 'c'
-    8 <- 32  # ' '
-    9 <- 100  # 'd'
-    10 <- 101  # 'e'
-    11 <- 102  # 'f'
+    4:string <- [abc def]
   ]
 ]
 
@@ -512,18 +488,7 @@ scenario interpolate-at-start [
     4:array:character/raw <- copy 3:address:array:character/raw/deref
   ]
   memory should contain [
-    4 <- 11  # length
-    5 <- 97  # 'a'
-    6 <- 98  # 'b'
-    7 <- 99  # 'c'
-    8 <- 44  # ','
-    9 <- 32  # ' '
-    10 <- 104  # 'h'
-    11 <- 101  # 'e'
-    12 <- 108  # 'l'
-    13 <- 108  # 'l'
-    14 <- 111  # 'o'
-    15 <- 33  # '!'
+    4:string <- [abc, hello!]
     16 <- 0  # out of bounds
   ]
 ]
@@ -536,17 +501,6 @@ scenario interpolate-at-end [
     4:array:character/raw <- copy 3:address:array:character/raw/deref
   ]
   memory should contain [
-    4 <- 10  # length
-    5 <- 104  # 'h'
-    6 <- 101  # 'e'
-    7 <- 108  # 'l'
-    8 <- 108  # 'l'
-    9 <- 111  # 'o'
-    10 <- 44  # ','
-    11 <- 32  # ' '
-    12 <- 97  # 'a'
-    13 <- 98  # 'b'
-    14 <- 99  # 'c'
-    15 <- 0  # out of bounds
+    4:string <- [hello, abc]
   ]
 ]