mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-13 03:32:22 +00:00
A new lexer is noticeably faster and memory efficient (although splitting a file to tokens is negligible in a whole pipeline). But the purpose of rewriting lexer was not just to speed up, but to allow writing code without spaces: `2+2` is now 4, not a valid identifier as earlier. The variety of symbols allowed in identifier has greatly reduced and is now similar to other languages. SrcLocation became 8 bytes on stack everywhere. Command-line flags were also reworked: - the input for Tolk compiler is only a single file now, it's parsed, and parsing continues while new #include are resolved - flags like -A -P and so on are no more needed, actually
120 lines
3.8 KiB
C++
120 lines
3.8 KiB
C++
/*
|
|
This file is part of TON Blockchain Library.
|
|
|
|
TON Blockchain Library is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
TON Blockchain Library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace tolk {
|
|
|
|
struct SrcFile {
|
|
struct SrcPosition {
|
|
int offset;
|
|
int line_no;
|
|
int char_no;
|
|
std::string_view line_str;
|
|
};
|
|
|
|
int file_id;
|
|
std::string rel_filename;
|
|
std::string abs_filename;
|
|
std::string text;
|
|
const SrcFile* included_from{nullptr};
|
|
|
|
SrcFile(int file_id, std::string rel_filename, std::string abs_filename, std::string&& text, const SrcFile* included_from)
|
|
: file_id(file_id)
|
|
, rel_filename(std::move(rel_filename))
|
|
, abs_filename(std::move(abs_filename))
|
|
, text(std::move(text))
|
|
, included_from(included_from) { }
|
|
|
|
SrcFile(const SrcFile& other) = delete;
|
|
SrcFile &operator=(const SrcFile&) = delete;
|
|
|
|
bool is_entrypoint_file() const;
|
|
bool is_offset_valid(int offset) const;
|
|
SrcPosition convert_offset(int offset) const;
|
|
};
|
|
|
|
class AllRegisteredSrcFiles {
|
|
std::vector<SrcFile*> all_src_files;
|
|
int last_file_id = -1;
|
|
|
|
public:
|
|
const SrcFile *find_file(int file_id) const;
|
|
const SrcFile* find_file(const std::string& abs_filename) const;
|
|
const SrcFile* register_file(const std::string& rel_filename, const std::string& abs_filename, std::string&& text, const SrcFile* included_from);
|
|
const std::vector<SrcFile*>& get_all_files() const { return all_src_files; }
|
|
};
|
|
|
|
struct Fatal final : std::exception {
|
|
std::string message;
|
|
|
|
explicit Fatal(std::string _msg) : message(std::move(_msg)) {
|
|
}
|
|
const char* what() const noexcept override {
|
|
return message.c_str();
|
|
}
|
|
};
|
|
|
|
std::ostream& operator<<(std::ostream& os, const Fatal& fatal);
|
|
|
|
// SrcLocation points to a location (line, column) in some loaded .tolk source SrcFile.
|
|
// Note, that instead of storing src_file, line_no, etc., only 2 ints are stored.
|
|
// The purpose is: sizeof(SrcLocation) == 8, so it's just passed/stored without pointers/refs, just like int64_t.
|
|
// When decoding SrcLocation into human-readable format, it's converted to SrcFile::SrcPosition via offset.
|
|
class SrcLocation {
|
|
friend class Lexer;
|
|
|
|
int file_id = -1; // file_id from AllRegisteredSrcFiles
|
|
int char_offset = -1; // offset from SrcFile::text
|
|
|
|
public:
|
|
|
|
SrcLocation() = default;
|
|
explicit SrcLocation(const SrcFile* src_file) : file_id(src_file->file_id) {
|
|
}
|
|
|
|
bool is_defined() const { return file_id != -1; }
|
|
const SrcFile* get_src_file() const;
|
|
|
|
void show(std::ostream& os) const;
|
|
void show_context(std::ostream& os) const;
|
|
|
|
void show_general_error(std::ostream& os, const std::string& message, const std::string& err_type) const;
|
|
void show_note(const std::string& err_msg) const;
|
|
void show_warning(const std::string& err_msg) const;
|
|
void show_error(const std::string& err_msg) const;
|
|
};
|
|
|
|
std::ostream& operator<<(std::ostream& os, SrcLocation loc);
|
|
|
|
struct ParseError : std::exception {
|
|
SrcLocation where;
|
|
std::string message;
|
|
ParseError(SrcLocation _where, std::string _msg) : where(_where), message(std::move(_msg)) {
|
|
}
|
|
|
|
const char* what() const noexcept override {
|
|
return message.c_str();
|
|
}
|
|
void show(std::ostream& os) const;
|
|
};
|
|
|
|
std::ostream& operator<<(std::ostream& os, const ParseError& error);
|
|
|
|
} // namespace tolk
|