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

difftreelog

source

crates/jsonnet-parser/src/expr.rs4.9 KiBsourcehistory
1use std::{fmt::Debug, rc::Rc};23#[derive(Debug, Clone, PartialEq)]4pub enum FieldName {5	/// {fixed: 2}6	Fixed(String),7	/// {["dyn"+"amic"]: 3}8	Dyn(LocExpr),9}1011#[derive(Debug, Clone, PartialEq)]12pub enum Visibility {13	/// :14	Normal,15	/// ::16	Hidden,17	/// :::18	Unhide,19}2021#[derive(Debug, Clone, PartialEq)]22pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);2324#[derive(Debug, Clone, PartialEq)]25pub struct FieldMember {26	pub name: FieldName,27	pub plus: bool,28	pub params: Option<ParamsDesc>,29	pub visibility: Visibility,30	pub value: LocExpr,31}3233#[derive(Debug, Clone, PartialEq)]34pub enum Member {35	Field(FieldMember),36	BindStmt(BindSpec),37	AssertStmt(AssertStmt),38}3940#[derive(Debug, Clone, Copy, PartialEq)]41pub enum UnaryOpType {42	Plus,43	Minus,44	BitNot,45	Not,46}4748#[derive(Debug, Clone, Copy, PartialEq)]49pub enum BinaryOpType {50	Mul,51	Div,52	Mod,5354	Add,55	Sub,5657	Lhs,58	Rhs,5960	Lt,61	Gt,62	Lte,63	Gte,6465	In,6667	Eq,68	Ne,6970	BitAnd,71	BitOr,72	BitXor,7374	And,75	Or,76}7778/// name, default value79#[derive(Debug, Clone, PartialEq)]80pub struct Param(pub String, pub Option<LocExpr>);81/// Defined function parameters82#[derive(Debug, Clone, PartialEq)]83pub struct ParamsDesc(pub Vec<Param>);84impl ParamsDesc {85	pub fn with_defaults(&self) -> Vec<Param> {86		self.0.iter().filter(|e| e.1.is_some()).cloned().collect()87	}88}8990#[derive(Debug, Clone, PartialEq)]91pub struct Arg(pub Option<String>, pub LocExpr);92#[derive(Debug, Clone, PartialEq)]93pub struct ArgsDesc(pub Vec<Arg>);9495#[derive(Debug, Clone, PartialEq)]96pub struct BindSpec {97	pub name: String,98	pub params: Option<ParamsDesc>,99	pub value: LocExpr,100}101102#[derive(Debug, Clone, PartialEq)]103pub struct IfSpecData(pub LocExpr);104#[derive(Debug, Clone, PartialEq)]105pub struct ForSpecData(pub String, pub LocExpr);106107#[derive(Debug, Clone, PartialEq)]108pub enum CompSpec {109	IfSpec(IfSpecData),110	ForSpec(ForSpecData),111}112113#[derive(Debug, Clone, PartialEq)]114pub enum ObjBody {115	MemberList(Vec<Member>),116	ObjComp {117		pre_locals: Vec<BindSpec>,118		key: LocExpr,119		value: LocExpr,120		post_locals: Vec<BindSpec>,121		first: ForSpecData,122		rest: Vec<CompSpec>,123	},124}125126#[derive(Debug, Clone, PartialEq)]127pub enum LiteralType {128	This,129	Super,130	Dollar,131	Null,132	True,133	False,134}135136#[derive(Debug, Clone, PartialEq)]137pub struct SliceDesc {138	pub start: Option<LocExpr>,139	pub end: Option<LocExpr>,140	pub step: Option<LocExpr>,141}142143/// Syntax base144#[derive(Debug, Clone, PartialEq)]145pub enum Expr {146	Literal(LiteralType),147148	/// String value: "hello"149	Str(String),150	/// Number: 1, 2.0, 2e+20151	Num(f64),152	/// Variable name: test153	Var(String),154155	/// Array of expressions: [1, 2, "Hello"]156	Arr(Vec<LocExpr>),157	/// Array comprehension:158	/// ```jsonnet159	///  ingredients: [160	///    { kind: kind, qty: 4 / 3 }161	///    for kind in [162	///      'Honey Syrup',163	///      'Lemon Juice',164	///      'Farmers Gin',165	///    ]166	///  ],167	/// ```168	ArrComp(LocExpr, Vec<CompSpec>),169170	/// Object: {a: 2}171	Obj(ObjBody),172	/// Object extension: var1 {b: 2}173	ObjExtend(LocExpr, ObjBody),174175	/// (obj)176	Parened(LocExpr),177178	/// Params in function definition179	/// hello, world, test = 2180	Params(ParamsDesc),181	/// Args in function call182	/// 2 + 2, 3, named = 6183	Args(ArgsDesc),184185	/// -2186	UnaryOp(UnaryOpType, LocExpr),187	/// 2 - 2188	BinaryOp(LocExpr, BinaryOpType, LocExpr),189	/// assert 2 == 2 : "Math is broken"190	AssertExpr(AssertStmt, LocExpr),191	/// local a = 2; { b: a }192	LocalExpr(Vec<BindSpec>, LocExpr),193194	/// a = 3195	Bind(BindSpec),196	/// import "hello"197	Import(String),198	/// importStr "file.txt"199	ImportStr(String),200	/// error "I'm broken"201	Error(LocExpr),202	/// a(b, c)203	Apply(LocExpr, ArgsDesc),204	///205	Select(LocExpr, String),206	/// a[b]207	Index(LocExpr, LocExpr),208	/// a[1::2]209	Slice(LocExpr, SliceDesc),210	/// function(x) x211	Function(ParamsDesc, LocExpr),212	/// if true == false then 1 else 2213	IfElse {214		cond: IfSpecData,215		cond_then: LocExpr,216		cond_else: Option<LocExpr>,217	},218	/// if 2 = 3219	IfSpec(IfSpecData),220	/// for elem in array221	ForSpec(ForSpecData),222}223224/// file, begin offset, end offset225#[derive(Clone, PartialEq)]226pub struct ExprLocation(pub String, pub usize, pub usize);227impl Debug for ExprLocation {228	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {229		write!(f, "{}:{:?}-{:?}", self.0, self.1, self.2)230	}231}232233/// Holds AST expression and its location in source file+234#[derive(Clone, PartialEq)]235pub struct LocExpr(pub Rc<Expr>, pub Option<Rc<ExprLocation>>);236impl Debug for LocExpr {237	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {238		write!(f, "{:?} from {:?}", self.0, self.1)239	}240}241242/// Creates LocExpr from Expr and ExprLocation components243#[macro_export]244macro_rules! loc_expr {245	($expr:expr, $need_loc:expr, ($name:expr, $start:expr, $end:expr)) => {246		LocExpr(247			std::rc::Rc::new($expr),248			if $need_loc {249				Some(std::rc::Rc::new(ExprLocation(250					$name.to_owned(),251					$start,252					$end,253				)))254			} else {255				None256				},257			)258	};259}260261/// Creates LocExpr without location info262#[macro_export]263macro_rules! loc_expr_todo {264	($expr:expr) => {265		LocExpr(Rc::new($expr), None)266	};267}