asherkin@263: /* vim: set ts=4 sw=4 tw=99 et: asherkin@263: * asherkin@263: * Copyright (C) 2012 David Anderson asherkin@263: * asherkin@263: * This file is part of SourcePawn. asherkin@263: * asherkin@263: * SourcePawn is free software: you can redistribute it and/or modify it under asherkin@263: * the terms of the GNU General Public License as published by the Free asherkin@263: * Software Foundation, either version 3 of the License, or (at your option) asherkin@263: * any later version. asherkin@263: * asherkin@263: * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY asherkin@263: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS asherkin@263: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. asherkin@263: * asherkin@263: * You should have received a copy of the GNU General Public License along with asherkin@263: * SourcePawn. If not, see http://www.gnu.org/licenses/. asherkin@263: */ asherkin@263: #ifndef _include_jitcraft_scanner_h_ asherkin@263: #define _include_jitcraft_scanner_h_ asherkin@263: asherkin@263: #include "Token.h" asherkin@263: #include "CompileContext.h" asherkin@263: #include "../Opcodes.h" asherkin@263: #include "../Vector.h" asherkin@263: asherkin@263: namespace ke { asherkin@263: asherkin@263: class Scanner asherkin@263: { asherkin@263: template asherkin@263: friend class AutoAllowTags; asherkin@263: asherkin@263: CompileContext &cc_; asherkin@263: const char *stream_; asherkin@263: size_t length_; asherkin@263: bool pushed_; asherkin@263: bool allowTags_; asherkin@263: char saved_; asherkin@263: const char *pos_; asherkin@263: Vector literal_; asherkin@263: TokenKind lastToken_; asherkin@263: SourcePosition last_; asherkin@263: SourcePosition cur_; asherkin@263: SourcePosition begin_; asherkin@263: asherkin@263: private: asherkin@263: char getChar(); asherkin@263: void putChar(char c); asherkin@263: void eatSingleLine(); asherkin@263: bool eatComment(); asherkin@263: void calcNewLine(char c); asherkin@263: int readEscapeCode(); asherkin@263: TokenKind stringLiteral(); asherkin@263: TokenKind hexLiteral(); asherkin@263: TokenKind numberLiteral(char first); asherkin@263: TokenKind identifier(char first); asherkin@263: asherkin@263: TokenKind next(); asherkin@263: asherkin@263: public: asherkin@263: Scanner(CompileContext &cc, const char *stream, size_t length); asherkin@263: asherkin@263: static double ParseDouble(const char *string); asherkin@263: asherkin@263: TokenKind scan(); asherkin@263: TokenKind peek(); asherkin@263: TokenKind last() const { asherkin@263: return lastToken_; asherkin@263: } asherkin@263: asherkin@263: bool tagsEnabled() const { asherkin@263: return allowTags_; asherkin@263: } asherkin@263: void setTagsEnabled(bool enabled) { asherkin@263: allowTags_ = enabled; asherkin@263: } asherkin@263: asherkin@263: // Beginning source position of the last instruction. asherkin@263: SourcePosition begin() const { asherkin@263: return begin_; asherkin@263: } asherkin@263: asherkin@263: // Note: the literal may have embedded NUL characters. asherkin@263: const char *literal() const { asherkin@263: return literal_.buffer(); asherkin@263: } asherkin@263: size_t literal_length() const { asherkin@263: return literal_.length() - 1; asherkin@263: } asherkin@263: }; asherkin@263: asherkin@263: template asherkin@263: class AutoAllowTags asherkin@263: { asherkin@263: Scanner &scanner_; asherkin@263: bool prev_; asherkin@263: asherkin@263: public: asherkin@263: AutoAllowTags(Scanner &scanner) asherkin@263: : scanner_(scanner), asherkin@263: prev_(scanner_.tagsEnabled()) asherkin@263: { asherkin@263: scanner_.setTagsEnabled(Enabled); asherkin@263: } asherkin@263: ~AutoAllowTags() asherkin@263: { asherkin@263: scanner_.setTagsEnabled(prev_); asherkin@263: } asherkin@263: }; asherkin@263: asherkin@263: } // namespace ke asherkin@263: asherkin@263: #endif // _include_jitcraft_scanner_h_