jak-project/common/goos/TextDB.h

98 lines
2.4 KiB
C
Raw Normal View History

#pragma once
2020-08-22 22:30:12 -04:00
/*!
* @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
*/
#include <string>
#include <vector>
#include <stdexcept>
#include <unordered_map>
#include <memory>
#include "common/goos/Object.h"
2020-08-22 22:30:12 -04:00
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<int> offset_by_line;
std::pair<int, int> 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<SourceText> frag;
};
class TextDb {
public:
void insert(const std::shared_ptr<SourceText>& frag);
void link(const Object& o, std::shared_ptr<SourceText> frag, int offset);
std::string get_info_for(const Object& o);
std::string get_info_for(const std::shared_ptr<SourceText>& frag, int offset);
private:
std::vector<std::shared_ptr<SourceText>> fragments;
std::unordered_map<std::shared_ptr<goos::HeapObject>, TextRef> map;
};
} // namespace goos