diff options
-rw-r--r-- | cpp/.traces/check_string_in_memory | 29 | ||||
-rw-r--r-- | cpp/041name | 8 | ||||
-rw-r--r-- | cpp/050scenario | 33 | ||||
-rw-r--r-- | cpp/051scenario_test.mu | 12 | ||||
-rw-r--r-- | cpp/060string.mu | 58 |
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] ] ] |