Move rust_tree_types contents into template
This commit is contained in:
parent
89f1f84857
commit
bceaad5b7e
@ -109,7 +109,84 @@ pub fn <%= @grammar.prefix %>value_get<%= suffix %>(pvalue: &<%= @grammar.prefix
|
||||
/** Tree node ID type (index into the context node arena). ID 0 is null. */
|
||||
pub type <%= @grammar.prefix %>node_id_t = u32;
|
||||
|
||||
<%= rust_tree_types %>
|
||||
/**
|
||||
* Tree node record.
|
||||
*
|
||||
* All tree nodes are stored contiguously in the context node arena. Child
|
||||
* links are stored in a shared children array: a node's children
|
||||
* occupy children[child_offset .. child_offset + n_fields]. Token payload
|
||||
* fields (token, pvalue, and any user fields) are only meaningful when
|
||||
* is_token is true.
|
||||
*/
|
||||
#[derive(Clone, Default)]
|
||||
pub struct <%= @grammar.prefix %>node_data_t {
|
||||
pub position: <%= @grammar.prefix %>position_t,
|
||||
pub end_position: <%= @grammar.prefix %>position_t,
|
||||
pub child_offset: <%= @grammar.prefix %>node_id_t,
|
||||
pub n_fields: u16,
|
||||
pub is_token: bool,
|
||||
pub token: <%= @grammar.prefix %>token_t,
|
||||
pub pvalue: <%= @grammar.prefix %>value_t,
|
||||
<% unless @grammar.token_user_fields.to_s.strip.empty? %>
|
||||
<%= @grammar.token_user_fields %>
|
||||
<% end %>
|
||||
}
|
||||
|
||||
/** Tree node handle types. */
|
||||
|
||||
/** Token tree node handle. */
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct <%= h_type("Token") %><'a> { context: &'a <%= @grammar.prefix %>context_t, id: <%= @grammar.prefix %>node_id_t }
|
||||
|
||||
impl<'a> <%= h_type("Token") %><'a> {
|
||||
/** Return whether this handle refers to a valid (non-null) node. */
|
||||
pub fn valid(&self) -> bool { self.id != 0 }
|
||||
/** Return the node ID (for identity comparison). */
|
||||
pub fn node_id(&self) -> <%= @grammar.prefix %>node_id_t { self.id }
|
||||
/** Access the underlying node record (token, pvalue, and user fields). */
|
||||
pub fn data(&self) -> &'a <%= @grammar.prefix %>node_data_t { &self.context.<%= @grammar.prefix %>tree_nodes[self.id as usize] }
|
||||
/** Text position of the first code point spanned by this node. */
|
||||
pub fn position(&self) -> <%= @grammar.prefix %>position_t { self.context.<%= @grammar.prefix %>tree_nodes[self.id as usize].position }
|
||||
/** Text position of the last code point spanned by this node. */
|
||||
pub fn end_position(&self) -> <%= @grammar.prefix %>position_t { self.context.<%= @grammar.prefix %>tree_nodes[self.id as usize].end_position }
|
||||
/** Number of child fields in this node. */
|
||||
pub fn n_fields(&self) -> u16 { if self.id != 0 { self.context.<%= @grammar.prefix %>tree_nodes[self.id as usize].n_fields } else { 0 } }
|
||||
/** Token ID for this token node. */
|
||||
pub fn token(&self) -> <%= @grammar.prefix %>token_t { self.context.<%= @grammar.prefix %>tree_nodes[self.id as usize].token }
|
||||
/** Parser value associated with this token node. */
|
||||
pub fn pvalue(&self) -> <%= @grammar.prefix %>value_t { self.context.<%= @grammar.prefix %>tree_nodes[self.id as usize].pvalue.clone() }
|
||||
}
|
||||
<% tree_node_rule_sets.each do |rule_set| %>
|
||||
|
||||
/** <%= rule_set.name %> tree node handle. */
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct <%= h_type(rule_set.name) %><'a> { context: &'a <%= @grammar.prefix %>context_t, id: <%= @grammar.prefix %>node_id_t }
|
||||
|
||||
impl<'a> <%= h_type(rule_set.name) %><'a> {
|
||||
/** Return whether this handle refers to a valid (non-null) node. */
|
||||
pub fn valid(&self) -> bool { self.id != 0 }
|
||||
/** Return the node ID (for identity comparison). */
|
||||
pub fn node_id(&self) -> <%= @grammar.prefix %>node_id_t { self.id }
|
||||
/** Access the underlying node record. */
|
||||
pub fn data(&self) -> &'a <%= @grammar.prefix %>node_data_t { &self.context.<%= @grammar.prefix %>tree_nodes[self.id as usize] }
|
||||
/** Text position of the first code point spanned by this node. */
|
||||
pub fn position(&self) -> <%= @grammar.prefix %>position_t { self.context.<%= @grammar.prefix %>tree_nodes[self.id as usize].position }
|
||||
/** Text position of the last code point spanned by this node. */
|
||||
pub fn end_position(&self) -> <%= @grammar.prefix %>position_t { self.context.<%= @grammar.prefix %>tree_nodes[self.id as usize].end_position }
|
||||
/** Number of child fields in this node. */
|
||||
pub fn n_fields(&self) -> u16 { if self.id != 0 { self.context.<%= @grammar.prefix %>tree_nodes[self.id as usize].n_fields } else { 0 } }
|
||||
<% each_tree_field(rule_set) do |rt, field_name, child_type, slot| %>
|
||||
|
||||
/** Access the <%= field_name %> child node. */
|
||||
pub fn <%= rust_ident(field_name) %>(&self) -> <%= child_type %><'a> {
|
||||
if self.id == 0 {
|
||||
return <%= child_type %> { context: self.context, id: 0 };
|
||||
}
|
||||
<%= child_type %> { context: self.context, id: self.context.<%= @grammar.prefix %>tree_children[self.context.<%= @grammar.prefix %>tree_nodes[self.id as usize].child_offset as usize + <%= slot %>] }
|
||||
}
|
||||
<% end %>
|
||||
}
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
/** Lexed token information. */
|
||||
|
||||
@ -755,79 +755,6 @@ class Propane
|
||||
typestring == "void *" ? "()" : typestring
|
||||
end
|
||||
|
||||
# Generate the Rust tree node record and handle types.
|
||||
#
|
||||
# Mirrors the C tree node record plus the C++ handle structs: each rule set
|
||||
# and the Token node get a handle type ({context, id}) with accessor methods.
|
||||
#
|
||||
# @return [String]
|
||||
# Rust tree node type definitions.
|
||||
def rust_tree_types
|
||||
p = @grammar.prefix
|
||||
out = []
|
||||
out << "/** Tree node record. */"
|
||||
out << "#[derive(Clone, Default)]"
|
||||
out << "pub struct #{p}node_data_t {"
|
||||
out << " pub position: #{p}position_t,"
|
||||
out << " pub end_position: #{p}position_t,"
|
||||
out << " pub child_offset: #{p}node_id_t,"
|
||||
out << " pub n_fields: u16,"
|
||||
out << " pub is_token: bool,"
|
||||
out << " pub token: #{p}token_t,"
|
||||
out << " pub pvalue: #{p}value_t,"
|
||||
unless @grammar.token_user_fields.to_s.strip.empty?
|
||||
out << @grammar.token_user_fields
|
||||
end
|
||||
out << "}"
|
||||
out << ""
|
||||
out << "/** Tree node handle types. */"
|
||||
tree_handle_types.each do |t|
|
||||
out << "#[derive(Clone, Copy)]"
|
||||
out << "pub struct #{t}<'a> { context: &'a #{p}context_t, id: #{p}node_id_t }"
|
||||
end
|
||||
out << ""
|
||||
# Common accessors for every handle type.
|
||||
tree_handle_types.each do |t|
|
||||
out << "impl<'a> #{t}<'a> {"
|
||||
out << " /** Return whether this handle refers to a valid (non-null) node. */"
|
||||
out << " pub fn valid(&self) -> bool { self.id != 0 }"
|
||||
out << " /** Return the node ID (for identity comparison). */"
|
||||
out << " pub fn node_id(&self) -> #{p}node_id_t { self.id }"
|
||||
out << " /** Access the underlying node record. */"
|
||||
out << " pub fn data(&self) -> &'a #{p}node_data_t { &self.context.#{p}tree_nodes[self.id as usize] }"
|
||||
out << " /** Text position of the first code point spanned by this node. */"
|
||||
out << " pub fn position(&self) -> #{p}position_t { self.context.#{p}tree_nodes[self.id as usize].position }"
|
||||
out << " /** Text position of the last code point spanned by this node. */"
|
||||
out << " pub fn end_position(&self) -> #{p}position_t { self.context.#{p}tree_nodes[self.id as usize].end_position }"
|
||||
out << " /** Number of child fields in this node. */"
|
||||
out << " pub fn n_fields(&self) -> u16 { if self.id != 0 { self.context.#{p}tree_nodes[self.id as usize].n_fields } else { 0 } }"
|
||||
if t == h_type("Token")
|
||||
out << " /** Token ID for this token node. */"
|
||||
out << " pub fn token(&self) -> #{p}token_t { self.context.#{p}tree_nodes[self.id as usize].token }"
|
||||
out << " /** Parser value associated with this token node. */"
|
||||
out << " pub fn pvalue(&self) -> #{p}value_t { self.context.#{p}tree_nodes[self.id as usize].pvalue.clone() }"
|
||||
end
|
||||
out << "}"
|
||||
end
|
||||
out << ""
|
||||
# Navigation accessors for rule set handles.
|
||||
tree_node_rule_sets.each do |rule_set|
|
||||
rtype = h_type(rule_set.name)
|
||||
out << "impl<'a> #{rtype}<'a> {"
|
||||
each_tree_field(rule_set) do |rt, field_name, child_type, slot|
|
||||
out << " /** Access the #{field_name} child node. */"
|
||||
out << " pub fn #{rust_ident(field_name)}(&self) -> #{child_type}<'a> {"
|
||||
out << " if self.id == 0 {"
|
||||
out << " return #{child_type} { context: self.context, id: 0 };"
|
||||
out << " }"
|
||||
out << " #{child_type} { context: self.context, id: self.context.#{p}tree_children[self.context.#{p}tree_nodes[self.id as usize].child_offset as usize + #{slot}] }"
|
||||
out << " }"
|
||||
end
|
||||
out << "}"
|
||||
end
|
||||
out.join("\n")
|
||||
end
|
||||
|
||||
# Get the lex function to use.
|
||||
#
|
||||
# @return [String]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user