macro_rules! ast_node {
(
$(#[$struct_meta:meta])*
struct $name:ident {
$(
$(#[$field_meta:meta])*
$field:ident: $ty:ty
),* $(,)?
}
) => {
$(#[$struct_meta])*
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct $name {
pub id: usize,
#[serde(with = "serde_helpers::display_from_str")]
pub src: SourceLocation,
$(
$(#[$field_meta])*
pub $field: $ty
),*
}
};
}
macro_rules! expr_node {
(
$(#[$struct_meta:meta])*
struct $name:ident {
$(
$(#[$field_meta:meta])*
$field:ident: $ty:ty
),* $(,)*
}
) => {
ast_node!(
$(#[$struct_meta])*
struct $name {
#[serde(default, deserialize_with = "serde_helpers::default_for_null")]
argument_types: Vec<TypeDescriptions>,
#[serde(default)]
is_constant: bool,
#[serde(default)]
is_l_value: bool,
#[serde(default)]
is_pure: bool,
#[serde(default)]
l_value_requested: bool,
type_descriptions: TypeDescriptions,
$(
$(#[$field_meta])*
$field: $ty
),*
}
);
}
}
macro_rules! stmt_node {
(
$(#[$struct_meta:meta])*
struct $name:ident {
$(
$(#[$field_meta:meta])*
$field:ident: $ty:ty
),* $(,)*
}
) => {
ast_node!(
$(#[$struct_meta])*
struct $name {
// TODO
documentation: Option<String>,
$(
$(#[$field_meta])*
$field: $ty
),*
}
);
}
}
macro_rules! node_group {
($group:ident; $( $name:ident ),* $(,)*) => {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "nodeType")]
pub enum $group {
$(
$name(Box<$name>),
)*
}
};
}
pub(crate) use ast_node;
pub(crate) use expr_node;
pub(crate) use node_group;
pub(crate) use stmt_node;