#include <tc.h>

#include <stdio.h>
#include <stdlib.h>

struct tree {
  struct tree tptr left;
  struct tree tptr right;
  int value;
};

struct tree tptr create_tree(int deep) {
  struct tree tptr res = tnew(struct tree);
  res->value = 1;
  if (deep <= 1) {
    res->left = NULL;
    res->right = NULL;
  } else {
    res->left = create_tree(deep-1);
    res->right = create_tree(deep-1);
  }
  tvalidate(*res);
  return res;
}


tfun void my_fun(tout int *res) {
  *res = 1;
}


struct my_str {
  int xxx[10];
};

tfun void tsum(const struct tree tptr _tree, 
	       const struct my_str tptr _str,
	       tout int *_res) {
  tval int left_sum, right_sum;

#if 1
  (const struct my_str*)_str;
#endif
  if (_tree->left != NULL) {
    tsum(_tree->left, _str, &left_sum);
  } else {
    left_sum = _tree->value;
  }
  if (_tree->right != NULL) {
    tsum(_tree->right, _str, &right_sum);
  } else { 
    right_sum = _tree->value;
  }

  *_res = left_sum + right_sum;
  {
    tval int my_out;
    TCALL((my_fun(&my_out)),(0));
    (int)my_out;
  }
}


tfun void add (const unsigned tptr _n, tout unsigned *_res)
{
  terrprint("add: here (*_n = %d)\n", *_n);
  *_res = *_n + 1;
  terrprint("add: here\n");
}

tfun void generate_1(const unsigned tptr _res) {
  terrprint("%s: res = %d\n", __FUNCTION__, *_res);
}

tfun void generate (tout unsigned *_res)
{
  int i, j = 0;
  for (i = 0; i < 10000000; i++)
    j++;
  *_res = 7;
  generate_1(_res);
}

int tmain (int argc, char* argv[])
{
  tval unsigned n;
  tval unsigned res;

  struct my_str tptr p = tnew(struct my_str);
  //tvalidate(*p);
  struct my_str str;
  *p = str;

  {
    struct tree tptr tree = create_tree(12);
    tval int sum;
    tsum(tree, p, &sum);
    terrprint("sum = %d\n", sum);
  }
  {
    generate(&n);
    TCALL(add(&n,&res),(0, GR_CI_FIXED));
    (volatile unsigned)res;
    terrprint("res(%u) = %u\n", n, res);
  }

  return 0;
}