diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-02-18 14:48:19 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-02-18 14:48:19 -0800 |
commit | 01b2852b653a81c4d5e197a0c52659c7e0dcaf5f (patch) | |
tree | 9c9864846c27191afd73b4c1a44810ac0fdd1091 /cpp | |
parent | 9fc64bbc95bb4e55f28f5262d0f5c660177f0a19 (diff) | |
download | mu-01b2852b653a81c4d5e197a0c52659c7e0dcaf5f.tar.gz |
782 - promote literate version to canonical C++ version
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/000organization (renamed from cpp/literate/000organization) | 0 | ||||
-rw-r--r-- | cpp/000test.cc | 28 | ||||
-rw-r--r-- | cpp/001test (renamed from cpp/literate/001test) | 0 | ||||
-rw-r--r-- | cpp/001trace.cc | 351 | ||||
-rw-r--r-- | cpp/002main.cc | 378 | ||||
-rw-r--r-- | cpp/002main.test.cc | 29 | ||||
-rw-r--r-- | cpp/002trace (renamed from cpp/literate/002trace) | 0 | ||||
-rw-r--r-- | cpp/002trace.tests (renamed from cpp/literate/002trace.tests) | 0 | ||||
-rw-r--r-- | cpp/009includes (renamed from cpp/literate/009includes) | 0 | ||||
-rw-r--r-- | cpp/010vm (renamed from cpp/literate/010vm) | 0 | ||||
-rw-r--r-- | cpp/011load (renamed from cpp/literate/011load) | 0 | ||||
-rw-r--r-- | cpp/012run (renamed from cpp/literate/012run) | 0 | ||||
-rw-r--r-- | cpp/boot.cc | 66 | ||||
-rwxr-xr-x | cpp/build_and_test_until (renamed from cpp/literate/build_and_test_until) | 0 | ||||
-rw-r--r-- | cpp/literate/makefile | 26 | ||||
-rw-r--r-- | cpp/literate/tangle/001trace.test.cc | 164 | ||||
-rw-r--r-- | cpp/makefile | 37 | ||||
-rw-r--r-- | cpp/tangle/000test.cc (renamed from cpp/literate/tangle/000test.cc) | 0 | ||||
-rw-r--r-- | cpp/tangle/001trace.cc (renamed from cpp/literate/tangle/001trace.cc) | 0 | ||||
-rw-r--r-- | cpp/tangle/001trace.test.cc (renamed from cpp/001trace.test.cc) | 0 | ||||
-rw-r--r-- | cpp/tangle/002main.cc (renamed from cpp/literate/tangle/002main.cc) | 0 | ||||
-rw-r--r-- | cpp/tangle/030tangle.cc (renamed from cpp/literate/tangle/030tangle.cc) | 0 | ||||
-rw-r--r-- | cpp/tangle/030tangle.test.cc (renamed from cpp/literate/tangle/030tangle.test.cc) | 0 | ||||
-rw-r--r-- | cpp/tangle/boot.cc (renamed from cpp/literate/tangle/boot.cc) | 0 | ||||
-rw-r--r-- | cpp/tangle/makefile (renamed from cpp/literate/tangle/makefile) | 0 | ||||
-rw-r--r-- | cpp/vimrc.vim (renamed from cpp/literate/vimrc.vim) | 0 |
26 files changed, 19 insertions, 1060 deletions
diff --git a/cpp/literate/000organization b/cpp/000organization index ba82dd52..ba82dd52 100644 --- a/cpp/literate/000organization +++ b/cpp/000organization diff --git a/cpp/000test.cc b/cpp/000test.cc deleted file mode 100644 index 1a731804..00000000 --- a/cpp/000test.cc +++ /dev/null @@ -1,28 +0,0 @@ -typedef void (*test_fn)(void); - -const test_fn Tests[] = { - #include "test_list" // auto-generated; see makefile -}; - -bool Passed = true; - -long Num_failures = 0; - -#define TEST(name) void test_##name() { Trace_file = #name; - -#define CHECK(X) \ - if (!(X)) { \ - ++Num_failures; \ - cerr << "\nF " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): " << #X << '\n'; \ - Passed = false; \ - return; \ - } - -#define CHECK_EQ(X, Y) \ - if ((X) != (Y)) { \ - ++Num_failures; \ - cerr << "\nF " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): " << #X << " == " << #Y << '\n'; \ - cerr << " got " << (X) << '\n'; /* BEWARE: multiple eval */ \ - Passed = false; \ - return; \ - } diff --git a/cpp/literate/001test b/cpp/001test index 45ec591d..45ec591d 100644 --- a/cpp/literate/001test +++ b/cpp/001test diff --git a/cpp/001trace.cc b/cpp/001trace.cc deleted file mode 100644 index 0de7c687..00000000 --- a/cpp/001trace.cc +++ /dev/null @@ -1,351 +0,0 @@ -bool Hide_warnings = false; - -struct trace_stream { - vector<pair<string, pair<int, string> > > past_lines; // [(layer label, frame, line)] - unordered_map<string, int> frame; - // accumulator for current line - ostringstream* curr_stream; - string curr_layer; - string dump_layer; - trace_stream() :curr_stream(NULL) {} - ~trace_stream() { if (curr_stream) delete curr_stream; } - - ostringstream& stream(string layer) { - newline(); - curr_stream = new ostringstream; - curr_layer = layer; - return *curr_stream; - } - - // be sure to call this before messing with curr_stream or curr_layer or frame - void newline() { - if (!curr_stream) return; - past_lines.push_back(pair<string, pair<int, string> >(curr_layer, pair<int, string>(frame[curr_layer], curr_stream->str()))); - if (curr_layer == "dump") - cerr << with_newline(curr_stream->str()); - else if ((!dump_layer.empty() && prefix_match(dump_layer, curr_layer)) - || (!Hide_warnings && curr_layer == "warn")) - cerr << curr_layer << "/" << frame[curr_layer] << ": " << with_newline(curr_stream->str()); - delete curr_stream; - curr_stream = NULL; - } - - string readable_contents(string layer) { // missing layer = everything, frame, hierarchical layers - newline(); - ostringstream output; - string real_layer, frame; - parse_layer_and_frame(layer, &real_layer, &frame); - for (vector<pair<string, pair<int, string> > >::iterator p = past_lines.begin(); p != past_lines.end(); ++p) - if (layer.empty() || prefix_match(real_layer, p->first)) - output << p->first << "/" << p->second.first << ": " << with_newline(p->second.second); - return output.str(); - } - - void dump_browseable_contents(string layer) { - ofstream dump("dump"); - dump << "<div class='frame' frame_index='1'>start</div>\n"; - for (vector<pair<string, pair<int, string> > >::iterator p = past_lines.begin(); p != past_lines.end(); ++p) { - if (p->first != layer) continue; - dump << "<div class='frame"; - if (p->second.first > 1) dump << " hidden"; - dump << "' frame_index='" << p->second.first << "'>"; - dump << p->second.second; - dump << "</div>\n"; - } - dump.close(); - } - - string with_newline(string s) { - if (s[s.size()-1] != '\n') return s+'\n'; - return s; - } -}; - - - -trace_stream* Trace_stream = NULL; - -// Top-level helper. IMPORTANT: can't nest. -#define trace(layer) !Trace_stream ? cerr /*print nothing*/ : Trace_stream->stream(layer) -// Warnings should go straight to cerr by default since calls to trace() have -// some unfriendly constraints (they delay printing, they can't nest) -#define raise ((!Trace_stream || !Hide_warnings) ? cerr /*do print*/ : Trace_stream->stream("warn")) << __FILE__ << ":" << __LINE__ << " " -// Just debug logging without any test support. -#define dbg cerr << __FUNCTION__ << '(' << __FILE__ << ':' << __LINE__ << ") " - -// raise << die exits after printing -- unless Hide_warnings is set. -struct die {}; -ostream& operator<<(ostream& os, unused die) { - if (Hide_warnings) return os; - os << "dying"; - exit(1); -} - -#define CLEAR_TRACE delete Trace_stream, Trace_stream = new trace_stream; - -#define DUMP(layer) cerr << Trace_stream->readable_contents(layer) - -// Trace_stream is a resource, lease_tracer uses RAII to manage it. -string Trace_file; -static string Trace_dir = ".traces/"; -struct lease_tracer { - lease_tracer() { Trace_stream = new trace_stream; } - ~lease_tracer() { -//? cerr << "write to file? " << Trace_file << "$\n"; //? 1 - if (!Trace_file.empty()) { -//? cerr << "writing\n"; //? 1 - ofstream fout((Trace_dir+Trace_file).c_str()); - fout << Trace_stream->readable_contents(""); - fout.close(); - } - delete Trace_stream, Trace_stream = NULL; Trace_file = ""; } -}; - -#define START_TRACING_UNTIL_END_OF_SCOPE lease_tracer leased_tracer; - -void trace_all(const string& label, const list<string>& in) { - for (list<string>::const_iterator p = in.begin(); p != in.end(); ++p) - trace(label) << *p; -} - -bool check_trace_contents(string FUNCTION, string FILE, int LINE, string expected) { // missing layer == anywhere, frame, hierarchical layers - vector<string> expected_lines = split(expected, ""); - size_t curr_expected_line = 0; - while (curr_expected_line < expected_lines.size() && expected_lines[curr_expected_line].empty()) - ++curr_expected_line; - if (curr_expected_line == expected_lines.size()) return true; - Trace_stream->newline(); - ostringstream output; - string layer, frame, contents; - parse_layer_frame_contents(expected_lines[curr_expected_line], &layer, &frame, &contents); - for (vector<pair<string, pair<int, string> > >::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { - if (!layer.empty() && !prefix_match(layer, p->first)) - continue; - - if (!frame.empty() && strtol(frame.c_str(), NULL, 0) != p->second.first) - continue; - - if (contents != p->second.second) - continue; - - ++curr_expected_line; - while (curr_expected_line < expected_lines.size() && expected_lines[curr_expected_line].empty()) - ++curr_expected_line; - if (curr_expected_line == expected_lines.size()) return true; - parse_layer_frame_contents(expected_lines[curr_expected_line], &layer, &frame, &contents); - } - - ++Num_failures; - cerr << "\nF " << FUNCTION << "(" << FILE << ":" << LINE << "): missing [" << contents << "] in trace:\n"; - DUMP(layer); - Passed = false; - return false; -} - -void parse_layer_frame_contents(const string& orig, string* layer, string* frame, string* contents) { - string layer_and_frame; - parse_contents(orig, ": ", &layer_and_frame, contents); - parse_layer_and_frame(layer_and_frame, layer, frame); -} - -void parse_contents(const string& s, const string& delim, string* prefix, string* contents) { - string::size_type pos = s.find(delim); - if (pos == NOT_FOUND) { - *prefix = ""; - *contents = s; - } - else { - *prefix = s.substr(0, pos); - *contents = s.substr(pos+delim.size()); - } -} - -void parse_layer_and_frame(const string& orig, string* layer, string* frame) { - size_t last_slash = orig.rfind('/'); - if (last_slash == NOT_FOUND - || last_slash == orig.size()-1 // trailing slash indicates hierarchical layer - || orig.find_last_not_of("0123456789") != last_slash) { - *layer = orig; - *frame = ""; - } - else { - *layer = orig.substr(0, last_slash); - *frame = orig.substr(last_slash+1); - } -} - - - -bool check_trace_contents(string FUNCTION, string FILE, int LINE, string layer, string expected) { // empty layer == everything, multiple layers, hierarchical layers - vector<string> expected_lines = split(expected, ""); -//? cout << "aa check2 " << layer << ": " << expected_lines.size() << '\n'; //? 1 - size_t curr_expected_line = 0; - while (curr_expected_line < expected_lines.size() && expected_lines[curr_expected_line].empty()) - ++curr_expected_line; - if (curr_expected_line == expected_lines.size()) return true; - Trace_stream->newline(); - ostringstream output; - vector<string> layers = split(layer, ","); - for (vector<pair<string, pair<int, string> > >::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { - if (!layer.empty() && !any_prefix_match(layers, p->first)) - continue; -//? cout << "comparing " << p->second.second << '\n'; //? 1 -//? cout << " with " << expected_lines[curr_expected_line] << '\n'; //? 1 - if (p->second.second != expected_lines[curr_expected_line]) - continue; - ++curr_expected_line; - while (curr_expected_line < expected_lines.size() && expected_lines[curr_expected_line].empty()) - ++curr_expected_line; - if (curr_expected_line == expected_lines.size()) return true; - } - - ++Num_failures; - cerr << "\nF " << FUNCTION << "(" << FILE << ":" << LINE << "): missing [" << expected_lines[curr_expected_line] << "] in trace:\n"; - DUMP(layer); - Passed = false; - return false; -} - -#define CHECK_TRACE_CONTENTS(...) check_trace_contents(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) - -int trace_count(string layer) { - return trace_count(layer, ""); -} - -int trace_count(string layer, string line) { - Trace_stream->newline(); - long result = 0; - vector<string> layers = split(layer, ","); - for (vector<pair<string, pair<int, string> > >::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { - if (any_prefix_match(layers, p->first)) - if (line == "" || p->second.second == line) - ++result; - } - return result; -} - -int trace_count(string layer, int frame, string line) { - Trace_stream->newline(); - long result = 0; - vector<string> layers = split(layer, ","); - for (vector<pair<string, pair<int, string> > >::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { - if (any_prefix_match(layers, p->first) && p->second.first == frame) - if (line == "" || p->second.second == line) - ++result; - } - return result; -} - -#define CHECK_TRACE_WARNS() CHECK(trace_count("warn") > 0) -#define CHECK_TRACE_DOESNT_WARN() \ - if (trace_count("warn") > 0) { \ - ++Num_failures; \ - cerr << "\nF " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): unexpected warnings\n"; \ - DUMP("warn"); \ - Passed = false; \ - return; \ - } - -bool trace_doesnt_contain(string layer, string line) { - return trace_count(layer, line) == 0; -} - -bool trace_doesnt_contain(string expected) { - vector<string> tmp = split(expected, ": "); - return trace_doesnt_contain(tmp[0], tmp[1]); -} - -bool trace_doesnt_contain(string layer, int frame, string line) { - return trace_count(layer, frame, line) == 0; -} - -#define CHECK_TRACE_DOESNT_CONTAIN(...) CHECK(trace_doesnt_contain(__VA_ARGS__)) - - - -// manage layer counts in Trace_stream using RAII -struct lease_trace_frame { - string layer; - lease_trace_frame(string l) :layer(l) { - if (!Trace_stream) return; - Trace_stream->newline(); - ++Trace_stream->frame[layer]; - } - ~lease_trace_frame() { - if (!Trace_stream) return; - Trace_stream->newline(); - --Trace_stream->frame[layer]; - } -}; -#define new_trace_frame(layer) lease_trace_frame leased_frame(layer); - -bool check_trace_contents(string FUNCTION, string FILE, int LINE, string layer, int frame, string expected) { // multiple layers, hierarchical layers - vector<string> expected_lines = split(expected, ""); // hack: doesn't handle newlines in embedded in lines - size_t curr_expected_line = 0; - while (curr_expected_line < expected_lines.size() && expected_lines[curr_expected_line].empty()) - ++curr_expected_line; - if (curr_expected_line == expected_lines.size()) return true; - Trace_stream->newline(); - ostringstream output; - vector<string> layers = split(layer, ","); - for (vector<pair<string, pair<int, string> > >::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { - if (!layer.empty() && !any_prefix_match(layers, p->first)) - continue; - if (p->second.first != frame) - continue; - if (p->second.second != expected_lines[curr_expected_line]) - continue; - ++curr_expected_line; - while (curr_expected_line < expected_lines.size() && expected_lines[curr_expected_line].empty()) - ++curr_expected_line; - if (curr_expected_line == expected_lines.size()) return true; - } - - ++Num_failures; - cerr << "\nF " << FUNCTION << "(" << FILE << ":" << LINE << "): missing [" << expected_lines[curr_expected_line] << "] in trace/" << frame << ":\n"; - DUMP(layer); - Passed = false; - return false; -} - -#define CHECK_TRACE_TOP(layer, expected) CHECK_TRACE_CONTENTS(layer, 1, expected) - - - -vector<string> split(string s, string delim) { - vector<string> result; - string::size_type begin=0, end=s.find(delim); - while (true) { - if (end == NOT_FOUND) { - result.push_back(string(s, begin, NOT_FOUND)); - break; - } - result.push_back(string(s, begin, end-begin)); - begin = end+delim.size(); - end = s.find(delim, begin); - } - return result; -} - -bool any_prefix_match(const vector<string>& pats, const string& needle) { - if (pats.empty()) return false; - if (*pats[0].rbegin() != '/') - // prefix match not requested - return find(pats.begin(), pats.end(), needle) != pats.end(); - // first pat ends in a '/'; assume all pats do. - for (vector<string>::const_iterator p = pats.begin(); p != pats.end(); ++p) - if (headmatch(needle, *p)) return true; - return false; -} - -bool prefix_match(const string& pat, const string& needle) { - if (*pat.rbegin() != '/') - // prefix match not requested - return pat == needle; - return headmatch(needle, pat); -} - -bool headmatch(const string& s, const string& pat) { - if (pat.size() > s.size()) return false; - return std::mismatch(pat.begin(), pat.end(), s.begin()).first == pat.end(); -} diff --git a/cpp/002main.cc b/cpp/002main.cc deleted file mode 100644 index c6b72104..00000000 --- a/cpp/002main.cc +++ /dev/null @@ -1,378 +0,0 @@ -//? enum recipe_number { -//? // arithmetic -//? add = 1, -//? subtract, -//? multiply, -//? divide, -//? divide_with_remainder, -//? -//? // boolean -//? conjunction, // 'and' is a keyword -//? disjunction, // 'or' is a keyword -//? negation, // 'not' is a keyword -//? -//? // comparison -//? equal, -//? not_equal, -//? less_than, -//? greater_than, -//? lesser_or_equal, -//? greater_or_equal, -//? -//? // control flow -//? jump, -//? jump_if, -//? jump_unless, -//? -//? // data management: scalars, arrays, and_records (structs) -//? copy, -//? get, -//? get_address, -//? index, -//? index_address, -//? allocate, -//? size, -//? length, -//? -//? // tagged_values require one primitive -//? save_type, -//? -//? // code points for characters -//? character_to_integer, -//? integer_to_character, -//? -//? // multiprocessing -//? fork, -//? fork_helper, -//? sleep, -//? assert, -//? assert_false, -//? -//? // cursor-based (text mode) interaction -//? cursor_mode, -//? retro_mode, -//? clear_host_screen, -//? clear_line_on_host, -//? cursor_on_host, -//? cursor_on_host_to_next_line, -//? cursor_up_on_host, -//? cursor_down_on_host, -//? cursor_right_on_host, -//? cursor_left_on_host, -//? print_character_to_host, -//? read_key_from_host, -//? -//? // debugging aides -//? _dump_memory, -//? _dump_trace, -//? _start_tracing, -//? _stop_tracing, -//? _dump_routine, -//? _dump_channel, -//? _quit, -//? _wait_for_key_from_host, -//? _print, -//? -//? // first-class continuations -//? current_continuation, -//? continue_from, -//? -//? // user-defined functions -//? next_input, -//? input, -//? prepare_reply, -//? reply, -//? -//? Max_primitive_recipe, -//? }; - -struct property { - vector<string> values; -}; - -typedef int type_number; - -struct type_info { - int size; - bool is_address; - bool is_record; - bool is_array; - vector<type_number> target; // only if is_address - vector<vector<type_number> > elements; // only if is_record or is_array - type_info() :size(0) {} -}; - -unordered_map<string, type_number> Type_number; -unordered_map<type_number, type_info> Type; -int Next_type_number = 1; - -unordered_map<int, int> Memory; - -struct reagent { - string name; - vector<type_number> types; - vector<pair<string, property> > properties; - reagent(string s) { - istringstream in(s); - name = slurp_until(in, ':'); - types.push_back(Type_number[slurp_until(in, '/')]); // todo: multiple types - } - string to_string() { - ostringstream out; - out << "{name: \"" << name << "\", type: " << types[0] << "}"; // todo: properties - return out.str(); - } -}; - -const int idle = 0; - -struct instruction { - bool is_label; - string label; // only if is_label - recipe_number operation; // only if !is_label - vector<reagent> ingredients; // only if !is_label - vector<reagent> products; // only if !is_label - instruction() :is_label(false), operation(idle) {} - void clear() { is_label=false; label.clear(); operation=idle; ingredients.clear(); products.clear(); } -}; - -struct recipe { - vector<instruction> step; -}; - -typedef int recipe_number; -unordered_map<string, recipe_number> Recipe_number; -unordered_map<recipe_number, recipe> Recipe; -int Next_recipe_number = 1; - -void load(string filename) { -} - -void run(string function_name) { -} - -void setup_memory() { - Memory.clear(); -} - -void setup_types() { - Type.clear(); Type_number.clear(); - Type_number["literal"] = 0; - Next_type_number = 1; - int integer = Type_number["integer"] = Next_type_number++; - Type[integer].size = 1; -} - -void setup_recipes() { - Recipe.clear(); Recipe_number.clear(); - Recipe_number["idle"] = 0; - Next_recipe_number = 1; - Recipe_number["copy"] = Next_recipe_number++; -//? dbg << "AAA " << Recipe_number["copy"] << '\n'; //? 1 -} - -void compile(string form) { - istringstream in(form); - in >> std::noskipws; - - string _recipe = next_word(in); -//? cout << _recipe << '\n'; //? 1 - if (_recipe != "recipe") - raise << "top-level forms must be of the form 'recipe _name_ [ _instruction_ ... ]'\n"; - - string recipe_name = next_word(in); -//? cout << '^' << recipe_name << "$\n"; //? 1 - if (recipe_name.empty()) - raise << "empty recipe name in " << form << '\n'; - int r = Recipe_number[recipe_name] = Next_recipe_number++; - -//? string foo = next_word(in); //? 1 -//? cout << '^' << foo << "$ (" << foo.size() << ")\n"; //? 1 - if (next_word(in) != "[") - raise << "recipe body must begin with '['\n"; - - skip_newlines(in); - - instruction curr; - while (next_instruction(in, &curr)) { - Recipe[r].step.push_back(curr); - } -} - -bool next_instruction(istream& in, instruction* curr) { - curr->clear(); - if (in.eof()) return false; - skip_whitespace(in); if (in.eof()) return false; - skip_newlines(in); if (in.eof()) return false; - -//? vector<string> ingredients, products; //? 1 - vector<string> words; - while (in.peek() != '\n') { - skip_whitespace(in); if (in.eof()) return false; - string word = next_word(in); if (in.eof()) return false; - words.push_back(word); - skip_whitespace(in); if (in.eof()) return false; - } - skip_newlines(in); if (in.eof()) return false; -//? cout << "words: "; //? 1 -//? for (vector<string>::iterator p = words.begin(); p != words.end(); ++p) { //? 1 -//? cout << *p << "; "; //? 1 -//? } //? 1 -//? cout << '\n'; //? 1 -//? return true; //? 1 - - if (words.size() == 1 && *(words[0].end()-1) == ':') { - curr->is_label = true; - words[0].erase(words[0].end()-1); - curr->label = words[0]; - trace("parse") << "label: " << curr->label; - return !in.eof(); - } - - vector<string>::iterator p = words.begin(); - if (find(words.begin(), words.end(), "<-") != words.end()) { -//? cout << "instruction yields products\n"; //? 1 - for (; *p != "<-"; ++p) { - if (*p == ",") continue; -//? cout << "product: " << *p << '\n'; //? 1 -//? products.push_back(*p); //? 1 - curr->products.push_back(reagent(*p)); - } - ++p; // skip <- - } -//? return true; //? 1 - - curr->operation = Recipe_number[*p]; ++p; - - for (; p != words.end(); ++p) { - if (*p == ",") continue; -//? cout << "ingredient: " << *p << '\n'; //? 1 - curr->ingredients.push_back(reagent(*p)); - } - - trace("parse") << "instruction: " << curr->operation; - for (vector<reagent>::iterator p = curr->ingredients.begin(); p != curr->ingredients.end(); ++p) { - trace("parse") << " ingredient: " << p->to_string(); - } - for (vector<reagent>::iterator p = curr->products.begin(); p != curr->products.end(); ++p) { - trace("parse") << " product: " << p->to_string(); - } - return !in.eof(); -} - -string next_word(istream& in) { - ostringstream out; -//? cout << "1: " << (int)in.peek() << '\n'; //? 1 - skip_whitespace(in); -//? cout << "2: " << (int)in.peek() << '\n'; //? 1 - slurp_word(in, out); -//? cout << "3: " << (int)in.peek() << '\n'; //? 1 -//? cout << out.str() << '\n'; //? 1 - return out.str(); -} - -void slurp_word(istream& in, ostream& out) { - char c; - if (in.peek() == ',') { - in >> c; - out << c; - return; - } - while (in >> c) { -//? cout << c << '\n'; //? 1 - if (isspace(c) || c == ',') { -//? cout << " space\n"; //? 1 - in.putback(c); - break; - } - out << c; - } -} - -void skip_whitespace(istream& in) { - while (isspace(in.peek()) && in.peek() != '\n') { -//? cout << "skip\n"; //? 1 - in.get(); - } -} - -void skip_newlines(istream& in) { - while (in.peek() == '\n') - in.get(); -} - -void skip_comma(istream& in) { - skip_whitespace(in); - if (in.peek() == ',') in.get(); - skip_whitespace(in); -} - -string slurp_until(istream& in, char delim) { - ostringstream out; - char c; - while (in >> c) { - if (c == delim) { - break; - } - out << c; - } - return out.str(); -} - - - -//// test harness - -void run_tests() { - for (unsigned long i=0; i < sizeof(Tests)/sizeof(Tests[0]); ++i) { - START_TRACING_UNTIL_END_OF_SCOPE; - setup(); - CLEAR_TRACE; - (*Tests[i])(); - verify(); - } - cerr << '\n'; - if (Num_failures > 0) - cerr << Num_failures << " failure" - << (Num_failures > 1 ? "s" : "") - << '\n'; -} - -void verify() { - if (!Passed) - ; - else - cerr << "."; -} - -void setup() { - setup_memory(); - setup_types(); - setup_recipes(); - Passed = true; -} - -string time_string() { - time_t t; - time(&t); - char buffer[10]; - if (!strftime(buffer, 10, "%H:%M:%S", localtime(&t))) - return ""; - return buffer; -} - -} // end namespace mu - -int main(int argc, const char* argv[]) { - if (argc == 2 && string(argv[1]) == "test") { - mu::run_tests(); - return 0; - } - - for (int i = 1; i < argc; ++i) { - mu::load(argv[i]); - } - mu::run("main"); -} - -namespace mu { diff --git a/cpp/002main.test.cc b/cpp/002main.test.cc deleted file mode 100644 index 72dbe41f..00000000 --- a/cpp/002main.test.cc +++ /dev/null @@ -1,29 +0,0 @@ -TEST(parse) - compile("recipe main [\n" - " 1:integer <- copy 23:literal\n" - "]\n"); - CHECK_TRACE_CONTENTS("parse", "instruction: 1 ingredient: {name: \"23\", type: 0} product: {name: \"1\", type: 1}"); -} - -TEST(parse_label) - compile("recipe main [\n" - " foo:\n" - "]\n"); - CHECK_TRACE_CONTENTS("parse", "label: foo"); - CHECK_TRACE_DOESNT_CONTAIN("parse", "instruction: 1"); -} - -TEST(parse2) - compile("recipe main [\n" - " 1:integer, 2:integer <- copy 23:literal\n" - "]\n"); - CHECK_TRACE_CONTENTS("parse", "instruction: 1 ingredient: {name: \"23\", type: 0} product: {name: \"1\", type: 1} product: {name: \"2\", type: 1}"); -} - -TEST(literal) - compile("recipe main [\n" - " 1:integer <- copy 23:literal\n" - "]\n"); - run("main"); - CHECK_EQ(Memory[1], 23); -} diff --git a/cpp/literate/002trace b/cpp/002trace index 4d584cb1..4d584cb1 100644 --- a/cpp/literate/002trace +++ b/cpp/002trace diff --git a/cpp/literate/002trace.tests b/cpp/002trace.tests index 00705346..00705346 100644 --- a/cpp/literate/002trace.tests +++ b/cpp/002trace.tests diff --git a/cpp/literate/009includes b/cpp/009includes index 5c9a8d65..5c9a8d65 100644 --- a/cpp/literate/009includes +++ b/cpp/009includes diff --git a/cpp/literate/010vm b/cpp/010vm index 3b8a7c96..3b8a7c96 100644 --- a/cpp/literate/010vm +++ b/cpp/010vm diff --git a/cpp/literate/011load b/cpp/011load index f2855e5f..f2855e5f 100644 --- a/cpp/literate/011load +++ b/cpp/011load diff --git a/cpp/literate/012run b/cpp/012run index f7b5469a..f7b5469a 100644 --- a/cpp/literate/012run +++ b/cpp/012run diff --git a/cpp/boot.cc b/cpp/boot.cc deleted file mode 100644 index 64a0c58e..00000000 --- a/cpp/boot.cc +++ /dev/null @@ -1,66 +0,0 @@ -// C++ style: -// no pointers except cell* -// use long as the default integer type; it's always large enough to hold pointers - -#define unused __attribute__((unused)) - -#include<cstdio> -#include<cstring> -#include<cstdlib> -#include<errno.h> -#include<time.h> -#include<math.h> -#include<vector> -using std::vector; -#include<list> -using std::list; -#include<stack> -using std::stack; -#include<utility> -using std::pair; - -#include<tr1/unordered_map> -using std::tr1::unordered_map; -#include<tr1/unordered_set> -using std::tr1::unordered_set; -#include<algorithm> - -#include<string> -using std::string; -const size_t NOT_FOUND = string::npos; - -#include<iostream> -using std::istream; -using std::ostream; -using std::iostream; -using std::cin; -using std::cout; -using std::cerr; - -#include<sstream> -using std::stringstream; -using std::istringstream; -using std::ostringstream; - -#include<fstream> -using std::ifstream; -using std::ofstream; - - - -// interpreter decls -namespace mu { - -#include "type_list" - -#include "function_list" - -// interpreter impl - -#include "file_list" - -// interpreter tests - -#include "test_file_list" - -} // namespace mu diff --git a/cpp/literate/build_and_test_until b/cpp/build_and_test_until index 3661c93a..3661c93a 100755 --- a/cpp/literate/build_and_test_until +++ b/cpp/build_and_test_until diff --git a/cpp/literate/makefile b/cpp/literate/makefile deleted file mode 100644 index 97187383..00000000 --- a/cpp/literate/makefile +++ /dev/null @@ -1,26 +0,0 @@ -mu: makefile tangle/tangle mu.cc - g++ -g -Wall -Wextra -fno-strict-aliasing mu.cc -o mu - -@./mu test - -# To see what the program looks like after all layers have been applied, read -# mu.cc -mu.cc: 0* - ./tangle/tangle --until 999 > mu.cc - @make autogenerated_lists >/dev/null - -tangle/tangle: - cd tangle && make - -# auto-generated files; by convention they end in '_list'. -.PHONY: autogenerated_lists -autogenerated_lists: mu.cc function_list test_list - -function_list: mu.cc - @grep -h "^[^ #].*) {" mu.cc |perl -pwe 's/ {.*/;/' > function_list - -test_list: mu.cc - @grep -h "^[[:space:]]*void test_" mu.cc |perl -pwe 's/^\s*void (.*)\(\) {.*/$$1,/' > test_list - -clean: - cd tangle && make clean - rm -rf mu.cc mu *_list diff --git a/cpp/literate/tangle/001trace.test.cc b/cpp/literate/tangle/001trace.test.cc deleted file mode 100644 index e0db457c..00000000 --- a/cpp/literate/tangle/001trace.test.cc +++ /dev/null @@ -1,164 +0,0 @@ -void test_trace_check_compares() { - CHECK_TRACE_CONTENTS("test layer", ""); - trace("test layer") << "foo"; - CHECK_TRACE_CONTENTS("test layer", "foo"); -} - -void test_trace_check_filters_layers() { - trace("test layer 1") << "foo"; - trace("test layer 2") << "bar"; - CHECK_TRACE_CONTENTS("test layer 1", "foo"); -} - -void test_trace_check_ignores_other_lines() { - trace("test layer 1") << "foo"; - trace("test layer 1") << "bar"; - CHECK_TRACE_CONTENTS("test layer 1", "foo"); -} - -void test_trace_check_always_finds_empty_lines() { - CHECK_TRACE_CONTENTS("test layer 1", ""); -} - -void test_trace_check_treats_empty_layers_as_wildcards() { - trace("test layer 1") << "foo"; - CHECK_TRACE_CONTENTS("", "foo"); -} - -void test_trace_check_multiple_lines_at_once() { - trace("test layer 1") << "foo"; - trace("test layer 2") << "bar"; - CHECK_TRACE_CONTENTS("", "foobar"); -} - -void test_trace_check_always_finds_empty_lines2() { - CHECK_TRACE_CONTENTS("test layer 1", ""); -} - -void test_trace_orders_across_layers() { - trace("test layer 1") << "foo"; - trace("test layer 2") << "bar"; - trace("test layer 1") << "qux"; - CHECK_TRACE_CONTENTS("", "foobarqux"); -} - -void test_trace_orders_across_layers2() { - trace("test layer 1") << "foo"; - trace("test layer 2") << "bar"; - trace("test layer 1") << "qux"; - CHECK_TRACE_CONTENTS("foobarqux"); -} - -void test_trace_checks_ordering_spanning_multiple_layers() { - trace("layer1") << "foo"; - trace("layer2") << "bar"; - trace("layer1") << "qux"; - CHECK_TRACE_CONTENTS("layer1: foolayer2: barlayer1: qux"); -} - -void test_trace_segments_within_layers() { - trace("test layer 1") << "foo"; - trace("test layer 2") << "bar"; - new_trace_frame("test layer 1"); - trace("test layer 1") << "qux"; - CHECK_TRACE_CONTENTS("test layer 1", "fooqux"); - CHECK_TRACE_CONTENTS("test layer 1", 0, "foo"); - CHECK_TRACE_DOESNT_CONTAIN("test layer 1", 1, "foo"); -} - -void test_trace_checks_ordering_across_layers_and_frames() { - trace("test layer 1") << "foo"; - trace("test layer 2") << "bar"; - new_trace_frame("test layer 1"); - trace("test layer 1") << "qux"; - CHECK_TRACE_CONTENTS("test layer 1/0: footest layer 2: bartest layer 1: qux"); - CHECK_TRACE_CONTENTS("test layer 1: footest layer 2: bartest layer 1/1: qux"); -} - -void trace_test_fn(int n) { - if (n == 0) return; - new_trace_frame("foo"); - trace("foo") << "before: " << n; - trace_test_fn(n-1); - trace("foo") << "after: " << n; -} - -void test_trace_keeps_level_together() { - CHECK_TRACE_CONTENTS("foo", ""); - trace_test_fn(4); - CHECK_TRACE_CONTENTS("foo", 2, "before: 3after: 3"); -} - -void test_trace_supports_multiple_layers() { - trace("test layer 1") << "foo"; - trace("test layer 2") << "bar"; - trace("test layer 1") << "qux"; - CHECK_TRACE_CONTENTS("test layer 1,test layer 2", "foobarqux"); -} - -void test_trace_supports_hierarchical_layers() { - trace("test layer/a") << "foo"; - trace("different layer/c") << "foo 2"; - trace("test layer/b") << "bar"; - CHECK_TRACE_CONTENTS("test layer/", "foobar"); -} - -void test_trace_supports_count() { - trace("test layer 1") << "foo"; - trace("test layer 1") << "foo"; - CHECK_EQ(trace_count("test layer 1", "foo"), 2); -} - -void test_trace_supports_count2() { - trace("test layer 1") << "foo"; - trace("test layer 1") << "bar"; - CHECK_EQ(trace_count("test layer 1"), 2); -} - -// pending: DUMP tests -// pending: readable_contents() adds newline if necessary. -// pending: RAISE also prints to stderr. -// pending: RAISE doesn't print to stderr if Hide_warnings is set. -// pending: RAISE doesn't have to be saved if Hide_warnings is set, just printed. -// pending: RAISE prints to stderr if Trace_stream is NULL. -// pending: RAISE prints to stderr if Trace_stream is NULL even if Hide_warnings is set. -// pending: RAISE << ... die() doesn't die if Hide_warnings is set. - - - -// can't check trace because trace methods call 'split' - -void test_split_returns_at_least_one_elem() { - vector<string> result = split("", ","); - CHECK_EQ(result.size(), 1); - CHECK_EQ(result[0], ""); -} - -void test_split_returns_entire_input_when_no_delim() { - vector<string> result = split("abc", ","); - CHECK_EQ(result.size(), 1); - CHECK_EQ(result[0], "abc"); -} - -void test_split_works() { - vector<string> result = split("abc,def", ","); - CHECK_EQ(result.size(), 2); - CHECK_EQ(result[0], "abc"); - CHECK_EQ(result[1], "def"); -} - -void test_split_works2() { - vector<string> result = split("abc,def,ghi", ","); - CHECK_EQ(result.size(), 3); - CHECK_EQ(result[0], "abc"); - CHECK_EQ(result[1], "def"); - CHECK_EQ(result[2], "ghi"); -} - -void test_split_handles_multichar_delim() { - vector<string> result = split("abc,,def,,ghi", ",,"); - CHECK_EQ(result.size(), 3); - CHECK_EQ(result[0], "abc"); - CHECK_EQ(result[1], "def"); - CHECK_EQ(result[2], "ghi"); -} diff --git a/cpp/makefile b/cpp/makefile index 0dcdbce5..97187383 100644 --- a/cpp/makefile +++ b/cpp/makefile @@ -1,25 +1,26 @@ -mu: makefile type_list function_list file_list test_file_list test_list - g++ -O3 -Wall -Wextra -fno-strict-aliasing boot.cc -o mu +mu: makefile tangle/tangle mu.cc + g++ -g -Wall -Wextra -fno-strict-aliasing mu.cc -o mu + -@./mu test -type_list: boot.cc [0-9]*.cc - @# assumes struct decl has space before '{' - @grep -h "^struct .* {" [0-9]*.cc |perl -pwe 's/(struct *[^ ]*).*/$$1;/' > type_list - @grep -h typedef [0-9]*.cc >> type_list +# To see what the program looks like after all layers have been applied, read +# mu.cc +mu.cc: 0* + ./tangle/tangle --until 999 > mu.cc + @make autogenerated_lists >/dev/null -function_list: boot.cc [0-9]*.cc - @# assumes function decl has space before '{' - @grep -h "^[^ #].*) {" [0-9]*.cc |perl -pwe 's/ {.*/;/' > function_list - @grep -h "^[[:space:]]*TEST(" [0-9]*.cc |perl -pwe 's/^\s*TEST\((.*)\)$$/void test_$$1();/' >> function_list +tangle/tangle: + cd tangle && make -file_list: boot.cc [0-9]*.cc - @ls [0-9]*.cc |grep -v "\.test\.cc$$" |perl -pwe 's/.*/#include "$$&"/' > file_list +# auto-generated files; by convention they end in '_list'. +.PHONY: autogenerated_lists +autogenerated_lists: mu.cc function_list test_list -test_file_list: [0-9]*.test.cc - @ls [0-9]*.test.cc |perl -pwe 's/.*/#include "$$&"/' > test_file_list +function_list: mu.cc + @grep -h "^[^ #].*) {" mu.cc |perl -pwe 's/ {.*/;/' > function_list -test_list: [0-9]*.cc - @grep -h "^[[:space:]]*void test_" [0-9]*.cc |perl -pwe 's/^\s*void (.*)\(\) {$$/$$1,/' > test_list - @grep -h "^[[:space:]]*TEST(" [0-9]*.cc |perl -pwe 's/^\s*TEST\((.*)\)$$/test_$$1,/' >> test_list +test_list: mu.cc + @grep -h "^[[:space:]]*void test_" mu.cc |perl -pwe 's/^\s*void (.*)\(\) {.*/$$1,/' > test_list clean: - rm -rf mu* *_list + cd tangle && make clean + rm -rf mu.cc mu *_list diff --git a/cpp/literate/tangle/000test.cc b/cpp/tangle/000test.cc index 2754b254..2754b254 100644 --- a/cpp/literate/tangle/000test.cc +++ b/cpp/tangle/000test.cc diff --git a/cpp/literate/tangle/001trace.cc b/cpp/tangle/001trace.cc index a99951e0..a99951e0 100644 --- a/cpp/literate/tangle/001trace.cc +++ b/cpp/tangle/001trace.cc diff --git a/cpp/001trace.test.cc b/cpp/tangle/001trace.test.cc index e0db457c..e0db457c 100644 --- a/cpp/001trace.test.cc +++ b/cpp/tangle/001trace.test.cc diff --git a/cpp/literate/tangle/002main.cc b/cpp/tangle/002main.cc index 851811c8..851811c8 100644 --- a/cpp/literate/tangle/002main.cc +++ b/cpp/tangle/002main.cc diff --git a/cpp/literate/tangle/030tangle.cc b/cpp/tangle/030tangle.cc index 2dda8667..2dda8667 100644 --- a/cpp/literate/tangle/030tangle.cc +++ b/cpp/tangle/030tangle.cc diff --git a/cpp/literate/tangle/030tangle.test.cc b/cpp/tangle/030tangle.test.cc index 36ce2d1f..36ce2d1f 100644 --- a/cpp/literate/tangle/030tangle.test.cc +++ b/cpp/tangle/030tangle.test.cc diff --git a/cpp/literate/tangle/boot.cc b/cpp/tangle/boot.cc index 89f943a8..89f943a8 100644 --- a/cpp/literate/tangle/boot.cc +++ b/cpp/tangle/boot.cc diff --git a/cpp/literate/tangle/makefile b/cpp/tangle/makefile index 3d938c09..3d938c09 100644 --- a/cpp/literate/tangle/makefile +++ b/cpp/tangle/makefile diff --git a/cpp/literate/vimrc.vim b/cpp/vimrc.vim index 65fd4575..65fd4575 100644 --- a/cpp/literate/vimrc.vim +++ b/cpp/vimrc.vim |