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

difftreelog

feat parse new object iteration syntax

tvmprlwuYaroslav Bolyukin2026-05-06parent: #0f5424f.patch.diff
in: master

10 files changed

modifiedcmds/jrsonnet/Cargo.tomldiffbeforeafterboth
31]31]
32# Destructuring of locals32# Destructuring of locals
33exp-destruct = ["jrsonnet-evaluator/exp-destruct"]33exp-destruct = ["jrsonnet-evaluator/exp-destruct"]
34# Iteration over objects yields [key, value] elements34# Iteration over objects using [key]: value syntax
35exp-object-iteration = ["jrsonnet-evaluator/exp-object-iteration"]35exp-object-iteration = ["jrsonnet-evaluator/exp-object-iteration"]
36# Bigint type36# Bigint type
37exp-bigint = ["jrsonnet-evaluator/exp-bigint", "jrsonnet-cli/exp-bigint"]37exp-bigint = ["jrsonnet-evaluator/exp-bigint", "jrsonnet-cli/exp-bigint"]
modifiedcrates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth
40 "jrsonnet-peg-parser?/exp-destruct",40 "jrsonnet-peg-parser?/exp-destruct",
41 "jrsonnet-ir-parser?/exp-destruct",41 "jrsonnet-ir-parser?/exp-destruct",
42]42]
43# Iteration over objects yields [key, value] elements43# Iteration over objects using [key]: value syntax
44exp-object-iteration = []44exp-object-iteration = [
45 "jrsonnet-ir/exp-object-iteration",
46 "jrsonnet-peg-parser?/exp-object-iteration",
47 "jrsonnet-ir-parser?/exp-object-iteration",
48]
45# Bigint type49# Bigint type
46exp-bigint = ["num-bigint", "jrsonnet-types/exp-bigint"]50exp-bigint = ["num-bigint", "jrsonnet-types/exp-bigint"]
modifiedcrates/jrsonnet-evaluator/src/analyze.rsdiffbeforeafterboth
1862 );1862 );
1863 (r, rest)1863 (r, rest)
1864 }1864 }
1865 #[cfg(feature = "exp-object-iteration")]
1866 CompSpec::ForObjSpec(_) => todo!(),
1865 }1867 }
1866 }1868 }
1867 let outer_depth = stack.depth;1869 let outer_depth = stack.depth;
modifiedcrates/jrsonnet-ir-parser/Cargo.tomldiffbeforeafterboth
1111
12[features]12[features]
13default = []13default = []
14experimental = ["exp-null-coaelse", "exp-destruct"]14experimental = ["exp-null-coaelse", "exp-destruct", "exp-object-iteration"]
15exp-null-coaelse = ["jrsonnet-ir/exp-null-coaelse"]15exp-null-coaelse = ["jrsonnet-ir/exp-null-coaelse"]
16exp-destruct = ["jrsonnet-ir/exp-destruct"]16exp-destruct = ["jrsonnet-ir/exp-destruct"]
17exp-object-iteration = ["jrsonnet-ir/exp-object-iteration"]
1718
18[dependencies]19[dependencies]
19insta.workspace = true20insta.workspace = true
modifiedcrates/jrsonnet-ir-parser/src/lib.rsdiffbeforeafterboth
66 !self.at_eof() && self.peek() == kind66 !self.at_eof() && self.peek() == kind
67 }67 }
6868
69 #[allow(dead_code)]
70 fn nth(&self, n: usize) -> SyntaxKind {
71 self.lexemes
72 .get(self.offset + n)
73 .map_or(SyntaxKind::EOF, |l| l.kind)
74 }
75
69 fn eat_any(&mut self) {76 fn eat_any(&mut self) {
70 self.offset += 1;77 self.offset += 1;
71 }78 }
561 }568 }
562}569}
563570
564fn for_spec(p: &mut Parser<'_>) -> Result<ForSpecData> {571fn for_spec(p: &mut Parser<'_>) -> Result<CompSpec> {
565 p.eat(T![for])?;572 p.eat(T![for])?;
573 #[cfg(feature = "exp-object-iteration")]
574 if p.at(T!['[']) && p.nth(1) == SyntaxKind::IDENT && p.nth(2) == T![']'] && p.nth(3) == T![:] {
575 p.eat(T!['['])?;
576 let key = ident(p)?;
577 p.eat(T![']'])?;
578 let visibility = visibility(p)?;
579 let value = destruct(p)?;
580 p.eat(T![in])?;
581 let over = expr(p)?;
582 return Ok(CompSpec::ForObjSpec(jrsonnet_ir::ForObjSpecData {
583 key,
584 visibility,
585 value,
586 over,
587 }));
588 }
566 let d = destruct(p)?;589 let d = destruct(p)?;
567 p.eat(T![in])?;590 p.eat(T![in])?;
568 let over = expr(p)?;591 let over = expr(p)?;
569 Ok(ForSpecData { destruct: d, over })592 Ok(CompSpec::ForSpec(ForSpecData { destruct: d, over }))
570}593}
571594
572fn compspecs(p: &mut Parser<'_>) -> Result<Vec<CompSpec>> {595fn compspecs(p: &mut Parser<'_>) -> Result<Vec<CompSpec>> {
573 let mut specs = Vec::new();596 let mut specs = Vec::new();
574 specs.push(CompSpec::ForSpec(for_spec(p)?));597 specs.push(for_spec(p)?);
575 loop {598 loop {
576 if p.at(T![for]) {599 if p.at(T![for]) {
577 specs.push(CompSpec::ForSpec(for_spec(p)?));600 specs.push(for_spec(p)?);
578 } else if p.at(T![if]) {601 } else if p.at(T![if]) {
579 let isd = if_spec_data(p)?;602 let isd = if_spec_data(p)?;
580 specs.push(CompSpec::IfSpec(isd));603 specs.push(CompSpec::IfSpec(isd));
modifiedcrates/jrsonnet-ir/Cargo.tomldiffbeforeafterboth
1212
13[features]13[features]
14default = []14default = []
15experimental = ["exp-destruct", "exp-null-coaelse"]15experimental = ["exp-destruct", "exp-null-coaelse", "exp-object-iteration"]
16exp-destruct = []16exp-destruct = []
17exp-null-coaelse = []17exp-null-coaelse = []
18exp-object-iteration = []
1819
19[dependencies]20[dependencies]
20jrsonnet-interner.workspace = true21jrsonnet-interner.workspace = true
modifiedcrates/jrsonnet-ir/src/expr.rsdiffbeforeafterboth
314 pub over: Expr,314 pub over: Expr,
315}315}
316
317#[cfg(feature = "exp-object-iteration")]
318#[derive(Debug, PartialEq, Acyclic)]
319pub struct ForObjSpecData {
320 pub key: IStr,
321 pub visibility: Visibility,
322 pub value: Destruct,
323 pub over: Expr,
324}
316325
317#[derive(Debug, PartialEq, Acyclic)]326#[derive(Debug, PartialEq, Acyclic)]
318pub enum CompSpec {327pub enum CompSpec {
319 IfSpec(IfSpecData),328 IfSpec(IfSpecData),
320 ForSpec(ForSpecData),329 ForSpec(ForSpecData),
330 #[cfg(feature = "exp-object-iteration")]
331 ForObjSpec(ForObjSpecData),
321}332}
322333
323#[derive(Debug, PartialEq, Acyclic)]334#[derive(Debug, PartialEq, Acyclic)]
modifiedcrates/jrsonnet-ir/src/visit.rsdiffbeforeafterboth
1use jrsonnet_interner::IStr;1use jrsonnet_interner::IStr;
22
3#[cfg(feature = "exp-object-iteration")]
4use crate::ForObjSpecData;
3use crate::{5use crate::{
4 ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BindSpec, CompSpec, Destruct, Expr, ExprParam,6 ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BindSpec, CompSpec, Destruct, Expr, ExprParam,
5 ExprParams, FieldMember, FieldName, ForSpecData, IfElse, IfSpecData, ImportKind, IndexPart,7 ExprParams, FieldMember, FieldName, ForSpecData, IfElse, IfSpecData, ImportKind, IndexPart,
69 visit_destruct(v, destruct);71 visit_destruct(v, destruct);
70 v.visit_expr(over);72 v.visit_expr(over);
71 }73 }
74 #[cfg(feature = "exp-object-iteration")]
75 CompSpec::ForObjSpec(for_obj_spec_data) => {
76 let ForObjSpecData {
77 key: _,
78 visibility: _,
79 value,
80 over,
81 } = for_obj_spec_data;
82 visit_destruct(v, value);
83 v.visit_expr(over);
84 }
72 }85 }
73}86}
74pub fn visit_params<V: Visitor>(v: &mut V, par: &ExprParams) {87pub fn visit_params<V: Visitor>(v: &mut V, par: &ExprParams) {
modifiedcrates/jrsonnet-peg-parser/Cargo.tomldiffbeforeafterboth
2222
23[features]23[features]
24default = []24default = []
25experimental = ["exp-destruct", "exp-null-coaelse"]25experimental = ["exp-destruct", "exp-null-coaelse", "exp-object-iteration"]
26exp-destruct = ["jrsonnet-ir/exp-destruct"]26exp-destruct = ["jrsonnet-ir/exp-destruct"]
27exp-null-coaelse = ["jrsonnet-ir/exp-null-coaelse"]27exp-null-coaelse = ["jrsonnet-ir/exp-null-coaelse"]
28exp-object-iteration = ["jrsonnet-ir/exp-object-iteration"]
2829
modifiedcrates/jrsonnet-peg-parser/src/lib.rsdiffbeforeafterboth
241 = i:spanned(<keyword("if")>, s) _ cond:expr(s) {IfSpecData { span: i.span, cond }}241 = i:spanned(<keyword("if")>, s) _ cond:expr(s) {IfSpecData { span: i.span, cond }}
242 pub rule forspec(s: &ParserSettings) -> ForSpecData242 pub rule forspec(s: &ParserSettings) -> ForSpecData
243 = keyword("for") _ destruct:destruct(s) _ keyword("in") _ over:expr(s) { ForSpecData { destruct, over } }243 = keyword("for") _ destruct:destruct(s) _ keyword("in") _ over:expr(s) { ForSpecData { destruct, over } }
244 rule ensure_object_iteration()
245 = "" {?
246 #[cfg(not(feature = "exp-object-iteration"))] return Err("!!!experimental object iteration was not enabled");
247 #[cfg(feature = "exp-object-iteration")] Ok(())
248 }
249 pub rule forobjspec(s: &ParserSettings) -> CompSpec
250 = ensure_object_iteration() keyword("for") _ "[" _ key:id() _ "]" _ vis:visibility() _ value:destruct(s) _ keyword("in") _ over:expr(s) {
251 #[cfg(feature = "exp-object-iteration")] return CompSpec::ForObjSpec(jrsonnet_ir::ForObjSpecData { key, visibility: vis, value, over });
252 #[cfg(not(feature = "exp-object-iteration"))] unreachable!("ensure_object_iteration will fail if feature is not enabled")
253 }
244 rule compspec(s: &ParserSettings) -> CompSpec254 rule compspec(s: &ParserSettings) -> CompSpec
245 = i:ifspec(s) { CompSpec::IfSpec(i) } / f:forspec(s) {CompSpec::ForSpec(f)}255 = i:ifspec(s) { CompSpec::IfSpec(i) } / f:forobjspec(s) { f } / f:forspec(s) {CompSpec::ForSpec(f)}
246 pub rule compspecs(s: &ParserSettings) -> Vec<CompSpec>256 pub rule compspecs(s: &ParserSettings) -> Vec<CompSpec>
247 = specs:compspec(s) ++ _ {?257 = specs:compspec(s) ++ _ {?
248 if !matches!(specs[0], CompSpec::ForSpec(_)) {258 if matches!(specs[0], CompSpec::IfSpec(_)) {
249 return Err("<first compspec should be for>")259 return Err("<first compspec should be for>")
250 }260 }
251 Ok(specs)261 Ok(specs)