mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2026-01-25 13:07:13 +00:00
symbol docs module implemented, part of file tree implemented
This commit is contained in:
parent
b56b72c98e
commit
100779d2d4
6 changed files with 232 additions and 55 deletions
|
|
@ -13,6 +13,7 @@ include_directories(include
|
||||||
|
|
||||||
add_executable(lang src/main.cpp
|
add_executable(lang src/main.cpp
|
||||||
include/tree_sitter_wrapper.hpp
|
include/tree_sitter_wrapper.hpp
|
||||||
|
include/name_tree.hpp
|
||||||
deps/tree-sitter-lang/src/tree_sitter/parser.h
|
deps/tree-sitter-lang/src/tree_sitter/parser.h
|
||||||
deps/tree-sitter-lang/src/parser.c
|
deps/tree-sitter-lang/src/parser.c
|
||||||
deps/tree-sitter/lib/src/lib.c)
|
deps/tree-sitter/lib/src/lib.c)
|
||||||
|
|
|
||||||
2
deps/tree-sitter-lang
vendored
2
deps/tree-sitter-lang
vendored
|
|
@ -1 +1 @@
|
||||||
Subproject commit d218e02a78c7a8b899c32794324b25beeb212afb
|
Subproject commit befa2f03954304d5812f9117a11fd47b02a4fd28
|
||||||
52
include/docs.hpp
Normal file
52
include/docs.hpp
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace file {
|
||||||
|
|
||||||
|
class SymbolDocs {
|
||||||
|
public:
|
||||||
|
SymbolDocs(std::string &&description)
|
||||||
|
: description_(std::move(description)) {}
|
||||||
|
|
||||||
|
SymbolDocs(const std::string &description) : description_(description) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool set_annotation_info(const std::string &annotation, T &&info) {
|
||||||
|
if (annotations_info_.count(annotation) == 0) {
|
||||||
|
annotations_info_[annotation] = std::forward<T>(info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string *get_description() { return &description_; }
|
||||||
|
|
||||||
|
const std::string *get_description() const { return &description_; }
|
||||||
|
|
||||||
|
std::optional<std::string *>
|
||||||
|
get_annotation_info(const std::string &annotation) {
|
||||||
|
auto info_iterator = annotations_info_.find(annotation);
|
||||||
|
if (info_iterator != annotations_info_.end()) {
|
||||||
|
return &info_iterator->second;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<const std::string *>
|
||||||
|
get_annotation_info(const std::string &annotation) const {
|
||||||
|
auto info_iterator = annotations_info_.find(annotation);
|
||||||
|
if (info_iterator != annotations_info_.end()) {
|
||||||
|
return &info_iterator->second;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string description_;
|
||||||
|
std::unordered_map<std::string, std::string> annotations_info_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace file
|
||||||
135
include/file_tree.hpp
Normal file
135
include/file_tree.hpp
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace file {
|
||||||
|
|
||||||
|
// DEBUG: using T = long long;
|
||||||
|
|
||||||
|
class Node {
|
||||||
|
public:
|
||||||
|
Node(std::pair<size_t, size_t> start_position,
|
||||||
|
std::pair<size_t, size_t> end_position)
|
||||||
|
: start_position_(start_position), end_position_(end_position) {}
|
||||||
|
|
||||||
|
std::pair<size_t, size_t> get_start_position() { return start_position_; }
|
||||||
|
|
||||||
|
std::pair<size_t, size_t> get_end_position() { return end_position_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::pair<size_t, size_t> start_position_;
|
||||||
|
std::pair<size_t, size_t> end_position_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct unit {};
|
||||||
|
struct null {};
|
||||||
|
|
||||||
|
class Literal : public Node {
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
Literal(Node node, T &&value) : Node(node), value_(std::forward<T>(value)) {}
|
||||||
|
|
||||||
|
template <typename T> std::optional<T *> get() {
|
||||||
|
if (std::holds_alternative<T>(value_)) {
|
||||||
|
return &std::get<T>(value_);
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> std::optional<const T *> get() const {
|
||||||
|
if (std::holds_alternative<T>(value_)) {
|
||||||
|
return &std::get<T>(value_);
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::variant<double, long long, std::string, char, bool, unit, null> value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Identifier : public Node {
|
||||||
|
public:
|
||||||
|
enum IdentifierType {
|
||||||
|
SIMPLE_NAME,
|
||||||
|
SIMPLE_TYPE,
|
||||||
|
TYPECLASS,
|
||||||
|
ARGUMENT_NAME,
|
||||||
|
ARGUMENT_TYPE,
|
||||||
|
ANNOTATION,
|
||||||
|
OPERATOR,
|
||||||
|
PLACEHOLDER,
|
||||||
|
};
|
||||||
|
|
||||||
|
Identifier(Node node, IdentifierType type, std::string &&value)
|
||||||
|
: Node(node), type_(type), value_(std::move(value)) {}
|
||||||
|
|
||||||
|
Identifier(Node node, IdentifierType type, const std::string &value)
|
||||||
|
: Node(node), type_(type), value_(value) {}
|
||||||
|
|
||||||
|
IdentifierType get_type() { return type_; }
|
||||||
|
|
||||||
|
std::string *get() { return &value_; }
|
||||||
|
|
||||||
|
const std::string *get() const { return &value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
IdentifierType type_;
|
||||||
|
std::string value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Type : public Node {
|
||||||
|
public:
|
||||||
|
Type(Node node, Identifier &&identifier, bool is_on_heap = false,
|
||||||
|
bool is_optional = false)
|
||||||
|
: Node(node), name_(std::move(identifier)), is_on_heap_(is_on_heap),
|
||||||
|
is_optional_(is_optional) {}
|
||||||
|
|
||||||
|
Type(Node node, const Identifier &identifier, bool is_on_heap = false,
|
||||||
|
bool is_optional = false)
|
||||||
|
: Node(node), name_(identifier), is_on_heap_(is_on_heap),
|
||||||
|
is_optional_(is_optional) {}
|
||||||
|
|
||||||
|
Type(Node node, Identifier &&identifier,
|
||||||
|
std::vector<std::unique_ptr<Type>> &¶meters, bool is_on_heap = false,
|
||||||
|
bool is_optional = false)
|
||||||
|
: Node(node), name_(std::move(identifier)),
|
||||||
|
parameters_(std::move(parameters)), is_on_heap_(is_on_heap),
|
||||||
|
is_optional_(is_optional) {}
|
||||||
|
|
||||||
|
Type(Node node, const Identifier &identifier,
|
||||||
|
std::vector<std::unique_ptr<Type>> &¶meters, bool is_on_heap = false,
|
||||||
|
bool is_optional = false)
|
||||||
|
: Node(node), name_(identifier), parameters_(std::move(parameters)),
|
||||||
|
is_on_heap_(is_on_heap), is_optional_(is_optional) {}
|
||||||
|
|
||||||
|
std::string *get_name() { return name_.get(); }
|
||||||
|
|
||||||
|
const std::string *get_name() const { return name_.get(); }
|
||||||
|
|
||||||
|
size_t get_parametrs_size() { return parameters_.size(); }
|
||||||
|
|
||||||
|
Type *get_parameter(size_t id) { return parameters_.at(id).get(); }
|
||||||
|
|
||||||
|
const Type *get_parameter(size_t id) const {
|
||||||
|
return parameters_.at(id).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_on_heap() { return is_on_heap_; }
|
||||||
|
|
||||||
|
bool is_optional() { return is_optional_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Identifier name_;
|
||||||
|
std::vector<std::unique_ptr<Type>> parameters_;
|
||||||
|
// or use allocator ??
|
||||||
|
bool is_on_heap_ = false;
|
||||||
|
bool is_optional_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// IN PROGRESS
|
||||||
|
|
||||||
|
} // namespace file
|
||||||
11
include/name_tree.hpp
Normal file
11
include/name_tree.hpp
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tree_sitter_wrapper.hpp"
|
||||||
|
|
||||||
|
// IN PROGRESS
|
||||||
|
class NameTree {
|
||||||
|
public:
|
||||||
|
NameTree() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
// for clangd
|
// for clangd
|
||||||
#include "tree_sitter/api.h"
|
#include "tree_sitter/api.h"
|
||||||
|
|
||||||
extern "C" const TSLanguage* tree_sitter_lang();
|
extern "C" const TSLanguage *tree_sitter_lang();
|
||||||
|
|
||||||
namespace parser {
|
namespace parser {
|
||||||
|
|
||||||
|
|
@ -13,11 +13,10 @@ class ParseTree {
|
||||||
public:
|
public:
|
||||||
class Node {
|
class Node {
|
||||||
public:
|
public:
|
||||||
Node(const TSNode& node, const std::string* source) : node_(node), source_(source) {}
|
Node(const TSNode &node, const std::string *source)
|
||||||
|
: node_(node), source_(source) {}
|
||||||
|
|
||||||
std::string GetType() {
|
std::string GetType() { return ts_node_type(node_); }
|
||||||
return ts_node_type(node_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<size_t, size_t> GetStartPoint() {
|
std::pair<size_t, size_t> GetStartPoint() {
|
||||||
TSPoint point = ts_node_start_point(node_);
|
TSPoint point = ts_node_start_point(node_);
|
||||||
|
|
@ -29,9 +28,7 @@ public:
|
||||||
return {point.row, point.column};
|
return {point.row, point.column};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetAsSExpression() {
|
std::string GetAsSExpression() { return ts_node_string(node_); }
|
||||||
return ts_node_string(node_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetValue() { // from source
|
std::string GetValue() { // from source
|
||||||
size_t start = ts_node_start_byte(node_);
|
size_t start = ts_node_start_byte(node_);
|
||||||
|
|
@ -39,43 +36,30 @@ public:
|
||||||
return source_->substr(start, end - start);
|
return source_->substr(start, end - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsNull() {
|
bool IsNull() { return ts_node_is_null(node_); }
|
||||||
return ts_node_is_null(node_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsNamed() {
|
bool IsNamed() { return ts_node_is_named(node_); }
|
||||||
return ts_node_is_named(node_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsMissing() {
|
bool IsMissing() { return ts_node_is_missing(node_); }
|
||||||
return ts_node_is_missing(node_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsExtra() { // comments, etc.
|
bool IsExtra() { // comments, etc.
|
||||||
return ts_node_is_extra(node_);
|
return ts_node_is_extra(node_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasError() {
|
bool HasError() { return ts_node_has_error(node_); }
|
||||||
return ts_node_has_error(node_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node NthChild(size_t n) {
|
Node NthChild(size_t n) { return Node(ts_node_child(node_, n), source_); }
|
||||||
return Node(ts_node_child(node_, n), source_);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ChildCount() {
|
size_t ChildCount() { return ts_node_child_count(node_); }
|
||||||
return ts_node_child_count(node_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node NthNamedChild(size_t n) {
|
Node NthNamedChild(size_t n) {
|
||||||
return Node(ts_node_named_child(node_, n), source_);
|
return Node(ts_node_named_child(node_, n), source_);
|
||||||
}
|
}
|
||||||
size_t NamedChildCount() {
|
size_t NamedChildCount() { return ts_node_named_child_count(node_); }
|
||||||
return ts_node_named_child_count(node_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node ChildByFieldName(const std::string& name) {
|
Node ChildByFieldName(const std::string &name) {
|
||||||
return Node(ts_node_child_by_field_name(node_, name.c_str(), name.size()), source_);
|
return Node(ts_node_child_by_field_name(node_, name.c_str(), name.size()),
|
||||||
|
source_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node PreviousSibling() {
|
Node PreviousSibling() {
|
||||||
|
|
@ -86,46 +70,40 @@ public:
|
||||||
return Node(ts_node_prev_named_sibling(node_), source_);
|
return Node(ts_node_prev_named_sibling(node_), source_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node NextSibling() {
|
Node NextSibling() { return Node(ts_node_next_sibling(node_), source_); }
|
||||||
return Node(ts_node_next_sibling(node_), source_);
|
|
||||||
}
|
|
||||||
|
|
||||||
Node NextNamedSibling() {
|
Node NextNamedSibling() {
|
||||||
return Node(ts_node_next_named_sibling(node_), source_);
|
return Node(ts_node_next_named_sibling(node_), source_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TSNode node_;
|
TSNode node_;
|
||||||
const std::string* source_;
|
const std::string *source_;
|
||||||
};
|
};
|
||||||
|
|
||||||
ParseTree(const std::string& source) : source_(source) {
|
ParseTree(const std::string &source) : source_(source) {
|
||||||
TSParser* parser = ts_parser_new();
|
TSParser *parser = ts_parser_new();
|
||||||
ts_parser_set_language(parser, tree_sitter_lang());
|
ts_parser_set_language(parser, tree_sitter_lang());
|
||||||
|
|
||||||
tree_ = ts_parser_parse_string(
|
tree_ = ts_parser_parse_string(parser, nullptr, source_.c_str(),
|
||||||
parser,
|
|
||||||
nullptr,
|
|
||||||
source_.c_str(),
|
|
||||||
source_.size());
|
source_.size());
|
||||||
|
|
||||||
ts_parser_delete(parser);
|
ts_parser_delete(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseTree(const ParseTree& parse_tree) : tree_(ts_tree_copy(parse_tree.tree_)), source_(parse_tree.source_) {}
|
ParseTree(const ParseTree &parse_tree)
|
||||||
|
: tree_(ts_tree_copy(parse_tree.tree_)), source_(parse_tree.source_) {}
|
||||||
|
|
||||||
Node GetRoot() const {
|
Node GetRoot() const { return Node(ts_tree_root_node(tree_), &source_); }
|
||||||
return Node(ts_tree_root_node(tree_), &source_);
|
|
||||||
}
|
|
||||||
|
|
||||||
~ParseTree() {
|
~ParseTree() { ts_tree_delete(tree_); }
|
||||||
ts_tree_delete(tree_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsProperlyParsed() { // TODO: find place
|
bool IsProperlyParsed() { // TODO: find place
|
||||||
return !GetRoot().HasError();
|
return !GetRoot().HasError();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TSTree* tree_;
|
TSTree *tree_;
|
||||||
std::string source_; // for token value extraction
|
std::string source_; // for token value extraction
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue