git.delta.rocks / jrsonnet / refs/commits / 864d125a72a2

difftreelog

refactor(ir) flatten

pvskvpwnYaroslav Bolyukin2026-04-25parent: #98b29c5.patch.diff
in: master

11 files changed

modifiedcrates/jrsonnet-ir-parser/src/lib.rsdiffbeforeafterboth
1use std::rc::Rc;
2
3use jrsonnet_gcmodule::Acyclic;1use jrsonnet_gcmodule::Acyclic;
4use jrsonnet_ir::{2use jrsonnet_ir::{
5 ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BinaryOpType, BindSpec, CompSpec, Destruct, Expr,3 unescape, ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BinaryOpType, BindSpec, CompSpec,
6 ExprParam, ExprParams, FieldMember, FieldName, ForSpecData, IStr, IfElse, IfSpecData,4 Destruct, Expr, ExprParam, ExprParams, FieldMember, FieldName, ForSpecData, IStr, IfElse,
7 ImportKind, IndexPart, LiteralType, Member, NumValue, ObjBody, ObjComp, ObjMembers, Slice,5 IfSpecData, ImportKind, IndexPart, LiteralType, Member, NumValue, ObjBody, ObjComp, ObjMembers,
8 SliceDesc, Source, Span, Spanned, UnaryOpType, Visibility, unescape,6 Slice, SliceDesc, Source, Span, Spanned, UnaryOpType, Visibility,
9};7};
10use jrsonnet_lexer::{Lexeme, Lexer, Span as LexSpan, SyntaxKind, T, collect_lexed_str_block};8use jrsonnet_lexer::{collect_lexed_str_block, Lexeme, Lexer, Span as LexSpan, SyntaxKind, T};
119
12pub struct ParserSettings {10pub struct ParserSettings {
13 pub source: Source,11 pub source: Source,
16#[derive(Debug, Clone)]14#[derive(Debug, Clone)]
17pub struct ParseError {15pub struct ParseError {
18 pub message: String,16 pub message: String,
19 pub location: LexSpan,17 pub location: Span,
20}18}
2119
22impl std::fmt::Display for ParseError {20impl std::fmt::Display for ParseError {
128 if self.offset == self.lexemes.len() {126 if self.offset == self.lexemes.len() {
129 let pos = self.lexemes.last().map_or(0, |v| v.range.1);127 let pos = self.lexemes.last().map_or(0, |v| v.range.1);
130 return ParseError {128 return ParseError {
131 location: LexSpan(pos, pos),129 location: Span(self.source.clone(), pos, pos),
132 message,130 message,
133 };131 };
134 }132 }
133 let LexSpan(start, end) = self.lexemes[self.offset].range;
135 ParseError {134 ParseError {
136 location: self.lexemes[self.offset].range,135 location: Span(self.source.clone(), start, end),
137 message,136 message,
138 }137 }
139 }138 }
293292
294fn destruct(p: &mut Parser<'_>) -> Result<Destruct> {293fn destruct(p: &mut Parser<'_>) -> Result<Destruct> {
295 if p.at(SyntaxKind::IDENT) {294 if p.at(SyntaxKind::IDENT) {
296 return Ok(Destruct::Full(ident(p)?));295 return Ok(Destruct::Full(spanned(p, ident)?));
297 }296 }
298 #[cfg(not(feature = "exp-destruct"))]297 #[cfg(not(feature = "exp-destruct"))]
299 return Err(p.error(format!("expected identifier, got {}", p.current_desc())));298 return Err(p.error(format!("expected identifier, got {}", p.current_desc())));
407 loop {406 loop {
408 let d = destruct(p)?;407 let d = destruct(p)?;
409 let default = if p.try_eat(T![=]) {408 let default = if p.try_eat(T![=]) {
410 Some(Rc::new(expr(p)?))409 Some(expr(p)?)
411 } else {410 } else {
412 None411 None
413 };412 };
441 if is_named {440 if is_named {
442 let name: IStr = ident(p)?;441 let name: IStr = ident(p)?;
443 p.eat(T![=])?;442 p.eat(T![=])?;
444 let value = Rc::new(expr(p)?);
445443
446 names.push(name);444 names.push(name);
447 values.push(value);445 values.push(expr(p)?);
448 named_started = true;446 named_started = true;
449 } else {447 } else {
450 if named_started {448 if named_started {
451 return Err(p.error("positional argument after named argument".into()));449 return Err(p.error("positional argument after named argument".into()));
452 }450 }
453 unnamed.push(Rc::new(expr(p)?));451 unnamed.push(expr(p)?);
454 }452 }
455 if !p.try_eat(T![,]) {453 if !p.try_eat(T![,]) {
456 break;454 break;
472 return Ok(BindSpec::Field { into: d, value });470 return Ok(BindSpec::Field { into: d, value });
473 }471 }
474 }472 }
475 let name = ident(p)?;473 let name_spanned = spanned(p, ident)?;
476 if p.try_eat(T!['(']) {474 if p.try_eat(T!['(']) {
477 let ps = params(p)?;475 let ps = params(p)?;
478 p.eat(T![')'])?;476 p.eat(T![')'])?;
479 p.eat(T![=])?;477 p.eat(T![=])?;
480 let value = Rc::new(expr(p)?);
481 Ok(BindSpec::Function {478 Ok(BindSpec::Function {
482 name,479 name: name_spanned.value,
483 params: ps,480 params: ps,
484 value,481 value: expr(p)?,
485 })482 })
486 } else {483 } else {
487 p.eat(T![=])?;484 p.eat(T![=])?;
488 let value = Rc::new(expr(p)?);
489 Ok(BindSpec::Field {485 Ok(BindSpec::Field {
490 into: Destruct::Full(name),486 into: Destruct::Full(name_spanned),
491 value,487 value: expr(p)?,
492 })488 })
493 }489 }
494}490}
529 let ps = params(p)?;525 let ps = params(p)?;
530 p.eat(T![')'])?;526 p.eat(T![')'])?;
531 let vis = visibility(p)?;527 let vis = visibility(p)?;
532 let value = Rc::new(expr(p)?);
533 Ok(FieldMember {528 Ok(FieldMember {
534 name,529 name,
535 plus: false,530 plus: false,
536 params: Some(ps),531 params: Some(ps),
537 visibility: vis,532 visibility: vis,
538 value,533 value: expr(p)?,
539 })534 })
540 } else {535 } else {
541 let plus = p.try_eat(T![+]);536 let plus = p.try_eat(T![+]);
542 let vis = visibility(p)?;537 let vis = visibility(p)?;
543 let value = Rc::new(expr(p)?);
544 Ok(FieldMember {538 Ok(FieldMember {
545 name,539 name,
546 plus,540 plus,
547 params: None,541 params: None,
548 visibility: vis,542 visibility: vis,
549 value,543 value: expr(p)?,
550 })544 })
551 }545 }
552}546}
589fn objinside(p: &mut Parser<'_>) -> Result<ObjBody> {583fn objinside(p: &mut Parser<'_>) -> Result<ObjBody> {
590 if p.at(T!['}']) {584 if p.at(T!['}']) {
591 return Ok(ObjBody::MemberList(ObjMembers {585 return Ok(ObjBody::MemberList(ObjMembers {
592 locals: Rc::new(Vec::new()),586 locals: Vec::new(),
593 asserts: Rc::new(Vec::new()),587 asserts: Vec::new(),
594 fields: Vec::new(),588 fields: Vec::new(),
595 }));589 }));
596 }590 }
627 }621 }
628 }622 }
629 Ok(ObjBody::ObjComp(ObjComp {623 Ok(ObjBody::ObjComp(ObjComp {
630 locals: Rc::new(locals),624 locals,
631 field: Rc::new(625 field: Box::new(
632 field_member.ok_or_else(|| p.error("missing object comprehension field".into()))?,626 field_member.ok_or_else(|| p.error("missing object comprehension field".into()))?,
633 ),627 ),
634 compspecs: specs,628 compspecs: specs,
645 }639 }
646 }640 }
647 Ok(ObjBody::MemberList(ObjMembers {641 Ok(ObjBody::MemberList(ObjMembers {
648 locals: Rc::new(locals),642 locals,
649 asserts: Rc::new(asserts),643 asserts,
650 fields,644 fields,
651 }))645 }))
652 }646 }
678 p.eat(T!['['])?;672 p.eat(T!['['])?;
679 if p.at(T![']']) {673 if p.at(T![']']) {
680 p.eat(T![']'])?;674 p.eat(T![']'])?;
681 return Ok(Expr::Arr(Rc::new(Vec::new())));675 return Ok(Expr::Arr(Vec::new()));
682 }676 }
683 let first = expr(p)?;677 let first = expr(p)?;
684 if p.at(T![for]) {678 if p.at(T![for]) {
685 let specs = compspecs(p)?;679 let specs = compspecs(p)?;
686 p.eat(T![']'])?;680 p.eat(T![']'])?;
687 Ok(Expr::ArrComp(Rc::new(first), specs))681 Ok(Expr::ArrComp(Box::new(first), specs))
688 } else if p.at(T![,]) && {682 } else if p.at(T![,]) && {
689 let next = p.offset + 1;683 let next = p.offset + 1;
690 next < p.lexemes.len() && p.lexemes[next].kind == T![for]684 next < p.lexemes.len() && p.lexemes[next].kind == T![for]
691 } {685 } {
692 p.eat(T![,])?;686 p.eat(T![,])?;
693 let specs = compspecs(p)?;687 let specs = compspecs(p)?;
694 p.eat(T![']'])?;688 p.eat(T![']'])?;
695 Ok(Expr::ArrComp(Rc::new(first), specs))689 Ok(Expr::ArrComp(Box::new(first), specs))
696 } else {690 } else {
697 let mut elems = vec![first];691 let mut elems = vec![first];
698 while p.try_eat(T![,]) {692 while p.try_eat(T![,]) {
702 elems.push(expr(p)?);696 elems.push(expr(p)?);
703 }697 }
704 p.eat(T![']'])?;698 p.eat(T![']'])?;
705 Ok(Expr::Arr(Rc::new(elems)))699 Ok(Expr::Arr(elems))
706 }700 }
707 }701 }
708702
735 let ps = params(p)?;729 let ps = params(p)?;
736 p.eat(T![')'])?;730 p.eat(T![')'])?;
737 let body = expr(p)?;731 let body = expr(p)?;
738 Ok(Expr::Function(ps, Rc::new(body)))732 Ok(Expr::Function(ps, Box::new(body)))
739 }733 }
740734
741 T![assert] => {735 T![assert] => {
742 let a = assert_stmt(p)?;736 let a = assert_stmt(p)?;
743 p.eat(T![;])?;737 p.eat(T![;])?;
744 let rest = expr(p)?;738 let rest = expr(p)?;
745 Ok(Expr::AssertExpr(Rc::new(AssertExpr { assert: a, rest })))739 Ok(Expr::AssertExpr(Box::new(AssertExpr { assert: a, rest })))
746 }740 }
747741
748 T![error] => {742 T![error] => {
891 p.eat(T!['{'])?;885 p.eat(T!['{'])?;
892 let body = objinside(p)?;886 let body = objinside(p)?;
893 p.eat(T!['}'])?;887 p.eat(T!['}'])?;
894 e = Expr::ObjExtend(Rc::new(e), body);888 e = Expr::ObjExtend(Box::new(e), body);
895 } else {889 } else {
896 break;890 break;
897 }891 }
1007 if let Some(desc) = lexeme.kind.error_description() {1001 if let Some(desc) = lexeme.kind.error_description() {
1008 return Err(ParseError {1002 return Err(ParseError {
1009 message: desc.to_owned(),1003 message: desc.to_owned(),
1010 location: lexeme.range,1004 location: Span(p.source.clone(), lexeme.range.0, lexeme.range.1),
1011 });1005 });
1012 }1006 }
1013 }1007 }
modifiedcrates/jrsonnet-ir-parser/src/snapshots/jrsonnet_ir_parser__tests__array_comp.snapdiffbeforeafterboth
10 ForSpec(10 ForSpec(
11 ForSpecData {11 ForSpecData {
12 destruct: Full(12 destruct: Full(
13 "x",13 "x" from virtual:<test>:7-8,
14 ),14 ),
15 over: Var(15 over: Var(
16 "arr" from virtual:<test>:12-15,16 "arr" from virtual:<test>:12-15,
modifiedcrates/jrsonnet-ir-parser/src/snapshots/jrsonnet_ir_parser__tests__function_and_call.snapdiffbeforeafterboth
10 exprs: [10 exprs: [
11 ExprParam {11 ExprParam {
12 destruct: Full(12 destruct: Full(
13 "x",13 "x" from virtual:<test>:8-9,
14 ),14 ),
15 default: None,15 default: None,
16 },16 },
17 ExprParam {17 ExprParam {
18 destruct: Full(18 destruct: Full(
19 "y",19 "y" from virtual:<test>:11-12,
20 ),20 ),
21 default: Some(21 default: Some(
22 Num(22 Num(
modifiedcrates/jrsonnet-ir-parser/src/snapshots/jrsonnet_ir_parser__tests__peg_snapshots@array_comp.jsonnet.snapdiffbeforeafterboth
35 ForSpec(35 ForSpec(
36 ForSpecData {36 ForSpecData {
37 destruct: Full(37 destruct: Full(
38 "x",38 "x" from virtual:<test>:23-24,
39 ),39 ),
40 over: Var(40 over: Var(
41 "arr" from virtual:<test>:28-31,41 "arr" from virtual:<test>:28-31,
52 ForSpec(52 ForSpec(
53 ForSpecData {53 ForSpecData {
54 destruct: Full(54 destruct: Full(
55 "a",55 "a" from virtual:<test>:41-42,
56 ),56 ),
57 over: Var(57 over: Var(
58 "b" from virtual:<test>:46-47,58 "b" from virtual:<test>:46-47,
70 ForSpec(70 ForSpec(
71 ForSpecData {71 ForSpecData {
72 destruct: Full(72 destruct: Full(
73 "e",73 "e" from virtual:<test>:57-58,
74 ),74 ),
75 over: Var(75 over: Var(
76 "f" from virtual:<test>:62-63,76 "f" from virtual:<test>:62-63,
modifiedcrates/jrsonnet-ir-parser/src/snapshots/jrsonnet_ir_parser__tests__peg_snapshots@default_nondefault.jsonnet.snapdiffbeforeafterboth
11 exprs: [11 exprs: [
12 ExprParam {12 ExprParam {
13 destruct: Full(13 destruct: Full(
14 "foo",14 "foo" from virtual:<test>:8-11,
15 ),15 ),
16 default: Some(16 default: Some(
17 Str(17 Str(
21 },21 },
22 ExprParam {22 ExprParam {
23 destruct: Full(23 destruct: Full(
24 "bar",24 "bar" from virtual:<test>:21-24,
25 ),25 ),
26 default: None,26 default: None,
27 },27 },
modifiedcrates/jrsonnet-ir-parser/src/snapshots/jrsonnet_ir_parser__tests__peg_snapshots@subexp.jsonnet.snapdiffbeforeafterboth
20 locals: [20 locals: [
21 Field {21 Field {
22 into: Full(22 into: Full(
23 "x",23 "x" from virtual:<test>:11-12,
24 ),24 ),
25 value: Num(25 value: Num(
26 1.0,26 1.0,
modifiedcrates/jrsonnet-ir/src/expr.rsdiffbeforeafterboth
1use std::{1use std::{
2 fmt::{self, Debug, Display},2 fmt::{self, Debug, Display},
3 ops::{Deref, RangeInclusive},3 ops::{Deref, RangeInclusive},
4 rc::Rc,
5};4};
65
7use jrsonnet_gcmodule::Acyclic;6use jrsonnet_gcmodule::Acyclic;
8use jrsonnet_interner::IStr;7use jrsonnet_interner::IStr;
98
10use crate::{9use crate::{
11 NumValue,
12 function::{FunctionSignature, ParamDefault, ParamName, ParamParse},10 function::{FunctionSignature, ParamDefault, ParamName, ParamParse},
13 source::Source,11 source::Source,
12 NumValue,
14};13};
1514
16#[derive(Debug, PartialEq, Acyclic)]15#[derive(Debug, PartialEq, Acyclic)]
50 pub plus: bool,49 pub plus: bool,
51 pub params: Option<ExprParams>,50 pub params: Option<ExprParams>,
52 pub visibility: Visibility,51 pub visibility: Visibility,
53 pub value: Rc<Expr>,52 pub value: Expr,
54}53}
5554
56#[derive(Debug, PartialEq, Acyclic)]55#[derive(Debug, PartialEq, Acyclic)]
156#[derive(Debug, PartialEq, Acyclic)]155#[derive(Debug, PartialEq, Acyclic)]
157pub struct ExprParam {156pub struct ExprParam {
158 pub destruct: Destruct,157 pub destruct: Destruct,
159 pub default: Option<Rc<Expr>>,158 pub default: Option<Expr>,
160}159}
161160
162/// Defined function parameters161/// Defined function parameters
163#[derive(Debug, Clone, PartialEq, Acyclic)]162#[derive(Debug, PartialEq, Acyclic)]
164pub struct ExprParams {163pub struct ExprParams {
165 pub exprs: Rc<Vec<ExprParam>>,164 pub exprs: Vec<ExprParam>,
166 pub signature: FunctionSignature,165 pub signature: FunctionSignature,
167 pub(crate) binds_len: usize,166 pub(crate) binds_len: usize,
168}167}
191 .collect(),190 .collect(),
192 ),191 ),
193 binds_len: exprs.iter().map(|v| v.destruct.binds_len()).sum(),192 binds_len: exprs.iter().map(|v| v.destruct.binds_len()).sum(),
194 exprs: Rc::new(exprs),193 exprs,
195 }194 }
196 }195 }
197}196}
198197
199#[derive(Debug, PartialEq, Acyclic)]198#[derive(Debug, PartialEq, Acyclic)]
200pub struct ArgsDesc {199pub struct ArgsDesc {
201 pub unnamed: Vec<Rc<Expr>>,200 pub unnamed: Vec<Expr>,
202 pub names: Vec<IStr>,201 pub names: Vec<IStr>,
203 pub values: Vec<Rc<Expr>>,202 pub values: Vec<Expr>,
204}203}
205impl ArgsDesc {204impl ArgsDesc {
206 pub fn new(unnamed: Vec<Rc<Expr>>, names: Vec<IStr>, values: Vec<Rc<Expr>>) -> Self {205 pub fn new(unnamed: Vec<Expr>, names: Vec<IStr>, values: Vec<Expr>) -> Self {
207 Self {206 Self {
208 unnamed,207 unnamed,
209 names,208 names,
222221
223#[derive(Debug, Clone, PartialEq, Acyclic)]222#[derive(Debug, Clone, PartialEq, Acyclic)]
224pub enum Destruct {223pub enum Destruct {
225 Full(IStr),224 Full(Spanned<IStr>),
226 #[cfg(feature = "exp-destruct")]225 #[cfg(feature = "exp-destruct")]
227 Skip,226 Skip,
228 #[cfg(feature = "exp-destruct")]227 #[cfg(feature = "exp-destruct")]
242 /// Name of destructure, used for function parameter names241 /// Name of destructure, used for function parameter names
243 pub fn name(&self) -> ParamName {242 pub fn name(&self) -> ParamName {
244 match self {243 match self {
245 Self::Full(name) => ParamName::Named(name.clone()),244 Self::Full(name) => ParamName::Named(name.value.clone()),
246 #[cfg(feature = "exp-destruct")]245 #[cfg(feature = "exp-destruct")]
247 _ => ParamName::Unnamed,246 _ => ParamName::Unnamed,
248 }247 }
286pub enum BindSpec {285pub enum BindSpec {
287 Field {286 Field {
288 into: Destruct,287 into: Destruct,
289 value: Rc<Expr>,288 value: Expr,
290 },289 },
291 Function {290 Function {
292 name: IStr,291 name: IStr,
293 params: ExprParams,292 params: ExprParams,
294 value: Rc<Expr>,293 value: Expr,
295 },294 },
296}295}
297impl BindSpec {296impl BindSpec {
323322
324#[derive(Debug, PartialEq, Acyclic)]323#[derive(Debug, PartialEq, Acyclic)]
325pub struct ObjComp {324pub struct ObjComp {
326 pub locals: Rc<Vec<BindSpec>>,325 pub locals: Vec<BindSpec>,
327 pub field: Rc<FieldMember>,326 pub field: Box<FieldMember>,
328 pub compspecs: Vec<CompSpec>,327 pub compspecs: Vec<CompSpec>,
329}328}
330329
331#[derive(Debug, PartialEq, Acyclic)]330#[derive(Debug, PartialEq, Acyclic)]
332pub struct ObjMembers {331pub struct ObjMembers {
333 pub locals: Rc<Vec<BindSpec>>,332 pub locals: Vec<BindSpec>,
334 pub asserts: Rc<Vec<AssertStmt>>,333 pub asserts: Vec<AssertStmt>,
335 pub fields: Vec<FieldMember>,334 pub fields: Vec<FieldMember>,
336}335}
337336
371 pub rhs: Expr,370 pub rhs: Expr,
372}371}
373372
374#[derive(Debug, PartialEq, Acyclic)]373#[derive(Debug, PartialEq, Acyclic, Clone, Copy)]
375pub enum ImportKind {374pub enum ImportKind {
376 Normal,375 Normal,
377 Str,376 Str,
404 Var(Spanned<IStr>),403 Var(Spanned<IStr>),
405404
406 /// Array of expressions: [1, 2, "Hello"]405 /// Array of expressions: [1, 2, "Hello"]
407 Arr(Rc<Vec<Expr>>),406 Arr(Vec<Expr>),
408 /// Array comprehension:407 /// Array comprehension:
409 /// ```jsonnet408 /// ```jsonnet
410 /// ingredients: [409 /// ingredients: [
416 /// ]415 /// ]
417 /// ],416 /// ],
418 /// ```417 /// ```
419 ArrComp(Rc<Expr>, Vec<CompSpec>),418 ArrComp(Box<Expr>, Vec<CompSpec>),
420419
421 /// Object: {a: 2}420 /// Object: {a: 2}
422 Obj(ObjBody),421 Obj(ObjBody),
423 /// Object extension: var1 {b: 2}422 /// Object extension: var1 {b: 2}
424 ObjExtend(Rc<Expr>, ObjBody),423 ObjExtend(Box<Expr>, ObjBody),
425424
426 /// -2425 /// -2
427 UnaryOp(UnaryOpType, Box<Expr>),426 UnaryOp(UnaryOpType, Box<Expr>),
428 /// 2 - 2427 /// 2 - 2
429 BinaryOp(Box<BinaryOp>),428 BinaryOp(Box<BinaryOp>),
430 /// assert 2 == 2 : "Math is broken"429 /// assert 2 == 2 : "Math is broken"
431 AssertExpr(Rc<AssertExpr>),430 AssertExpr(Box<AssertExpr>),
432 /// local a = 2; { b: a }431 /// local a = 2; { b: a }
433 LocalExpr(Vec<BindSpec>, Box<Expr>),432 LocalExpr(Vec<BindSpec>, Box<Expr>),
434433
444 parts: Vec<IndexPart>,443 parts: Vec<IndexPart>,
445 },444 },
446 /// function(x) x445 /// function(x) x
447 Function(ExprParams, Rc<Expr>),446 Function(ExprParams, Box<Expr>),
448 /// if true == false then 1 else 2447 /// if true == false then 1 else 2
449 IfElse(Box<IfElse>),448 IfElse(Box<IfElse>),
450 Slice(Box<Slice>),449 Slice(Box<Slice>),
modifiedcrates/jrsonnet-peg-parser/src/lib.rsdiffbeforeafterboth
61 rule keyword(id: &'static str) -> ()61 rule keyword(id: &'static str) -> ()
62 = #{|input, pos| input.parse_string_literal(pos, id)} end_of_ident()62 = #{|input, pos| input.parse_string_literal(pos, id)} end_of_ident()
6363
64 pub rule param(s: &ParserSettings) -> ExprParam = destruct:destruct(s) expr:(_ "=" _ expr:expr(s){expr})? { ExprParam { destruct, default: expr.map(Rc::new) } }64 pub rule param(s: &ParserSettings) -> ExprParam = destruct:destruct(s) default:(_ "=" _ default:expr(s){default})? { ExprParam { destruct, default } }
65 pub rule params(s: &ParserSettings) -> ExprParams65 pub rule params(s: &ParserSettings) -> ExprParams
66 = params:param(s) ** comma() comma()? { ExprParams::new(params) }66 = params:param(s) ** comma() comma()? { ExprParams::new(params) }
67 / { ExprParams::new(Vec::new()) }67 / { ExprParams::new(Vec::new()) }
6868
69 pub rule arg(s: &ParserSettings) -> (Option<IStr>, Rc<Expr>)69 pub rule arg(s: &ParserSettings) -> (Option<IStr>, Expr)
70 = name:(quiet! { (s:id() _ "=" !['='] _ {s})? } / expected!("<argument name>")) expr:expr(s) {(name, Rc::new(expr))}70 = name:(quiet! { (s:id() _ "=" !['='] _ {s})? } / expected!("<argument name>")) expr:expr(s) {(name, expr)}
7171
72 pub rule args(s: &ParserSettings) -> ArgsDesc72 pub rule args(s: &ParserSettings) -> ArgsDesc
73 = args:arg(s)**comma() comma()? {?73 = args:arg(s)**comma() comma()? {?
123 #[cfg(not(feature = "exp-destruct"))] Err("!!!experimental destructuring was not enabled")123 #[cfg(not(feature = "exp-destruct"))] Err("!!!experimental destructuring was not enabled")
124 }124 }
125 pub rule destruct(s: &ParserSettings) -> Destruct125 pub rule destruct(s: &ParserSettings) -> Destruct
126 = v:id() {Destruct::Full(v)}126 = v:spanned(<id()>, s) {Destruct::Full(v)}
127 / "?" {?127 / "?" {?
128 #[cfg(feature = "exp-destruct")] return Ok(Destruct::Skip);128 #[cfg(feature = "exp-destruct")] return Ok(Destruct::Skip);
129 #[cfg(not(feature = "exp-destruct"))] Err("!!!experimental destructuring was not enabled")129 #[cfg(not(feature = "exp-destruct"))] Err("!!!experimental destructuring was not enabled")
132 / obj:destruct_object(s) {obj}132 / obj:destruct_object(s) {obj}
133133
134 pub rule bind(s: &ParserSettings) -> BindSpec134 pub rule bind(s: &ParserSettings) -> BindSpec
135 = into:destruct(s) _ "=" _ value:expr(s) {BindSpec::Field{into, value: Rc::new(value)}}135 = into:destruct(s) _ "=" _ value:expr(s) {BindSpec::Field{into, value}}
136 / name:id() _ "(" _ params:params(s) _ ")" _ "=" _ value:expr(s) {BindSpec::Function{name, params, value: Rc::new(value)}}136 / name:id() _ "(" _ params:params(s) _ ")" _ "=" _ value:expr(s) {BindSpec::Function{name, params, value}}
137137
138 pub rule assertion(s: &ParserSettings) -> AssertStmt138 pub rule assertion(s: &ParserSettings) -> AssertStmt
139 = keyword("assert") _ assertion:spanned(<expr(s)>, s) message:(_ ":" _ e:expr(s) {e})? { AssertStmt{assertion, message} }139 = keyword("assert") _ assertion:spanned(<expr(s)>, s) message:(_ ":" _ e:expr(s) {e})? { AssertStmt{assertion, message} }
187 plus: plus.is_some(),187 plus: plus.is_some(),
188 params: None,188 params: None,
189 visibility,189 visibility,
190 value: Rc::new(value),190 value,
191 }}191 }}
192 / name:spanned(<field_name(s)>, s) _ "(" _ params:params(s) _ ")" _ visibility:visibility() _ value:expr(s) {FieldMember{192 / name:spanned(<field_name(s)>, s) _ "(" _ params:params(s) _ ")" _ visibility:visibility() _ value:expr(s) {FieldMember{
193 name,193 name,
194 plus: false,194 plus: false,
195 params: Some(params),195 params: Some(params),
196 visibility,196 visibility,
197 value: Rc::new(value),197 value,
198 }}198 }}
199 pub rule obj_local(s: &ParserSettings) -> BindSpec199 pub rule obj_local(s: &ParserSettings) -> BindSpec
200 = keyword("local") _ bind:bind(s) {bind}200 = keyword("local") _ bind:bind(s) {bind}
217 }217 }
218 }218 }
219 ObjBody::ObjComp(ObjComp {219 ObjBody::ObjComp(ObjComp {
220 locals: Rc::new(locals),220 locals,
221 field: field.map(Rc::new).ok_or("<missing object comprehension field>")?,221 field: Box::new(field.ok_or("<missing object comprehension field>")?),
222 compspecs222 compspecs
223 })223 })
224 } else {224 } else {
233 }233 }
234 }234 }
235 ObjBody::MemberList(ObjMembers {235 ObjBody::MemberList(ObjMembers {
236 locals: Rc::new(locals),236 locals,
237 asserts: Rc::new(asserts),237 asserts,
238 fields238 fields
239 })239 })
240 })240 })
259 pub rule obj_expr(s: &ParserSettings) -> Expr259 pub rule obj_expr(s: &ParserSettings) -> Expr
260 = "{" _ body:objinside(s) _ "}" {Expr::Obj(body)}260 = "{" _ body:objinside(s) _ "}" {Expr::Obj(body)}
261 pub rule array_expr(s: &ParserSettings) -> Expr261 pub rule array_expr(s: &ParserSettings) -> Expr
262 = "[" _ elems:(expr(s) ** comma()) _ comma()? "]" {Expr::Arr(Rc::new(elems))}262 = "[" _ elems:(expr(s) ** comma()) _ comma()? "]" {Expr::Arr(elems)}
263 pub rule array_comp_expr(s: &ParserSettings) -> Expr263 pub rule array_comp_expr(s: &ParserSettings) -> Expr
264 = "[" _ expr:expr(s) _ comma()? _ specs:(r: compspecs(s) _ {r}) "]" {264 = "[" _ expr:expr(s) _ comma()? _ specs:(r: compspecs(s) _ {r}) "]" {
265 Expr::ArrComp(Rc::new(expr), specs)265 Expr::ArrComp(Box::new(expr), specs)
266 }266 }
267 pub rule number_expr(s: &ParserSettings) -> Expr267 pub rule number_expr(s: &ParserSettings) -> Expr
268 = n:number() {? if let Some(n) = NumValue::new(n) {268 = n:number() {? if let Some(n) = NumValue::new(n) {
315 / local_expr(s)315 / local_expr(s)
316 / if_then_else_expr(s)316 / if_then_else_expr(s)
317317
318 / keyword("function") _ "(" _ params:params(s) _ ")" _ expr:expr(s) {Expr::Function(params, Rc::new(expr))}318 / keyword("function") _ "(" _ params:params(s) _ ")" _ expr:expr(s) {Expr::Function(params, Box::new(expr))}
319 / assert:assertion(s) _ ";" _ rest:expr(s) { Expr::AssertExpr(Rc::new(AssertExpr{319 / assert:assertion(s) _ ";" _ rest:expr(s) { Expr::AssertExpr(Box::new(AssertExpr{
320 assert, rest320 assert, rest
321 })) }321 })) }
322322
390 value:(@) _ "[" _ slice:slice_desc(s) _ "]" {Expr::Slice(Box::new(Slice{value, slice}))}390 value:(@) _ "[" _ slice:slice_desc(s) _ "]" {Expr::Slice(Box::new(Slice{value, slice}))}
391 indexable:(@) _ parts:index_part(s)+ {Expr::Index{indexable: Box::new(indexable), parts}}391 indexable:(@) _ parts:index_part(s)+ {Expr::Index{indexable: Box::new(indexable), parts}}
392 a:(@) _ args:spanned(<"(" _ a:args(s) _ ")" {a}>, s) ts:(_ keyword("tailstrict"))? {Expr::Apply(Box::new(a), args, ts.is_some())}392 a:(@) _ args:spanned(<"(" _ a:args(s) _ ")" {a}>, s) ts:(_ keyword("tailstrict"))? {Expr::Apply(Box::new(a), args, ts.is_some())}
393 a:(@) _ "{" _ body:objinside(s) _ "}" {Expr::ObjExtend(Rc::new(a), body)}393 a:(@) _ "{" _ body:objinside(s) _ "}" {Expr::ObjExtend(Box::new(a), body)}
394 --394 --
395 e:expr_basic(s) {e}395 e:expr_basic(s) {e}
396 "(" _ e:expr(s) _ ")" {e}396 "(" _ e:expr(s) _ ")" {e}
modifiedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@array_comp.jsonnet.snapdiffbeforeafterboth
35 ForSpec(35 ForSpec(
36 ForSpecData {36 ForSpecData {
37 destruct: Full(37 destruct: Full(
38 "x",38 "x" from virtual:<test>:23-24,
39 ),39 ),
40 over: Var(40 over: Var(
41 "arr" from virtual:<test>:28-31,41 "arr" from virtual:<test>:28-31,
52 ForSpec(52 ForSpec(
53 ForSpecData {53 ForSpecData {
54 destruct: Full(54 destruct: Full(
55 "a",55 "a" from virtual:<test>:41-42,
56 ),56 ),
57 over: Var(57 over: Var(
58 "b" from virtual:<test>:46-47,58 "b" from virtual:<test>:46-47,
70 ForSpec(70 ForSpec(
71 ForSpecData {71 ForSpecData {
72 destruct: Full(72 destruct: Full(
73 "e",73 "e" from virtual:<test>:57-58,
74 ),74 ),
75 over: Var(75 over: Var(
76 "f" from virtual:<test>:62-63,76 "f" from virtual:<test>:62-63,
modifiedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@default_nondefault.jsonnet.snapdiffbeforeafterboth
11 exprs: [11 exprs: [
12 ExprParam {12 ExprParam {
13 destruct: Full(13 destruct: Full(
14 "foo",14 "foo" from virtual:<test>:8-11,
15 ),15 ),
16 default: Some(16 default: Some(
17 Str(17 Str(
21 },21 },
22 ExprParam {22 ExprParam {
23 destruct: Full(23 destruct: Full(
24 "bar",24 "bar" from virtual:<test>:21-24,
25 ),25 ),
26 default: None,26 default: None,
27 },27 },
modifiedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@subexp.jsonnet.snapdiffbeforeafterboth
20 locals: [20 locals: [
21 Field {21 Field {
22 into: Full(22 into: Full(
23 "x",23 "x" from virtual:<test>:11-12,
24 ),24 ),
25 value: Num(25 value: Num(
26 1.0,26 1.0,