about summary refs log tree commit diff stats
path: root/cpp
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-03-30 21:22:29 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-03-30 21:22:29 -0700
commit66b97b4d923274e1b6d2fd97df16cb73d820169b (patch)
tree9d05c3e8301381608d9619eae976c5459fbfa5d2 /cpp
parenta7b6abf6262c1ac556c2cf9a5890eccb4d6b6872 (diff)
downloadmu-66b97b4d923274e1b6d2fd97df16cb73d820169b.tar.gz
996 - string literals
Diffstat (limited to 'cpp')
-rw-r--r--cpp/.traces/convert_names_passes_dummy2
-rw-r--r--cpp/.traces/run_dummy2
-rw-r--r--cpp/.traces/string_literal9
-rw-r--r--cpp/010vm10
-rw-r--r--cpp/011load3
-rw-r--r--cpp/025name1
-rw-r--r--cpp/026new6
-rw-r--r--cpp/029string29
8 files changed, 57 insertions, 5 deletions
diff --git a/cpp/.traces/convert_names_passes_dummy b/cpp/.traces/convert_names_passes_dummy
index 08f69ed6..c836a7aa 100644
--- a/cpp/.traces/convert_names_passes_dummy
+++ b/cpp/.traces/convert_names_passes_dummy
@@ -1,6 +1,6 @@
 parse/0: instruction: 1
 parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: [0: literal]}
-parse/0:   product: {name: "_", value: 0, type: , properties: [_: ]}
+parse/0:   product: {name: "_", value: 0, type: 0, properties: [_: dummy]}
 parse/0:   product: {name: "x", value: 0, type: 1, properties: [x: integer]}
 name/0: assign x 1
 after-brace/0: recipe main
diff --git a/cpp/.traces/run_dummy b/cpp/.traces/run_dummy
index b6aa736f..0fe1b491 100644
--- a/cpp/.traces/run_dummy
+++ b/cpp/.traces/run_dummy
@@ -1,6 +1,6 @@
 parse/0: instruction: 1
 parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: [0: literal]}
-parse/0:   product: {name: "_", value: 0, type: , properties: [_: ]}
+parse/0:   product: {name: "_", value: 0, type: 0, properties: [_: dummy]}
 after-brace/0: recipe main
 after-brace/0: copy ...
 run/0: instruction main/0
diff --git a/cpp/.traces/string_literal b/cpp/.traces/string_literal
new file mode 100644
index 00000000..d07ce441
--- /dev/null
+++ b/cpp/.traces/string_literal
@@ -0,0 +1,9 @@
+parse/0: instruction: 24
+parse/0:   ingredient: {name: "abc def", value: 0, type: 0, properties: [abc def: literal-string]}
+parse/0:   product: {name: "s", value: 0, type: 2-4-0, properties: [s: address:array:character]}
+new/0: abc def -> 0
+name/0: assign s 1
+after-brace/0: recipe main
+after-brace/0: new ...
+run/0: instruction main/0
+mem/0: storing 1000 in location 1
diff --git a/cpp/010vm b/cpp/010vm
index 76ccc4bf..966b095e 100644
--- a/cpp/010vm
+++ b/cpp/010vm
@@ -148,9 +148,11 @@ void setup_recipes() {
   // Reagents have the form <name>:<type>:<type>:.../<property>/<property>/...
   reagent::reagent(string s) :value(0), initialized(false) {
     istringstream in(s);
+    in >> std::noskipws;
     // properties
     while (!in.eof()) {
       istringstream row(slurp_until(in, '/'));
+      row >> std::noskipws;
       string name = slurp_until(row, ':');
       vector<string> values;
       while (!row.eof())
@@ -162,6 +164,14 @@ void setup_recipes() {
     for (size_t i = 0; i < properties[0].second.size(); ++i) {
       types.push_back(Type_number[properties[0].second[i]]);
     }
+    if (name == "_" && types.empty()) {
+      types.push_back(0);
+      properties[0].second.push_back("dummy");
+    }
+    else if (types.empty()) {  // hacky test for string
+      types.push_back(0);
+      properties[0].second.push_back("literal-string");
+    }
   }
   reagent::reagent() :value(0), initialized(false) {}
   string reagent::to_string() {
diff --git a/cpp/011load b/cpp/011load
index 696c99f7..1e86ae3d 100644
--- a/cpp/011load
+++ b/cpp/011load
@@ -35,7 +35,8 @@ recipe_number add_recipe(istream& in) {
   recipe_number r = Recipe_number[recipe_name];
 //?   cout << recipe_name << ": adding recipe " << r << '\n'; //? 3
 
-  if (next_word(in) != "[")
+  skip_whitespace(in);
+  if (in.get() != '[')
     raise << "recipe body must begin with '['\n";
 
   skip_comments_and_newlines(in);
diff --git a/cpp/025name b/cpp/025name
index 2514714f..0d13bf40 100644
--- a/cpp/025name
+++ b/cpp/025name
@@ -132,6 +132,7 @@ if (inst.operation == Recipe_number["get"]
     || inst.operation == Recipe_number["get-address"]) {
   // at least 2 args, and second arg is offset
   assert(inst.ingredients.size() >= 2);
+//?   cout << inst.ingredients[1].to_string() << '\n'; //? 1
   assert(isa_literal(inst.ingredients[1]));
   if (inst.ingredients[1].name.find_first_not_of("0123456789") == string::npos) continue;
   // since first non-address in base type must be a record, we don't have to canonize
diff --git a/cpp/026new b/cpp/026new
index ffb4429a..1991be5b 100644
--- a/cpp/026new
+++ b/cpp/026new
@@ -27,9 +27,11 @@ Type_number["type"] = 0;
 if (inst.operation == Recipe_number["new"]) {
   // first arg must be of type 'type'
   assert(inst.ingredients.size() >= 1);
+//?   cout << inst.ingredients[0].to_string() << '\n'; //? 1
   assert(isa_literal(inst.ingredients[0]));
-  assert(inst.ingredients[0].properties[0].second[0] == "type");
-  inst.ingredients[0].value = Type_number[inst.ingredients[0].name];
+  if (inst.ingredients[0].properties[0].second[0] == "type") {
+    inst.ingredients[0].value = Type_number[inst.ingredients[0].name];
+  }
   trace("new") << inst.ingredients[0].name << " -> " << inst.ingredients[0].value;
 }
 
diff --git a/cpp/029string b/cpp/029string
new file mode 100644
index 00000000..4379c8ec
--- /dev/null
+++ b/cpp/029string
@@ -0,0 +1,29 @@
+:(scenario "string_literal")
+recipe main [
+  s:address:array:character <- new [abc def]
+]
++parse:   ingredient: {name: "abc def", value: 0, type: 0, properties: [abc def: literal-string]}
+
+:(before "End Mu Types Initialization")
+Type_number["literal-string"] = 0;
+
+:(after "string next_word(istream& in)")
+if (in.peek() == '[') return slurp_quoted(in);
+
+:(code)
+string slurp_quoted(istream& in) {
+  assert(!in.eof());
+  assert(in.get() == '[');
+  ostringstream out;
+  int size = 1;
+  while (!in.eof()) {
+    char c = in.get();
+    if (c == '[') ++size;
+    if (c == ']') --size;
+    if (size == 0) break;
+//?     cout << c << '\n'; //? 1
+    out << c;
+//?     cout << out.str() << "$\n"; //? 1
+  }
+  return out.str();
+}