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

difftreelog

source

crates/jsonnet-parser/src/expr.rs5.2 KiBsourcehistory
1use std::{2	fmt::{Debug, Display},3	rc::Rc,4};56#[derive(Debug, Clone, PartialEq)]7pub enum FieldName {8	/// {fixed: 2}9	Fixed(String),10	/// {["dyn"+"amic"]: 3}11	Dyn(LocExpr),12}1314#[derive(Debug, Clone, PartialEq)]15pub enum Visibility {16	/// :17	Normal,18	/// ::19	Hidden,20	/// :::21	Unhide,22}2324#[derive(Debug, Clone, PartialEq)]25pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);2627#[derive(Debug, Clone, PartialEq)]28pub struct FieldMember {29	pub name: FieldName,30	pub plus: bool,31	pub params: Option<ParamsDesc>,32	pub visibility: Visibility,33	pub value: LocExpr,34}3536#[derive(Debug, Clone, PartialEq)]37pub enum Member {38	Field(FieldMember),39	BindStmt(BindSpec),40	AssertStmt(AssertStmt),41}4243#[derive(Debug, Clone, Copy, PartialEq)]44pub enum UnaryOpType {45	Plus,46	Minus,47	BitNot,48	Not,49}5051#[derive(Debug, Clone, Copy, PartialEq)]52pub enum BinaryOpType {53	Mul,54	Div,55	Mod,5657	Add,58	Sub,5960	Lhs,61	Rhs,6263	Lt,64	Gt,65	Lte,66	Gte,6768	In,6970	Eq,71	Ne,7273	BitAnd,74	BitOr,75	BitXor,7677	And,78	Or,79}8081/// name, default value82#[derive(Debug, Clone, PartialEq)]83pub struct Param(pub String, pub Option<LocExpr>);84/// Defined function parameters85#[derive(Debug, Clone, PartialEq)]86pub struct ParamsDesc(pub Vec<Param>);87impl ParamsDesc {88	pub fn with_defaults(&self) -> Vec<Param> {89		self.0.iter().filter(|e| e.1.is_some()).cloned().collect()90	}91}9293#[derive(Debug, Clone, PartialEq)]94pub struct Arg(pub Option<String>, pub LocExpr);95#[derive(Debug, Clone, PartialEq)]96pub struct ArgsDesc(pub Vec<Arg>);9798#[derive(Debug, Clone, PartialEq)]99pub struct BindSpec {100	pub name: String,101	pub params: Option<ParamsDesc>,102	pub value: LocExpr,103}104105#[derive(Debug, Clone, PartialEq)]106pub struct IfSpecData(pub LocExpr);107#[derive(Debug, Clone, PartialEq)]108pub struct ForSpecData(pub String, pub LocExpr);109110#[derive(Debug, Clone, PartialEq)]111pub enum CompSpec {112	IfSpec(IfSpecData),113	ForSpec(ForSpecData),114}115116#[derive(Debug, Clone, PartialEq)]117pub enum ObjBody {118	MemberList(Vec<Member>),119	ObjComp {120		pre_locals: Vec<BindSpec>,121		key: LocExpr,122		value: LocExpr,123		post_locals: Vec<BindSpec>,124		first: ForSpecData,125		rest: Vec<CompSpec>,126	},127}128129#[derive(Debug, Clone, PartialEq)]130pub enum LiteralType {131	This,132	Super,133	Dollar,134	Null,135	True,136	False,137}138impl Display for LiteralType {139	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {140		use LiteralType::*;141		match self {142			This => write!(f, "this"),143			Null => write!(f, "null"),144			True => write!(f, "true"),145			False => write!(f, "false"),146			_ => panic!("non printable item"),147		}148	}149}150151#[derive(Debug, Clone, PartialEq)]152pub struct SliceDesc {153	pub start: Option<LocExpr>,154	pub end: Option<LocExpr>,155	pub step: Option<LocExpr>,156}157158/// Syntax base159#[derive(Debug, Clone, PartialEq)]160pub enum Expr {161	Literal(LiteralType),162163	/// String value: "hello"164	Str(String),165	/// Number: 1, 2.0, 2e+20166	Num(f64),167	/// Variable name: test168	Var(String),169170	/// Array of expressions: [1, 2, "Hello"]171	Arr(Vec<LocExpr>),172	/// Array comprehension:173	/// ```jsonnet174	///  ingredients: [175	///    { kind: kind, qty: 4 / 3 }176	///    for kind in [177	///      'Honey Syrup',178	///      'Lemon Juice',179	///      'Farmers Gin',180	///    ]181	///  ],182	/// ```183	ArrComp(LocExpr, ForSpecData, Vec<CompSpec>),184185	/// Object: {a: 2}186	Obj(ObjBody),187	/// Object extension: var1 {b: 2}188	ObjExtend(LocExpr, ObjBody),189190	/// (obj)191	Parened(LocExpr),192193	/// Params in function definition194	/// hello, world, test = 2195	Params(ParamsDesc),196	/// Args in function call197	/// 2 + 2, 3, named = 6198	Args(ArgsDesc),199200	/// -2201	UnaryOp(UnaryOpType, LocExpr),202	/// 2 - 2203	BinaryOp(LocExpr, BinaryOpType, LocExpr),204	/// assert 2 == 2 : "Math is broken"205	AssertExpr(AssertStmt, LocExpr),206	/// local a = 2; { b: a }207	LocalExpr(Vec<BindSpec>, LocExpr),208209	/// a = 3210	Bind(BindSpec),211	/// import "hello"212	Import(String),213	/// importStr "file.txt"214	ImportStr(String),215	/// error "I'm broken"216	Error(LocExpr),217	/// a(b, c)218	Apply(LocExpr, ArgsDesc),219	///220	Select(LocExpr, String),221	/// a[b]222	Index(LocExpr, LocExpr),223	/// a[1::2]224	Slice(LocExpr, SliceDesc),225	/// function(x) x226	Function(ParamsDesc, LocExpr),227	/// if true == false then 1 else 2228	IfElse {229		cond: IfSpecData,230		cond_then: LocExpr,231		cond_else: Option<LocExpr>,232	},233	/// if 2 = 3234	IfSpec(IfSpecData),235	/// for elem in array236	ForSpec(ForSpecData),237}238239/// file, begin offset, end offset240#[derive(Clone, PartialEq)]241pub struct ExprLocation(pub String, pub usize, pub usize);242impl Debug for ExprLocation {243	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {244		write!(f, "{}:{:?}", self.0, self.1)245	}246}247248/// Holds AST expression and its location in source file+249#[derive(Clone, PartialEq)]250pub struct LocExpr(pub Rc<Expr>, pub Option<Rc<ExprLocation>>);251impl Debug for LocExpr {252	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {253		write!(f, "{:?} from {:?}", self.0, self.1)254	}255}256257/// Creates LocExpr from Expr and ExprLocation components258#[macro_export]259macro_rules! loc_expr {260	($expr:expr, $need_loc:expr, ($name:expr, $start:expr, $end:expr)) => {261		LocExpr(262			Rc::new($expr),263			if $need_loc {264				Some(Rc::new(ExprLocation($name.to_owned(), $start, $end)))265			} else {266				None267			},268		)269	};270}271272/// Creates LocExpr without location info273#[macro_export]274macro_rules! loc_expr_todo {275	($expr:expr) => {276		LocExpr(Rc::new($expr), None)277	};278}