jak-project/common/goos/Reader.h
Tyler Wilding 8bba3d7fd7
REPL: Add clear-screen / auto-complete / basic hints and syntax highlighting (#316)
* swap to replxx from linenoise

* repl: Implement form auto-tab-completion

* repl: color coordinate the prompts

* repl: Add some basic syntax highlighting, bracket pairs and forms (all one color)

* repl: A more consistent starting screen for the repl

* repl: bug fix for auto-complete

* debug linux

* linting
2021-03-07 23:41:21 -05:00

106 lines
2.8 KiB
C++

#pragma once
/*!
* @file Reader.h
*
* The Reader converts text into GOOS object, for interpreting or compiling.
* The Reader also stores the GOOS symbol table, and is able to figure out where forms
* came from, for printing error messages about forms.
*
* The reader also know where the source folder is, through an environment variable set when
* launching the compiler or the compiler test.
*/
#include <memory>
#include <cassert>
#include <utility>
#include <unordered_map>
#include "common/goos/Object.h"
#include "common/goos/TextDB.h"
#include "ReplUtils.h"
namespace goos {
/*!
* Wrapper around a source of text that allows reading/peeking.
*/
struct TextStream {
explicit TextStream(std::shared_ptr<SourceText> ptr) { text = std::move(ptr); }
std::shared_ptr<SourceText> text;
int seek = 0;
int line_count = 0;
char peek() {
assert(seek < text->get_size());
return text->get_text()[seek];
}
char peek(int i) {
assert(seek + i < text->get_size());
return text->get_text()[seek + i];
}
char read() {
assert(seek < text->get_size());
char c = text->get_text()[seek++];
if (c == '\n')
line_count++;
return c;
}
bool text_remains() { return seek < text->get_size(); }
bool text_remains(int i) { return seek + i < text->get_size(); }
void seek_past_whitespace_and_comments();
};
/*!
* A Token used for parsing.
*/
struct Token {
std::shared_ptr<SourceText> source_text;
int source_offset;
int source_line;
std::string text;
};
class Reader {
public:
Reader();
Object read_from_string(const std::string& str, bool add_top_level = true);
Object read_from_stdin(const std::string& prompt, ReplWrapper& repl);
Object read_from_file(const std::vector<std::string>& file_path);
std::string get_source_dir();
SymbolTable symbolTable;
TextDb db;
private:
Object internal_read(std::shared_ptr<SourceText> text, bool add_top_level = true);
Object read_list(TextStream& stream, bool expect_close_paren = true);
bool read_object(Token& tok, TextStream& ts, Object& obj);
bool read_array(TextStream& stream, Object& o);
void throw_reader_error(TextStream& here, const std::string& err, int seek_offset);
Token get_next_token(TextStream& stream);
bool try_token_as_symbol(const Token& tok, Object& obj);
bool try_token_as_char(const Token& tok, Object& obj);
bool try_token_as_float(const Token& tok, Object& obj);
bool try_token_as_binary(const Token& tok, Object& obj);
bool try_token_as_hex(const Token& tok, Object& obj);
bool try_token_as_integer(const Token& tok, Object& obj);
bool read_string(TextStream& stream, Object& obj);
void add_reader_macro(const std::string& shortcut, std::string replacement);
char valid_symbols_chars[256];
std::unordered_map<std::string, std::string> reader_macros;
};
std::string get_readable_string(const char* in);
} // namespace goos