#ifndef SCOPEDEPENDENTFUNCTIONS_H
#define SCOPEDEPENDENTFUNCTIONS_H

#include <cassert>
#include <deque>
#include <string>
#include <iostream>
using namespace std;

#include <rpn.h>


/* Brief: Function form of @+ .*/
class stateevalset : public rpnfunction
{
public:

  stateevalset() {}
  stateevalset(deque<rpnbase*>& ds, bool const evaluate=true);
  ~stateevalset() {}
  rpnbase* copy() const;

  string const name() const { return string("stateevalset"); }

  void eval( deque<rpnbase*>& ds );
};

/* Brief: Function form of @- .*/
class stateevalunset : public rpnfunction
{
public:

  stateevalunset() {}
  stateevalunset(deque<rpnbase*>& ds, bool const evaluate=true);
  ~stateevalunset() {}
  rpnbase* copy() const;

  string const name() const { return string("stateevalunset"); }

  void eval( deque<rpnbase*>& ds );
};

class stateevalquery : public rpnfunction
{
public:

  stateevalquery() {}
  stateevalquery(deque<rpnbase*>& ds, bool const evaluate=true);
  ~stateevalquery() {}
  rpnbase* copy() const;

  string const name() const 
    { return string("stateevalis"); }

  void eval( deque<rpnbase*>& ds );
};

/* Brief: Read in a environment. This resets
 the current environment. 

   Note: load and dictadd are coupled classes
    in responsibity for maintaining a valid 
    dictionary(pointers).   

   In rpn the user can edit their user functions
   and the dictionary holds a pointer to
   that function.
*/
class load: public rpnfunction
{
  void bin();
public:

  load() {}
  load(deque<rpnbase*>& ds, bool const evaluate=true);
  ~load() {}
  rpnbase* copy() const;

  void visit(deque<rpnbase*>& ds,rpnstring& fname);

  string const name() const { return string("load"); }

  void eval( deque<rpnbase*>& ds );
};

/* Brief: Write the environment out to a a file. */
class rpnsave: public rpnfunction
{
  void writevariables(ostream& os, rpnprogram* p);
  void writeprogram(ostream& os, rpnprogram* p);
public:

  rpnsave() {}
  rpnsave(deque<rpnbase*>& ds, bool const evaluate=true);
  ~rpnsave() {}
  rpnbase* copy() const;

  void visit(deque<rpnbase*>& ds,rpnstring& fname);

  string const name() const { return string("save"); }

  void eval( deque<rpnbase*>& ds );
};

/* Brief: Add a user function to the dictionary. */
class dictadd: public rpnfunction
{
public:

  dictadd() {}
  dictadd(deque<rpnbase*>& ds, bool const evaluate=true);
  ~dictadd() {}
  rpnbase* copy() const;

  void visit(deque<rpnbase*>& ds,rpnstring& fname);

  string const name() const 
    { return string("dictadd"); }

  void eval( deque<rpnbase*>& ds );
};

/* Brief: Interpret the string as input. */
class rpninterp: public rpnfunction
{
public:

  rpninterp() {}
  rpninterp(deque<rpnbase*>& ds, bool const evaluate=true);
  ~rpninterp() {}
  rpnbase* copy() const;

  void visit(deque<rpnbase*>& ds,rpnstring& s );

  string const name() const { return string("interp"); }

  void eval( deque<rpnbase*>& ds );
};

/*
class read: public rpnfunction
{
  void bin();
public:

  read() {}
  read(deque<rpnbase*>& ds, bool const evaluate=true);
  ~read() {}
  rpnbase* copy() const;

  void visit(deque<rpnbase*>& ds,rpnstring& fname);

  string const name() const { return string("read"); }

  void eval( deque<rpnbase*>& ds );
};
*/


// 
//  Initialize the scope dependent functions, 
//  called after scope initialized. 
//
class initscopedependentfunctions
{
public:

  initscopedependentfunctions();

};





#endif



