about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--010vm.cc4
-rw-r--r--014literal_noninteger.cc33
-rw-r--r--023jump.cc22
-rw-r--r--030container.cc5
-rw-r--r--040brace.cc20
5 files changed, 60 insertions, 24 deletions
diff --git a/010vm.cc b/010vm.cc
index c5e13543..6b94e4a3 100644
--- a/010vm.cc
+++ b/010vm.cc
@@ -41,12 +41,12 @@ struct instruction {
 struct reagent {
   vector<pair<string, vector<string> > > properties;
   string name;
-  long long int value;
+  double value;
   bool initialized;
   vector<type_number> types;
   reagent(string s);
   reagent();
-  void set_value(long long int v) { value = v; initialized = true; }
+  void set_value(double v) { value = v; initialized = true; }
   string to_string() const;
 };
 
diff --git a/014literal_noninteger.cc b/014literal_noninteger.cc
new file mode 100644
index 00000000..94242f41
--- /dev/null
+++ b/014literal_noninteger.cc
@@ -0,0 +1,33 @@
+//: Support literal non-integers.
+//: '3.14159:literal' is ugly, so we'll just say '3.14159' for non-integers.
+
+:(scenarios load)
+:(scenario noninteger_literal)
+recipe main [
+  1:number <- copy 3.14159
+]
++parse:   ingredient: {name: "3.14159", value: 3.14159, type: 0, properties: ["3.14159": "literal-number"]}
+
+:(after "reagent::reagent(string s)")
+  if (is_noninteger(s)) {
+    name = s;
+    types.push_back(0);
+    properties.push_back(pair<string, vector<string> >(name, vector<string>()));
+    properties.back().second.push_back("literal-number");
+    set_value(to_double(s));
+    return;
+  }
+
+:(code)
+bool is_noninteger(const string& s) {
+  return s.find_first_not_of("0123456789-.") == NOT_FOUND
+      && s.find('.') != NOT_FOUND;
+}
+
+double to_double(string n) {
+  char* end = NULL;
+  // safe because string.c_str() is guaranteed to be null-terminated
+  double result = strtod(n.c_str(), &end);
+  assert(*end == '\0');
+  return result;
+}
diff --git a/023jump.cc b/023jump.cc
index acf2f95d..b847a66c 100644
--- a/023jump.cc
+++ b/023jump.cc
@@ -1,5 +1,15 @@
 //: Jump primitives
 
+:(scenario jump_can_skip_instructions)
+recipe main [
+  jump 1:offset
+  1:number <- copy 1:literal
+]
++run: instruction main/0
++run: ingredient 0 is 1
+-run: instruction main/1
+-mem: storing 1 in location 1
+
 :(before "End Primitive Recipe Declarations")
 JUMP,
 :(before "End Primitive Recipe Numbers")
@@ -14,15 +24,9 @@ case JUMP: {
   break;
 }
 
-:(scenario jump_can_skip_instructions)
-recipe main [
-  jump 1:offset
-  1:number <- copy 1:literal
-]
-+run: instruction main/0
-+run: ingredient 0 is 1
--run: instruction main/1
--mem: storing 1 in location 1
+//: special type to designate jump targets
+:(before "End Mu Types Initialization")
+Type_number["offset"] = 0;
 
 :(scenario jump_backward)
 recipe main [
diff --git a/030container.cc b/030container.cc
index 6df68c0a..71ef229c 100644
--- a/030container.cc
+++ b/030container.cc
@@ -132,11 +132,6 @@ case GET: {
   break;
 }
 
-//: 'get' requires a literal in ingredient 1. We'll use a synonym called
-//: 'offset'.
-:(before "End Mu Types Initialization")
-Type_number["offset"] = 0;
-
 :(scenario get_handles_nested_container_elements)
 recipe main [
   12:number <- copy 34:literal
diff --git a/040brace.cc b/040brace.cc
index 6fde1713..ec9c6a4d 100644
--- a/040brace.cc
+++ b/040brace.cc
@@ -40,21 +40,23 @@ void transform_braces(const recipe_number r) {
 //?   cout << "AAA transform_braces\n"; //? 1
 //?   exit(0); //? 1
   const int OPEN = 0, CLOSE = 1;
-  list<pair<int/*OPEN/CLOSE*/, /*step*/index_t> > braces;
-  for (index_t index = 0; index < Recipe[r].steps.size(); ++index) {
+  // use signed integer for step index because we'll be doing arithmetic on it
+  list<pair<int/*OPEN/CLOSE*/, /*step*/long long int> > braces;
+  for (long long int index = 0; index < static_cast<long long int>(Recipe[r].steps.size()); ++index) {
     const instruction& inst = Recipe[r].steps.at(index);
     if (inst.label == "{") {
       trace("brace") << r << ": push (open, " << index << ")";
-      braces.push_back(pair<int,index_t>(OPEN, index));
+      braces.push_back(pair<int,long long int>(OPEN, index));
     }
     if (inst.label == "}") {
       trace("brace") << "push (close, " << index << ")";
-      braces.push_back(pair<int,index_t>(CLOSE, index));
+      braces.push_back(pair<int,long long int>(CLOSE, index));
     }
   }
-  stack</*step*/index_t> open_braces;
+  stack</*step*/long long int> open_braces;
   trace("after-brace") << "recipe " << Recipe[r].name;
-  for (index_t index = 0; index < Recipe[r].steps.size(); ++index) {
+  for (long long int index = 0; index < static_cast<long long int>(Recipe[r].steps.size()); ++index) {
+//?     cerr << index << '\n'; //? 1
     instruction& inst = Recipe[r].steps.at(index);
 //?     cout << "AAA " << inst.name << ": " << inst.operation << '\n'; //? 1
     if (inst.label == "{") open_braces.push(index);
@@ -154,9 +156,11 @@ void transform_braces(const recipe_number r) {
   }
 }
 
-int matching_brace(index_t index, const list<pair<int, index_t> >& braces) {
+// returns a signed integer not just so that we can return -1 but also to
+// enable future signed arithmetic
+long long int matching_brace(long long int index, const list<pair<int, long long int> >& braces) {
   int stacksize = 0;
-  for (list<pair<int, index_t> >::const_iterator p = braces.begin(); p != braces.end(); ++p) {
+  for (list<pair<int, long long int> >::const_iterator p = braces.begin(); p != braces.end(); ++p) {
     if (p->second < index) continue;
     stacksize += (p->first ? 1 : -1);
     if (stacksize == 0) return p->second;