1use std::{2 fmt::{self, Debug, Display},3 ops::Deref,4 rc::Rc,5};67use jrsonnet_gcmodule::Trace;8use jrsonnet_interner::IStr;9#[cfg(feature = "serde")]10use serde::{Deserialize, Serialize};11#[cfg(feature = "structdump")]12use structdump::Codegen;1314use crate::source::Source;1516#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]17#[cfg_attr(feature = "structdump", derive(Codegen))]18#[derive(Debug, PartialEq, Trace)]19pub enum FieldName {20 21 Fixed(IStr),22 23 Dyn(LocExpr),24}2526#[cfg_attr(feature = "structdump", derive(Codegen))]27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]28#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]29pub enum Visibility {30 31 Normal,32 33 Hidden,34 35 Unhide,36}3738impl Visibility {39 pub fn is_visible(&self) -> bool {40 matches!(self, Self::Normal | Self::Unhide)41 }42}4344#[cfg_attr(feature = "structdump", derive(Codegen))]45#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]46#[derive(Clone, Debug, PartialEq, Trace)]47pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);4849#[cfg_attr(feature = "structdump", derive(Codegen))]50#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]51#[derive(Debug, PartialEq, Trace)]52pub struct FieldMember {53 pub name: FieldName,54 pub plus: bool,55 pub params: Option<ParamsDesc>,56 pub visibility: Visibility,57 pub value: LocExpr,58}5960#[cfg_attr(feature = "structdump", derive(Codegen))]61#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]62#[derive(Debug, PartialEq, Trace)]63pub enum Member {64 Field(FieldMember),65 BindStmt(BindSpec),66 AssertStmt(AssertStmt),67}6869#[cfg_attr(feature = "structdump", derive(Codegen))]70#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]71#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]72pub enum UnaryOpType {73 Plus,74 Minus,75 BitNot,76 Not,77}7879impl Display for UnaryOpType {80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {81 use UnaryOpType::*;82 write!(83 f,84 "{}",85 match self {86 Plus => "+",87 Minus => "-",88 BitNot => "~",89 Not => "!",90 }91 )92 }93}9495#[cfg_attr(feature = "structdump", derive(Codegen))]96#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]97#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]98pub enum BinaryOpType {99 Mul,100 Div,101102 103 Mod,104105 Add,106 Sub,107108 Lhs,109 Rhs,110111 Lt,112 Gt,113 Lte,114 Gte,115116 BitAnd,117 BitOr,118 BitXor,119120 Eq,121 Neq,122123 And,124 Or,125126 127 In,128}129130impl Display for BinaryOpType {131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {132 use BinaryOpType::*;133 write!(134 f,135 "{}",136 match self {137 Mul => "*",138 Div => "/",139 Mod => "%",140 Add => "+",141 Sub => "-",142 Lhs => "<<",143 Rhs => ">>",144 Lt => "<",145 Gt => ">",146 Lte => "<=",147 Gte => ">=",148 BitAnd => "&",149 BitOr => "|",150 BitXor => "^",151 Eq => "==",152 Neq => "!=",153 And => "&&",154 Or => "||",155 In => "in",156 }157 )158 }159}160161162#[cfg_attr(feature = "structdump", derive(Codegen))]163#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]164#[derive(Debug, PartialEq, Trace)]165pub struct Param(pub Destruct, pub Option<LocExpr>);166167168#[cfg_attr(feature = "structdump", derive(Codegen))]169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]170#[derive(Debug, Clone, PartialEq, Trace)]171pub struct ParamsDesc(pub Rc<Vec<Param>>);172173impl Deref for ParamsDesc {174 type Target = Vec<Param>;175 fn deref(&self) -> &Self::Target {176 &self.0177 }178}179180#[cfg_attr(feature = "structdump", derive(Codegen))]181#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]182#[derive(Debug, PartialEq, Trace)]183pub struct ArgsDesc {184 pub unnamed: Vec<LocExpr>,185 pub named: Vec<(IStr, LocExpr)>,186}187impl ArgsDesc {188 pub fn new(unnamed: Vec<LocExpr>, named: Vec<(IStr, LocExpr)>) -> Self {189 Self { unnamed, named }190 }191}192193#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]194#[derive(Debug, Clone, PartialEq, Eq, Trace)]195pub enum DestructRest {196 197 Keep(IStr),198 199 Drop,200}201202#[cfg_attr(feature = "structdump", derive(Codegen))]203#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]204#[derive(Debug, Clone, PartialEq, Trace)]205pub enum Destruct {206 Full(IStr),207 #[cfg(feature = "exp-destruct")]208 Skip,209 #[cfg(feature = "exp-destruct")]210 Array {211 start: Vec<Destruct>,212 rest: Option<DestructRest>,213 end: Vec<Destruct>,214 },215 #[cfg(feature = "exp-destruct")]216 Object {217 fields: Vec<(IStr, Option<Destruct>, Option<LocExpr>)>,218 rest: Option<DestructRest>,219 },220}221impl Destruct {222 223 pub fn name(&self) -> Option<IStr> {224 match self {225 Self::Full(name) => Some(name.clone()),226 #[cfg(feature = "exp-destruct")]227 _ => None,228 }229 }230}231232#[cfg_attr(feature = "structdump", derive(Codegen))]233#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]234#[derive(Debug, Clone, PartialEq, Trace)]235pub enum BindSpec {236 Field {237 into: Destruct,238 value: LocExpr,239 },240 Function {241 name: IStr,242 params: ParamsDesc,243 value: LocExpr,244 },245}246247#[cfg_attr(feature = "structdump", derive(Codegen))]248#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]249#[derive(Debug, PartialEq, Trace)]250pub struct IfSpecData(pub LocExpr);251252#[cfg_attr(feature = "structdump", derive(Codegen))]253#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]254#[derive(Debug, PartialEq, Trace)]255pub struct ForSpecData(pub IStr, pub LocExpr);256257#[cfg_attr(feature = "structdump", derive(Codegen))]258#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]259#[derive(Debug, PartialEq, Trace)]260pub enum CompSpec {261 IfSpec(IfSpecData),262 ForSpec(ForSpecData),263}264265#[cfg_attr(feature = "structdump", derive(Codegen))]266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]267#[derive(Debug, PartialEq, Trace)]268pub struct ObjComp {269 pub pre_locals: Vec<BindSpec>,270 pub key: LocExpr,271 pub plus: bool,272 pub value: LocExpr,273 pub post_locals: Vec<BindSpec>,274 pub compspecs: Vec<CompSpec>,275}276277#[cfg_attr(feature = "structdump", derive(Codegen))]278#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]279#[derive(Debug, PartialEq, Trace)]280pub enum ObjBody {281 MemberList(Vec<Member>),282 ObjComp(ObjComp),283}284285#[cfg_attr(feature = "structdump", derive(Codegen))]286#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]287#[derive(Debug, PartialEq, Eq, Clone, Copy, Trace)]288pub enum LiteralType {289 This,290 Super,291 Dollar,292 Null,293 True,294 False,295}296297#[cfg_attr(feature = "structdump", derive(Codegen))]298#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]299#[derive(Debug, PartialEq, Trace)]300pub struct SliceDesc {301 pub start: Option<LocExpr>,302 pub end: Option<LocExpr>,303 pub step: Option<LocExpr>,304}305306307#[cfg_attr(feature = "structdump", derive(Codegen))]308#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]309#[derive(Debug, PartialEq, Trace)]310pub enum Expr {311 Literal(LiteralType),312313 314 Str(IStr),315 316 Num(f64),317 318 Var(IStr),319320 321 Arr(Vec<LocExpr>),322 323 324 325 326 327 328 329 330 331 332 333 ArrComp(LocExpr, Vec<CompSpec>),334335 336 Obj(ObjBody),337 338 ObjExtend(LocExpr, ObjBody),339340 341 Parened(LocExpr),342343 344 UnaryOp(UnaryOpType, LocExpr),345 346 BinaryOp(LocExpr, BinaryOpType, LocExpr),347 348 AssertExpr(AssertStmt, LocExpr),349 350 LocalExpr(Vec<BindSpec>, LocExpr),351352 353 Import(IStr),354 355 ImportStr(IStr),356 357 ImportBin(IStr),358 359 ErrorStmt(LocExpr),360 361 Apply(LocExpr, ArgsDesc, bool),362 363 Index(LocExpr, LocExpr),364 365 Function(ParamsDesc, LocExpr),366 367 IfElse {368 cond: IfSpecData,369 cond_then: LocExpr,370 cond_else: Option<LocExpr>,371 },372 Slice(LocExpr, SliceDesc),373}374375376#[cfg_attr(feature = "structdump", derive(Codegen))]377#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]378#[derive(Clone, PartialEq, Eq, Trace)]379#[trace(skip)]380#[repr(C)]381pub struct ExprLocation(pub Source, pub u32, pub u32);382impl ExprLocation {383 pub fn belongs_to(&self, other: &ExprLocation) -> bool {384 other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2385 }386}387388#[cfg(target_pointer_width = "64")]389static_assertions::assert_eq_size!(ExprLocation, [u8; 16]);390391impl Debug for ExprLocation {392 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {393 write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)394 }395}396397398#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]399#[cfg_attr(feature = "structdump", derive(Codegen))]400#[derive(Clone, PartialEq, Trace)]401pub struct LocExpr(pub Rc<Expr>, pub ExprLocation);402403#[cfg(target_pointer_width = "64")]404static_assertions::assert_eq_size!(LocExpr, [u8; 24]);405406impl Debug for LocExpr {407 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {408 if f.alternate() {409 write!(f, "{:#?}", self.0)?;410 } else {411 write!(f, "{:?}", self.0)?;412 }413 write!(f, " from {:?}", self.1)?;414 Ok(())415 }416}