use crate::span::Span;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Ident {
pub name: String,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TypeExpr {
pub name: Ident,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Program {
pub items: Vec<Item>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Item {
Function(Function),
Struct(StructDecl),
Mod(ModDecl),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Function {
pub name: Ident,
pub is_pub: bool,
pub params: Vec<Param>,
pub return_type: Option<TypeExpr>,
pub body: Block,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Param {
pub name: Ident,
pub mutable: bool,
pub ty: TypeExpr,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct StructDecl {
pub name: Ident,
pub is_pub: bool,
pub fields: Vec<FieldDecl>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct FieldDecl {
pub name: Ident,
pub ty: TypeExpr,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ModDecl {
pub name: Ident,
pub is_pub: bool,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Stmt {
Let {
name: Ident,
mutable: bool,
ty: Option<TypeExpr>,
value: Expr,
span: Span,
},
Assign {
target: Expr,
value: Expr,
span: Span,
},
Expr {
expr: Expr,
span: Span,
has_semi: bool,
},
Return {
value: Option<Expr>,
span: Span,
},
While {
cond: Expr,
body: Block,
span: Span,
},
Break {
span: Span,
},
Continue {
span: Span,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct Block {
pub stmts: Vec<Stmt>,
pub tail: Option<Box<Expr>>,
pub span: Span,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnaryOp {
Neg,
Not,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinaryOp {
Or,
And,
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
Add,
Sub,
Mul,
Div,
Rem,
}
impl BinaryOp {
pub fn as_str(self) -> &'static str {
match self {
BinaryOp::Or => "||",
BinaryOp::And => "&&",
BinaryOp::Eq => "==",
BinaryOp::Ne => "!=",
BinaryOp::Lt => "<",
BinaryOp::Le => "<=",
BinaryOp::Gt => ">",
BinaryOp::Ge => ">=",
BinaryOp::Add => "+",
BinaryOp::Sub => "-",
BinaryOp::Mul => "*",
BinaryOp::Div => "/",
BinaryOp::Rem => "%",
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Expr {
pub kind: ExprKind,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ExprKind {
Integer(String),
Float(String),
Bool(bool),
String(String),
Path {
module: Option<Ident>,
name: Ident,
},
Unary {
op: UnaryOp,
operand: Box<Expr>,
},
Binary {
op: BinaryOp,
lhs: Box<Expr>,
rhs: Box<Expr>,
},
Call {
callee: Box<Expr>,
args: Vec<Expr>,
},
Field {
base: Box<Expr>,
name: Ident,
},
StructLit {
name: Ident,
fields: Vec<(Ident, Expr)>,
},
Block(Block),
If {
cond: Box<Expr>,
then: Block,
else_: Option<Block>,
},
Intrinsic {
name: Ident,
format: (String, Span),
args: Vec<Expr>,
},
}