Preprocessor::Preprocessor(String aFileName, int aMaxErrorNum) { curFileName = aFileName; curFile = new ifstream(curFileName.getCString(), ios::in); lineNumber = colNumber = 1; errorNum = warningNum = 0; maxErrorNum = aMaxErrorNum; backtracked = 0; if (!curFile->is_open()) { throw String("Error: couldn't open file."); delete curFile; curFile = NULL; return; } unsigned char i; for (i=0; i<255; i++) { firstIdentifierChars[i] = isLetterChar(i) || i=='_'; nextIdentifierChars[i] = isLetterChar(i) || isNumberChar(i) || i=='_'; firstNumberChars[i] = isNumberChar(i) || i=='.'; nextNumberChars[i] = isLetterChar(i) || isNumberChar(i) || i=='_' || i=='.'; specialChars[i] = false; } }
String Preprocessor::peek (unsigned int position) { while (tokens.size() <= position) { if (!getToken()) return String(); } return tokens [position].token; }
String Preprocessor::get() { if (tokens.empty()) { if (!getToken()) return String(); } String token = tokens.front().token; tokens.pop_front(); return token; }
String getCode(ULong code) { if (code <= 0xFFFF) return String (code, 16, 4); else return String (code, 16, 8); }
bool Preprocessor::getToken() { eatComments(); // Save current position PreprocessorPosition pos = PreprocessorPosition (*this, curFileName, lineNumber, colNumber); char firstChar = getChar(); char secondChar; while (true) { if (!firstChar) return false; // Options if (firstChar == '#') { String option; firstChar = getChar(); while (nextIdentifierChars [firstChar]) { option += firstChar; firstChar = getChar(); } while (firstChar == ' ') firstChar = getChar(); String param; while (true) { if (firstChar == '\n' || firstChar == '\r') break; if (firstChar == '\\') { firstChar = getChar(); while (firstChar != '\n') { if (!isWhiteSpace (firstChar)) startError() << "\"" << firstChar << "\" found after \"\\\"." << endl; firstChar = getChar(); } while (isWhiteSpace (firstChar)) { firstChar = getChar(); } param += ' '; } else { param += firstChar; firstChar = getChar(); } } param += ' '; String::const_iterator i = param.end(); do { i --; } while (i != param.begin() && isWhiteSpace (*i)); addOption (option, String (param.begin(), i + 1), pos); } else { // Identifiers if (firstIdentifierChars [firstChar]) { // Get identifier String identifier; do { identifier += firstChar; firstChar = getChar(); } while (nextIdentifierChars [firstChar]); if (firstChar) putBackChar (firstChar); tokens.push_back (Token (identifier, pos)); return true; } else { // Numbers if (firstNumberChars [firstChar]) { // Get number String number; do { number += firstChar; firstChar = getChar(); } while (nextNumberChars [firstChar]); if (firstChar) putBackChar (firstChar); tokens.push_back (Token (number, pos)); return true; } else { // Special sequences like "==" or "->" if (specialChars [firstChar]) { secondChar = peekChar(); if (isSpecialToken(firstChar, secondChar)) { tokens.push_back (Token (String (firstChar) + String (secondChar), pos)); getChar(); return true; } } tokens.push_back (Token (String (firstChar), pos)); return true; } } } eatComments(); pos.fileName = curFileName; pos.lineNumber = lineNumber; pos.colNumber = colNumber; firstChar = getChar(); } }