about summary refs log tree commit diff stats
path: root/archive/1.vm/015literal_noninteger.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-01-01 17:04:37 -0800
committerKartik Agaram <vc@akkartik.com>2020-01-01 17:04:37 -0800
commit2a4088119cf41175457414dfa59bd4064b8f0562 (patch)
tree64fe184e399f9870ebd481a90eec34d51e5dff68 /archive/1.vm/015literal_noninteger.cc
parent23fd294d85959c6b476bcdc35ed6ad508cc99b8f (diff)
downloadmu-2a4088119cf41175457414dfa59bd4064b8f0562.tar.gz
5852
Diffstat (limited to 'archive/1.vm/015literal_noninteger.cc')
-rw-r--r--archive/1.vm/015literal_noninteger.cc51
1 files changed, 51 insertions, 0 deletions
diff --git a/archive/1.vm/015literal_noninteger.cc b/archive/1.vm/015literal_noninteger.cc
new file mode 100644
index 00000000..12f24586
--- /dev/null
+++ b/archive/1.vm/015literal_noninteger.cc
@@ -0,0 +1,51 @@
+//: Support literal non-integers.
+
+void test_noninteger_literal() {
+  load(
+      "def main [\n"
+      "  1:number <- copy 3.14159\n"
+      "]\n"
+  );
+  CHECK_TRACE_CONTENTS(
+      "parse:   ingredient: {3.14159: \"literal-fractional-number\"}\n"
+  );
+}
+
+:(after "Parsing reagent(string s)")
+if (is_noninteger(s)) {
+  name = s;
+  type = new type_tree("literal-fractional-number", 0);
+  set_value(to_double(s));
+  return;
+}
+
+:(code)
+bool is_noninteger(const string& s) {
+  return s.find_first_not_of("0123456789-.") == string::npos  // no other characters
+      && s.find_first_of("0123456789") != string::npos  // at least one digit
+      && s.find('-', 1) == string::npos  // '-' only at first position
+      && std::count(s.begin(), s.end(), '.') == 1;  // exactly one decimal point
+}
+
+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;
+}
+
+void test_is_noninteger() {
+  CHECK(!is_noninteger("1234"));
+  CHECK(!is_noninteger("1a2"));
+  CHECK(is_noninteger("234.0"));
+  CHECK(!is_noninteger("..."));
+  CHECK(!is_noninteger("."));
+  CHECK(is_noninteger("2."));
+  CHECK(is_noninteger(".2"));
+  CHECK(is_noninteger("-.2"));
+  CHECK(is_noninteger("-2."));
+  CHECK(!is_noninteger("--.2"));
+  CHECK(!is_noninteger(".-2"));
+  CHECK(!is_noninteger("..2"));
+}