use crate::parser::ast::literals::{Literal, MacroDelimiter};
use crate::parser::ast::operators::{BinaryOp, CompoundOp, UnaryOp};
use crate::parser::ast::ownership::OwnershipHint;
use crate::parser::ast::types::{AssociatedType, SourceLocation, Type, TypeParam};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Parameter<'ast> {
pub name: String, pub pattern: Option<Pattern<'ast>>, pub type_: Type,
pub ownership: OwnershipHint,
pub is_mutable: bool, pub decorators: Vec<Decorator<'ast>>, }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Decorator<'ast> {
pub name: String,
pub arguments: Vec<(String, &'ast Expression<'ast>)>, }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FunctionDecl<'ast> {
pub name: String,
pub is_pub: bool, pub is_extern: bool, pub type_params: Vec<TypeParam>, pub where_clause: Vec<(String, Vec<String>)>, pub decorators: Vec<Decorator<'ast>>,
pub is_async: bool,
pub parameters: Vec<Parameter<'ast>>,
pub return_type: Option<Type>,
pub return_decorators: Vec<Decorator<'ast>>, pub body: Vec<&'ast Statement<'ast>>, pub parent_type: Option<String>, pub impl_trait: Option<String>,
pub doc_comment: Option<String>, }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StructField<'ast> {
pub name: String,
pub field_type: Type,
pub decorators: Vec<Decorator<'ast>>,
pub is_pub: bool,
pub doc_comment: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StructDecl<'ast> {
pub name: String,
pub is_pub: bool, pub is_extern: bool, pub type_params: Vec<TypeParam>, pub where_clause: Vec<(String, Vec<String>)>, pub fields: Vec<StructField<'ast>>,
pub tuple_fields: Option<Vec<Type>>, pub decorators: Vec<Decorator<'ast>>,
pub doc_comment: Option<String>, }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct EnumVariant {
pub name: String,
pub data: EnumVariantData,
pub doc_comment: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum EnumVariantData {
Unit, Tuple(Vec<Type>), Struct(Vec<(String, Type)>), }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct EnumDecl {
pub name: String,
pub is_pub: bool, pub type_params: Vec<TypeParam>, pub variants: Vec<EnumVariant>,
pub doc_comment: Option<String>, }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Statement<'ast> {
Let {
pattern: Pattern<'ast>,
mutable: bool,
type_: Option<Type>,
value: &'ast Expression<'ast>,
else_block: Option<Vec<&'ast Statement<'ast>>>,
location: SourceLocation,
},
Const {
name: String,
type_: Type,
value: &'ast Expression<'ast>,
location: SourceLocation,
},
Static {
name: String,
mutable: bool,
type_: Type,
value: &'ast Expression<'ast>,
location: SourceLocation,
},
Assignment {
target: &'ast Expression<'ast>,
value: &'ast Expression<'ast>,
compound_op: Option<CompoundOp>,
location: SourceLocation,
},
Return {
value: Option<&'ast Expression<'ast>>,
location: SourceLocation,
},
Expression {
expr: &'ast Expression<'ast>,
location: SourceLocation,
},
If {
condition: &'ast Expression<'ast>,
then_block: Vec<&'ast Statement<'ast>>,
else_block: Option<Vec<&'ast Statement<'ast>>>,
location: SourceLocation,
},
Match {
value: &'ast Expression<'ast>,
arms: Vec<MatchArm<'ast>>,
location: SourceLocation,
},
For {
pattern: Pattern<'ast>,
iterable: &'ast Expression<'ast>,
body: Vec<&'ast Statement<'ast>>,
location: SourceLocation,
},
Loop {
body: Vec<&'ast Statement<'ast>>,
location: SourceLocation,
},
While {
condition: &'ast Expression<'ast>,
body: Vec<&'ast Statement<'ast>>,
location: SourceLocation,
},
Thread {
body: Vec<&'ast Statement<'ast>>,
location: SourceLocation,
},
Async {
body: Vec<&'ast Statement<'ast>>,
location: SourceLocation,
},
Defer {
statement: &'ast Statement<'ast>,
location: SourceLocation,
},
Break {
location: SourceLocation,
},
Continue {
location: SourceLocation,
},
Use {
path: Vec<String>,
alias: Option<String>,
is_pub: bool, location: SourceLocation,
},
}
impl<'ast> Statement<'ast> {
pub fn location(&self) -> SourceLocation {
match self {
Statement::Let { location, .. } => location.clone(),
Statement::Const { location, .. } => location.clone(),
Statement::Static { location, .. } => location.clone(),
Statement::Assignment { location, .. } => location.clone(),
Statement::Return { location, .. } => location.clone(),
Statement::Expression { location, .. } => location.clone(),
Statement::If { location, .. } => location.clone(),
Statement::Match { location, .. } => location.clone(),
Statement::For { location, .. } => location.clone(),
Statement::Loop { location, .. } => location.clone(),
Statement::While { location, .. } => location.clone(),
Statement::Thread { location, .. } => location.clone(),
Statement::Async { location, .. } => location.clone(),
Statement::Defer { location, .. } => location.clone(),
Statement::Break { location, .. } => location.clone(),
Statement::Continue { location, .. } => location.clone(),
Statement::Use { location, .. } => location.clone(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MatchArm<'ast> {
pub pattern: Pattern<'ast>,
pub guard: Option<&'ast Expression<'ast>>, pub body: &'ast Expression<'ast>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum EnumPatternBinding<'ast> {
None, Wildcard, Single(String), Tuple(Vec<Pattern<'ast>>), Struct(Vec<(String, Pattern<'ast>)>, bool), }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Pattern<'ast> {
Wildcard,
Identifier(String),
EnumVariant(String, EnumPatternBinding<'ast>), Literal(Literal),
Tuple(Vec<Pattern<'ast>>), Or(Vec<Pattern<'ast>>), Reference(&'ast Pattern<'ast>), Ref(String), RefMut(String), MutBinding(String), }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Expression<'ast> {
Literal {
value: Literal,
location: SourceLocation,
},
Identifier {
name: String,
location: SourceLocation,
},
Binary {
left: &'ast Expression<'ast>,
op: BinaryOp,
right: &'ast Expression<'ast>,
location: SourceLocation,
},
Unary {
op: UnaryOp,
operand: &'ast Expression<'ast>,
location: SourceLocation,
},
Call {
function: &'ast Expression<'ast>,
arguments: Vec<(Option<String>, &'ast Expression<'ast>)>, location: SourceLocation,
},
MethodCall {
object: &'ast Expression<'ast>,
method: String,
type_args: Option<Vec<Type>>, arguments: Vec<(Option<String>, &'ast Expression<'ast>)>, location: SourceLocation,
},
FieldAccess {
object: &'ast Expression<'ast>,
field: String,
location: SourceLocation,
},
StructLiteral {
name: String,
fields: Vec<(String, &'ast Expression<'ast>)>,
location: SourceLocation,
},
MapLiteral {
pairs: Vec<(&'ast Expression<'ast>, &'ast Expression<'ast>)>, location: SourceLocation,
},
Range {
start: &'ast Expression<'ast>,
end: &'ast Expression<'ast>,
inclusive: bool,
location: SourceLocation,
},
Closure {
parameters: Vec<String>,
body: &'ast Expression<'ast>,
location: SourceLocation,
},
Cast {
expr: &'ast Expression<'ast>,
type_: Type,
location: SourceLocation,
},
Index {
object: &'ast Expression<'ast>,
index: &'ast Expression<'ast>,
location: SourceLocation,
},
Tuple {
elements: Vec<&'ast Expression<'ast>>, location: SourceLocation,
},
Array {
elements: Vec<&'ast Expression<'ast>>, location: SourceLocation,
},
MacroInvocation {
name: String,
args: Vec<&'ast Expression<'ast>>,
delimiter: MacroDelimiter, is_repeat: bool, location: SourceLocation,
},
TryOp {
expr: &'ast Expression<'ast>, location: SourceLocation,
},
Await {
expr: &'ast Expression<'ast>, location: SourceLocation,
},
ChannelSend {
channel: &'ast Expression<'ast>,
value: &'ast Expression<'ast>,
location: SourceLocation,
},
ChannelRecv {
channel: &'ast Expression<'ast>,
location: SourceLocation,
},
Block {
statements: Vec<&'ast Statement<'ast>>,
is_unsafe: bool,
location: SourceLocation,
},
}
impl<'ast> Expression<'ast> {
pub fn location(&self) -> SourceLocation {
match self {
Expression::Literal { location, .. } => location.clone(),
Expression::Identifier { location, .. } => location.clone(),
Expression::Binary { location, .. } => location.clone(),
Expression::Unary { location, .. } => location.clone(),
Expression::Call { location, .. } => location.clone(),
Expression::MethodCall { location, .. } => location.clone(),
Expression::FieldAccess { location, .. } => location.clone(),
Expression::StructLiteral { location, .. } => location.clone(),
Expression::MapLiteral { location, .. } => location.clone(),
Expression::Range { location, .. } => location.clone(),
Expression::Closure { location, .. } => location.clone(),
Expression::Cast { location, .. } => location.clone(),
Expression::Index { location, .. } => location.clone(),
Expression::Tuple { location, .. } => location.clone(),
Expression::Array { location, .. } => location.clone(),
Expression::MacroInvocation { location, .. } => location.clone(),
Expression::TryOp { location, .. } => location.clone(),
Expression::Await { location, .. } => location.clone(),
Expression::ChannelSend { location, .. } => location.clone(),
Expression::ChannelRecv { location, .. } => location.clone(),
Expression::Block { location, .. } => location.clone(),
}
}
}
impl std::hash::Hash for Literal {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
match self {
Literal::Int(i) => {
0u8.hash(state);
i.hash(state);
}
Literal::IntSuffixed(i, suffix) => {
5u8.hash(state);
i.hash(state);
suffix.hash(state);
}
Literal::Float(f) => {
1u8.hash(state);
f.to_bits().hash(state);
}
Literal::String(s) => {
2u8.hash(state);
s.hash(state);
}
Literal::Char(c) => {
3u8.hash(state);
c.hash(state);
}
Literal::Bool(b) => {
4u8.hash(state);
b.hash(state);
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TraitDecl<'ast> {
pub name: String,
pub generics: Vec<String>, pub supertraits: Vec<String>, pub associated_types: Vec<AssociatedType>, pub methods: Vec<TraitMethod<'ast>>,
pub doc_comment: Option<String>, }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TraitMethod<'ast> {
pub name: String,
pub parameters: Vec<Parameter<'ast>>,
pub return_type: Option<Type>,
pub is_async: bool,
pub body: Option<Vec<&'ast Statement<'ast>>>, pub doc_comment: Option<String>, }
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ImplBlock<'ast> {
pub type_name: String,
pub type_params: Vec<TypeParam>, pub where_clause: Vec<(String, Vec<String>)>, pub trait_name: Option<String>, pub trait_type_args: Option<Vec<Type>>, pub associated_types: Vec<AssociatedType>, pub functions: Vec<FunctionDecl<'ast>>,
pub decorators: Vec<Decorator<'ast>>,
pub is_extern: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Item<'ast> {
Function {
decl: FunctionDecl<'ast>,
location: SourceLocation,
},
Struct {
decl: StructDecl<'ast>,
location: SourceLocation,
},
Enum {
decl: EnumDecl,
location: SourceLocation,
},
Trait {
decl: TraitDecl<'ast>,
location: SourceLocation,
},
Impl {
block: ImplBlock<'ast>,
location: SourceLocation,
},
Const {
name: String,
is_pub: bool,
type_: Type,
value: &'ast Expression<'ast>,
location: SourceLocation,
},
Static {
name: String,
mutable: bool,
type_: Type,
value: &'ast Expression<'ast>,
location: SourceLocation,
},
ExternLet {
name: String,
type_: Type,
decorators: Vec<Decorator<'ast>>,
is_pub: bool,
location: SourceLocation,
},
Use {
path: Vec<String>,
alias: Option<String>,
is_pub: bool, location: SourceLocation,
}, Mod {
name: String,
items: Vec<Item<'ast>>,
is_public: bool,
location: SourceLocation,
}, BoundAlias {
name: String,
traits: Vec<String>,
location: SourceLocation,
}, TypeAlias {
name: String,
target: Type,
is_pub: bool,
location: SourceLocation,
}, }
impl<'ast> Item<'ast> {
pub fn location(&self) -> SourceLocation {
match self {
Item::Function { location, .. } => location.clone(),
Item::Struct { location, .. } => location.clone(),
Item::Enum { location, .. } => location.clone(),
Item::Trait { location, .. } => location.clone(),
Item::Impl { location, .. } => location.clone(),
Item::Const { location, .. } => location.clone(),
Item::Static { location, .. } => location.clone(),
Item::ExternLet { location, .. } => location.clone(),
Item::Use { location, .. } => location.clone(),
Item::Mod { location, .. } => location.clone(),
Item::BoundAlias { location, .. } => location.clone(),
Item::TypeAlias { location, .. } => location.clone(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Program<'ast> {
pub items: Vec<Item<'ast>>,
}