1use std::{2 fmt::{self, Debug, Display},3 ops::Deref,4 rc::Rc,5};67use gcmodule::Trace;8use jrsonnet_interner::IStr;9#[cfg(feature = "serde")]10use serde::{Deserialize, Serialize};1112use crate::source::Source;1314#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]15#[derive(Debug, PartialEq, Trace)]16pub enum FieldName {17 18 Fixed(IStr),19 20 Dyn(LocExpr),21}2223#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]24#[derive(Debug, Clone, Copy, PartialEq, Trace)]25pub enum Visibility {26 27 Normal,28 29 Hidden,30 31 Unhide,32}3334impl Visibility {35 pub fn is_visible(&self) -> bool {36 matches!(self, Self::Normal | Self::Unhide)37 }38}3940#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]41#[derive(Clone, Debug, PartialEq, Trace)]42pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);4344#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]45#[derive(Debug, PartialEq, Trace)]46pub struct FieldMember {47 pub name: FieldName,48 pub plus: bool,49 pub params: Option<ParamsDesc>,50 pub visibility: Visibility,51 pub value: LocExpr,52}5354#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]55#[derive(Debug, PartialEq, Trace)]56pub enum Member {57 Field(FieldMember),58 BindStmt(BindSpec),59 AssertStmt(AssertStmt),60}6162#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]63#[derive(Debug, Clone, Copy, PartialEq, Trace)]64pub enum UnaryOpType {65 Plus,66 Minus,67 BitNot,68 Not,69}7071impl Display for UnaryOpType {72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {73 use UnaryOpType::*;74 write!(75 f,76 "{}",77 match self {78 Plus => "+",79 Minus => "-",80 BitNot => "~",81 Not => "!",82 }83 )84 }85}8687#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]88#[derive(Debug, Clone, Copy, PartialEq, Trace)]89pub enum BinaryOpType {90 Mul,91 Div,9293 94 Mod,9596 Add,97 Sub,9899 Lhs,100 Rhs,101102 Lt,103 Gt,104 Lte,105 Gte,106107 BitAnd,108 BitOr,109 BitXor,110111 Eq,112 Neq,113114 And,115 Or,116117 118 In,119}120121impl Display for BinaryOpType {122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {123 use BinaryOpType::*;124 write!(125 f,126 "{}",127 match self {128 Mul => "*",129 Div => "/",130 Mod => "%",131 Add => "+",132 Sub => "-",133 Lhs => "<<",134 Rhs => ">>",135 Lt => "<",136 Gt => ">",137 Lte => "<=",138 Gte => ">=",139 BitAnd => "&",140 BitOr => "|",141 BitXor => "^",142 Eq => "==",143 Neq => "!=",144 And => "&&",145 Or => "||",146 In => "in",147 }148 )149 }150}151152153#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]154#[derive(Debug, PartialEq, Trace)]155pub struct Param(pub IStr, pub Option<LocExpr>);156157158#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]159#[derive(Debug, Clone, PartialEq, Trace)]160pub struct ParamsDesc(pub Rc<Vec<Param>>);161162impl Deref for ParamsDesc {163 type Target = Vec<Param>;164 fn deref(&self) -> &Self::Target {165 &self.0166 }167}168169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]170#[derive(Debug, PartialEq, Trace)]171pub struct ArgsDesc {172 pub unnamed: Vec<LocExpr>,173 pub named: Vec<(IStr, LocExpr)>,174}175impl ArgsDesc {176 pub fn new(unnamed: Vec<LocExpr>, named: Vec<(IStr, LocExpr)>) -> Self {177 Self { unnamed, named }178 }179}180181#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]182#[derive(Debug, Clone, PartialEq, Trace)]183pub enum DestructRest {184 185 Keep(IStr),186 187 Drop,188}189190#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]191#[derive(Debug, Clone, PartialEq, Trace)]192pub enum Destruct {193 Full(IStr),194 #[cfg(feature = "exp-destruct")]195 Skip,196 #[cfg(feature = "exp-destruct")]197 Array {198 start: Vec<Destruct>,199 rest: Option<DestructRest>,200 end: Vec<Destruct>,201 },202 #[cfg(feature = "exp-destruct")]203 Object {204 fields: Vec<(IStr, Option<Destruct>)>,205 rest: Option<DestructRest>,206 },207}208impl Destruct {209 pub fn name(&self) -> Option<IStr> {210 match self {211 Self::Full(name) => Some(name.clone()),212 #[cfg(feature = "exp-destruct")]213 _ => None,214 }215 }216}217218#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]219#[derive(Debug, Clone, PartialEq, Trace)]220pub enum BindSpec {221 Field {222 into: Destruct,223 value: LocExpr,224 },225 Function {226 name: IStr,227 params: ParamsDesc,228 value: LocExpr,229 },230}231232#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]233#[derive(Debug, PartialEq, Trace)]234pub struct IfSpecData(pub LocExpr);235236#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]237#[derive(Debug, PartialEq, Trace)]238pub struct ForSpecData(pub IStr, pub LocExpr);239240#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]241#[derive(Debug, PartialEq, Trace)]242pub enum CompSpec {243 IfSpec(IfSpecData),244 ForSpec(ForSpecData),245}246247#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]248#[derive(Debug, PartialEq, Trace)]249pub struct ObjComp {250 pub pre_locals: Vec<BindSpec>,251 pub key: LocExpr,252 pub plus: bool,253 pub value: LocExpr,254 pub post_locals: Vec<BindSpec>,255 pub compspecs: Vec<CompSpec>,256}257258#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]259#[derive(Debug, PartialEq, Trace)]260pub enum ObjBody {261 MemberList(Vec<Member>),262 ObjComp(ObjComp),263}264265#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]266#[derive(Debug, PartialEq, Clone, Copy, Trace)]267pub enum LiteralType {268 This,269 Super,270 Dollar,271 Null,272 True,273 False,274}275276#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]277#[derive(Debug, PartialEq, Trace)]278pub struct SliceDesc {279 pub start: Option<LocExpr>,280 pub end: Option<LocExpr>,281 pub step: Option<LocExpr>,282}283284285#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]286#[derive(Debug, PartialEq, Trace)]287pub enum Expr {288 Literal(LiteralType),289290 291 Str(IStr),292 293 Num(f64),294 295 Var(IStr),296297 298 Arr(Vec<LocExpr>),299 300 301 302 303 304 305 306 307 308 309 310 ArrComp(LocExpr, Vec<CompSpec>),311312 313 Obj(ObjBody),314 315 ObjExtend(LocExpr, ObjBody),316317 318 Parened(LocExpr),319320 321 UnaryOp(UnaryOpType, LocExpr),322 323 BinaryOp(LocExpr, BinaryOpType, LocExpr),324 325 AssertExpr(AssertStmt, LocExpr),326 327 LocalExpr(Vec<BindSpec>, LocExpr),328329 330 Import(IStr),331 332 ImportStr(IStr),333 334 ImportBin(IStr),335 336 ErrorStmt(LocExpr),337 338 Apply(LocExpr, ArgsDesc, bool),339 340 Index(LocExpr, LocExpr),341 342 Function(ParamsDesc, LocExpr),343 344 IntrinsicThisFile,345 346 IntrinsicId,347 348 Intrinsic(IStr),349 350 IfElse {351 cond: IfSpecData,352 cond_then: LocExpr,353 cond_else: Option<LocExpr>,354 },355 Slice(LocExpr, SliceDesc),356}357358359#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]360#[derive(Clone, PartialEq, Trace)]361#[skip_trace]362#[repr(C)]363pub struct ExprLocation(pub Source, pub u32, pub u32);364impl ExprLocation {365 pub fn belongs_to(&self, other: &ExprLocation) -> bool {366 other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2367 }368}369370#[cfg(target_pointer_width = "64")]371static_assertions::assert_eq_size!(ExprLocation, [u8; 16]);372373impl Debug for ExprLocation {374 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {375 write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)376 }377}378379380#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]381#[derive(Clone, PartialEq, Trace)]382pub struct LocExpr(pub Rc<Expr>, pub ExprLocation);383384#[cfg(target_pointer_width = "64")]385static_assertions::assert_eq_size!(LocExpr, [u8; 24]);386387impl Debug for LocExpr {388 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {389 if f.alternate() {390 write!(f, "{:#?}", self.0)?;391 } else {392 write!(f, "{:?}", self.0)?;393 }394 write!(f, " from {:?}", self.1)?;395 Ok(())396 }397}