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

difftreelog

source

crates/jrsonnet-parser/src/expr.rs10.1 KiBsourcehistory
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	/// {fixed: 2}19	Fixed(IStr),20	/// {["dyn"+"amic"]: 3}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	/// Implemented as intrinsic, put here for completeness125	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}182183/// name, default value184#[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}192193/// Defined function parameters194#[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}331332/// Syntax base333#[cfg_attr(feature = "serialize", derive(Serialize))]334#[cfg_attr(feature = "deserialize", derive(Deserialize))]335#[derive(Debug, PartialEq)]336pub enum Expr {337	Literal(LiteralType),338339	/// String value: "hello"340	Str(IStr),341	/// Number: 1, 2.0, 2e+20342	Num(f64),343	/// Variable name: test344	Var(IStr),345346	/// Array of expressions: [1, 2, "Hello"]347	Arr(Vec<LocExpr>),348	/// Array comprehension:349	/// ```jsonnet350	///  ingredients: [351	///    { kind: kind, qty: 4 / 3 }352	///    for kind in [353	///      'Honey Syrup',354	///      'Lemon Juice',355	///      'Farmers Gin',356	///    ]357	///  ],358	/// ```359	ArrComp(LocExpr, Vec<CompSpec>),360361	/// Object: {a: 2}362	Obj(ObjBody),363	/// Object extension: var1 {b: 2}364	ObjExtend(LocExpr, ObjBody),365366	/// (obj)367	Parened(LocExpr),368369	/// -2370	UnaryOp(UnaryOpType, LocExpr),371	/// 2 - 2372	BinaryOp(LocExpr, BinaryOpType, LocExpr),373	/// assert 2 == 2 : "Math is broken"374	AssertExpr(AssertStmt, LocExpr),375	/// local a = 2; { b: a }376	LocalExpr(Vec<BindSpec>, LocExpr),377378	/// import "hello"379	Import(PathBuf),380	/// importStr "file.txt"381	ImportStr(PathBuf),382	/// error "I'm broken"383	ErrorStmt(LocExpr),384	/// a(b, c)385	Apply(LocExpr, ArgsDesc, bool),386	/// a[b]387	Index(LocExpr, LocExpr),388	/// function(x) x389	Function(ParamsDesc, LocExpr),390	/// std.primitiveEquals391	Intrinsic(IStr),392	/// if true == false then 1 else 2393	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}403404/// file, begin offset, end offset405#[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}419420/// Holds AST expression and its location in source file421#[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}443444/// Creates LocExpr from Expr and ExprLocation components445#[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}458459/// Creates LocExpr without location info460#[macro_export]461macro_rules! loc_expr_todo {462	($expr:expr) => {463		LocExpr(Rc::new($expr), None)464	};465}