https://github.com/akkartik/mu1/blob/master/015literal_noninteger.cc
1
2
3 :(scenarios load)
4 :(scenario noninteger_literal)
5 def main [
6 1:number <- copy 3.14159
7 ]
8 +parse: ingredient: {3.14159: "literal-fractional-number"}
9
10 :(after "Parsing reagent(string s)")
11 if (is_noninteger(s)) {
12 name = s;
13 type = new type_tree("literal-fractional-number", 0);
14 set_value(to_double(s));
15 return;
16 }
17
18 :(code)
19 bool is_noninteger(const string& s) {
20 return s.find_first_not_of("0123456789-.") == string::npos
21 && s.find_first_of("0123456789") != string::npos
22 && s.find('-', 1) == string::npos
23 && std::count(s.begin(), s.end(), '.') == 1;
24 }
25
26 double to_double(string n) {
27 char* end = NULL;
28
29 double result = strtod(n.c_str(), &end);
30 assert(*end == '\0');
31 return result;
32 }
33
34 void test_is_noninteger() {
35 CHECK(!is_noninteger("1234"));
36 CHECK(!is_noninteger("1a2"));
37 CHECK(is_noninteger("234.0"));
38 CHECK(!is_noninteger("..."));
39 CHECK(!is_noninteger("."));
40 CHECK(is_noninteger("2."));
41 CHECK(is_noninteger(".2"));
42 CHECK(is_noninteger("-.2"));
43 CHECK(is_noninteger("-2."));
44 CHECK(!is_noninteger("--.2"));
45 CHECK(!is_noninteger(".-2"));
46 CHECK(!is_noninteger("..2"));
47 }