git.delta.rocks / jrsonnet / refs/commits / d512ff65b472

difftreelog

source

crates/jrsonnet-parser/src/expr.rs9.2 KiBsourcehistory
1use jrsonnet_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, Trace)]17#[trivially_drop]18pub enum FieldName {19	/// {fixed: 2}20	Fixed(IStr),21	/// {["dyn"+"amic"]: 3}22	Dyn(LocExpr),23}2425#[cfg_attr(feature = "serialize", derive(Serialize))]26#[cfg_attr(feature = "deserialize", derive(Deserialize))]27#[derive(Debug, Clone, Copy, PartialEq, Trace)]28#[trivially_drop]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 = "serialize", derive(Serialize))]45#[cfg_attr(feature = "deserialize", derive(Deserialize))]46#[derive(Clone, Debug, PartialEq, Trace)]47#[trivially_drop]48pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);4950#[cfg_attr(feature = "serialize", derive(Serialize))]51#[cfg_attr(feature = "deserialize", derive(Deserialize))]52#[derive(Debug, PartialEq, Trace)]53#[trivially_drop]54pub struct FieldMember {55	pub name: FieldName,56	pub plus: bool,57	pub params: Option<ParamsDesc>,58	pub visibility: Visibility,59	pub value: LocExpr,60}6162#[cfg_attr(feature = "serialize", derive(Serialize))]63#[cfg_attr(feature = "deserialize", derive(Deserialize))]64#[derive(Debug, PartialEq, Trace)]65#[trivially_drop]66pub enum Member {67	Field(FieldMember),68	BindStmt(BindSpec),69	AssertStmt(AssertStmt),70}7172#[cfg_attr(feature = "serialize", derive(Serialize))]73#[cfg_attr(feature = "deserialize", derive(Deserialize))]74#[derive(Debug, Clone, Copy, PartialEq, Trace)]75#[trivially_drop]76pub enum UnaryOpType {77	Plus,78	Minus,79	BitNot,80	Not,81}8283impl Display for UnaryOpType {84	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {85		use UnaryOpType::*;86		write!(87			f,88			"{}",89			match self {90				Plus => "+",91				Minus => "-",92				BitNot => "~",93				Not => "!",94			}95		)96	}97}9899#[cfg_attr(feature = "serialize", derive(Serialize))]100#[cfg_attr(feature = "deserialize", derive(Deserialize))]101#[derive(Debug, Clone, Copy, PartialEq, Trace)]102#[trivially_drop]103pub enum BinaryOpType {104	Mul,105	Div,106107	/// Implemented as intrinsic, put here for completeness108	Mod,109110	Add,111	Sub,112113	Lhs,114	Rhs,115116	Lt,117	Gt,118	Lte,119	Gte,120121	BitAnd,122	BitOr,123	BitXor,124125	Eq,126	Neq,127128	And,129	Or,130131	// Equialent to std.objectHasEx(a, b, true)132	In,133}134135impl Display for BinaryOpType {136	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {137		use BinaryOpType::*;138		write!(139			f,140			"{}",141			match self {142				Mul => "*",143				Div => "/",144				Mod => "%",145				Add => "+",146				Sub => "-",147				Lhs => "<<",148				Rhs => ">>",149				Lt => "<",150				Gt => ">",151				Lte => "<=",152				Gte => ">=",153				BitAnd => "&",154				BitOr => "|",155				BitXor => "^",156				Eq => "==",157				Neq => "!=",158				And => "&&",159				Or => "||",160				In => "in",161			}162		)163	}164}165166/// name, default value167#[cfg_attr(feature = "serialize", derive(Serialize))]168#[cfg_attr(feature = "deserialize", derive(Deserialize))]169#[derive(Debug, PartialEq, Trace)]170#[trivially_drop]171pub struct Param(pub IStr, pub Option<LocExpr>);172173/// Defined function parameters174#[cfg_attr(feature = "serialize", derive(Serialize))]175#[cfg_attr(feature = "deserialize", derive(Deserialize))]176#[derive(Debug, Clone, PartialEq)]177pub struct ParamsDesc(pub Rc<Vec<Param>>);178179/// Safety:180/// AST is acyclic, and there should be no gc pointers181unsafe impl Trace for ParamsDesc {182	unsafe_empty_trace!();183}184impl Finalize for ParamsDesc {}185186impl Deref for ParamsDesc {187	type Target = Vec<Param>;188	fn deref(&self) -> &Self::Target {189		&self.0190	}191}192193#[cfg_attr(feature = "serialize", derive(Serialize))]194#[cfg_attr(feature = "deserialize", derive(Deserialize))]195#[derive(Debug, PartialEq, Trace)]196#[trivially_drop]197pub struct Arg(pub Option<String>, pub LocExpr);198199#[cfg_attr(feature = "serialize", derive(Serialize))]200#[cfg_attr(feature = "deserialize", derive(Deserialize))]201#[derive(Debug, PartialEq, Trace)]202#[trivially_drop]203pub struct ArgsDesc(pub Vec<Arg>);204205impl Deref for ArgsDesc {206	type Target = Vec<Arg>;207	fn deref(&self) -> &Self::Target {208		&self.0209	}210}211212#[cfg_attr(feature = "serialize", derive(Serialize))]213#[cfg_attr(feature = "deserialize", derive(Deserialize))]214#[derive(Debug, Clone, PartialEq, Trace)]215#[trivially_drop]216pub struct BindSpec {217	pub name: IStr,218	pub params: Option<ParamsDesc>,219	pub value: LocExpr,220}221222#[cfg_attr(feature = "serialize", derive(Serialize))]223#[cfg_attr(feature = "deserialize", derive(Deserialize))]224#[derive(Debug, PartialEq, Trace)]225#[trivially_drop]226pub struct IfSpecData(pub LocExpr);227228#[cfg_attr(feature = "serialize", derive(Serialize))]229#[cfg_attr(feature = "deserialize", derive(Deserialize))]230#[derive(Debug, PartialEq, Trace)]231#[trivially_drop]232pub struct ForSpecData(pub IStr, pub LocExpr);233234#[cfg_attr(feature = "serialize", derive(Serialize))]235#[cfg_attr(feature = "deserialize", derive(Deserialize))]236#[derive(Debug, PartialEq, Trace)]237#[trivially_drop]238pub enum CompSpec {239	IfSpec(IfSpecData),240	ForSpec(ForSpecData),241}242243#[cfg_attr(feature = "serialize", derive(Serialize))]244#[cfg_attr(feature = "deserialize", derive(Deserialize))]245#[derive(Debug, PartialEq, Trace)]246#[trivially_drop]247pub struct ObjComp {248	pub pre_locals: Vec<BindSpec>,249	pub key: LocExpr,250	pub plus: bool,251	pub value: LocExpr,252	pub post_locals: Vec<BindSpec>,253	pub compspecs: Vec<CompSpec>,254}255256#[cfg_attr(feature = "serialize", derive(Serialize))]257#[cfg_attr(feature = "deserialize", derive(Deserialize))]258#[derive(Debug, PartialEq, Trace)]259#[trivially_drop]260pub enum ObjBody {261	MemberList(Vec<Member>),262	ObjComp(ObjComp),263}264265#[cfg_attr(feature = "serialize", derive(Serialize))]266#[cfg_attr(feature = "deserialize", derive(Deserialize))]267#[derive(Debug, PartialEq, Clone, Copy, Trace)]268#[trivially_drop]269pub enum LiteralType {270	This,271	Super,272	Dollar,273	Null,274	True,275	False,276}277278#[cfg_attr(feature = "serialize", derive(Serialize))]279#[cfg_attr(feature = "deserialize", derive(Deserialize))]280#[derive(Debug, PartialEq, Trace)]281#[trivially_drop]282pub struct SliceDesc {283	pub start: Option<LocExpr>,284	pub end: Option<LocExpr>,285	pub step: Option<LocExpr>,286}287288/// Syntax base289#[cfg_attr(feature = "serialize", derive(Serialize))]290#[cfg_attr(feature = "deserialize", derive(Deserialize))]291#[derive(Debug, PartialEq, Trace)]292#[trivially_drop]293pub enum Expr {294	Literal(LiteralType),295296	/// String value: "hello"297	Str(IStr),298	/// Number: 1, 2.0, 2e+20299	Num(f64),300	/// Variable name: test301	Var(IStr),302303	/// Array of expressions: [1, 2, "Hello"]304	Arr(Vec<LocExpr>),305	/// Array comprehension:306	/// ```jsonnet307	///  ingredients: [308	///    { kind: kind, qty: 4 / 3 }309	///    for kind in [310	///      'Honey Syrup',311	///      'Lemon Juice',312	///      'Farmers Gin',313	///    ]314	///  ],315	/// ```316	ArrComp(LocExpr, Vec<CompSpec>),317318	/// Object: {a: 2}319	Obj(ObjBody),320	/// Object extension: var1 {b: 2}321	ObjExtend(LocExpr, ObjBody),322323	/// (obj)324	Parened(LocExpr),325326	/// -2327	UnaryOp(UnaryOpType, LocExpr),328	/// 2 - 2329	BinaryOp(LocExpr, BinaryOpType, LocExpr),330	/// assert 2 == 2 : "Math is broken"331	AssertExpr(AssertStmt, LocExpr),332	/// local a = 2; { b: a }333	LocalExpr(Vec<BindSpec>, LocExpr),334335	/// import "hello"336	Import(PathBuf),337	/// importStr "file.txt"338	ImportStr(PathBuf),339	/// error "I'm broken"340	ErrorStmt(LocExpr),341	/// a(b, c)342	Apply(LocExpr, ArgsDesc, bool),343	/// a[b]344	Index(LocExpr, LocExpr),345	/// function(x) x346	Function(ParamsDesc, LocExpr),347	/// std.primitiveEquals348	Intrinsic(IStr),349	/// if true == false then 1 else 2350	IfElse {351		cond: IfSpecData,352		cond_then: LocExpr,353		cond_else: Option<LocExpr>,354	},355	Slice(LocExpr, SliceDesc),356}357358/// file, begin offset, end offset359#[cfg_attr(feature = "serialize", derive(Serialize))]360#[cfg_attr(feature = "deserialize", derive(Deserialize))]361#[derive(Clone, PartialEq, Trace)]362#[trivially_drop]363pub struct ExprLocation(pub Rc<Path>, pub usize, pub usize);364365impl Debug for ExprLocation {366	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {367		write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)368	}369}370371/// Holds AST expression and its location in source file372#[cfg_attr(feature = "serialize", derive(Serialize))]373#[cfg_attr(feature = "deserialize", derive(Deserialize))]374#[derive(Clone, PartialEq)]375pub struct LocExpr(pub Rc<Expr>, pub Option<ExprLocation>);376/// Safety:377/// AST is acyclic, and there should be no gc pointers378unsafe impl Trace for LocExpr {379	unsafe_empty_trace!();380}381impl Finalize for LocExpr {}382383impl Debug for LocExpr {384	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {385		if f.alternate() {386			write!(f, "{:#?}", self.0)?;387		} else {388			write!(f, "{:?}", self.0)?;389		}390		if let Some(loc) = &self.1 {391			write!(f, " from {:?}", loc)?;392		}393		Ok(())394	}395}396397/// Creates LocExpr from Expr and ExprLocation components398#[macro_export]399macro_rules! loc_expr {400	($expr:expr, $need_loc:expr,($name:expr, $start:expr, $end:expr)) => {401		LocExpr(402			std::rc::Rc::new($expr),403			if $need_loc {404				Some(ExprLocation($name, $start, $end))405			} else {406				None407			},408		)409	};410}411412/// Creates LocExpr without location info413#[macro_export]414macro_rules! loc_expr_todo {415	($expr:expr) => {416		LocExpr(Rc::new($expr), None)417	};418}