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

difftreelog

source

crates/jrsonnet-parser/src/expr.rs7.1 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 struct BindSpec {183	pub name: IStr,184	pub params: Option<ParamsDesc>,185	pub value: LocExpr,186}187188#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]189#[derive(Debug, PartialEq, Trace)]190pub struct IfSpecData(pub LocExpr);191192#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]193#[derive(Debug, PartialEq, Trace)]194pub struct ForSpecData(pub IStr, pub LocExpr);195196#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]197#[derive(Debug, PartialEq, Trace)]198pub enum CompSpec {199	IfSpec(IfSpecData),200	ForSpec(ForSpecData),201}202203#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]204#[derive(Debug, PartialEq, Trace)]205pub struct ObjComp {206	pub pre_locals: Vec<BindSpec>,207	pub key: LocExpr,208	pub plus: bool,209	pub value: LocExpr,210	pub post_locals: Vec<BindSpec>,211	pub compspecs: Vec<CompSpec>,212}213214#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]215#[derive(Debug, PartialEq, Trace)]216pub enum ObjBody {217	MemberList(Vec<Member>),218	ObjComp(ObjComp),219}220221#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]222#[derive(Debug, PartialEq, Clone, Copy, Trace)]223pub enum LiteralType {224	This,225	Super,226	Dollar,227	Null,228	True,229	False,230}231232#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]233#[derive(Debug, PartialEq, Trace)]234pub struct SliceDesc {235	pub start: Option<LocExpr>,236	pub end: Option<LocExpr>,237	pub step: Option<LocExpr>,238}239240/// Syntax base241#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]242#[derive(Debug, PartialEq, Trace)]243pub enum Expr {244	Literal(LiteralType),245246	/// String value: "hello"247	Str(IStr),248	/// Number: 1, 2.0, 2e+20249	Num(f64),250	/// Variable name: test251	Var(IStr),252253	/// Array of expressions: [1, 2, "Hello"]254	Arr(Vec<LocExpr>),255	/// Array comprehension:256	/// ```jsonnet257	///  ingredients: [258	///    { kind: kind, qty: 4 / 3 }259	///    for kind in [260	///      'Honey Syrup',261	///      'Lemon Juice',262	///      'Farmers Gin',263	///    ]264	///  ],265	/// ```266	ArrComp(LocExpr, Vec<CompSpec>),267268	/// Object: {a: 2}269	Obj(ObjBody),270	/// Object extension: var1 {b: 2}271	ObjExtend(LocExpr, ObjBody),272273	/// (obj)274	Parened(LocExpr),275276	/// -2277	UnaryOp(UnaryOpType, LocExpr),278	/// 2 - 2279	BinaryOp(LocExpr, BinaryOpType, LocExpr),280	/// assert 2 == 2 : "Math is broken"281	AssertExpr(AssertStmt, LocExpr),282	/// local a = 2; { b: a }283	LocalExpr(Vec<BindSpec>, LocExpr),284285	/// import "hello"286	Import(PathBuf),287	/// importStr "file.txt"288	ImportStr(PathBuf),289	/// importBin "file.txt"290	ImportBin(PathBuf),291	/// error "I'm broken"292	ErrorStmt(LocExpr),293	/// a(b, c)294	Apply(LocExpr, ArgsDesc, bool),295	/// a[b]296	Index(LocExpr, LocExpr),297	/// function(x) x298	Function(ParamsDesc, LocExpr),299	/// std.primitiveEquals300	Intrinsic(IStr),301	/// if true == false then 1 else 2302	IfElse {303		cond: IfSpecData,304		cond_then: LocExpr,305		cond_else: Option<LocExpr>,306	},307	Slice(LocExpr, SliceDesc),308}309310/// file, begin offset, end offset311#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]312#[derive(Clone, PartialEq, Trace)]313#[skip_trace]314pub struct ExprLocation(pub Rc<Path>, pub usize, pub usize);315impl ExprLocation {316	pub fn belongs_to(&self, other: &ExprLocation) -> bool {317		other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2318	}319}320321impl Debug for ExprLocation {322	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {323		write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)324	}325}326327/// Holds AST expression and its location in source file328#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]329#[derive(Clone, PartialEq, Trace)]330pub struct LocExpr(pub Rc<Expr>, pub ExprLocation);331332impl Debug for LocExpr {333	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {334		if f.alternate() {335			write!(f, "{:#?}", self.0)?;336		} else {337			write!(f, "{:?}", self.0)?;338		}339		write!(f, " from {:?}", self.1)?;340		Ok(())341	}342}