#include "compiler/rules/metadata.h" #include #include #include "compiler/rule.h" namespace tree_sitter { namespace rules { using std::move; using std::string; bool Alias::operator==(const Alias &other) const { return value == other.value && is_named == other.is_named; } bool Alias::operator!=(const Alias &other) const { return !operator==(other); } bool Alias::operator<(const Alias &other) const { if (value < other.value) return true; if (other.value < value) return false; return is_named < other.is_named; } Metadata::Metadata(const Rule &rule, MetadataParams params) : rule(std::make_shared(rule)), params(params) {} bool Metadata::operator==(const Metadata &other) const { return rule->operator==(*other.rule) && params == other.params; } template static Metadata add_metadata(Rule &&rule, T &&callback) { if (rule.is()) { Metadata metadata = rule.get_unchecked(); callback(metadata.params); return metadata; } else { MetadataParams params; callback(params); return Metadata{move(rule), params}; } } Metadata Metadata::merge(Rule &&rule, MetadataParams new_params) { return add_metadata(move(rule), [&](MetadataParams ¶ms) { if (new_params.has_precedence && !params.has_precedence) { params.has_precedence = true; params.precedence = new_params.precedence; } if (new_params.has_associativity && !params.has_associativity) { params.has_associativity = true; params.associativity = new_params.associativity; } if (new_params.dynamic_precedence != 0) { params.dynamic_precedence = new_params.dynamic_precedence; } if (new_params.is_string) params.is_string = true; if (new_params.is_active) params.is_active = true; if (new_params.is_main_token) params.is_main_token = true; if (!new_params.alias.value.empty()) { params.alias = new_params.alias; } }); } Metadata Metadata::token(Rule &&rule) { return add_metadata(move(rule), [](MetadataParams ¶ms) { params.is_token = true; }); } Metadata Metadata::active_prec(int precedence, Rule &&rule) { return add_metadata(move(rule), [&](MetadataParams ¶ms) { params.has_precedence = true; params.precedence = precedence; params.is_active = true; }); } Metadata Metadata::prec(int precedence, Rule &&rule) { return add_metadata(move(rule), [&](MetadataParams ¶ms) { if (!params.has_precedence) { params.has_precedence = true; params.precedence = precedence; } }); } Metadata Metadata::prec_left(int precedence, Rule &&rule) { return add_metadata(move(rule), [&](MetadataParams ¶ms) { if (!params.has_precedence) { params.has_precedence = true; params.precedence = precedence; } if (!params.has_associativity) { params.has_associativity = true; params.associativity = AssociativityLeft; } }); } Metadata Metadata::prec_right(int precedence, Rule &&rule) { return add_metadata(move(rule), [&](MetadataParams ¶ms) { if (!params.has_precedence) { params.has_precedence = true; params.precedence = precedence; } if (!params.has_associativity) { params.has_associativity = true; params.associativity = AssociativityRight; } }); } Metadata Metadata::prec_dynamic(int dynamic_precedence, Rule &&rule) { return add_metadata(move(rule), [&](MetadataParams ¶ms) { params.dynamic_precedence = dynamic_precedence; }); } Metadata Metadata::separator(Rule &&rule) { return add_metadata(move(rule), [&](MetadataParams ¶ms) { if (!params.has_precedence) { params.has_precedence = true; params.precedence = INT_MIN; } params.is_active = true; }); } Metadata Metadata::main_token(Rule &&rule) { return add_metadata(move(rule), [&](MetadataParams ¶ms) { if (!params.has_precedence) { params.has_precedence = true; params.precedence = 0; } params.is_main_token = true; }); } Metadata Metadata::alias(string &&value, bool is_named, Rule &&rule) { return add_metadata(move(rule), [&](MetadataParams ¶ms) { params.alias.value = move(value); params.alias.is_named = is_named; }); } } // namespace rules } // namespace tree_sitter