Use a separate type for storing field map headers
This commit is contained in:
parent
51a9f14f7d
commit
d8a2c0dda2
5 changed files with 50 additions and 31 deletions
|
|
@ -383,7 +383,7 @@ impl Generator {
|
|||
|
||||
fn add_field_sequences(&mut self) {
|
||||
let mut flat_field_maps = vec![];
|
||||
let mut next_flat_field_map_index = self.parse_table.child_infos.len();
|
||||
let mut next_flat_field_map_index = 0;
|
||||
self.get_field_map_id(
|
||||
&Vec::new(),
|
||||
&mut flat_field_maps,
|
||||
|
|
@ -412,29 +412,41 @@ impl Generator {
|
|||
}
|
||||
}
|
||||
|
||||
add_line!(self, "static const TSFieldMapping ts_field_map[] = {{",);
|
||||
add_line!(
|
||||
self,
|
||||
"static const TSFieldMapSlice ts_field_map_slices[] = {{",
|
||||
);
|
||||
indent!(self);
|
||||
|
||||
add_line!(self, "/* child info id -> (field map index, count) */");
|
||||
for (child_info_id, (row_id, length)) in field_map_ids.into_iter().enumerate() {
|
||||
if length > 0 {
|
||||
add_line!(self, "[{}] = {{{}, {}, 0}},", child_info_id, row_id, length);
|
||||
add_line!(
|
||||
self,
|
||||
"[{}] = {{.index = {}, .length = {}}},",
|
||||
child_info_id,
|
||||
row_id,
|
||||
length
|
||||
);
|
||||
}
|
||||
}
|
||||
dedent!(self);
|
||||
add_line!(self, "}};");
|
||||
add_line!(self, "");
|
||||
|
||||
add!(self, "\n");
|
||||
add_line!(self, "/* field id -> child index */");
|
||||
add_line!(
|
||||
self,
|
||||
"static const TSFieldMapEntry ts_field_map_entries[] = {{",
|
||||
);
|
||||
indent!(self);
|
||||
for (row_index, field_pairs) in flat_field_maps.into_iter().skip(1) {
|
||||
add_line!(self, "[{}] =", row_index);
|
||||
indent!(self);
|
||||
for (field_name, location) in field_pairs {
|
||||
add_line!(
|
||||
self,
|
||||
"{{{}, {}, {}}},",
|
||||
self.field_id(&field_name),
|
||||
location.index,
|
||||
location.inherited
|
||||
);
|
||||
add_whitespace!(self);
|
||||
add!(self, "{{{}, {}", self.field_id(&field_name), location.index);
|
||||
if location.inherited {
|
||||
add!(self, ", .inherited = true");
|
||||
}
|
||||
add!(self, "}},\n");
|
||||
}
|
||||
dedent!(self);
|
||||
}
|
||||
|
|
@ -887,8 +899,15 @@ impl Generator {
|
|||
add_line!(self, ".field_count = FIELD_COUNT,");
|
||||
|
||||
if !self.field_names.is_empty() {
|
||||
add_line!(self, ".field_map = (const TSFieldMapping *)ts_field_map,");
|
||||
add_line!(self, ".field_names = ts_field_names,");
|
||||
add_line!(
|
||||
self,
|
||||
".field_map_slices = (const TSFieldMapSlice *)ts_field_map_slices,"
|
||||
);
|
||||
add_line!(
|
||||
self,
|
||||
".field_map_entries = (const TSFieldMapEntry *)ts_field_map_entries,"
|
||||
);
|
||||
}
|
||||
|
||||
add_line!(
|
||||
|
|
@ -1007,7 +1026,7 @@ impl Generator {
|
|||
}
|
||||
|
||||
fn field_id(&self, field_name: &String) -> String {
|
||||
format!("field_id_{}", field_name)
|
||||
format!("field_{}", field_name)
|
||||
}
|
||||
|
||||
fn metadata_for_symbol(&self, symbol: Symbol) -> (&str, VariableType) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,12 @@ typedef struct {
|
|||
TSFieldId field_id;
|
||||
uint8_t child_index;
|
||||
bool inherited;
|
||||
} TSFieldMapping;
|
||||
} TSFieldMapEntry;
|
||||
|
||||
typedef struct {
|
||||
uint16_t index;
|
||||
uint16_t length;
|
||||
} TSFieldMapSlice;
|
||||
|
||||
typedef uint16_t TSStateId;
|
||||
|
||||
|
|
@ -106,7 +111,8 @@ struct TSLanguage {
|
|||
void (*deserialize)(void *, const char *, unsigned);
|
||||
} external_scanner;
|
||||
uint32_t field_count;
|
||||
const TSFieldMapping *field_map;
|
||||
const TSFieldMapSlice *field_map_slices;
|
||||
const TSFieldMapEntry *field_map_entries;
|
||||
const char **field_names;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -90,18 +90,12 @@ ts_language_alias_sequence(const TSLanguage *self, uint32_t child_info_id) {
|
|||
static inline void ts_language_field_map(
|
||||
const TSLanguage *self,
|
||||
uint32_t child_info_id,
|
||||
const TSFieldMapping **start,
|
||||
const TSFieldMapping **end
|
||||
const TSFieldMapEntry **start,
|
||||
const TSFieldMapEntry **end
|
||||
) {
|
||||
// To find the field mappings for a given child info id, first index
|
||||
// into the field map using the child info id directly. This 'header'
|
||||
// row contains two values:
|
||||
// * the index where the field mappings start
|
||||
// * the number of field mappings.
|
||||
const TSFieldMapping *field_map = self->field_map;
|
||||
TSFieldMapping header = field_map[child_info_id];
|
||||
*start = &field_map[header.field_id];
|
||||
*end = &field_map[header.field_id] + header.child_index;
|
||||
TSFieldMapSlice slice = self->field_map_slices[child_info_id];
|
||||
*start = &self->field_map_entries[slice.index];
|
||||
*end = &self->field_map_entries[slice.index] + slice.length;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -461,7 +461,7 @@ TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id) {
|
|||
recur:
|
||||
if (!field_id || ts_node_child_count(self) == 0) return ts_node__null();
|
||||
|
||||
const TSFieldMapping *field_map, *field_map_end;
|
||||
const TSFieldMapEntry *field_map, *field_map_end;
|
||||
ts_language_field_map(
|
||||
self.tree->language,
|
||||
ts_node__subtree(self).ptr->child_info_id,
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *_self) {
|
|||
}
|
||||
}
|
||||
|
||||
const TSFieldMapping *field_map, *field_map_end;
|
||||
const TSFieldMapEntry *field_map, *field_map_end;
|
||||
ts_language_field_map(
|
||||
self->tree->language,
|
||||
parent_entry->subtree->ptr->child_info_id,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue