file: pre.h
#ifndef pre_h
#define pre_h
#include <iostream.h>
#include <fstream.h>
#include <stddef.h>
#include <vector.h>
#include <set.h>
#include <String.h>
#include <map.h>
#include "direct.h"
#define max_len 100
#define max_args 3
class directive; //OVERLOAD CALL: directive: direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?)
struct strless {
inline bool operator() (String a, String b) const //OVERLOAD CALL: operator: error.cc(arg_out), error.cc(error), error.cc(error), error.cc(error), filter.cc(foo), filtermain.cc(comp_String), direct.cpp(include), direct.cpp(define), direct.cpp(ifdef), direct.cpp(ifndef), direct.cpp(_else), direct.cpp(endif)
{ return (a < b);}
};
inline void line::print()
{
cout << line_num << ": " << compilable << " :"<< curr_line <<endl;
}
class preprocessor {
public:
//friends
friend class ifndef;
preprocessor(String filename); //constructor
~preprocessor();
//interface = public methods
public:
bool next(line &out);//returns true if there is a new //OVERLOAD CALL: next: resolved_line.cc(resolved_line), line.cpp(line), pre.cpp(preprocessor)
//line. out is a reference to the next line.
//members
private:
vector<ifstream*> _unfinished_files; //stack of files from #include
set<String, strless> _defined; //stack of things #defined.
int _depth; //depth of conditionals #ifdef, #ifndef, #else
vector<bool> _else_legal; //signals that #else can
//be used here.
int line_number; //current line number in processed file
//(ie. after includes)
bool _compilable; //current state, changed by ifdef, ifndef,
//else, endif
bool _is_pound; //is_pound() is called, and the value is stored here.
String file_line; //the line read from the file.
String *_arg; //arguments in file_line, only valid if is_pound=true
int numarg; //number of args in file_line, only valid if is_pound=true
map<String, directive*, strless> direct; //map of directives. //OVERLOAD CALL: directive: direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?)
//Accessors
public:
inline vector<ifstream*>& unfinished_files()
{return _unfinished_files;}
inline set<String, strless> &defined() {return _defined;}
inline int &depth() {return _depth;}
inline vector<bool> &else_legal() {return _else_legal;}
inline bool compilable(bool c) {_compilable =c; return _compilable;} // mutator
inline bool compilable() {return _compilable;}
//this should be bool c= _compilable, add
inline String *arg(){return _arg;}
//implementation=private methods
private:
bool is_char (char a) const; //used by is_comment and is_pound
bool is_comment() const;
bool is_pound() const;
bool is_compilable() const;
bool value_defined() const;
int get_key() const;
String eatws(String) const;
void initialize_directive();
}; //end class definition - preprocessor
//////////////////////////////////////////////////////
inline bool preprocessor::is_char(char a) const
{
String s=eatws(file_line);
if (s.empty())
return false;
else
return (s.firstchar() == a);
}
//////////////////////////////////////////////////////
inline bool preprocessor::is_pound() const
{
return (is_char('#'));
}
//////////////////////////////////////////////////////
inline bool preprocessor::is_comment() const
{
return (is_char(';'));
}
///////////////////////////////////////////////////////
inline bool preprocessor::is_compilable() const
{/*returns true if I send a true flag for compilable.
false for comments, and #<keyword> except for #define x y.
It sends true for this case of #define x y so that the
rest of the program can change it into an EQU.
also isn't compilable if the line is empty.*/
return !(is_comment()
||(is_pound() && (!value_defined()))
||(eatws(file_line).empty())
);
}
//////////////////////////////////////////////////
#endif
C++ to HTML Conversion by ctoohtml