git.delta.rocks / jrsonnet / refs/commits / 32f6ee5b9541

difftreelog

source

crates/jrsonnet-parser/src/expr.rs7.9 KiBsourcehistory
1use std::{2	fmt::{Debug, Display},3	ops::Deref,4	path::{Path, PathBuf},5	rc::Rc,6};78use gcmodule::Trace;9use jrsonnet_interner::IStr;10#[cfg(feature = "serde")]11use serde::{Deserialize, Serialize};1213#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]14#[derive(Debug, PartialEq, Trace)]15pub enum FieldName {16	/// {fixed: 2}17	Fixed(IStr),18	/// {["dyn"+"amic"]: 3}19	Dyn(LocExpr),20}2122#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]23#[derive(Debug, Clone, Copy, PartialEq, Trace)]24pub enum Visibility {25	/// :26	Normal,27	/// ::28	Hidden,29	/// :::30	Unhide,31}3233impl Visibility {34	pub fn is_visible(&self) -> bool {35		matches!(self, Self::Normal | Self::Unhide)36	}37}3839#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]40#[derive(Clone, Debug, PartialEq, Trace)]41pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);4243#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]44#[derive(Debug, PartialEq, Trace)]45pub struct FieldMember {46	pub name: FieldName,47	pub plus: bool,48	pub params: Option<ParamsDesc>,49	pub visibility: Visibility,50	pub value: LocExpr,51}5253#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]54#[derive(Debug, PartialEq, Trace)]55pub enum Member {56	Field(FieldMember),57	BindStmt(BindSpec),58	AssertStmt(AssertStmt),59}6061#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]62#[derive(Debug, Clone, Copy, PartialEq, Trace)]63pub enum UnaryOpType {64	Plus,65	Minus,66	BitNot,67	Not,68}6970impl Display for UnaryOpType {71	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {72		use UnaryOpType::*;73		write!(74			f,75			"{}",76			match self {77				Plus => "+",78				Minus => "-",79				BitNot => "~",80				Not => "!",81			}82		)83	}84}8586#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]87#[derive(Debug, Clone, Copy, PartialEq, Trace)]88pub enum BinaryOpType {89	Mul,90	Div,9192	/// Implemented as intrinsic, put here for completeness93	Mod,9495	Add,96	Sub,9798	Lhs,99	Rhs,100101	Lt,102	Gt,103	Lte,104	Gte,105106	BitAnd,107	BitOr,108	BitXor,109110	Eq,111	Neq,112113	And,114	Or,115116	// Equialent to std.objectHasEx(a, b, true)117	In,118}119120impl Display for BinaryOpType {121	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {122		use BinaryOpType::*;123		write!(124			f,125			"{}",126			match self {127				Mul => "*",128				Div => "/",129				Mod => "%",130				Add => "+",131				Sub => "-",132				Lhs => "<<",133				Rhs => ">>",134				Lt => "<",135				Gt => ">",136				Lte => "<=",137				Gte => ">=",138				BitAnd => "&",139				BitOr => "|",140				BitXor => "^",141				Eq => "==",142				Neq => "!=",143				And => "&&",144				Or => "||",145				In => "in",146			}147		)148	}149}150151/// name, default value152#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]153#[derive(Debug, PartialEq, Trace)]154pub struct Param(pub IStr, pub Option<LocExpr>);155156/// Defined function parameters157#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]158#[derive(Debug, Clone, PartialEq, Trace)]159pub struct ParamsDesc(pub Rc<Vec<Param>>);160161impl Deref for ParamsDesc {162	type Target = Vec<Param>;163	fn deref(&self) -> &Self::Target {164		&self.0165	}166}167168#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]169#[derive(Debug, PartialEq, Trace)]170pub struct ArgsDesc {171	pub unnamed: Vec<LocExpr>,172	pub named: Vec<(IStr, LocExpr)>,173}174impl ArgsDesc {175	pub fn new(unnamed: Vec<LocExpr>, named: Vec<(IStr, LocExpr)>) -> Self {176		Self { unnamed, named }177	}178}179180#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]181#[derive(Debug, Clone, PartialEq, Trace)]182pub enum DestructRest {183	/// ...rest184	Keep(IStr),185	/// ...186	Drop,187}188189#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]190#[derive(Debug, Clone, PartialEq, Trace)]191pub enum Destruct {192	Full(IStr),193	#[cfg(feature = "exp-destruct")]194	Skip,195	#[cfg(feature = "exp-destruct")]196	Array {197		start: Vec<Destruct>,198		rest: Option<DestructRest>,199		end: Vec<Destruct>,200	},201	#[cfg(feature = "exp-destruct")]202	Object {203		fields: Vec<(IStr, Option<Destruct>)>,204		rest: Option<DestructRest>,205	},206}207impl Destruct {208	pub fn name(&self) -> Option<IStr> {209		match self {210			Self::Full(name) => Some(name.clone()),211			#[cfg(feature = "exp-destruct")]212			_ => None,213		}214	}215}216217#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]218#[derive(Debug, Clone, PartialEq, Trace)]219pub enum BindSpec {220	Field {221		into: Destruct,222		value: LocExpr,223	},224	Function {225		name: IStr,226		params: ParamsDesc,227		value: LocExpr,228	},229}230231#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]232#[derive(Debug, PartialEq, Trace)]233pub struct IfSpecData(pub LocExpr);234235#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]236#[derive(Debug, PartialEq, Trace)]237pub struct ForSpecData(pub IStr, pub LocExpr);238239#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]240#[derive(Debug, PartialEq, Trace)]241pub enum CompSpec {242	IfSpec(IfSpecData),243	ForSpec(ForSpecData),244}245246#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]247#[derive(Debug, PartialEq, Trace)]248pub struct ObjComp {249	pub pre_locals: Vec<BindSpec>,250	pub key: LocExpr,251	pub plus: bool,252	pub value: LocExpr,253	pub post_locals: Vec<BindSpec>,254	pub compspecs: Vec<CompSpec>,255}256257#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]258#[derive(Debug, PartialEq, Trace)]259pub enum ObjBody {260	MemberList(Vec<Member>),261	ObjComp(ObjComp),262}263264#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]265#[derive(Debug, PartialEq, Clone, Copy, Trace)]266pub enum LiteralType {267	This,268	Super,269	Dollar,270	Null,271	True,272	False,273}274275#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]276#[derive(Debug, PartialEq, Trace)]277pub struct SliceDesc {278	pub start: Option<LocExpr>,279	pub end: Option<LocExpr>,280	pub step: Option<LocExpr>,281}282283/// Syntax base284#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]285#[derive(Debug, PartialEq, Trace)]286pub enum Expr {287	Literal(LiteralType),288289	/// String value: "hello"290	Str(IStr),291	/// Number: 1, 2.0, 2e+20292	Num(f64),293	/// Variable name: test294	Var(IStr),295296	/// Array of expressions: [1, 2, "Hello"]297	Arr(Vec<LocExpr>),298	/// Array comprehension:299	/// ```jsonnet300	///  ingredients: [301	///    { kind: kind, qty: 4 / 3 }302	///    for kind in [303	///      'Honey Syrup',304	///      'Lemon Juice',305	///      'Farmers Gin',306	///    ]307	///  ],308	/// ```309	ArrComp(LocExpr, Vec<CompSpec>),310311	/// Object: {a: 2}312	Obj(ObjBody),313	/// Object extension: var1 {b: 2}314	ObjExtend(LocExpr, ObjBody),315316	/// (obj)317	Parened(LocExpr),318319	/// -2320	UnaryOp(UnaryOpType, LocExpr),321	/// 2 - 2322	BinaryOp(LocExpr, BinaryOpType, LocExpr),323	/// assert 2 == 2 : "Math is broken"324	AssertExpr(AssertStmt, LocExpr),325	/// local a = 2; { b: a }326	LocalExpr(Vec<BindSpec>, LocExpr),327328	/// import "hello"329	Import(PathBuf),330	/// importStr "file.txt"331	ImportStr(PathBuf),332	/// importBin "file.txt"333	ImportBin(PathBuf),334	/// error "I'm broken"335	ErrorStmt(LocExpr),336	/// a(b, c)337	Apply(LocExpr, ArgsDesc, bool),338	/// a[b]339	Index(LocExpr, LocExpr),340	/// function(x) x341	Function(ParamsDesc, LocExpr),342	/// std.thisFile343	IntrinsicThisFile,344	/// std.id,345	IntrinsicId,346	/// std.primitiveEquals347	Intrinsic(IStr),348	/// if true == false then 1 else 2349	IfElse {350		cond: IfSpecData,351		cond_then: LocExpr,352		cond_else: Option<LocExpr>,353	},354	Slice(LocExpr, SliceDesc),355}356357/// file, begin offset, end offset358#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]359#[derive(Clone, PartialEq, Trace)]360#[skip_trace]361pub struct ExprLocation(pub Rc<Path>, pub usize, pub usize);362impl ExprLocation {363	pub fn belongs_to(&self, other: &ExprLocation) -> bool {364		other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2365	}366}367368impl Debug for ExprLocation {369	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::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);378379impl Debug for LocExpr {380	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {381		if f.alternate() {382			write!(f, "{:#?}", self.0)?;383		} else {384			write!(f, "{:?}", self.0)?;385		}386		write!(f, " from {:?}", self.1)?;387		Ok(())388	}389}