slang_solidity 1.3.5

A modular set of compiler APIs empowering the next generation of Solidity code analysis and developer tooling. Written in Rust and distributed in multiple languages.
Documentation
{% 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 %}