#pragma once /*! * @file TextDB.h * The Text Database for storing source code text. * This allows us to ask for things like "where did this form come from?" * and be able to print the file name and offset into the file, as well as the line. * * The purpose is to be able to have an error message like: * * Error on (+ a b): a has invalid type (string) * From my-file.gc, line 25: * (+ 1 (+ a b)) ; compute the sum */ #ifndef JAK1_TEXTDB_H #define JAK1_TEXTDB_H #include #include #include #include #include #include "common/goos/Object.h" namespace goos { /*! * Parent class for source-code text organized in lines */ class SourceText { public: explicit SourceText(std::string r); SourceText() = default; const char* get_text() { return text.c_str(); } int get_size() { return text.size(); } virtual std::string get_description() = 0; std::string get_line_containing_offset(int offset); int get_line_idx(int offset); virtual ~SourceText(){}; protected: void build_offsets(); std::string text; std::vector offset_by_line; std::pair get_containing_line(int offset); }; /*! * Text from the REPL prompt */ class ReplText : public SourceText { public: explicit ReplText(const std::string& text_) : SourceText(text_) {} std::string get_description() override { return "REPL"; } ~ReplText() = default; }; /*! * Text generated by the program itself (like for example, with (read "hello")) */ class ProgramString : public SourceText { public: explicit ProgramString(const std::string& text_) : SourceText(text_) {} std::string get_description() override { return "Program string"; } ~ProgramString() = default; }; /*! * Text from a file. */ class FileText : public SourceText { public: FileText(std::string filename_); std::string get_description() { return filename; } ~FileText() = default; private: std::string filename; }; struct TextRef { int offset; std::shared_ptr frag; }; class TextDb { public: void insert(const std::shared_ptr& frag); void link(const Object& o, std::shared_ptr frag, int offset); std::string get_info_for(const Object& o); std::string get_info_for(const std::shared_ptr& frag, int offset); private: std::vector> fragments; std::unordered_map, TextRef> map; }; } // namespace goos #endif // JAK1_TEXTDB_H