file: pre.cpp

#include <stdio.h> #include "direct.h" #include "pre.h" preprocessor::preprocessor(String assembly_file) :_unfinished_files() { ifstream *file=new ifstream; file->open(assembly_file, ios::in); // fprintf(stderr, "file==%x\n", file); //debug _unfinished_files.push_back(file); //puts main file on the file stack. _else_legal.push_back(false); //you can't have an else outside of //a #if... _depth=0; //depth in if's is zero. line_number=0; _compilable=true; //compile code. _arg=new String[max_args +1]; initialize_directive(); } ////////////////////////////////////////////////////// preprocessor::~preprocessor() { /* //destroy the set of things "defined" _defined.clear(); //destroy the map of directive functions. //OVERLOAD CALL: directive: direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?) direct.clear(); */ // debug } ////////////////////////////////////////////////////// bool preprocessor::next(line &out) { //vars bool flag; ifstream *file= new ifstream; bool c=compilable(); //compilable char char_line[max_len]; //later will change it so that I //can read in any size line. add if (!_unfinished_files.empty()) { file=_unfinished_files.back(); if(!file->eof()) { file->getline(char_line, max_len); file_line=(String) char_line; //Do something with the line. _is_pound=is_pound(); if (_is_pound) numarg=get_key(); //if c is false, then #ifdef, #ifndef, or #else says that we do not //compile this line. if c is true, then we do. is_compilable //tells us if the line itself is compilable (ie. not a comment //or directive, except #define x y) //OVERLOAD CALL: directive: direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?) if (!is_compilable()) c=false; out=line(file_line,++line_number, c); //the line is ready to be sent, now do preparations //for next line if this line was a directive. //OVERLOAD CALL: directive: direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?) if (_is_pound){ map<String, directive*, strless>::iterator call; //OVERLOAD CALL: directive: direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?) call = direct.find(_arg[0]); if (call!=direct.end()) (*(*call).second) (this); else //they used '#' at the front of the line without calling a //directive. error on this line. //OVERLOAD CALL: directive: direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?) ; } //Done with the line. flag=true; } else { // file == EOF. file->close(); //done with the file. _unfinished_files.pop_back(); flag=next(out); } } //calls next again, so it opens up next file, and tries again. //OVERLOAD CALL: next: resolved_line.cc(resolved_line), line.cpp(line), pre.cpp(preprocessor) else // no more files...done { flag=false; if (depth !=0) //call an error, a #endif was expected. ;} return flag; } ////////////////////////////////////////////////////// bool preprocessor::value_defined() const { if (_arg[0] !="define") return false; else return (numarg==3); //'#define x y' has three args, include #define. } ///////////////////////////////////////////////// /* Description: This function gets the first identifier from the line. skips over #,;,tab,space used to get the keywords after a # returns a pointer to a copy of the identifier. This function is only called if is_pound is true. THis method gets the first two arguments from the line, and it also returns how many arguments it got 1: just the directive //OVERLOAD CALL: directive: direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?) 2: and one argument 3: two arguments. 4: more than two arguments */ int preprocessor::get_key() const { int numarg; Regex delim = "[ \t]+"; numarg=split(eatws(file_line), _arg, max_args+1, delim); _arg[0].del("#"); //deletes the first '#' from the directive. //OVERLOAD CALL: directive: direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?), direct.h(?) return (numarg); } /////////////////////////////////////////////// /* name: eatws Description: takes in a string, eats all of the white space at the front of the string, then returns a string with all this white space gone. white space is 'space' and 'tab'. */ String preprocessor::eatws(String out) const { bool done=false; //set done=true when a non-space, non-tab character is hit. char f; if (!out.empty()) { while ( (out.length() >0) && (!done)) { f=out.firstchar(); if ( (f==' ') || (f=='\t')) out.del(f); else done = true; } } return out; } ///////////////////////////////////////////////


Back to Source File Index


C++ to HTML Conversion by ctoohtml