// $Id: $ -*- c++ -*-
/*
 * $Log: $
 *
 *
 */

#ifndef __COMPACT_SEMANTICS_TYPEVALIDATOR_H__
#define __COMPACT_SEMANTICS_TYPEVALIDATOR_H__

#include "semantics/SemanticProcessor.h"

#include <string>
#include <iostream>
#include <sstream>
#include <stack>
#include <cdk/SymbolTable.h>

class TypeValidator : public virtual SemanticProcessor {
  cdk::SymbolTable &_symtab;
  
  // semantic analysis
  bool _errors;

  public:
    TypeValidator(std::ostream &os, cdk::SymbolTable &symtab)
      : SemanticProcessor(os), _symtab(symtab), _errors(false) {}

  public:
    ~TypeValidator();

  public:
    void processNode     (cdk::node::Node      *const node, int lvl) { throw 42; }
    void processNil      (cdk::node::Nil       *const node, int lvl) {}
    void processData     (cdk::node::Data      *const node, int lvl) {}
    void processComposite(cdk::node::Composite *const node, int lvl);
    void processSequence (cdk::node::Sequence  *const node, int lvl);

    template <typename T> void processSimple(cdk::node::expression::Simple<T> *const node, int lvl) { throw 42; }
    void processInteger   (cdk::node::expression::Integer    *const node, int lvl);
    void processDouble    (cdk::node::expression::Double     *const node, int lvl);
    void processString    (cdk::node::expression::String     *const node, int lvl);
    void processIdentifier(cdk::node::expression::Identifier *const node, int lvl);

    void processUnaryExpression(cdk::node::expression::UnaryExpression *const node, int lvl) { throw 42; }
    void processNEG(cdk::node::expression::NEG *const node, int lvl);

    void processBinaryExpression(cdk::node::expression::BinaryExpression *const node, int lvl) { throw 42; }
    void processADD(cdk::node::expression::ADD *const node, int lvl);
    void processSUB(cdk::node::expression::SUB *const node, int lvl);
    void processMUL(cdk::node::expression::MUL *const node, int lvl);
    void processDIV(cdk::node::expression::DIV *const node, int lvl);
    void processMOD(cdk::node::expression::MOD *const node, int lvl);
    void processLT (cdk::node::expression::LT  *const node, int lvl);
    void processLE (cdk::node::expression::LE  *const node, int lvl);
    void processGE (cdk::node::expression::GE  *const node, int lvl);
    void processGT (cdk::node::expression::GT  *const node, int lvl);
    void processNE (cdk::node::expression::NE  *const node, int lvl);
    void processEQ (cdk::node::expression::EQ  *const node, int lvl);

  protected:
    virtual void processArithmeticExpression(cdk::node::expression::BinaryExpression *const node, int lvl) { throw 42; }
    virtual void processIntOnlyExpression   (cdk::node::expression::BinaryExpression *const node, int lvl);

  protected:
    virtual void processScalarLogicalExpression (cdk::node::expression::BinaryExpression *const node, int lvl);
    virtual void processBooleanLogicalExpression(cdk::node::expression::BinaryExpression *const node, int lvl);
    virtual void processGeneralLogicalExpression(cdk::node::expression::BinaryExpression *const node, int lvl);

  public:
    void processProgramNode   (ProgramNode    *const node, int lvl) {}
    void processPrintNode     (PrintNode      *const node, int lvl) {}
    void processReadNode      (ReadNode       *const node, int lvl);
    void processWhileNode     (WhileNode      *const node, int lvl);
    void processAssignmentNode(AssignmentNode *const node, int lvl);
    void processIfNode        (IfNode         *const node, int lvl);
    void processIfElseNode    (IfElseNode     *const node, int lvl);

}; // class TypeValidator

#endif
