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

difftreelog

source

crates/jrsonnet-parser/src/expr.rs8.1 KiBsourcehistory
1use jrsonnet_interner::IStr;2#[cfg(feature = "deserialize")]3use serde::Deserialize;4#[cfg(feature = "serialize")]5use serde::Serialize;6use std::{7	fmt::{Debug, Display},8	ops::Deref,9	path::PathBuf,10	rc::Rc,11};1213#[cfg_attr(feature = "serialize", derive(Serialize))]14#[cfg_attr(feature = "deserialize", derive(Deserialize))]15#[derive(Debug, PartialEq)]16pub enum FieldName {17	/// {fixed: 2}18	Fixed(IStr),19	/// {["dyn"+"amic"]: 3}20	Dyn(LocExpr),21}2223#[cfg_attr(feature = "serialize", derive(Serialize))]24#[cfg_attr(feature = "deserialize", derive(Deserialize))]25#[derive(Debug, Clone, Copy, PartialEq)]26pub enum Visibility {27	/// :28	Normal,29	/// ::30	Hidden,31	/// :::32	Unhide,33}3435impl Visibility {36	pub fn is_visible(&self) -> bool {37		matches!(self, Self::Normal | Self::Unhide)38	}39}4041#[cfg_attr(feature = "serialize", derive(Serialize))]42#[cfg_attr(feature = "deserialize", derive(Deserialize))]43#[derive(Clone, Debug, PartialEq)]44pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);4546#[cfg_attr(feature = "serialize", derive(Serialize))]47#[cfg_attr(feature = "deserialize", derive(Deserialize))]48#[derive(Debug, PartialEq)]49pub struct FieldMember {50	pub name: FieldName,51	pub plus: bool,52	pub params: Option<ParamsDesc>,53	pub visibility: Visibility,54	pub value: LocExpr,55}5657#[cfg_attr(feature = "serialize", derive(Serialize))]58#[cfg_attr(feature = "deserialize", derive(Deserialize))]59#[derive(Debug, PartialEq)]60pub enum Member {61	Field(FieldMember),62	BindStmt(BindSpec),63	AssertStmt(AssertStmt),64}6566#[cfg_attr(feature = "serialize", derive(Serialize))]67#[cfg_attr(feature = "deserialize", derive(Deserialize))]68#[derive(Debug, Clone, Copy, PartialEq)]69pub enum UnaryOpType {70	Plus,71	Minus,72	BitNot,73	Not,74}75impl Display for UnaryOpType {76	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {77		use UnaryOpType::*;78		write!(79			f,80			"{}",81			match self {82				Plus => "+",83				Minus => "-",84				BitNot => "~",85				Not => "!",86			}87		)88	}89}9091#[cfg_attr(feature = "serialize", derive(Serialize))]92#[cfg_attr(feature = "deserialize", derive(Deserialize))]93#[derive(Debug, Clone, Copy, PartialEq)]94pub enum BinaryOpType {95	Mul,96	Div,9798	/// Implemented as intrinsic, put here for completeness99	Mod,100101	Add,102	Sub,103104	Lhs,105	Rhs,106107	Lt,108	Gt,109	Lte,110	Gte,111112	BitAnd,113	BitOr,114	BitXor,115116	Eq,117	Neq,118119	And,120	Or,121}122impl Display for BinaryOpType {123	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {124		use BinaryOpType::*;125		write!(126			f,127			"{}",128			match self {129				Mul => "*",130				Div => "/",131				Mod => "%",132				Add => "+",133				Sub => "-",134				Lhs => "<<",135				Rhs => ">>",136				Lt => "<",137				Gt => ">",138				Lte => "<=",139				Gte => ">=",140				BitAnd => "&",141				BitOr => "|",142				BitXor => "^",143				Eq => "==",144				Neq => "!=",145				And => "&&",146				Or => "||",147			}148		)149	}150}151152/// name, default value153#[cfg_attr(feature = "serialize", derive(Serialize))]154#[cfg_attr(feature = "deserialize", derive(Deserialize))]155#[derive(Debug, PartialEq)]156pub struct Param(pub IStr, pub Option<LocExpr>);157158/// Defined function parameters159#[cfg_attr(feature = "serialize", derive(Serialize))]160#[cfg_attr(feature = "deserialize", derive(Deserialize))]161#[derive(Debug, Clone, PartialEq)]162pub struct ParamsDesc(pub Rc<Vec<Param>>);163impl Deref for ParamsDesc {164	type Target = Vec<Param>;165	fn deref(&self) -> &Self::Target {166		&self.0167	}168}169170#[cfg_attr(feature = "serialize", derive(Serialize))]171#[cfg_attr(feature = "deserialize", derive(Deserialize))]172#[derive(Debug, PartialEq)]173pub struct Arg(pub Option<String>, pub LocExpr);174175#[cfg_attr(feature = "serialize", derive(Serialize))]176#[cfg_attr(feature = "deserialize", derive(Deserialize))]177#[derive(Debug, PartialEq)]178pub struct ArgsDesc(pub Vec<Arg>);179impl Deref for ArgsDesc {180	type Target = Vec<Arg>;181	fn deref(&self) -> &Self::Target {182		&self.0183	}184}185186#[cfg_attr(feature = "serialize", derive(Serialize))]187#[cfg_attr(feature = "deserialize", derive(Deserialize))]188#[derive(Debug, Clone, PartialEq)]189pub struct BindSpec {190	pub name: IStr,191	pub params: Option<ParamsDesc>,192	pub value: LocExpr,193}194195#[cfg_attr(feature = "serialize", derive(Serialize))]196#[cfg_attr(feature = "deserialize", derive(Deserialize))]197#[derive(Debug, PartialEq)]198pub struct IfSpecData(pub LocExpr);199200#[cfg_attr(feature = "serialize", derive(Serialize))]201#[cfg_attr(feature = "deserialize", derive(Deserialize))]202#[derive(Debug, PartialEq)]203pub struct ForSpecData(pub IStr, pub LocExpr);204205#[cfg_attr(feature = "serialize", derive(Serialize))]206#[cfg_attr(feature = "deserialize", derive(Deserialize))]207#[derive(Debug, PartialEq)]208pub enum CompSpec {209	IfSpec(IfSpecData),210	ForSpec(ForSpecData),211}212213#[cfg_attr(feature = "serialize", derive(Serialize))]214#[cfg_attr(feature = "deserialize", derive(Deserialize))]215#[derive(Debug, PartialEq)]216pub struct ObjComp {217	pub pre_locals: Vec<BindSpec>,218	pub key: LocExpr,219	pub value: LocExpr,220	pub post_locals: Vec<BindSpec>,221	pub compspecs: Vec<CompSpec>,222}223224#[cfg_attr(feature = "serialize", derive(Serialize))]225#[cfg_attr(feature = "deserialize", derive(Deserialize))]226#[derive(Debug, PartialEq)]227pub enum ObjBody {228	MemberList(Vec<Member>),229	ObjComp(ObjComp),230}231232#[cfg_attr(feature = "serialize", derive(Serialize))]233#[cfg_attr(feature = "deserialize", derive(Deserialize))]234#[derive(Debug, PartialEq, Clone, Copy)]235pub enum LiteralType {236	This,237	Super,238	Dollar,239	Null,240	True,241	False,242}243244#[derive(Debug, PartialEq)]245pub struct SliceDesc {246	pub start: Option<LocExpr>,247	pub end: Option<LocExpr>,248	pub step: Option<LocExpr>,249}250251/// Syntax base252#[cfg_attr(feature = "serialize", derive(Serialize))]253#[cfg_attr(feature = "deserialize", derive(Deserialize))]254#[derive(Debug, PartialEq)]255pub enum Expr {256	Literal(LiteralType),257258	/// String value: "hello"259	Str(IStr),260	/// Number: 1, 2.0, 2e+20261	Num(f64),262	/// Variable name: test263	Var(IStr),264265	/// Array of expressions: [1, 2, "Hello"]266	Arr(Vec<LocExpr>),267	/// Array comprehension:268	/// ```jsonnet269	///  ingredients: [270	///    { kind: kind, qty: 4 / 3 }271	///    for kind in [272	///      'Honey Syrup',273	///      'Lemon Juice',274	///      'Farmers Gin',275	///    ]276	///  ],277	/// ```278	ArrComp(LocExpr, Vec<CompSpec>),279280	/// Object: {a: 2}281	Obj(ObjBody),282	/// Object extension: var1 {b: 2}283	ObjExtend(LocExpr, ObjBody),284285	/// (obj)286	Parened(LocExpr),287288	/// -2289	UnaryOp(UnaryOpType, LocExpr),290	/// 2 - 2291	BinaryOp(LocExpr, BinaryOpType, LocExpr),292	/// assert 2 == 2 : "Math is broken"293	AssertExpr(AssertStmt, LocExpr),294	/// local a = 2; { b: a }295	LocalExpr(Vec<BindSpec>, LocExpr),296297	/// import "hello"298	Import(PathBuf),299	/// importStr "file.txt"300	ImportStr(PathBuf),301	/// error "I'm broken"302	ErrorStmt(LocExpr),303	/// a(b, c)304	Apply(LocExpr, ArgsDesc, bool),305	/// a[b]306	Index(LocExpr, LocExpr),307	/// function(x) x308	Function(ParamsDesc, LocExpr),309	/// std.primitiveEquals310	Intrinsic(IStr),311	/// if true == false then 1 else 2312	IfElse {313		cond: IfSpecData,314		cond_then: LocExpr,315		cond_else: Option<LocExpr>,316	},317}318319/// file, begin offset, end offset320#[cfg_attr(feature = "serialize", derive(Serialize))]321#[cfg_attr(feature = "deserialize", derive(Deserialize))]322#[derive(Clone, PartialEq)]323pub struct ExprLocation(pub Rc<PathBuf>, pub usize, pub usize);324impl Debug for ExprLocation {325	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {326		write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)327	}328}329330/// Holds AST expression and its location in source file331#[cfg_attr(feature = "serialize", derive(Serialize))]332#[cfg_attr(feature = "deserialize", derive(Deserialize))]333#[derive(Clone, PartialEq)]334pub struct LocExpr(pub Rc<Expr>, pub Option<ExprLocation>);335impl Debug for LocExpr {336	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {337		if f.alternate() {338			write!(f, "{:#?}", self.0)?;339		} else {340			write!(f, "{:?}", self.0)?;341		}342		if let Some(loc) = &self.1 {343			write!(f, " from {:?}", loc)?;344		}345		Ok(())346	}347}348349/// Creates LocExpr from Expr and ExprLocation components350#[macro_export]351macro_rules! loc_expr {352	($expr:expr, $need_loc:expr,($name:expr, $start:expr, $end:expr)) => {353		LocExpr(354			std::rc::Rc::new($expr),355			if $need_loc {356				Some(ExprLocation($name, $start, $end))357			} else {358				None359			},360		)361	};362}363364/// Creates LocExpr without location info365#[macro_export]366macro_rules! loc_expr_todo {367	($expr:expr) => {368		LocExpr(Rc::new($expr), None)369	};370}