git.delta.rocks / jrsonnet / refs/commits / 0374cd028e16

difftreelog

source

crates/jrsonnet-parser/src/expr.rs8.1 KiBsourcehistory
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	/// {fixed: 2}18	Fixed(IStr),19	/// {["dyn"+"amic"]: 3}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	/// Implemented as intrinsic, put here for completeness94	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	// Equialent to std.objectHasEx(a, b, true)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}151152/// name, default value153#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]154#[derive(Debug, PartialEq, Trace)]155pub struct Param(pub IStr, pub Option<LocExpr>);156157/// Defined function parameters158#[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	/// ...rest185	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}283284/// Syntax base285#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]286#[derive(Debug, PartialEq, Trace)]287pub enum Expr {288	Literal(LiteralType),289290	/// String value: "hello"291	Str(IStr),292	/// Number: 1, 2.0, 2e+20293	Num(f64),294	/// Variable name: test295	Var(IStr),296297	/// Array of expressions: [1, 2, "Hello"]298	Arr(Vec<LocExpr>),299	/// Array comprehension:300	/// ```jsonnet301	///  ingredients: [302	///    { kind: kind, qty: 4 / 3 }303	///    for kind in [304	///      'Honey Syrup',305	///      'Lemon Juice',306	///      'Farmers Gin',307	///    ]308	///  ],309	/// ```310	ArrComp(LocExpr, Vec<CompSpec>),311312	/// Object: {a: 2}313	Obj(ObjBody),314	/// Object extension: var1 {b: 2}315	ObjExtend(LocExpr, ObjBody),316317	/// (obj)318	Parened(LocExpr),319320	/// -2321	UnaryOp(UnaryOpType, LocExpr),322	/// 2 - 2323	BinaryOp(LocExpr, BinaryOpType, LocExpr),324	/// assert 2 == 2 : "Math is broken"325	AssertExpr(AssertStmt, LocExpr),326	/// local a = 2; { b: a }327	LocalExpr(Vec<BindSpec>, LocExpr),328329	/// import "hello"330	Import(IStr),331	/// importStr "file.txt"332	ImportStr(IStr),333	/// importBin "file.txt"334	ImportBin(IStr),335	/// error "I'm broken"336	ErrorStmt(LocExpr),337	/// a(b, c)338	Apply(LocExpr, ArgsDesc, bool),339	/// a[b]340	Index(LocExpr, LocExpr),341	/// function(x) x342	Function(ParamsDesc, LocExpr),343	/// std.thisFile344	IntrinsicThisFile,345	/// std.id,346	IntrinsicId,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 = "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}378379/// Holds AST expression and its location in source file380#[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}