use alloc::{
boxed::Box,
string::String,
vec::Vec,
};
use core::{
fmt,
fmt::Display,
};
use battler_data::Fraction;
#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct BoolLiteral(pub bool);
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NumberLiteral {
Unsigned(Fraction<u64>),
Signed(Fraction<i64>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct StringLiteral(pub String);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct List(pub Values);
#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct Identifier(pub String);
#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct ValueExpr(pub Box<Expr>);
#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct ValueFunctionCall(pub FunctionCall);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ValueAssignment(pub Box<Assignment>);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FormattedString {
pub template: StringLiteral,
pub args: Values,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Var {
pub name: Identifier,
pub member_access: Vec<Identifier>,
}
impl Var {
pub fn full_name(&self) -> String {
let mut name = self.name.0.clone();
for member in &self.member_access {
name.push('.');
name.push_str(&member.0);
}
name
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Value {
UndefinedLiteral,
BoolLiteral(BoolLiteral),
NumberLiteral(NumberLiteral),
StringLiteral(StringLiteral),
List(List),
Var(Var),
ValueExpr(ValueExpr),
ValueFunctionCall(ValueFunctionCall),
ValueAssignment(ValueAssignment),
FormattedString(FormattedString),
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct Values(pub Vec<Value>);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FunctionCall {
pub function: Identifier,
pub args: Values,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Assignment {
pub lhs: Var,
pub rhs: Expr,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Operator {
Not,
UnaryPlus,
Exponent,
Multiply,
Divide,
Modulo,
Add,
Subtract,
LessThan,
LessThanOrEqual,
GreaterThan,
GreaterThanOrEqual,
Has,
HasAny,
Equal,
NotEqual,
And,
Or,
}
impl From<Operator> for &str {
fn from(value: Operator) -> Self {
match value {
Operator::Not => "!",
Operator::UnaryPlus => "+",
Operator::Exponent => "^",
Operator::Multiply => "*",
Operator::Divide => "/",
Operator::Modulo => "%",
Operator::Add => "+",
Operator::Subtract => "-",
Operator::LessThan => "<",
Operator::LessThanOrEqual => "<=",
Operator::GreaterThan => ">",
Operator::GreaterThanOrEqual => ">=",
Operator::Has => "has",
Operator::HasAny => "hasany",
Operator::Equal => "==",
Operator::NotEqual => "!=",
Operator::And => "and",
Operator::Or => "or",
}
}
}
impl Display for Operator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", Into::<&str>::into(*self))
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Expr {
Value(Value),
PrefixUnaryExpr(PrefixUnaryExpr),
BinaryExpr(BinaryExpr),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PrefixUnaryExpr {
pub ops: Vec<Operator>,
pub expr: Box<Expr>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BinaryExprRhs {
pub op: Operator,
pub expr: Box<Expr>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BinaryExpr {
pub lhs: Box<Expr>,
pub rhs: Vec<BinaryExprRhs>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct IfStatement(pub Expr);
#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct ElseIfStatement(pub Option<IfStatement>);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ForEachStatement {
pub var: Var,
pub range: Value,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct ReturnStatement(pub Option<Expr>);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ContinueStatement;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BreakStatement;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RequireStatement {
pub condition: Expr,
pub else_return: Option<Option<Expr>>,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub enum Statement {
#[default]
Empty,
FunctionCall(FunctionCall),
Assignment(Assignment),
IfStatement(IfStatement),
ElseIfStatement(ElseIfStatement),
ForEachStatement(ForEachStatement),
ReturnStatement(ReturnStatement),
Continue(ContinueStatement),
Break(BreakStatement),
RequireStatement(RequireStatement),
}