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

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 jrsonnet_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, Eq, 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, Eq, 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, Eq, 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 Destruct, 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, Eq, 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>, Option<LocExpr>)>,205		rest: Option<DestructRest>,206	},207}208impl Destruct {209	/// Name of destructure, used for function parameter names210	pub fn name(&self) -> Option<IStr> {211		match self {212			Self::Full(name) => Some(name.clone()),213			#[cfg(feature = "exp-destruct")]214			_ => None,215		}216	}217}218219#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]220#[derive(Debug, Clone, PartialEq, Trace)]221pub enum BindSpec {222	Field {223		into: Destruct,224		value: LocExpr,225	},226	Function {227		name: IStr,228		params: ParamsDesc,229		value: LocExpr,230	},231}232233#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]234#[derive(Debug, PartialEq, Trace)]235pub struct IfSpecData(pub LocExpr);236237#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]238#[derive(Debug, PartialEq, Trace)]239pub struct ForSpecData(pub IStr, pub LocExpr);240241#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]242#[derive(Debug, PartialEq, Trace)]243pub enum CompSpec {244	IfSpec(IfSpecData),245	ForSpec(ForSpecData),246}247248#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]249#[derive(Debug, PartialEq, Trace)]250pub struct ObjComp {251	pub pre_locals: Vec<BindSpec>,252	pub key: LocExpr,253	pub plus: bool,254	pub value: LocExpr,255	pub post_locals: Vec<BindSpec>,256	pub compspecs: Vec<CompSpec>,257}258259#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]260#[derive(Debug, PartialEq, Trace)]261pub enum ObjBody {262	MemberList(Vec<Member>),263	ObjComp(ObjComp),264}265266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]267#[derive(Debug, PartialEq, Eq, Clone, Copy, Trace)]268pub enum LiteralType {269	This,270	Super,271	Dollar,272	Null,273	True,274	False,275}276277#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]278#[derive(Debug, PartialEq, Trace)]279pub struct SliceDesc {280	pub start: Option<LocExpr>,281	pub end: Option<LocExpr>,282	pub step: Option<LocExpr>,283}284285/// Syntax base286#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]287#[derive(Debug, PartialEq, Trace)]288pub enum Expr {289	Literal(LiteralType),290291	/// String value: "hello"292	Str(IStr),293	/// Number: 1, 2.0, 2e+20294	Num(f64),295	/// Variable name: test296	Var(IStr),297298	/// Array of expressions: [1, 2, "Hello"]299	Arr(Vec<LocExpr>),300	/// Array comprehension:301	/// ```jsonnet302	///  ingredients: [303	///    { kind: kind, qty: 4 / 3 }304	///    for kind in [305	///      'Honey Syrup',306	///      'Lemon Juice',307	///      'Farmers Gin',308	///    ]309	///  ],310	/// ```311	ArrComp(LocExpr, Vec<CompSpec>),312313	/// Object: {a: 2}314	Obj(ObjBody),315	/// Object extension: var1 {b: 2}316	ObjExtend(LocExpr, ObjBody),317318	/// (obj)319	Parened(LocExpr),320321	/// -2322	UnaryOp(UnaryOpType, LocExpr),323	/// 2 - 2324	BinaryOp(LocExpr, BinaryOpType, LocExpr),325	/// assert 2 == 2 : "Math is broken"326	AssertExpr(AssertStmt, LocExpr),327	/// local a = 2; { b: a }328	LocalExpr(Vec<BindSpec>, LocExpr),329330	/// import "hello"331	Import(IStr),332	/// importStr "file.txt"333	ImportStr(IStr),334	/// importBin "file.txt"335	ImportBin(IStr),336	/// error "I'm broken"337	ErrorStmt(LocExpr),338	/// a(b, c)339	Apply(LocExpr, ArgsDesc, bool),340	/// a[b]341	Index(LocExpr, LocExpr),342	/// function(x) x343	Function(ParamsDesc, LocExpr),344	/// if true == false then 1 else 2345	IfElse {346		cond: IfSpecData,347		cond_then: LocExpr,348		cond_else: Option<LocExpr>,349	},350	Slice(LocExpr, SliceDesc),351}352353/// file, begin offset, end offset354#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]355#[derive(Clone, PartialEq, Eq, Trace)]356#[trace(skip)]357#[repr(C)]358pub struct ExprLocation(pub Source, pub u32, pub u32);359impl ExprLocation {360	pub fn belongs_to(&self, other: &ExprLocation) -> bool {361		other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2362	}363}364365#[cfg(target_pointer_width = "64")]366static_assertions::assert_eq_size!(ExprLocation, [u8; 16]);367368impl Debug for ExprLocation {369	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {370		write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)371	}372}373374/// Holds AST expression and its location in source file375#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]376#[derive(Clone, PartialEq, Trace)]377pub struct LocExpr(pub Rc<Expr>, pub ExprLocation);378379#[cfg(target_pointer_width = "64")]380static_assertions::assert_eq_size!(LocExpr, [u8; 24]);381382impl Debug for LocExpr {383	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {384		if f.alternate() {385			write!(f, "{:#?}", self.0)?;386		} else {387			write!(f, "{:?}", self.0)?;388		}389		write!(f, " from {:?}", self.1)?;390		Ok(())391	}392}