#include "ast.hh"
#include "visitor.hh"
using namespace ast;

#include <cstdio>
#include <iostream>

int yyparse();
ast::DProg *dprog = 0;

// most of the ast testing is done with the pprint test and the
// analysis tests, here we just check the traversal (in a *very*
// simple manner).
class Counter : public Visitor {
    int _count;
public:
    Counter() : _count(0) { };

    int count() const { return _count; }

    virtual void visit (RExpr     &rexpr) { _count++; }
    virtual void visit (WhenExpr  &when_expr) { _count++; }
    virtual void visit (WhereExpr &where_expr) { _count++; }
    
    virtual void visit (Range     &range) { _count++; }
    virtual void visit (Values    &values) { _count++; }
    virtual void visit (SimpleFun &simple_fun) { _count++; }

    virtual void visit (IDExpr      &id_expr) { _count++; }
    virtual void visit (IntegerExpr &integer_expr) { _count++; }
    virtual void visit (MatrixExpr  &matrix_expr) { _count++; }
    virtual void visit (FunCallExpr &fun_call_expr) { _count++; }
    virtual void visit (BinOpExpr   &binop_expr) { _count++; }
    virtual void visit (NEGExpr     &neg_expr) { _count++; }

    virtual void visit (RelBExpr &bexpr) { _count++; }
    virtual void visit (ANDBExpr &bexpr) { _count++; }
    virtual void visit (ORBExpr  &bexpr) { _count++; }
    virtual void visit (NOTBExpr &bexpr) { _count++; }
    virtual void visit (TrueExpr &bexpr) { _count++; }
    
    virtual void visit (Update   &update) { _count++; }
    
    virtual void visit (ValDeclaration    &val_decl) { _count++; }
    virtual void visit (FunDeclaration    &fun_decl) { _count++; }
    virtual void visit (MatrixDeclaration &matrix_decl) { _count++; }

    virtual void visit (DProg  &dprog) { _count++; }
};

int
main (int argc, char *argv[])
{
  FILE *f;

  /* FIXME: I really want some "real" option parsing here... */

  /* re-open 'stdin' and 'stdout' if these are given on the command
   * line */
  if (argv[1] != NULL) {
    f = freopen(argv[1], "r", stdin);
    if (f == NULL)
      {
	std::cerr << "Couldn't open input file `"
		  << argv[1] << "'\n";
	exit(1);
      }
  }

  yyparse();
  if (!dprog) return 2;		// parse error!

  Counter c;
  dprog->accept_top_down(c);
  std::cout << "counted " << c.count() << " ast-nodes\n";

  return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1