git.delta.rocks / jrsonnet / refs/commits / 4f4be44d138e

difftreelog

source

crates/jrsonnet-parser/src/expr.rs7.0 KiBsourcehistory
1use gcmodule::Trace;2use jrsonnet_interner::IStr;3#[cfg(feature = "serde")]4use serde::{Deserialize, Serialize};5use std::{6	fmt::{Debug, Display},7	ops::Deref,8	path::{Path, PathBuf},9	rc::Rc,10};1112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]13#[derive(Debug, PartialEq, Trace)]14pub enum FieldName {15	/// {fixed: 2}16	Fixed(IStr),17	/// {["dyn"+"amic"]: 3}18	Dyn(LocExpr),19}2021#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]22#[derive(Debug, Clone, Copy, PartialEq, Trace)]23pub enum Visibility {24	/// :25	Normal,26	/// ::27	Hidden,28	/// :::29	Unhide,30}3132impl Visibility {33	pub fn is_visible(&self) -> bool {34		matches!(self, Self::Normal | Self::Unhide)35	}36}3738#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]39#[derive(Clone, Debug, PartialEq, Trace)]40pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);4142#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]43#[derive(Debug, PartialEq, Trace)]44pub struct FieldMember {45	pub name: FieldName,46	pub plus: bool,47	pub params: Option<ParamsDesc>,48	pub visibility: Visibility,49	pub value: LocExpr,50}5152#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]53#[derive(Debug, PartialEq, Trace)]54pub enum Member {55	Field(FieldMember),56	BindStmt(BindSpec),57	AssertStmt(AssertStmt),58}5960#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]61#[derive(Debug, Clone, Copy, PartialEq, Trace)]62pub enum UnaryOpType {63	Plus,64	Minus,65	BitNot,66	Not,67}6869impl Display for UnaryOpType {70	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {71		use UnaryOpType::*;72		write!(73			f,74			"{}",75			match self {76				Plus => "+",77				Minus => "-",78				BitNot => "~",79				Not => "!",80			}81		)82	}83}8485#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]86#[derive(Debug, Clone, Copy, PartialEq, Trace)]87pub enum BinaryOpType {88	Mul,89	Div,9091	/// Implemented as intrinsic, put here for completeness92	Mod,9394	Add,95	Sub,9697	Lhs,98	Rhs,99100	Lt,101	Gt,102	Lte,103	Gte,104105	BitAnd,106	BitOr,107	BitXor,108109	Eq,110	Neq,111112	And,113	Or,114115	// Equialent to std.objectHasEx(a, b, true)116	In,117}118119impl Display for BinaryOpType {120	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {121		use BinaryOpType::*;122		write!(123			f,124			"{}",125			match self {126				Mul => "*",127				Div => "/",128				Mod => "%",129				Add => "+",130				Sub => "-",131				Lhs => "<<",132				Rhs => ">>",133				Lt => "<",134				Gt => ">",135				Lte => "<=",136				Gte => ">=",137				BitAnd => "&",138				BitOr => "|",139				BitXor => "^",140				Eq => "==",141				Neq => "!=",142				And => "&&",143				Or => "||",144				In => "in",145			}146		)147	}148}149150/// name, default value151#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]152#[derive(Debug, PartialEq, Trace)]153pub struct Param(pub IStr, pub Option<LocExpr>);154155/// Defined function parameters156#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]157#[derive(Debug, Clone, PartialEq, Trace)]158pub struct ParamsDesc(pub Rc<Vec<Param>>);159160impl Deref for ParamsDesc {161	type Target = Vec<Param>;162	fn deref(&self) -> &Self::Target {163		&self.0164	}165}166167#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]168#[derive(Debug, PartialEq, Trace)]169pub struct ArgsDesc {170	pub unnamed: Vec<LocExpr>,171	pub named: Vec<(IStr, LocExpr)>,172}173impl ArgsDesc {174	pub fn new(unnamed: Vec<LocExpr>, named: Vec<(IStr, LocExpr)>) -> Self {175		Self { unnamed, named }176	}177}178179#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]180#[derive(Debug, Clone, PartialEq, Trace)]181pub struct BindSpec {182	pub name: IStr,183	pub params: Option<ParamsDesc>,184	pub value: LocExpr,185}186187#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]188#[derive(Debug, PartialEq, Trace)]189pub struct IfSpecData(pub LocExpr);190191#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]192#[derive(Debug, PartialEq, Trace)]193pub struct ForSpecData(pub IStr, pub LocExpr);194195#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]196#[derive(Debug, PartialEq, Trace)]197pub enum CompSpec {198	IfSpec(IfSpecData),199	ForSpec(ForSpecData),200}201202#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]203#[derive(Debug, PartialEq, Trace)]204pub struct ObjComp {205	pub pre_locals: Vec<BindSpec>,206	pub key: LocExpr,207	pub plus: bool,208	pub value: LocExpr,209	pub post_locals: Vec<BindSpec>,210	pub compspecs: Vec<CompSpec>,211}212213#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]214#[derive(Debug, PartialEq, Trace)]215pub enum ObjBody {216	MemberList(Vec<Member>),217	ObjComp(ObjComp),218}219220#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]221#[derive(Debug, PartialEq, Clone, Copy, Trace)]222pub enum LiteralType {223	This,224	Super,225	Dollar,226	Null,227	True,228	False,229}230231#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]232#[derive(Debug, PartialEq, Trace)]233pub struct SliceDesc {234	pub start: Option<LocExpr>,235	pub end: Option<LocExpr>,236	pub step: Option<LocExpr>,237}238239/// Syntax base240#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]241#[derive(Debug, PartialEq, Trace)]242pub enum Expr {243	Literal(LiteralType),244245	/// String value: "hello"246	Str(IStr),247	/// Number: 1, 2.0, 2e+20248	Num(f64),249	/// Variable name: test250	Var(IStr),251252	/// Array of expressions: [1, 2, "Hello"]253	Arr(Vec<LocExpr>),254	/// Array comprehension:255	/// ```jsonnet256	///  ingredients: [257	///    { kind: kind, qty: 4 / 3 }258	///    for kind in [259	///      'Honey Syrup',260	///      'Lemon Juice',261	///      'Farmers Gin',262	///    ]263	///  ],264	/// ```265	ArrComp(LocExpr, Vec<CompSpec>),266267	/// Object: {a: 2}268	Obj(ObjBody),269	/// Object extension: var1 {b: 2}270	ObjExtend(LocExpr, ObjBody),271272	/// (obj)273	Parened(LocExpr),274275	/// -2276	UnaryOp(UnaryOpType, LocExpr),277	/// 2 - 2278	BinaryOp(LocExpr, BinaryOpType, LocExpr),279	/// assert 2 == 2 : "Math is broken"280	AssertExpr(AssertStmt, LocExpr),281	/// local a = 2; { b: a }282	LocalExpr(Vec<BindSpec>, LocExpr),283284	/// import "hello"285	Import(PathBuf),286	/// importStr "file.txt"287	ImportStr(PathBuf),288	/// error "I'm broken"289	ErrorStmt(LocExpr),290	/// a(b, c)291	Apply(LocExpr, ArgsDesc, bool),292	/// a[b]293	Index(LocExpr, LocExpr),294	/// function(x) x295	Function(ParamsDesc, LocExpr),296	/// std.primitiveEquals297	Intrinsic(IStr),298	/// if true == false then 1 else 2299	IfElse {300		cond: IfSpecData,301		cond_then: LocExpr,302		cond_else: Option<LocExpr>,303	},304	Slice(LocExpr, SliceDesc),305}306307/// file, begin offset, end offset308#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]309#[derive(Clone, PartialEq, Trace)]310#[skip_trace]311pub struct ExprLocation(pub Rc<Path>, pub usize, pub usize);312impl ExprLocation {313	pub fn belongs_to(&self, other: &ExprLocation) -> bool {314		other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2315	}316}317318impl Debug for ExprLocation {319	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {320		write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)321	}322}323324/// Holds AST expression and its location in source file325#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]326#[derive(Clone, PartialEq, Trace)]327pub struct LocExpr(pub Rc<Expr>, pub ExprLocation);328329impl Debug for LocExpr {330	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {331		if f.alternate() {332			write!(f, "{:#?}", self.0)?;333		} else {334			write!(f, "{:?}", self.0)?;335		}336		write!(f, " from {:?}", self.1)?;337		Ok(())338	}339}