about summary refs log tree commit diff stats
path: root/apps
ModeNameSize
-rw-r--r--README.md1360log stats plain blame
-rw-r--r--arith.mu5532log stats plain blame
-rwxr-xr-xassort46677log stats plain blame
-rw-r--r--assort.subx51460log stats plain blame
-rwxr-xr-xbraces48732log stats plain blame
-rw-r--r--braces.subx11035log stats plain blame
d---------browse156log stats plain
-rwxr-xr-xcalls53727log stats plain blame
-rw-r--r--calls.subx60588log stats plain blame
-rwxr-xr-xcrenshaw2-146018log stats plain blame
-rw-r--r--crenshaw2-1.subx29588log stats plain blame
-rwxr-xr-xcrenshaw2-1b46565log stats plain blame
-rw-r--r--crenshaw2-1b.subx39758log stats plain blame
-rwxr-xr-xdquotes50299log stats plain blame
-rw-r--r--dquotes.subx98799log stats plain blame
-rwxr-xr-xex1229log stats plain blame
-rw-r--r--ex1.mu268log stats plain blame
-rw-r--r--ex1.subx381log stats plain blame
-rwxr-xr-xex10296log stats plain blame
-rw-r--r--ex10.subx3658log stats plain blame
-rwxr-xr-xex111210log stats plain blame
-rw-r--r--ex11.subx15939log stats plain blame
-rwxr-xr-xex12266log stats plain blame
-rw-r--r--ex12.subx1709log stats plain blame
-rwxr-xr-xex13243log stats plain blame
-rw-r--r--ex13.subx1060log stats plain blame
-rwxr-xr-xex14213log stats plain blame
-rw-r--r--ex14.subx923log stats plain blame
-rwxr-xr-xex2235log stats plain blame
-rw-r--r--ex2.mu342log stats plain blame
-rw-r--r--ex2.subx386log stats plain blame
-rwxr-xr-xex3247log stats plain blame
-rw-r--r--ex3.2.mu573log stats plain blame
-rw-r--r--ex3.mu362log stats plain blame
-rw-r--r--ex3.subx1313log stats plain blame
-rwxr-xr-xex4268log stats plain blame
-rw-r--r--ex4.subx798log stats plain blame
-rwxr-xr-xex5268log stats plain blame
-rw-r--r--ex5.subx1687log stats plain blame
-rwxr-xr-xex6264log stats plain blame
-rw-r--r--ex6.subx1123log stats plain blame
-rwxr-xr-xex7398log stats plain blame
-rw-r--r--ex7.subx3569log stats plain blame
-rwxr-xr-xex8266log stats plain blame
-rw-r--r--ex8.subx2601log stats plain blame
-rwxr-xr-xex9260log stats plain blame
-rw-r--r--ex9.subx2953log stats plain blame
-rwxr-xr-xfactorial45128log stats plain blame
-rw-r--r--factorial.mu1445log stats plain blame
-rw-r--r--factorial.subx7353log stats plain blame
-rw-r--r--factorial2.subx3144log stats plain blame
-rw-r--r--factorial3.subx2098log stats plain blame
-rw-r--r--factorial4.subx2197log stats plain blame
-rw-r--r--hello.mu170log stats plain blame
-rwxr-xr-xhex48857log stats plain blame
-rw-r--r--hex.subx74844log stats plain blame
-rwxr-xr-xmu576603log stats plain blame
-rw-r--r--mu.subx1542947log stats plain blame
-rwxr-xr-xpack59367log stats plain blame
-rw-r--r--pack.subx294655log stats plain blame
-rw-r--r--parse-int.mu1143log stats plain blame
-rw-r--r--print-file.mu1022log stats plain blame
-rwxr-xr-xrandom23601log stats plain blame
-rw-r--r--random.subx2303log stats plain blame
d---------raytracing618log stats plain
-rw-r--r--rpn.mu3745log stats plain blame
-rwxr-xr-xsigils61101log stats plain blame
-rw-r--r--sigils.subx246814log stats plain blame
-rw-r--r--subx-params.subx397log stats plain blame
-rwxr-xr-xsurvey56609log stats plain blame
-rw-r--r--survey.subx256646log stats plain blame
-rwxr-xr-xtests45468log stats plain blame
-rw-r--r--tests.subx15655log stats plain blame
-rw-r--r--texture.mu1343log stats plain blame
d---------tile567log stats plain
-rw-r--r--tui.mu855log stats plain blame
-rw-r--r--vimrc.vim89log stats plain blame
="w"> hunk.end()) { out.splice(target, hunk); out.erase(target, balancing_curly(target)); } else { list<Line>::iterator next = balancing_curly(target); list<Line> old_version; old_version.splice(old_version.begin(), out, target, next); old_version.pop_back(); old_version.pop_front(); // contents only please, not surrounding curlies list<Line>::iterator new_pos = find_trim(hunk, ":OLD_CONTENTS"); indent_all(old_version, new_pos); hunk.splice(new_pos, old_version); hunk.erase(new_pos); out.splice(next, hunk); } } return; } raise << "unknown directive " << cmd << '\n'; } list<Line>::iterator locate_target(list<Line>& out, istream& directive_stream) { string pat = next_tangle_token(directive_stream); if (pat == "") return out.end(); string next_token = next_tangle_token(directive_stream); if (next_token == "") { return find_substr(out, pat); } // first way to do nested pattern: pattern 'following' intermediate else if (next_token == "following") { string pat2 = next_tangle_token(directive_stream); if (pat2 == "") return out.end(); list<Line>::iterator intermediate = find_substr(out, pat2); if (intermediate == out.end()) return out.end(); return find_substr(out, intermediate, pat); } // second way to do nested pattern: intermediate 'then' pattern else if (next_token == "then") { list<Line>::iterator intermediate = find_substr(out, pat); if (intermediate == out.end()) return out.end(); string pat2 = next_tangle_token(directive_stream); if (pat2 == "") return out.end(); return find_substr(out, intermediate, pat2); } raise << "unknown keyword in directive: " << next_token << '\n'; return out.end(); } // indent all lines in l like indentation at exemplar void indent_all(list<Line>& l, list<Line>::iterator exemplar) { string curr_indent = indent(exemplar->contents); for (list<Line>::iterator p = l.begin(); p != l.end(); ++p) if (!p->contents.empty()) p->contents.insert(p->contents.begin(), curr_indent.begin(), curr_indent.end()); } string next_tangle_token(istream& in) { in >> std::noskipws; ostringstream out; skip_whitespace(in); if (in.peek() == '"') slurp_tangle_string(in, out); else slurp_word(in, out); return out.str(); } void slurp_tangle_string(istream& in, ostream& out) { in.get(); char c; while (in >> c) { if (c == '\\') // only works for double-quotes continue; if (c == '"') break; out << c; } } void slurp_word(istream& in, ostream& out) { char c; while (in >> c) { if (isspace(c) || c == ')') { in.putback(c); break; } out << c; } } void skip_whitespace(istream& in) { while (isspace(in.peek())) in.get(); } list<Line>::iterator balancing_curly(list<Line>::iterator curr) { long open_curlies = 0; do { for (string::iterator p = curr->contents.begin(); p != curr->contents.end(); ++p) { if (*p == '{') ++open_curlies; if (*p == '}') --open_curlies; } ++curr; // no guard so far against unbalanced curly, including inside comments or strings } while (open_curlies != 0); return curr; } // A scenario is one or more sessions separated by calls to CLEAR_TRACE ('===') // A session is one or more lines of input // followed by a return value ('=>') // followed by one or more lines expected in trace in order ('+') // followed by one or more lines trace shouldn't include ('-') // Remember to update is_input below if you add to this format. void emit_test(const string& name, list<Line>& lines, list<Line>& result) { Line tmp; tmp.line_number = front(lines).line_number-1; // line number of directive tmp.filename = front(lines).filename; tmp.contents = "TEST("+name+")"; result.push_back(tmp); #define SHIFT(new_contents) { \ Line tmp; \ tmp.line_number = front(lines).line_number; \ tmp.filename = front(lines).filename; \ tmp.contents = new_contents; \ result.push_back(tmp); \ lines.pop_front(); \ } while (any_non_input_line(lines)) { while (!lines.empty() && starts_with(front(lines).contents, "% ")) { string line = front(lines).contents.substr(strlen("% ")); SHIFT(" "+line); } result.push_back(input_lines(lines)); if (!lines.empty() && !front(lines).contents.empty() && front(lines).contents[0] == '+') result.push_back(expected_in_trace(lines)); while (!lines.empty() && !front(lines).contents.empty() && front(lines).contents[0] == '-') { result.push_back(expected_not_in_trace(front(lines))); lines.pop_front(); } if (!lines.empty() && front(lines).contents == "===") { Line tmp; tmp.line_number = front(lines).line_number; tmp.filename = front(lines).filename; tmp.contents = " CLEAR_TRACE;"; result.push_back(tmp); lines.pop_front(); } if (!lines.empty() && front(lines).contents == "?") { Line tmp; tmp.line_number = front(lines).line_number; tmp.filename = front(lines).filename; tmp.contents = " DUMP(\"\");"; result.push_back(tmp); lines.pop_front(); } } Line tmp2; if (!lines.empty()) { tmp2.line_number = front(lines).line_number; tmp2.filename = front(lines).filename; } tmp2.contents = "}"; result.push_back(tmp2); while (!lines.empty() && (trim(front(lines).contents).empty() || starts_with(front(lines).contents, "//"))) lines.pop_front(); if (!lines.empty()) { cerr << lines.size() << " unprocessed lines in scenario.\n"; exit(1); } } bool is_input(const string& line) { if (line.empty()) return true; return line != "===" && line[0] != '+' && line[0] != '-' && !starts_with(line, "=>"); } Line input_lines(list<Line>& hunk) { Line result; result.line_number = hunk.front().line_number; result.filename = hunk.front().filename; while (!hunk.empty() && is_input(hunk.front().contents)) { result.contents += hunk.front().contents+""; // temporary delimiter; replace with escaped newline after escaping other backslashes hunk.pop_front(); } result.contents = " "+Toplevel+"(\""+escape(result.contents)+"\");"; return result; } Line expected_in_trace(list<Line>& hunk) { Line result; result.line_number = hunk.front().line_number; result.filename = hunk.front().filename; while (!hunk.empty() && !front(hunk).contents.empty() && front(hunk).contents[0] == '+') { hunk.front().contents.erase(0, 1); result.contents += hunk.front().contents+""; hunk.pop_front(); } result.contents = " CHECK_TRACE_CONTENTS(\""+escape(result.contents)+"\");"; return result; } Line expected_not_in_trace(const Line& line) { Line result; result.line_number = line.line_number; result.filename = line.filename; result.contents = " CHECK_TRACE_DOESNT_CONTAIN(\""+escape(line.contents.substr(1))+"\");"; return result; } list<Line>::iterator find_substr(list<Line>& in, const string& pat) { for (list<Line>::iterator p = in.begin(); p != in.end(); ++p) if (p->contents.find(pat) != NOT_FOUND) return p; return in.end(); } list<Line>::iterator find_substr(list<Line>& in, list<Line>::iterator p, const string& pat) { for (; p != in.end(); ++p) if (p->contents.find(pat) != NOT_FOUND) return p; return in.end(); } list<Line>::iterator find_trim(list<Line>& in, const string& pat) { for (list<Line>::iterator p = in.begin(); p != in.end(); ++p) if (trim(p->contents) == pat) return p; return in.end(); } string escape(string s) { s = replace_all(s, "\\", "\\\\"); s = replace_all(s, "\"", "\\\""); s = replace_all(s, "", "\\n"); return s; } string replace_all(string s, const string& a, const string& b) { for (size_t pos = s.find(a); pos != NOT_FOUND; pos = s.find(a, pos+b.size())) s = s.replace(pos, a.size(), b); return s; } bool any_line_starts_with(const list<Line>& lines, const string& pat) { for (list<Line>::const_iterator p = lines.begin(); p != lines.end(); ++p) if (starts_with(p->contents, pat)) return true; return false; } bool any_non_input_line(const list<Line>& lines) { for (list<Line>::const_iterator p = lines.begin(); p != lines.end(); ++p) if (!is_input(p->contents)) return true; return false; } // does s start with pat, after skipping whitespace? // pat can't start with whitespace bool starts_with(const string& s, const string& pat) { for (size_t pos = 0; pos < s.size(); ++pos) if (!isspace(s[pos])) return s.compare(pos, pat.size(), pat) == 0; return false; } string indent(const string& s) { for (size_t pos = 0; pos < s.size(); ++pos) if (!isspace(s[pos])) return s.substr(0, pos); return ""; } string strip_indent(const string& s, size_t n) { if (s.empty()) return ""; string::const_iterator curr = s.begin(); while (curr != s.end() && n > 0 && isspace(*curr)) { ++curr; --n; } return string(curr, s.end()); } string trim(const string& s) { string::const_iterator first = s.begin(); while (first != s.end() && isspace(*first)) ++first; if (first == s.end()) return ""; string::const_iterator last = --s.end(); while (last != s.begin() && isspace(*last)) --last; ++last; return string(first, last); } const Line& front(const list<Line>& l) { assert(!l.empty()); return l.front(); }