1use std::{fmt::Debug, rc::Rc};23#[derive(Debug, Clone, PartialEq)]4pub enum FieldName {5 6 Fixed(String),7 8 Dyn(LocExpr),9}1011#[derive(Debug, Clone, PartialEq)]12pub enum Visibility {13 14 Normal,15 16 Hidden,17 18 Unhide,19}2021#[derive(Debug, Clone, PartialEq)]22pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);2324#[derive(Debug, Clone, PartialEq)]25pub struct FieldMember {26 pub name: FieldName,27 pub plus: bool,28 pub params: Option<ParamsDesc>,29 pub visibility: Visibility,30 pub value: LocExpr,31}3233#[derive(Debug, Clone, PartialEq)]34pub enum Member {35 Field(FieldMember),36 BindStmt(BindSpec),37 AssertStmt(AssertStmt),38}3940#[derive(Debug, Clone, Copy, PartialEq)]41pub enum UnaryOpType {42 Plus,43 Minus,44 BitNot,45 Not,46}4748#[derive(Debug, Clone, Copy, PartialEq)]49pub enum BinaryOpType {50 Mul,51 Div,52 Mod,5354 Add,55 Sub,5657 Lhs,58 Rhs,5960 Lt,61 Gt,62 Lte,63 Gte,6465 In,6667 Eq,68 Ne,6970 BitAnd,71 BitOr,72 BitXor,7374 And,75 Or,76}777879#[derive(Debug, Clone, PartialEq)]80pub struct Param(pub String, pub Option<LocExpr>);8182#[derive(Debug, Clone, PartialEq)]83pub struct ParamsDesc(pub Vec<Param>);84impl ParamsDesc {85 pub fn with_defaults(&self) -> Vec<Param> {86 self.0.iter().filter(|e| e.1.is_some()).cloned().collect()87 }88}8990#[derive(Debug, Clone, PartialEq)]91pub struct Arg(pub Option<String>, pub LocExpr);92#[derive(Debug, Clone, PartialEq)]93pub struct ArgsDesc(pub Vec<Arg>);9495#[derive(Debug, Clone, PartialEq)]96pub struct BindSpec {97 pub name: String,98 pub params: Option<ParamsDesc>,99 pub value: LocExpr,100}101102#[derive(Debug, Clone, PartialEq)]103pub struct IfSpecData(pub LocExpr);104#[derive(Debug, Clone, PartialEq)]105pub struct ForSpecData(pub String, pub LocExpr);106107#[derive(Debug, Clone, PartialEq)]108pub enum CompSpec {109 IfSpec(IfSpecData),110 ForSpec(ForSpecData),111}112113#[derive(Debug, Clone, PartialEq)]114pub enum ObjBody {115 MemberList(Vec<Member>),116 ObjComp {117 pre_locals: Vec<BindSpec>,118 key: LocExpr,119 value: LocExpr,120 post_locals: Vec<BindSpec>,121 first: ForSpecData,122 rest: Vec<CompSpec>,123 },124}125126#[derive(Debug, Clone, PartialEq)]127pub enum LiteralType {128 This,129 Super,130 Dollar,131 Null,132 True,133 False,134}135136#[derive(Debug, Clone, PartialEq)]137pub struct SliceDesc {138 pub start: Option<LocExpr>,139 pub end: Option<LocExpr>,140 pub step: Option<LocExpr>,141}142143144#[derive(Debug, Clone, PartialEq)]145pub enum Expr {146 Literal(LiteralType),147148 149 Str(String),150 151 Num(f64),152 153 Var(String),154155 156 Arr(Vec<LocExpr>),157 158 159 160 161 162 163 164 165 166 167 168 ArrComp(LocExpr, ForSpecData, Vec<CompSpec>),169170 171 Obj(ObjBody),172 173 ObjExtend(LocExpr, ObjBody),174175 176 Parened(LocExpr),177178 179 180 Params(ParamsDesc),181 182 183 Args(ArgsDesc),184185 186 UnaryOp(UnaryOpType, LocExpr),187 188 BinaryOp(LocExpr, BinaryOpType, LocExpr),189 190 AssertExpr(AssertStmt, LocExpr),191 192 LocalExpr(Vec<BindSpec>, LocExpr),193194 195 Bind(BindSpec),196 197 Import(String),198 199 ImportStr(String),200 201 Error(LocExpr),202 203 Apply(LocExpr, ArgsDesc),204 205 Select(LocExpr, String),206 207 Index(LocExpr, LocExpr),208 209 Slice(LocExpr, SliceDesc),210 211 Function(ParamsDesc, LocExpr),212 213 IfElse {214 cond: IfSpecData,215 cond_then: LocExpr,216 cond_else: Option<LocExpr>,217 },218 219 IfSpec(IfSpecData),220 221 ForSpec(ForSpecData),222}223224225#[derive(Clone, PartialEq)]226pub struct ExprLocation(pub String, pub usize, pub usize);227impl Debug for ExprLocation {228 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {229 write!(f, "{}:{:?}-{:?}", self.0, self.1, self.2)230 }231}232233234#[derive(Clone, PartialEq)]235pub struct LocExpr(pub Rc<Expr>, pub Option<Rc<ExprLocation>>);236impl Debug for LocExpr {237 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {238 write!(f, "{:?} from {:?}", self.0, self.1)239 }240}241242243#[macro_export]244macro_rules! loc_expr {245 ($expr:expr, $need_loc:expr, ($name:expr, $start:expr, $end:expr)) => {246 LocExpr(247 std::rc::Rc::new($expr),248 if $need_loc {249 Some(std::rc::Rc::new(ExprLocation($name.to_owned(), $start, $end)))250 } else {251 None252 },253 )254 };255}256257258#[macro_export]259macro_rules! loc_expr_todo {260 ($expr:expr) => {261 LocExpr(Rc::new($expr), None)262 };263}