1use gc::{unsafe_empty_trace, Finalize, Trace};2use jrsonnet_interner::IStr;3#[cfg(feature = "deserialize")]4use serde::Deserialize;5#[cfg(feature = "serialize")]6use serde::Serialize;7use std::{8 fmt::{Debug, Display},9 ops::Deref,10 path::{Path, PathBuf},11 rc::Rc,12};1314#[cfg_attr(feature = "serialize", derive(Serialize))]15#[cfg_attr(feature = "deserialize", derive(Deserialize))]16#[derive(Debug, PartialEq)]17pub enum FieldName {18 19 Fixed(IStr),20 21 Dyn(LocExpr),22}23impl Finalize for FieldName {}24unsafe impl Trace for FieldName {25 unsafe_empty_trace!();26}2728#[cfg_attr(feature = "serialize", derive(Serialize))]29#[cfg_attr(feature = "deserialize", derive(Deserialize))]30#[derive(Debug, Clone, Copy, PartialEq)]31pub enum Visibility {32 33 Normal,34 35 Hidden,36 37 Unhide,38}39impl Finalize for Visibility {}40unsafe impl Trace for Visibility {41 unsafe_empty_trace!();42}4344impl Visibility {45 pub fn is_visible(&self) -> bool {46 matches!(self, Self::Normal | Self::Unhide)47 }48}4950#[cfg_attr(feature = "serialize", derive(Serialize))]51#[cfg_attr(feature = "deserialize", derive(Deserialize))]52#[derive(Clone, Debug, PartialEq)]53pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);54impl Finalize for AssertStmt {}55unsafe impl Trace for AssertStmt {56 unsafe_empty_trace!();57}5859#[cfg_attr(feature = "serialize", derive(Serialize))]60#[cfg_attr(feature = "deserialize", derive(Deserialize))]61#[derive(Debug, PartialEq)]62pub struct FieldMember {63 pub name: FieldName,64 pub plus: bool,65 pub params: Option<ParamsDesc>,66 pub visibility: Visibility,67 pub value: LocExpr,68}69impl Finalize for FieldMember {}70unsafe impl Trace for FieldMember {71 unsafe_empty_trace!();72}7374#[cfg_attr(feature = "serialize", derive(Serialize))]75#[cfg_attr(feature = "deserialize", derive(Deserialize))]76#[derive(Debug, PartialEq)]77pub enum Member {78 Field(FieldMember),79 BindStmt(BindSpec),80 AssertStmt(AssertStmt),81}82impl Finalize for Member {}83unsafe impl Trace for Member {84 unsafe_empty_trace!();85}8687#[cfg_attr(feature = "serialize", derive(Serialize))]88#[cfg_attr(feature = "deserialize", derive(Deserialize))]89#[derive(Debug, Clone, Copy, PartialEq)]90pub enum UnaryOpType {91 Plus,92 Minus,93 BitNot,94 Not,95}96impl Finalize for UnaryOpType {}97unsafe impl Trace for UnaryOpType {98 unsafe_empty_trace!();99}100101impl Display for UnaryOpType {102 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {103 use UnaryOpType::*;104 write!(105 f,106 "{}",107 match self {108 Plus => "+",109 Minus => "-",110 BitNot => "~",111 Not => "!",112 }113 )114 }115}116117#[cfg_attr(feature = "serialize", derive(Serialize))]118#[cfg_attr(feature = "deserialize", derive(Deserialize))]119#[derive(Debug, Clone, Copy, PartialEq)]120pub enum BinaryOpType {121 Mul,122 Div,123124 125 Mod,126127 Add,128 Sub,129130 Lhs,131 Rhs,132133 Lt,134 Gt,135 Lte,136 Gte,137138 BitAnd,139 BitOr,140 BitXor,141142 Eq,143 Neq,144145 And,146 Or,147}148impl Finalize for BinaryOpType {}149unsafe impl Trace for BinaryOpType {150 unsafe_empty_trace!();151}152153impl Display for BinaryOpType {154 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {155 use BinaryOpType::*;156 write!(157 f,158 "{}",159 match self {160 Mul => "*",161 Div => "/",162 Mod => "%",163 Add => "+",164 Sub => "-",165 Lhs => "<<",166 Rhs => ">>",167 Lt => "<",168 Gt => ">",169 Lte => "<=",170 Gte => ">=",171 BitAnd => "&",172 BitOr => "|",173 BitXor => "^",174 Eq => "==",175 Neq => "!=",176 And => "&&",177 Or => "||",178 }179 )180 }181}182183184#[cfg_attr(feature = "serialize", derive(Serialize))]185#[cfg_attr(feature = "deserialize", derive(Deserialize))]186#[derive(Debug, PartialEq)]187pub struct Param(pub IStr, pub Option<LocExpr>);188impl Finalize for Param {}189unsafe impl Trace for Param {190 unsafe_empty_trace!();191}192193194#[cfg_attr(feature = "serialize", derive(Serialize))]195#[cfg_attr(feature = "deserialize", derive(Deserialize))]196#[derive(Debug, Clone, PartialEq)]197pub struct ParamsDesc(pub Rc<Vec<Param>>);198impl Finalize for ParamsDesc {}199unsafe impl Trace for ParamsDesc {200 unsafe_empty_trace!();201}202203impl Deref for ParamsDesc {204 type Target = Vec<Param>;205 fn deref(&self) -> &Self::Target {206 &self.0207 }208}209210#[cfg_attr(feature = "serialize", derive(Serialize))]211#[cfg_attr(feature = "deserialize", derive(Deserialize))]212#[derive(Debug, PartialEq)]213pub struct Arg(pub Option<String>, pub LocExpr);214impl Finalize for Arg {}215unsafe impl Trace for Arg {216 unsafe_empty_trace!();217}218219#[cfg_attr(feature = "serialize", derive(Serialize))]220#[cfg_attr(feature = "deserialize", derive(Deserialize))]221#[derive(Debug, PartialEq)]222pub struct ArgsDesc(pub Vec<Arg>);223impl Finalize for ArgsDesc {}224unsafe impl Trace for ArgsDesc {225 unsafe_empty_trace!();226}227228impl Deref for ArgsDesc {229 type Target = Vec<Arg>;230 fn deref(&self) -> &Self::Target {231 &self.0232 }233}234235#[cfg_attr(feature = "serialize", derive(Serialize))]236#[cfg_attr(feature = "deserialize", derive(Deserialize))]237#[derive(Debug, Clone, PartialEq)]238pub struct BindSpec {239 pub name: IStr,240 pub params: Option<ParamsDesc>,241 pub value: LocExpr,242}243impl Finalize for BindSpec {}244unsafe impl Trace for BindSpec {245 unsafe_empty_trace!();246}247248#[cfg_attr(feature = "serialize", derive(Serialize))]249#[cfg_attr(feature = "deserialize", derive(Deserialize))]250#[derive(Debug, PartialEq)]251pub struct IfSpecData(pub LocExpr);252impl Finalize for IfSpecData {}253unsafe impl Trace for IfSpecData {254 unsafe_empty_trace!();255}256257#[cfg_attr(feature = "serialize", derive(Serialize))]258#[cfg_attr(feature = "deserialize", derive(Deserialize))]259#[derive(Debug, PartialEq)]260pub struct ForSpecData(pub IStr, pub LocExpr);261impl Finalize for ForSpecData {}262unsafe impl Trace for ForSpecData {263 unsafe_empty_trace!();264}265266#[cfg_attr(feature = "serialize", derive(Serialize))]267#[cfg_attr(feature = "deserialize", derive(Deserialize))]268#[derive(Debug, PartialEq)]269pub enum CompSpec {270 IfSpec(IfSpecData),271 ForSpec(ForSpecData),272}273impl Finalize for CompSpec {}274unsafe impl Trace for CompSpec {275 unsafe_empty_trace!();276}277278#[cfg_attr(feature = "serialize", derive(Serialize))]279#[cfg_attr(feature = "deserialize", derive(Deserialize))]280#[derive(Debug, PartialEq)]281pub struct ObjComp {282 pub pre_locals: Vec<BindSpec>,283 pub key: LocExpr,284 pub value: LocExpr,285 pub post_locals: Vec<BindSpec>,286 pub compspecs: Vec<CompSpec>,287}288impl Finalize for ObjComp {}289unsafe impl Trace for ObjComp {290 unsafe_empty_trace!();291}292293#[cfg_attr(feature = "serialize", derive(Serialize))]294#[cfg_attr(feature = "deserialize", derive(Deserialize))]295#[derive(Debug, PartialEq)]296pub enum ObjBody {297 MemberList(Vec<Member>),298 ObjComp(ObjComp),299}300impl Finalize for ObjBody {}301unsafe impl Trace for ObjBody {302 unsafe_empty_trace!();303}304305#[cfg_attr(feature = "serialize", derive(Serialize))]306#[cfg_attr(feature = "deserialize", derive(Deserialize))]307#[derive(Debug, PartialEq, Clone, Copy)]308pub enum LiteralType {309 This,310 Super,311 Dollar,312 Null,313 True,314 False,315}316impl Finalize for LiteralType {}317unsafe impl Trace for LiteralType {318 unsafe_empty_trace!();319}320321#[derive(Debug, PartialEq)]322pub struct SliceDesc {323 pub start: Option<LocExpr>,324 pub end: Option<LocExpr>,325 pub step: Option<LocExpr>,326}327impl Finalize for SliceDesc {}328unsafe impl Trace for SliceDesc {329 unsafe_empty_trace!();330}331332333#[cfg_attr(feature = "serialize", derive(Serialize))]334#[cfg_attr(feature = "deserialize", derive(Deserialize))]335#[derive(Debug, PartialEq)]336pub enum Expr {337 Literal(LiteralType),338339 340 Str(IStr),341 342 Num(f64),343 344 Var(IStr),345346 347 Arr(Vec<LocExpr>),348 349 350 351 352 353 354 355 356 357 358 359 ArrComp(LocExpr, Vec<CompSpec>),360361 362 Obj(ObjBody),363 364 ObjExtend(LocExpr, ObjBody),365366 367 Parened(LocExpr),368369 370 UnaryOp(UnaryOpType, LocExpr),371 372 BinaryOp(LocExpr, BinaryOpType, LocExpr),373 374 AssertExpr(AssertStmt, LocExpr),375 376 LocalExpr(Vec<BindSpec>, LocExpr),377378 379 Import(PathBuf),380 381 ImportStr(PathBuf),382 383 ErrorStmt(LocExpr),384 385 Apply(LocExpr, ArgsDesc, bool),386 387 Index(LocExpr, LocExpr),388 389 Function(ParamsDesc, LocExpr),390 391 Intrinsic(IStr),392 393 IfElse {394 cond: IfSpecData,395 cond_then: LocExpr,396 cond_else: Option<LocExpr>,397 },398}399impl Finalize for Expr {}400unsafe impl Trace for Expr {401 unsafe_empty_trace!();402}403404405#[cfg_attr(feature = "serialize", derive(Serialize))]406#[cfg_attr(feature = "deserialize", derive(Deserialize))]407#[derive(Clone, PartialEq)]408pub struct ExprLocation(pub Rc<Path>, pub usize, pub usize);409impl Finalize for ExprLocation {}410unsafe impl Trace for ExprLocation {411 unsafe_empty_trace!();412}413414impl Debug for ExprLocation {415 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {416 write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)417 }418}419420421#[cfg_attr(feature = "serialize", derive(Serialize))]422#[cfg_attr(feature = "deserialize", derive(Deserialize))]423#[derive(Clone, PartialEq)]424pub struct LocExpr(pub Rc<Expr>, pub Option<ExprLocation>);425impl Finalize for LocExpr {}426unsafe impl Trace for LocExpr {427 unsafe_empty_trace!();428}429430impl Debug for LocExpr {431 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {432 if f.alternate() {433 write!(f, "{:#?}", self.0)?;434 } else {435 write!(f, "{:?}", self.0)?;436 }437 if let Some(loc) = &self.1 {438 write!(f, " from {:?}", loc)?;439 }440 Ok(())441 }442}443444445#[macro_export]446macro_rules! loc_expr {447 ($expr:expr, $need_loc:expr,($name:expr, $start:expr, $end:expr)) => {448 LocExpr(449 std::rc::Rc::new($expr),450 if $need_loc {451 Some(ExprLocation($name, $start, $end))452 } else {453 None454 },455 )456 };457}458459460#[macro_export]461macro_rules! loc_expr_todo {462 ($expr:expr) => {463 LocExpr(Rc::new($expr), None)464 };465}