about summary refs log tree commit diff stats
path: root/cpp/050scenario.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-05-05 21:17:24 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-05-05 21:17:24 -0700
commitb96af395b9af2ff9df94b3e82213171f30827c8d (patch)
tree17c8c12648ccc25625e2534ec8d74fbe8f1542cc /cpp/050scenario.cc
parent2e3b597fe85b654e82b891c22d50754fa5a26156 (diff)
downloadmu-b96af395b9af2ff9df94b3e82213171f30827c8d.tar.gz
1276 - make C++ version the default
I've tried to update the Readme, but there are at least a couple of issues.
Diffstat (limited to 'cpp/050scenario.cc')
-rw-r--r--cpp/050scenario.cc477
1 files changed, 0 insertions, 477 deletions
diff --git a/cpp/050scenario.cc b/cpp/050scenario.cc
deleted file mode 100644
index 07279d39..00000000
--- a/cpp/050scenario.cc
+++ /dev/null
@@ -1,477 +0,0 @@
-//: Mu scenarios. This will get long, but these are the tests we want to
-//: support in this layer.
-
-//: You can use variable names in scenarios, but for the most part we'll use
-//: raw location numbers, because that lets us make assertions on memory.
-//: Tests should avoid abstraction as far as possible.
-:(scenarios run_mu_scenario)
-:(scenario scenario_block)
-scenario foo [
-  run [
-    1:integer <- copy 13:literal
-  ]
-  memory-should-contain [
-    1 <- 13
-  ]
-]
-# checks are inside scenario
-
-:(scenario scenario_multiple_blocks)
-scenario foo [
-  run [
-    1:integer <- copy 13:literal
-  ]
-  memory-should-contain [
-    1 <- 13
-  ]
-  run [
-    2:integer <- copy 13:literal
-  ]
-  memory-should-contain [
-    1 <- 13
-    2 <- 13
-  ]
-]
-
-:(scenario scenario_check_memory_and_trace)
-scenario foo [
-  run [
-    1:integer <- copy 13:literal
-    trace [a], [a b c]
-  ]
-  memory-should-contain [
-    1 <- 13
-  ]
-  trace-should-contain [
-    a: a b c
-  ]
-  trace-should-not-contain [
-    a: x y z
-  ]
-]
-
-//:: Core data structure
-
-:(before "End Types")
-struct scenario {
-  string name;
-  string to_run;
-};
-
-:(before "End Globals")
-vector<scenario> Scenarios;
-
-//:: Parse the 'scenario' form.
-//: Simply store the text of the scenario.
-
-:(before "End Command Handlers")
-else if (command == "scenario") {
-  Scenarios.push_back(parse_scenario(in));
-}
-
-:(code)
-scenario parse_scenario(istream& in) {
-  scenario result;
-  result.name = next_word(in);
-  skip_bracket(in, "'scenario' must begin with '['");
-  ostringstream buffer;
-  slurp_until_matching_bracket(in, buffer);
-  result.to_run = buffer.str();
-  return result;
-}
-
-//:: Run scenarios when we run 'mu test'.
-//: Treat the text of the scenario as a regular series of instructions.
-
-:(before "End Tests")
-time_t mu_time; time(&mu_time);
-cerr << "\nMu tests: " << ctime(&mu_time);
-for (index_t i = 0; i < Scenarios.size(); ++i) {
-//?   cerr << Passed << '\n'; //? 1
-  run_mu_scenario(Scenarios[i]);
-  if (Passed) cerr << ".";
-}
-
-:(before "End Globals")
-const scenario* Current_scenario = NULL;
-:(code)
-void run_mu_scenario(const scenario& s) {
-  Current_scenario = &s;
-  bool not_already_inside_test = !Trace_stream;
-  if (not_already_inside_test) {
-    Trace_file = s.name;
-    Trace_stream = new trace_stream;
-    setup();
-  }
-  run("recipe "+s.name+" [ " + s.to_run + " ]");
-  if (not_already_inside_test) {
-    teardown();
-    ofstream fout((Trace_dir+Trace_file).c_str());
-    fout << Trace_stream->readable_contents("");
-    fout.close();
-    delete Trace_stream;
-    Trace_stream = NULL;
-    Trace_file = "";
-  }
-  Current_scenario = NULL;
-}
-
-//:: The special instructions we want to support inside scenarios.
-//: In a compiler for the mu VM these will require more work.
-
-//: 'run' interprets a string as a set of instructions
-
-:(scenarios run)
-:(scenario run)
-#? % Trace_stream->dump_layer = "all";
-recipe main [
-  run [
-    1:integer <- copy 13:literal
-  ]
-]
-+mem: storing 13 in location 1
-
-:(before "End Primitive Recipe Declarations")
-RUN,
-:(before "End Primitive Recipe Numbers")
-Recipe_number["run"] = RUN;
-:(before "End Primitive Recipe Implementations")
-case RUN: {
-//?   cout << "recipe " << current_instruction().ingredients[0].name << '\n'; //? 1
-  ostringstream tmp;
-  tmp << "recipe run" << Next_recipe_number << " [ " << current_instruction().ingredients[0].name << " ]";
-//?   Show_rest_of_stream = true; //? 1
-  vector<recipe_number> tmp_recipe = load(tmp.str());
-  // Predefined Scenario Locals In Run.
-  // End Predefined Scenario Locals In Run.
-  transform_all();
-//?   cout << tmp_recipe[0] << ' ' << Recipe_number["main"] << '\n'; //? 1
-  Current_routine->calls.push(call(tmp_recipe[0]));
-  continue;  // not done with caller; don't increment current_step_index()
-}
-
-:(scenario run_multiple)
-recipe main [
-  run [
-    1:integer <- copy 13:literal
-  ]
-  run [
-    2:integer <- copy 13:literal
-  ]
-]
-+mem: storing 13 in location 1
-+mem: storing 13 in location 2
-
-//: 'memory-should-contain' raises warnings if specific locations aren't as expected
-//: Also includes some special support for checking strings.
-
-:(scenario memory_check)
-% Hide_warnings = true;
-recipe main [
-  memory-should-contain [
-    1 <- 13
-  ]
-]
-+run: checking location 1
-+warn: expected location 1 to contain 13 but saw 0
-
-:(before "End Primitive Recipe Declarations")
-MEMORY_SHOULD_CONTAIN,
-:(before "End Primitive Recipe Numbers")
-Recipe_number["memory-should-contain"] = MEMORY_SHOULD_CONTAIN;
-:(before "End Primitive Recipe Implementations")
-case MEMORY_SHOULD_CONTAIN: {
-//?   cout << current_instruction().ingredients[0].name << '\n'; //? 1
-  check_memory(current_instruction().ingredients[0].name);
-  break;
-}
-
-:(code)
-void check_memory(const string& s) {
-  istringstream in(s);
-  in >> std::noskipws;
-  set<index_t> locations_checked;
-  while (true) {
-    skip_whitespace_and_comments(in);
-    if (in.eof()) break;
-    string lhs = next_word(in);
-    if (!is_number(lhs)) {
-      check_type(lhs, in);
-      continue;
-    }
-    int address = to_int(lhs);
-    skip_whitespace_and_comments(in);
-    string _assign;  in >> _assign;  assert(_assign == "<-");
-    skip_whitespace_and_comments(in);
-    int value = 0;  in >> value;
-    if (locations_checked.find(address) != locations_checked.end())
-      raise << "duplicate expectation for location " << address << '\n';
-    trace("run") << "checking location " << address;
-    if (Memory[address] != value) {
-      if (Current_scenario)
-        raise << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain " << value << " but saw " << Memory[address] << '\n';
-      else
-        raise << "expected location " << address << " to contain " << value << " but saw " << Memory[address] << '\n';
-      Passed = false;
-      return;
-    }
-    locations_checked.insert(address);
-  }
-}
-
-void check_type(const string& lhs, istream& in) {
-  reagent x(lhs);
-  if (x.properties[0].second[0] == "string") {
-    x.set_value(to_int(x.name));
-    skip_whitespace_and_comments(in);
-    string _assign = next_word(in);
-    assert(_assign == "<-");
-    skip_whitespace_and_comments(in);
-    string literal = next_word(in);
-    index_t address = x.value;
-    // exclude quoting brackets
-    assert(literal[0] == '[');  literal.erase(0, 1);
-    assert(literal[literal.size()-1] == ']');  literal.erase(literal.size()-1);
-    check_string(address, literal);
-    return;
-  }
-  raise << "don't know how to check memory for " << lhs << '\n';
-}
-
-void check_string(index_t address, const string& literal) {
-  trace("run") << "checking string length at " << address;
-  if (Memory[address] != static_cast<signed>(literal.size()))
-    raise << "expected location " << address << " to contain length " << literal.size() << " of string [" << literal << "] but saw " << Memory[address] << '\n';
-  ++address;  // now skip length
-  for (index_t i = 0; i < literal.size(); ++i) {
-    trace("run") << "checking location " << address+i;
-    if (Memory[address+i] != literal[i])
-      raise << "expected location " << (address+i) << " to contain " << literal[i] << " but saw " << Memory[address+i] << '\n';
-  }
-}
-
-:(scenario memory_check_multiple)
-% Hide_warnings = true;
-recipe main [
-  memory-should-contain [
-    1 <- 0
-    1 <- 0
-  ]
-]
-+warn: duplicate expectation for location 1
-
-:(scenario memory_check_string_length)
-% Hide_warnings = true;
-recipe main [
-  1:integer <- copy 3:literal
-  2:integer <- copy 97:literal  # 'a'
-  3:integer <- copy 98:literal  # 'b'
-  4:integer <- copy 99:literal  # 'c'
-  memory-should-contain [
-    1:string <- [ab]
-  ]
-]
-+warn: expected location 1 to contain length 2 of string [ab] but saw 3
-
-:(scenario memory_check_string)
-recipe main [
-  1:integer <- copy 3:literal
-  2:integer <- copy 97:literal  # 'a'
-  3:integer <- copy 98:literal  # 'b'
-  4:integer <- copy 99:literal  # 'c'
-  memory-should-contain [
-    1:string <- [abc]
-  ]
-]
-+run: checking string length at 1
-+run: checking location 2
-+run: checking location 3
-+run: checking location 4
-
-:(code)
-//: 'trace-should-contain' is like the '+' lines in our scenarios so far
-// Like runs of contiguous '+' lines, order is important. The trace checks
-// that the lines are present *and* in the specified sequence. (There can be
-// other lines in between.)
-
-:(scenario trace_check_warns_on_failure)
-% Hide_warnings = true;
-recipe main [
-  trace-should-contain [
-    a: b
-    a: d
-  ]
-]
-+warn: missing [b] in trace layer a
-
-:(before "End Primitive Recipe Declarations")
-TRACE_SHOULD_CONTAIN,
-:(before "End Primitive Recipe Numbers")
-Recipe_number["trace-should-contain"] = TRACE_SHOULD_CONTAIN;
-:(before "End Primitive Recipe Implementations")
-case TRACE_SHOULD_CONTAIN: {
-  check_trace(current_instruction().ingredients[0].name);
-  break;
-}
-
-:(code)
-// simplified version of check_trace_contents() that emits warnings rather
-// than just printing to stderr
-bool check_trace(const string& expected) {
-  Trace_stream->newline();
-  vector<pair<string, string> > expected_lines = parse_trace(expected);
-  if (expected_lines.empty()) return true;
-  index_t curr_expected_line = 0;
-  for (vector<pair<string, pair<int, string> > >::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) {
-    if (expected_lines[curr_expected_line].first != p->first) continue;
-    if (expected_lines[curr_expected_line].second != p->second.second) continue;
-    // match
-    ++curr_expected_line;
-    if (curr_expected_line == expected_lines.size()) return true;
-  }
-
-  raise << "missing [" << expected_lines[curr_expected_line].second << "] "
-        << "in trace layer " << expected_lines[curr_expected_line].first << '\n';
-  Passed = false;
-  return false;
-}
-
-vector<pair<string, string> > parse_trace(const string& expected) {
-  vector<string> buf = split(expected, "\n");
-  vector<pair<string, string> > result;
-  for (index_t i = 0; i < buf.size(); ++i) {
-    buf[i] = trim(buf[i]);
-    if (buf[i].empty()) continue;
-    index_t delim = buf[i].find(": ");
-    result.push_back(pair<string, string>(buf[i].substr(0, delim), buf[i].substr(delim+2)));
-  }
-  return result;
-}
-
-:(scenario trace_check_warns_on_failure_in_later_line)
-% Hide_warnings = true;
-recipe main [
-  run [
-    trace [a], [b]
-  ]
-  trace-should-contain [
-    a: b
-    a: d
-  ]
-]
-+warn: missing [d] in trace layer a
-
-:(scenario trace_check_passes_silently)
-% Hide_warnings = true;
-recipe main [
-  run [
-    trace [a], [b]
-  ]
-  trace-should-contain [
-    a: b
-  ]
-]
--warn: missing [b] in trace layer a
-
-//: 'trace-should-not-contain' is like the '-' lines in our scenarios so far
-//: Each trace line is separately checked for absense. Order is *not*
-//: important, so you can't say things like "B should not exist after A."
-
-:(scenario trace_negative_check_warns_on_failure)
-% Hide_warnings = true;
-recipe main [
-  run [
-    trace [a], [b]
-  ]
-  trace-should-not-contain [
-    a: b
-  ]
-]
-+warn: unexpected [b] in trace layer a
-
-:(before "End Primitive Recipe Declarations")
-TRACE_SHOULD_NOT_CONTAIN,
-:(before "End Primitive Recipe Numbers")
-Recipe_number["trace-should-not-contain"] = TRACE_SHOULD_NOT_CONTAIN;
-:(before "End Primitive Recipe Implementations")
-case TRACE_SHOULD_NOT_CONTAIN: {
-  check_trace_missing(current_instruction().ingredients[0].name);
-  break;
-}
-
-:(code)
-// simplified version of check_trace_contents() that emits warnings rather
-// than just printing to stderr
-bool check_trace_missing(const string& in) {
-  Trace_stream->newline();
-  vector<pair<string, string> > lines = parse_trace(in);
-  for (index_t i = 0; i < lines.size(); ++i) {
-    if (trace_count(lines[i].first, lines[i].second) != 0) {
-      raise << "unexpected [" << lines[i].second << "] in trace layer " << lines[i].first << '\n';
-      Passed = false;
-      return false;
-    }
-  }
-  return true;
-}
-
-:(scenario trace_negative_check_passes_silently)
-% Hide_warnings = true;
-recipe main [
-  trace-should-not-contain [
-    a: b
-  ]
-]
--warn: unexpected [b] in trace layer a
-
-:(scenario trace_negative_check_warns_on_any_unexpected_line)
-% Hide_warnings = true;
-recipe main [
-  run [
-    trace [a], [d]
-  ]
-  trace-should-not-contain [
-    a: b
-    a: d
-  ]
-]
-+warn: unexpected [d] in trace layer a
-
-//:: Helpers
-
-:(code)
-// just for the scenarios running scenarios in C++ layers
-void run_mu_scenario(const string& form) {
-  istringstream in(form);
-  in >> std::noskipws;
-  string _scenario = next_word(in);
-//?   cout << _scenario << '\n'; //? 1
-  assert(_scenario == "scenario");
-  scenario s = parse_scenario(in);
-  run_mu_scenario(s);
-}
-
-void slurp_until_matching_bracket(istream& in, ostream& out) {
-  int brace_depth = 1;  // just scanned '['
-  char c;
-  while (in >> c) {
-    if (c == '[') ++brace_depth;
-    if (c == ']') --brace_depth;
-    if (brace_depth == 0) break;  // drop final ']'
-    out << c;
-  }
-}
-
-// see tests for this function in tangle/030tangle.test.cc
-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);
-}