#[cfg(feature = "deserialize")]
use serde::Deserialize;
#[cfg(feature = "serialize")]
use serde::Serialize;
use std::{fmt::Debug, ops::Deref, path::PathBuf, rc::Rc};
#[cfg(feature = "dump")]
use structdump_derive::Codegen;
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub enum FieldName {
Fixed(Rc<str>),
Dyn(LocExpr),
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Visibility {
Normal,
Hidden,
Unhide,
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub struct FieldMember {
pub name: FieldName,
pub plus: bool,
pub params: Option<ParamsDesc>,
pub visibility: Visibility,
pub value: LocExpr,
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub enum Member {
Field(FieldMember),
BindStmt(BindSpec),
AssertStmt(AssertStmt),
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum UnaryOpType {
Plus,
Minus,
BitNot,
Not,
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BinaryOpType {
Mul,
Div,
Add,
Sub,
Lhs,
Rhs,
Lt,
Gt,
Lte,
Gte,
BitAnd,
BitOr,
BitXor,
And,
Or,
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub struct Param(pub Rc<str>, pub Option<LocExpr>);
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub struct ParamsDesc(pub Rc<Vec<Param>>);
impl Deref for ParamsDesc {
type Target = Vec<Param>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub struct Arg(pub Option<String>, pub LocExpr);
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub struct ArgsDesc(pub Vec<Arg>);
impl Deref for ArgsDesc {
type Target = Vec<Arg>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub struct BindSpec {
pub name: Rc<str>,
pub params: Option<ParamsDesc>,
pub value: LocExpr,
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub struct IfSpecData(pub LocExpr);
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub struct ForSpecData(pub Rc<str>, pub LocExpr);
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub enum CompSpec {
IfSpec(IfSpecData),
ForSpec(ForSpecData),
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub struct ObjComp {
pub pre_locals: Vec<BindSpec>,
pub key: LocExpr,
pub value: LocExpr,
pub post_locals: Vec<BindSpec>,
pub compspecs: Vec<CompSpec>,
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub enum ObjBody {
MemberList(Vec<Member>),
ObjComp(ObjComp),
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum LiteralType {
This,
Super,
Dollar,
Null,
True,
False,
}
#[derive(Debug, PartialEq)]
pub struct SliceDesc {
pub start: Option<LocExpr>,
pub end: Option<LocExpr>,
pub step: Option<LocExpr>,
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Debug, PartialEq)]
pub enum Expr {
Literal(LiteralType),
Str(Rc<str>),
Num(f64),
Var(Rc<str>),
Arr(Vec<LocExpr>),
ArrComp(LocExpr, Vec<CompSpec>),
Obj(ObjBody),
ObjExtend(LocExpr, ObjBody),
Parened(LocExpr),
UnaryOp(UnaryOpType, LocExpr),
BinaryOp(LocExpr, BinaryOpType, LocExpr),
AssertExpr(AssertStmt, LocExpr),
LocalExpr(Vec<BindSpec>, LocExpr),
Import(PathBuf),
ImportStr(PathBuf),
ErrorStmt(LocExpr),
Apply(LocExpr, ArgsDesc, bool),
Index(LocExpr, LocExpr),
Function(ParamsDesc, LocExpr),
IfElse {
cond: IfSpecData,
cond_then: LocExpr,
cond_else: Option<LocExpr>,
},
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Clone, PartialEq)]
pub struct ExprLocation(pub Rc<PathBuf>, pub usize, pub usize);
impl Debug for ExprLocation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)
}
}
#[cfg_attr(feature = "dump", derive(Codegen))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
#[derive(Clone, PartialEq)]
pub struct LocExpr(pub Rc<Expr>, pub Option<ExprLocation>);
impl Debug for LocExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?} from {:?}", self.0, self.1)
}
}
#[macro_export]
macro_rules! loc_expr {
($expr:expr, $need_loc:expr,($name:expr, $start:expr, $end:expr)) => {
LocExpr(
std::rc::Rc::new($expr),
if $need_loc {
Some(ExprLocation($name, $start, $end))
} else {
None
},
)
};
}
#[macro_export]
macro_rules! loc_expr_todo {
($expr:expr) => {
LocExpr(Rc::new($expr), None)
};
}