use crate::span::Span;
#[derive(Debug, Clone, PartialEq)]
pub struct SourceFile {
pub statements: Vec<Statement>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Statement {
Include { path: String, span: Span },
Use { path: String, span: Span },
Assignment {
name: String,
expr: Expr,
span: Span,
},
ModuleDefinition {
name: String,
params: Vec<Parameter>,
body: Vec<Self>,
span: Span,
},
FunctionDefinition {
name: String,
params: Vec<Parameter>,
body: Expr,
span: Span,
},
ModuleInstantiation {
name: String,
args: Vec<Argument>,
children: Vec<Self>,
modifiers: Modifiers,
span: Span,
},
IfElse {
condition: Expr,
then_body: Vec<Self>,
else_body: Option<Vec<Self>>,
span: Span,
},
Block { body: Vec<Self>, span: Span },
Empty { span: Span },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[allow(clippy::struct_excessive_bools)]
pub struct Modifiers {
pub root: bool,
pub highlight: bool,
pub background: bool,
pub disable: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Expr {
pub kind: ExprKind,
pub span: Span,
}
impl Expr {
#[must_use]
pub const fn new(kind: ExprKind, span: Span) -> Self {
Self { kind, span }
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ExprKind {
Number(f64),
String(String),
BoolTrue,
BoolFalse,
Undef,
Identifier(String),
UnaryOp { op: UnaryOp, operand: Box<Expr> },
BinaryOp {
op: BinaryOp,
left: Box<Expr>,
right: Box<Expr>,
},
Ternary {
condition: Box<Expr>,
then_expr: Box<Expr>,
else_expr: Box<Expr>,
},
FunctionCall {
callee: Box<Expr>,
args: Vec<Argument>,
},
Index { object: Box<Expr>, index: Box<Expr> },
MemberAccess { object: Box<Expr>, member: String },
Vector(Vec<Expr>),
Range {
start: Box<Expr>,
step: Option<Box<Expr>>,
end: Box<Expr>,
},
Let {
assignments: Vec<Argument>,
body: Box<Expr>,
},
Assert {
args: Vec<Argument>,
body: Option<Box<Expr>>,
},
Echo {
args: Vec<Argument>,
body: Option<Box<Expr>>,
},
AnonymousFunction {
params: Vec<Parameter>,
body: Box<Expr>,
},
LcFor {
assignments: Vec<Argument>,
body: Box<Expr>,
},
LcForC {
init: Vec<Argument>,
condition: Box<Expr>,
update: Vec<Argument>,
body: Box<Expr>,
},
LcIf {
condition: Box<Expr>,
then_expr: Box<Expr>,
else_expr: Option<Box<Expr>>,
},
LcLet {
assignments: Vec<Argument>,
body: Box<Expr>,
},
LcEach { body: Box<Expr> },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnaryOp {
Negate,
Not,
Plus,
BinaryNot,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinaryOp {
LogicalOr,
LogicalAnd,
Equal,
NotEqual,
Less,
LessEqual,
Greater,
GreaterEqual,
BitwiseOr,
BitwiseAnd,
ShiftLeft,
ShiftRight,
Add,
Subtract,
Multiply,
Divide,
Modulo,
Exponent,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Parameter {
pub name: String,
pub default: Option<Expr>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Argument {
pub name: Option<String>,
pub value: Expr,
pub span: Span,
}
impl Statement {
#[must_use]
pub const fn span(&self) -> Span {
match self {
Self::Include { span, .. }
| Self::Use { span, .. }
| Self::Assignment { span, .. }
| Self::ModuleDefinition { span, .. }
| Self::FunctionDefinition { span, .. }
| Self::ModuleInstantiation { span, .. }
| Self::IfElse { span, .. }
| Self::Block { span, .. }
| Self::Empty { span, .. } => *span,
}
}
}