diff options
author | Kartik Agaram <github@akkartik.com> | 2019-04-13 20:40:20 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-13 20:40:20 -0700 |
commit | 7e32b35c9c54e111841f0ed4f9f7343367055460 (patch) | |
tree | 21c62ac450e69fd4b1dc98b545860767101bed1e /subx | |
parent | ebb4f558699a325afc234b5125bce0d02aee370a (diff) | |
parent | 1209ddac2b17242a001c257e661973c050d6b2e4 (diff) | |
download | mu-7e32b35c9c54e111841f0ed4f9f7343367055460.tar.gz |
Merge pull request #18 from charles-l/master
Add support for escape sequences in string literals.
Diffstat (limited to 'subx')
-rw-r--r-- | subx/003trace.cc | 24 | ||||
-rw-r--r-- | subx/003trace.test.cc | 5 | ||||
-rw-r--r-- | subx/038---literal_strings.cc | 17 | ||||
-rw-r--r-- | subx/Readme.md | 5 |
4 files changed, 39 insertions, 12 deletions
diff --git a/subx/003trace.cc b/subx/003trace.cc index 9717fb80..e1dadaf6 100644 --- a/subx/003trace.cc +++ b/subx/003trace.cc @@ -129,6 +129,21 @@ struct trace_line { } }; +string unescape_newline(string& s) { + std::stringstream ss; + for(char c : s) { + if(c == '\n') + ss << "\\n"; + else + ss << c; + } + return ss.str(); +} + +void dump_trace_line(ostream& s, trace_line &t) { + s << std::setw(4) << t.depth << ' ' << t.label << ": " << unescape_newline(t.contents) << '\n'; +} + //: Starting a new trace line. :(before "End trace_stream Methods") ostream& stream(string label) { @@ -164,7 +179,7 @@ void trace_stream::newline() { // maybe incrementally dump trace trace_line& t = past_lines.back(); if (should_incrementally_print_trace()) { - cerr << std::setw(4) << t.depth << ' ' << t.label << ": " << t.contents << '\n'; + dump_trace_line(cerr, t); } // End trace Commit } @@ -301,7 +316,8 @@ bool check_trace_contents(string FUNCTION, string FILE, int LINE, string expecte split_label_contents(expected_lines.at(curr_expected_line), &label, &contents); for (vector<trace_line>::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { if (label != p->label) continue; - if (contents != trim(p->contents)) continue; + string t = trim(p->contents); + if (contents != unescape_newline(t)) continue; ++curr_expected_line; while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty()) ++curr_expected_line; @@ -429,7 +445,7 @@ else if (is_equal(*arg, "--trace")) { } :(before "End trace Commit") if (Trace_file) { - Trace_file << std::setw(4) << t.depth << ' ' << t.label << ": " << t.contents << '\n'; + dump_trace_line(Trace_file, t); } :(before "End One-time Setup") atexit(cleanup_main); @@ -446,7 +462,7 @@ string readable_contents(string label) { label = trim(label); for (vector<trace_line>::iterator p = past_lines.begin(); p != past_lines.end(); ++p) if (label.empty() || label == p->label) - output << std::setw(4) << p->depth << ' ' << p->label << ": " << p->contents << '\n'; + dump_trace_line(output, *p); return output.str(); } diff --git a/subx/003trace.test.cc b/subx/003trace.test.cc index addc1f44..bec1b789 100644 --- a/subx/003trace.test.cc +++ b/subx/003trace.test.cc @@ -64,6 +64,11 @@ void test_trace_count_ignores_trailing_whitespace() { CHECK_EQ(trace_count("test layer 1", "foo"), 1); } +void test_trace_unescapes_newlines() { + trace("test layer 1") << "f\no\no\n" << end(); + CHECK_TRACE_CONTENTS("test layer 1: f\\no\\no"); +} + // pending: DUMP tests // pending: readable_contents() adds newline if necessary. // pending: raise also prints to stderr. diff --git a/subx/038---literal_strings.cc b/subx/038---literal_strings.cc index b7cb0aa4..19ed2690 100644 --- a/subx/038---literal_strings.cc +++ b/subx/038---literal_strings.cc @@ -77,11 +77,11 @@ void add_global_to_data_segment(const string& name, const word& value, segment& void test_instruction_with_string_literal() { parse_instruction_character_by_character( - "a \"abc def\" z\n" // two spaces inside string + "a \"abc def\\nwee\" z\n" // two spaces inside string ); CHECK_TRACE_CONTENTS( "parse2: word: a\n" - "parse2: word: \"abc def\"\n" + "parse2: word: \"abc def\\nwee\"\n" "parse2: word: z\n" ); // no other words @@ -123,7 +123,18 @@ void parse_instruction_character_by_character(const string& line_data, vector<li d << c; while (has_data(in)) { in >> c; - d << c; + if(c == '\\') { + in >> c; + if(c == 'n') d << '\n'; + else if(c == 't') d << '\t'; + else if(c == '"') d << '"'; + else { + raise << "parse_instruction_character_by_character: unknown escape sequence '\\" << c << "'\n" << end(); + return; + } + } else { + d << c; + } if (c == '"') break; } result.words.back().data = d.str(); diff --git a/subx/Readme.md b/subx/Readme.md index f842adfd..cc5d7b07 100644 --- a/subx/Readme.md +++ b/subx/Readme.md @@ -651,11 +651,6 @@ from a slice: * `skip-chars-matching-in-slice`: curr, end, delimiter byte -> new-curr (in `EAX`) * `skip-chars-not-matching-in-slice`: curr, end, delimiter byte -> new-curr (in `EAX`) -## Known issues - -* String literals support no escape sequences. In particular, no way to - represent newlines. - ## Resources * [Single-page cheatsheet for the x86 ISA](https://net.cs.uni-bonn.de/fileadmin/user_upload/plohmann/x86_opcode_structure_and_instruction_overview.pdf) |