/* SI 413 Fall 2011
 * Little program to test the Frame class implementation
 */

#include <iostream>
#include <cstdlib>
using namespace std;
#include "frame.hpp"

// Check that this value equals that number; otherwise error.
void check(Value val, int num) {
  if (val.num() != num) {
    cerr << "Check failed! Expected value was " << num << endl;
    exit(1);
  }
}

int main() {
  // Make a new frame, with null parent (like a global scope frame)
  Frame* f1 = new Frame;
  f1->bind("a",5);

  check (f1->lookup("a"), 5);

  // Make a child frame of f1
  Frame* f2 = new Frame(f1);
  
  // Check the lookup into the parent frame
  check(f2->lookup("a"), 5);

  // Give this one a re-binding of a, and a brand-new binding of b
  f2->rebind("a",13);
  f2->bind("b", 19);

  // Check that a got changed in f1
  check(f1->lookup("a"), 13);
  check(f2->lookup("b"), 19);

  // Make a couple more frames
  Frame* f3 = new Frame(f2);
  Frame* f4 = new Frame(f1);

  // Changing a in f4 should change it everywhere.
  f4->rebind("a", 25);
  check(f1->lookup("a"), 25);
  check(f2->lookup("a"), 25);
  check(f3->lookup("a"), 25);

  // Make a new b in f3, make sure it's really new.
  f3->bind("b", 36);
  check(f2->lookup("b"), 19);
  check(f3->lookup("b"), 36);

  f3->rebind("b", 51);
  check(f2->lookup("b"), 19);
  check(f3->lookup("b"), 51);
  
  cout << "All checks passed!" << endl;
  return 0;
}