1use std::{2 fmt::{Debug, Display},3 rc::Rc,4};56#[derive(Debug, Clone, PartialEq)]7pub enum FieldName {8 9 Fixed(String),10 11 Dyn(LocExpr),12}1314#[derive(Debug, Clone, PartialEq)]15pub enum Visibility {16 17 Normal,18 19 Hidden,20 21 Unhide,22}2324#[derive(Debug, Clone, PartialEq)]25pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);2627#[derive(Debug, Clone, PartialEq)]28pub struct FieldMember {29 pub name: FieldName,30 pub plus: bool,31 pub params: Option<ParamsDesc>,32 pub visibility: Visibility,33 pub value: LocExpr,34}3536#[derive(Debug, Clone, PartialEq)]37pub enum Member {38 Field(FieldMember),39 BindStmt(BindSpec),40 AssertStmt(AssertStmt),41}4243#[derive(Debug, Clone, Copy, PartialEq)]44pub enum UnaryOpType {45 Plus,46 Minus,47 BitNot,48 Not,49}5051#[derive(Debug, Clone, Copy, PartialEq)]52pub enum BinaryOpType {53 Mul,54 Div,55 Mod,5657 Add,58 Sub,5960 Lhs,61 Rhs,6263 Lt,64 Gt,65 Lte,66 Gte,6768 In,6970 Eq,71 Ne,7273 BitAnd,74 BitOr,75 BitXor,7677 And,78 Or,79}808182#[derive(Debug, Clone, PartialEq)]83pub struct Param(pub String, pub Option<LocExpr>);8485#[derive(Debug, Clone, PartialEq)]86pub struct ParamsDesc(pub Vec<Param>);87impl ParamsDesc {88 pub fn with_defaults(&self) -> Vec<Param> {89 self.0.iter().filter(|e| e.1.is_some()).cloned().collect()90 }91}9293#[derive(Debug, Clone, PartialEq)]94pub struct Arg(pub Option<String>, pub LocExpr);95#[derive(Debug, Clone, PartialEq)]96pub struct ArgsDesc(pub Vec<Arg>);9798#[derive(Debug, Clone, PartialEq)]99pub struct BindSpec {100 pub name: String,101 pub params: Option<ParamsDesc>,102 pub value: LocExpr,103}104105#[derive(Debug, Clone, PartialEq)]106pub struct IfSpecData(pub LocExpr);107#[derive(Debug, Clone, PartialEq)]108pub struct ForSpecData(pub String, pub LocExpr);109110#[derive(Debug, Clone, PartialEq)]111pub enum CompSpec {112 IfSpec(IfSpecData),113 ForSpec(ForSpecData),114}115116#[derive(Debug, Clone, PartialEq)]117pub enum ObjBody {118 MemberList(Vec<Member>),119 ObjComp {120 pre_locals: Vec<BindSpec>,121 key: LocExpr,122 value: LocExpr,123 post_locals: Vec<BindSpec>,124 first: ForSpecData,125 rest: Vec<CompSpec>,126 },127}128129#[derive(Debug, Clone, PartialEq)]130pub enum LiteralType {131 This,132 Super,133 Dollar,134 Null,135 True,136 False,137}138impl Display for LiteralType {139 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {140 use LiteralType::*;141 match self {142 This => write!(f, "this"),143 Null => write!(f, "null"),144 True => write!(f, "true"),145 False => write!(f, "false"),146 _ => panic!("non printable item"),147 }148 }149}150151#[derive(Debug, Clone, PartialEq)]152pub struct SliceDesc {153 pub start: Option<LocExpr>,154 pub end: Option<LocExpr>,155 pub step: Option<LocExpr>,156}157158159#[derive(Debug, Clone, PartialEq)]160pub enum Expr {161 Literal(LiteralType),162163 164 Str(String),165 166 Num(f64),167 168 Var(String),169170 171 Arr(Vec<LocExpr>),172 173 174 175 176 177 178 179 180 181 182 183 ArrComp(LocExpr, ForSpecData, Vec<CompSpec>),184185 186 Obj(ObjBody),187 188 ObjExtend(LocExpr, ObjBody),189190 191 Parened(LocExpr),192193 194 195 Params(ParamsDesc),196 197 198 Args(ArgsDesc),199200 201 UnaryOp(UnaryOpType, LocExpr),202 203 BinaryOp(LocExpr, BinaryOpType, LocExpr),204 205 AssertExpr(AssertStmt, LocExpr),206 207 LocalExpr(Vec<BindSpec>, LocExpr),208209 210 Bind(BindSpec),211 212 Import(String),213 214 ImportStr(String),215 216 Error(LocExpr),217 218 Apply(LocExpr, ArgsDesc),219 220 Select(LocExpr, String),221 222 Index(LocExpr, LocExpr),223 224 Slice(LocExpr, SliceDesc),225 226 Function(ParamsDesc, LocExpr),227 228 IfElse {229 cond: IfSpecData,230 cond_then: LocExpr,231 cond_else: Option<LocExpr>,232 },233 234 IfSpec(IfSpecData),235 236 ForSpec(ForSpecData),237}238239240#[derive(Clone, PartialEq)]241pub struct ExprLocation(pub String, pub usize, pub usize);242impl Debug for ExprLocation {243 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {244 write!(f, "{}:{:?}", self.0, self.1)245 }246}247248249#[derive(Clone, PartialEq)]250pub struct LocExpr(pub Rc<Expr>, pub Option<Rc<ExprLocation>>);251impl Debug for LocExpr {252 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {253 write!(f, "{:?} from {:?}", self.0, self.1)254 }255}256257258#[macro_export]259macro_rules! loc_expr {260 ($expr:expr, $need_loc:expr, ($name:expr, $start:expr, $end:expr)) => {261 LocExpr(262 Rc::new($expr),263 if $need_loc {264 Some(Rc::new(ExprLocation($name.to_owned(), $start, $end)))265 } else {266 None267 },268 )269 };270}271272273#[macro_export]274macro_rules! loc_expr_todo {275 ($expr:expr) => {276 LocExpr(Rc::new($expr), None)277 };278}