{% macro render_nodes(language) -%}
{%- set target = model.ir_languages[language].target -%}
use std::rc::Rc;
use std::vec::Vec;
use crate::cst::TerminalNode;
use metaslang_cst::nodes::NodeId;
//
// Sequences:
//
{% for parent_type, sequence in target.sequences %}
pub type {{ parent_type }} = Rc<{{ parent_type }}Struct>;
#[derive(Debug)]
pub struct {{ parent_type }}Struct {
pub node_id: NodeId,
{%- for field in sequence.fields %}
pub {{ field.label | snake_case }}:
{%- if field.type.kind == "Terminal" -%}
{%- if field.is_optional -%}
Option<Rc<TerminalNode>>,
{%- else -%}
Rc<TerminalNode>,
{%- endif -%}
{%- elif field.type.kind == "UniqueTerminal" -%}
{%- if field.is_optional -%}
bool,
{%- else -%}
Rc<TerminalNode>,
{%- endif -%}
{%- else -%}
{%- if field.is_optional -%}
Option<{{ field.type.name }}>,
{%- else -%}
{{ field.type.name }},
{%- endif -%}
{%- endif -%}
{% endfor -%}
}
{% endfor %}
//
// Choices:
//
{% for parent_type, choice in target.choices %}
#[derive(Clone, Debug)]
pub enum {{ parent_type }} {
{% for nonterminal in choice.variants | filter(attribute="kind", value="Nonterminal") -%}
{{ nonterminal.name }}({{ nonterminal.name }}),
{%- endfor -%}
{% for terminal in choice.variants | filter(attribute="kind", value="Terminal") -%}
{{ terminal.name }}(Rc<TerminalNode>),
{%- endfor -%}
{% for terminal in choice.variants | filter(attribute="kind", value="UniqueTerminal") -%}
{{ terminal.name }},
{%- endfor -%}
}
{% endfor %}
//
// Repeated & Separated
//
{% for parent_type, collection in target.collections %}
pub type {{ parent_type }} = Vec<
{%- if collection.item_type.is_terminal -%}
Rc<TerminalNode>
{%- else -%}
{{ collection.item_type.name }}
{%- endif -%}
>;
{% endfor %}
{% endmacro render_nodes %}