00001 /* 00002 * CompileUnit.h - The core of the compiler 00003 * 00004 * Copyright (C) 2002-2003 The Pentagram Team 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #ifndef COMPILEUNIT_H 00022 #define COMPILEUNIT_H 00023 00024 #include "CompileNodes.h" 00025 #include "IDataSource.h" 00026 #include "FileSystem.h" 00027 00028 #include <list> 00029 #include <fstream> 00030 00031 class llcFlexLexer; 00032 00033 class CompileUnit 00034 { 00035 public: 00036 enum CState { CSTATE_NEW, CSTATE_FAIL, CSTATE_WORKING, CSTATE_FINISHED, CSTATE_WARNED }; 00037 00038 CompileUnit(FileSystem *filesystem); 00039 00040 ~CompileUnit() 00041 {} 00042 00043 bool parse(); 00044 bool parse_openblock(); 00045 bool parse_closeblock(); 00046 00047 void debugPrint(std::ostream &o, CompileNode *n) const; 00048 void debugPrint(std::ostream &o) const; 00049 00050 // state handling 00051 CState state() const { return _state; }; 00052 bool setState(const CState cs); 00053 00054 LLCToken expect() const { return _expect; }; 00055 bool warned() const { return _warned; }; 00056 bool compileComplete() const { if((state()==CSTATE_FINISHED) && (filelist.size()==0)) return true; return false; }; 00057 00058 private: 00059 // internal print stuff 00060 void debugPrintHead(std::ostream &o, CompileNode *n=0) const; 00061 void debugPrintBody(std::ostream &o) const; 00062 00063 // parser shortcut checking 00064 inline bool found(const LLCToken &tok) const { return nodes.size()>0 && nodes.front()->isA(tok); } 00065 bool consume(const LLCToken &tok); 00066 00067 std::list<CompileNode *> nodes; // the temporary node list, cleared upon finding a seperator 00068 00069 //std::list<ExpressionNode *> expressions; // the current expression stack 00070 //StatNode *currstat; // the current statement we're building 00071 //FuncNode *currfunc; // the current function we're operating on 00072 ClassNode *currclass; // the current class (and thus current file) we're operating on 00073 std::list<ClassNode *> tailclasses; // the classes we've previously compiled 00074 /* The basic logic of the above is that we parse expressions until the stack is full, 00075 then fold the expressions down to one expression 'tree' which then gets attached 00076 to the RHS of the currstat, which then gets appended to the internal statement 00077 list of currfunc, which when the function is finished parsing gets appended to 00078 the tail of the funclist inside currclass, once the class is finished it gets stored 00079 on the tailclasses stack. 00080 We can actually probably discard most of the data in the class and store it's info in 00081 a different data structure for outputting to some sort of index struct. 00082 00083 Scarily enough, I think this is the simplest way of massaging this... 00084 */ 00085 00086 std::ifstream *ifile; // real file we use 00087 IDataSource *idatasource; // temp data source 00088 00089 llcFlexLexer *parser; 00090 00091 FileSystem * const filesys; // the filesystem from Application 00092 00093 CState _state; // the current state of the compile 00094 bool _ccomplete; // have we compiled all possible files? 00095 00096 FileSystem::FileList filelist; // the remaining files we need to compile 00097 00098 LLCToken _expect; // the expect state 00099 bool _warned; // have we warned? 00100 #ifdef COMPILER_TEST 00101 uint32 testidx; 00102 #endif 00103 }; 00104 00105 #endif 00106 00107