difftreelog
refactor(ir) drop Parened expr
in: master
4 files changed
crates/jrsonnet-evaluator/src/async_import.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/async_import.rs
+++ b/crates/jrsonnet-evaluator/src/async_import.rs
@@ -211,7 +211,7 @@
find_imports(expr, out);
}
}
- Expr::Parened(expr) | Expr::UnaryOp(_, expr) | Expr::ErrorStmt(expr) => {
+ Expr::UnaryOp(_, expr) | Expr::ErrorStmt(expr) => {
find_imports(expr, out);
}
}
crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs
@@ -53,7 +53,6 @@
| Expr::Num(_)
| Expr::Literal(LiteralType::False | LiteralType::True | LiteralType::Null) => true,
Expr::Arr(a) => a.iter().all(is_trivial),
- Expr::Parened(e) => is_trivial(e),
_ => false,
}
}
@@ -76,7 +75,6 @@
.collect(),
))
}
- Expr::Parened(e) => evaluate_trivial(e)?,
_ => return None,
})
}
@@ -414,7 +412,6 @@
Literal(LiteralType::True) => Val::Bool(true),
Literal(LiteralType::False) => Val::Bool(false),
Literal(LiteralType::Null) => Val::Null,
- Parened(e) => evaluate(ctx, e)?,
Str(v) => Val::string(v.clone()),
Num(v) => Val::try_num(*v)?,
// I have tried to remove special behavior from super by implementing standalone-super
crates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth1use std::{2 fmt::{self, Debug, Display},3 ops::Deref,4 rc::Rc,5};67use jrsonnet_gcmodule::Acyclic;8use jrsonnet_interner::IStr;910use crate::source::Source;1112#[derive(Debug, PartialEq, Acyclic)]13pub enum FieldName {14 /// {fixed: 2}15 Fixed(IStr),16 /// {["dyn"+"amic"]: 3}17 Dyn(LocExpr),18}1920#[derive(Debug, Clone, Copy, PartialEq, Eq, Acyclic)]21#[repr(u8)]22pub enum Visibility {23 /// :24 Normal,25 /// ::26 Hidden,27 /// :::28 Unhide,29}3031impl Visibility {32 pub fn is_visible(&self) -> bool {33 matches!(self, Self::Normal | Self::Unhide)34 }35}3637#[derive(Clone, Debug, PartialEq, Acyclic)]38pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);3940#[derive(Debug, PartialEq, Acyclic)]41pub struct FieldMember {42 pub name: FieldName,43 pub plus: bool,44 pub params: Option<ParamsDesc>,45 pub visibility: Visibility,46 pub value: LocExpr,47}4849#[derive(Debug, PartialEq, Acyclic)]50pub enum Member {51 Field(FieldMember),52 BindStmt(BindSpec),53 AssertStmt(AssertStmt),54}5556#[derive(Debug, Clone, Copy, PartialEq, Eq, Acyclic)]57pub enum UnaryOpType {58 Plus,59 Minus,60 BitNot,61 Not,62}6364impl Display for UnaryOpType {65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {66 use UnaryOpType::*;67 write!(68 f,69 "{}",70 match self {71 Plus => "+",72 Minus => "-",73 BitNot => "~",74 Not => "!",75 }76 )77 }78}7980#[derive(Debug, Clone, Copy, PartialEq, Eq, Acyclic)]81pub enum BinaryOpType {82 Mul,83 Div,8485 /// Implemented as intrinsic, put here for completeness86 Mod,8788 Add,89 Sub,9091 Lhs,92 Rhs,9394 Lt,95 Gt,96 Lte,97 Gte,9899 BitAnd,100 BitOr,101 BitXor,102103 Eq,104 Neq,105106 And,107 Or,108 #[cfg(feature = "exp-null-coaelse")]109 NullCoaelse,110111 // Equialent to std.objectHasEx(a, b, true)112 In,113}114115impl Display for BinaryOpType {116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {117 use BinaryOpType::*;118 write!(119 f,120 "{}",121 match self {122 Mul => "*",123 Div => "/",124 Mod => "%",125 Add => "+",126 Sub => "-",127 Lhs => "<<",128 Rhs => ">>",129 Lt => "<",130 Gt => ">",131 Lte => "<=",132 Gte => ">=",133 BitAnd => "&",134 BitOr => "|",135 BitXor => "^",136 Eq => "==",137 Neq => "!=",138 And => "&&",139 Or => "||",140 In => "in",141 #[cfg(feature = "exp-null-coaelse")]142 NullCoaelse => "??",143 }144 )145 }146}147148/// name, default value149#[derive(Debug, PartialEq, Acyclic)]150pub struct Param(pub Destruct, pub Option<LocExpr>);151152/// Defined function parameters153#[derive(Debug, Clone, PartialEq, Acyclic)]154pub struct ParamsDesc(pub Rc<Vec<Param>>);155156impl Deref for ParamsDesc {157 type Target = Vec<Param>;158 fn deref(&self) -> &Self::Target {159 &self.0160 }161}162163#[derive(Debug, PartialEq, Acyclic)]164pub struct ArgsDesc {165 pub unnamed: Vec<LocExpr>,166 pub named: Vec<(IStr, LocExpr)>,167}168impl ArgsDesc {169 pub fn new(unnamed: Vec<LocExpr>, named: Vec<(IStr, LocExpr)>) -> Self {170 Self { unnamed, named }171 }172}173174#[derive(Debug, Clone, PartialEq, Eq, Acyclic)]175pub enum DestructRest {176 /// ...rest177 Keep(IStr),178 /// ...179 Drop,180}181182#[derive(Debug, Clone, PartialEq, Acyclic)]183pub enum Destruct {184 Full(IStr),185 #[cfg(feature = "exp-destruct")]186 Skip,187 #[cfg(feature = "exp-destruct")]188 Array {189 start: Vec<Destruct>,190 rest: Option<DestructRest>,191 end: Vec<Destruct>,192 },193 #[cfg(feature = "exp-destruct")]194 Object {195 fields: Vec<(IStr, Option<Destruct>, Option<LocExpr>)>,196 rest: Option<DestructRest>,197 },198}199impl Destruct {200 /// Name of destructure, used for function parameter names201 pub fn name(&self) -> Option<IStr> {202 match self {203 Self::Full(name) => Some(name.clone()),204 #[cfg(feature = "exp-destruct")]205 _ => None,206 }207 }208 pub fn capacity_hint(&self) -> usize {209 #[cfg(feature = "exp-destruct")]210 fn cap_rest(rest: &Option<DestructRest>) -> usize {211 match rest {212 Some(DestructRest::Keep(_)) => 1,213 Some(DestructRest::Drop) => 0,214 None => 0,215 }216 }217 match self {218 Self::Full(_) => 1,219 #[cfg(feature = "exp-destruct")]220 Self::Skip => 0,221 #[cfg(feature = "exp-destruct")]222 Self::Array { start, rest, end } => {223 start.iter().map(Destruct::capacity_hint).sum::<usize>()224 + end.iter().map(Destruct::capacity_hint).sum::<usize>()225 + cap_rest(rest)226 }227 #[cfg(feature = "exp-destruct")]228 Self::Object { fields, rest } => {229 let mut out = 0;230 for (_, into, _) in fields {231 match into {232 Some(v) => out += v.capacity_hint(),233 // Field is destructured to default name234 None => out += 1,235 }236 }237 out + cap_rest(rest)238 }239 }240 }241}242243#[derive(Debug, Clone, PartialEq, Acyclic)]244pub enum BindSpec {245 Field {246 into: Destruct,247 value: LocExpr,248 },249 Function {250 name: IStr,251 params: ParamsDesc,252 value: LocExpr,253 },254}255impl BindSpec {256 pub fn capacity_hint(&self) -> usize {257 match self {258 BindSpec::Field { into, .. } => into.capacity_hint(),259 BindSpec::Function { .. } => 1,260 }261 }262}263264#[derive(Debug, PartialEq, Acyclic)]265pub struct IfSpecData(pub LocExpr);266267#[derive(Debug, PartialEq, Acyclic)]268pub struct ForSpecData(pub Destruct, pub LocExpr);269270#[derive(Debug, PartialEq, Acyclic)]271pub enum CompSpec {272 IfSpec(IfSpecData),273 ForSpec(ForSpecData),274}275276#[derive(Debug, PartialEq, Acyclic)]277pub struct ObjComp {278 pub pre_locals: Vec<BindSpec>,279 pub field: FieldMember,280 pub post_locals: Vec<BindSpec>,281 pub compspecs: Vec<CompSpec>,282}283284#[derive(Debug, PartialEq, Acyclic)]285pub enum ObjBody {286 MemberList(Vec<Member>),287 ObjComp(ObjComp),288}289290#[derive(Debug, PartialEq, Eq, Clone, Copy, Acyclic)]291pub enum LiteralType {292 This,293 Super,294 Dollar,295 Null,296 True,297 False,298}299300#[derive(Debug, PartialEq, Acyclic)]301pub struct SliceDesc {302 pub start: Option<LocExpr>,303 pub end: Option<LocExpr>,304 pub step: Option<LocExpr>,305}306307/// Syntax base308#[derive(Debug, PartialEq, Acyclic)]309pub enum Expr {310 Literal(LiteralType),311312 /// String value: "hello"313 Str(IStr),314 /// Number: 1, 2.0, 2e+20315 Num(f64),316 /// Variable name: test317 Var(IStr),318319 /// Array of expressions: [1, 2, "Hello"]320 Arr(Vec<LocExpr>),321 /// Array comprehension:322 /// ```jsonnet323 /// ingredients: [324 /// { kind: kind, qty: 4 / 3 }325 /// for kind in [326 /// 'Honey Syrup',327 /// 'Lemon Juice',328 /// 'Farmers Gin',329 /// ]330 /// ],331 /// ```332 ArrComp(LocExpr, Vec<CompSpec>),333334 /// Object: {a: 2}335 Obj(ObjBody),336 /// Object extension: var1 {b: 2}337 ObjExtend(LocExpr, ObjBody),338339 /// (obj)340 Parened(LocExpr),341342 /// -2343 UnaryOp(UnaryOpType, LocExpr),344 /// 2 - 2345 BinaryOp(LocExpr, BinaryOpType, LocExpr),346 /// assert 2 == 2 : "Math is broken"347 AssertExpr(AssertStmt, LocExpr),348 /// local a = 2; { b: a }349 LocalExpr(Vec<BindSpec>, LocExpr),350351 /// import "hello"352 Import(LocExpr),353 /// importStr "file.txt"354 ImportStr(LocExpr),355 /// importBin "file.txt"356 ImportBin(LocExpr),357 /// error "I'm broken"358 ErrorStmt(LocExpr),359 /// a(b, c)360 Apply(LocExpr, ArgsDesc, bool),361 /// a[b], a.b, a?.b362 Index {363 indexable: LocExpr,364 parts: Vec<IndexPart>,365 },366 /// function(x) x367 Function(ParamsDesc, LocExpr),368 /// if true == false then 1 else 2369 IfElse {370 cond: IfSpecData,371 cond_then: LocExpr,372 cond_else: Option<LocExpr>,373 },374 Slice(LocExpr, SliceDesc),375}376377#[derive(Debug, PartialEq, Acyclic)]378pub struct IndexPart {379 pub value: LocExpr,380 #[cfg(feature = "exp-null-coaelse")]381 pub null_coaelse: bool,382}383384/// file, begin offset, end offset385#[derive(Clone, PartialEq, Eq, Acyclic)]386#[repr(C)]387pub struct Span(pub Source, pub u32, pub u32);388impl Span {389 pub fn belongs_to(&self, other: &Span) -> bool {390 other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2391 }392}393394static_assertions::assert_eq_size!(Span, (usize, usize));395396impl Debug for Span {397 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {398 write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)399 }400}401402/// Holds AST expression and its location in source file403#[derive(Clone, PartialEq, Acyclic)]404pub struct LocExpr(Rc<(Expr, Span)>);405impl LocExpr {406 pub fn new(expr: Expr, span: Span) -> Self {407 Self(Rc::new((expr, span)))408 }409 #[inline]410 pub fn span(&self) -> Span {411 self.0 .1.clone()412 }413 #[inline]414 pub fn expr(&self) -> &Expr {415 &self.0 .0416 }417}418419static_assertions::assert_eq_size!(LocExpr, usize);420421impl Debug for LocExpr {422 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {423 let expr = self.expr();424 if f.alternate() {425 write!(f, "{:#?}", expr)?;426 } else {427 write!(f, "{:?}", expr)?;428 }429 write!(f, " from {:?}", self.span())?;430 Ok(())431 }432}1use std::{2 fmt::{self, Debug, Display},3 ops::Deref,4 rc::Rc,5};67use jrsonnet_gcmodule::Acyclic;8use jrsonnet_interner::IStr;910use crate::source::Source;1112#[derive(Debug, PartialEq, Acyclic)]13pub enum FieldName {14 /// {fixed: 2}15 Fixed(IStr),16 /// {["dyn"+"amic"]: 3}17 Dyn(LocExpr),18}1920#[derive(Debug, Clone, Copy, PartialEq, Eq, Acyclic)]21#[repr(u8)]22pub enum Visibility {23 /// :24 Normal,25 /// ::26 Hidden,27 /// :::28 Unhide,29}3031impl Visibility {32 pub fn is_visible(&self) -> bool {33 matches!(self, Self::Normal | Self::Unhide)34 }35}3637#[derive(Clone, Debug, PartialEq, Acyclic)]38pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);3940#[derive(Debug, PartialEq, Acyclic)]41pub struct FieldMember {42 pub name: FieldName,43 pub plus: bool,44 pub params: Option<ParamsDesc>,45 pub visibility: Visibility,46 pub value: LocExpr,47}4849#[derive(Debug, PartialEq, Acyclic)]50pub enum Member {51 Field(FieldMember),52 BindStmt(BindSpec),53 AssertStmt(AssertStmt),54}5556#[derive(Debug, Clone, Copy, PartialEq, Eq, Acyclic)]57pub enum UnaryOpType {58 Plus,59 Minus,60 BitNot,61 Not,62}6364impl Display for UnaryOpType {65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {66 use UnaryOpType::*;67 write!(68 f,69 "{}",70 match self {71 Plus => "+",72 Minus => "-",73 BitNot => "~",74 Not => "!",75 }76 )77 }78}7980#[derive(Debug, Clone, Copy, PartialEq, Eq, Acyclic)]81pub enum BinaryOpType {82 Mul,83 Div,8485 /// Implemented as intrinsic, put here for completeness86 Mod,8788 Add,89 Sub,9091 Lhs,92 Rhs,9394 Lt,95 Gt,96 Lte,97 Gte,9899 BitAnd,100 BitOr,101 BitXor,102103 Eq,104 Neq,105106 And,107 Or,108 #[cfg(feature = "exp-null-coaelse")]109 NullCoaelse,110111 // Equialent to std.objectHasEx(a, b, true)112 In,113}114115impl Display for BinaryOpType {116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {117 use BinaryOpType::*;118 write!(119 f,120 "{}",121 match self {122 Mul => "*",123 Div => "/",124 Mod => "%",125 Add => "+",126 Sub => "-",127 Lhs => "<<",128 Rhs => ">>",129 Lt => "<",130 Gt => ">",131 Lte => "<=",132 Gte => ">=",133 BitAnd => "&",134 BitOr => "|",135 BitXor => "^",136 Eq => "==",137 Neq => "!=",138 And => "&&",139 Or => "||",140 In => "in",141 #[cfg(feature = "exp-null-coaelse")]142 NullCoaelse => "??",143 }144 )145 }146}147148/// name, default value149#[derive(Debug, PartialEq, Acyclic)]150pub struct Param(pub Destruct, pub Option<LocExpr>);151152/// Defined function parameters153#[derive(Debug, Clone, PartialEq, Acyclic)]154pub struct ParamsDesc(pub Rc<Vec<Param>>);155156impl Deref for ParamsDesc {157 type Target = Vec<Param>;158 fn deref(&self) -> &Self::Target {159 &self.0160 }161}162163#[derive(Debug, PartialEq, Acyclic)]164pub struct ArgsDesc {165 pub unnamed: Vec<LocExpr>,166 pub named: Vec<(IStr, LocExpr)>,167}168impl ArgsDesc {169 pub fn new(unnamed: Vec<LocExpr>, named: Vec<(IStr, LocExpr)>) -> Self {170 Self { unnamed, named }171 }172}173174#[derive(Debug, Clone, PartialEq, Eq, Acyclic)]175pub enum DestructRest {176 /// ...rest177 Keep(IStr),178 /// ...179 Drop,180}181182#[derive(Debug, Clone, PartialEq, Acyclic)]183pub enum Destruct {184 Full(IStr),185 #[cfg(feature = "exp-destruct")]186 Skip,187 #[cfg(feature = "exp-destruct")]188 Array {189 start: Vec<Destruct>,190 rest: Option<DestructRest>,191 end: Vec<Destruct>,192 },193 #[cfg(feature = "exp-destruct")]194 Object {195 fields: Vec<(IStr, Option<Destruct>, Option<LocExpr>)>,196 rest: Option<DestructRest>,197 },198}199impl Destruct {200 /// Name of destructure, used for function parameter names201 pub fn name(&self) -> Option<IStr> {202 match self {203 Self::Full(name) => Some(name.clone()),204 #[cfg(feature = "exp-destruct")]205 _ => None,206 }207 }208 pub fn capacity_hint(&self) -> usize {209 #[cfg(feature = "exp-destruct")]210 fn cap_rest(rest: &Option<DestructRest>) -> usize {211 match rest {212 Some(DestructRest::Keep(_)) => 1,213 Some(DestructRest::Drop) => 0,214 None => 0,215 }216 }217 match self {218 Self::Full(_) => 1,219 #[cfg(feature = "exp-destruct")]220 Self::Skip => 0,221 #[cfg(feature = "exp-destruct")]222 Self::Array { start, rest, end } => {223 start.iter().map(Destruct::capacity_hint).sum::<usize>()224 + end.iter().map(Destruct::capacity_hint).sum::<usize>()225 + cap_rest(rest)226 }227 #[cfg(feature = "exp-destruct")]228 Self::Object { fields, rest } => {229 let mut out = 0;230 for (_, into, _) in fields {231 match into {232 Some(v) => out += v.capacity_hint(),233 // Field is destructured to default name234 None => out += 1,235 }236 }237 out + cap_rest(rest)238 }239 }240 }241}242243#[derive(Debug, Clone, PartialEq, Acyclic)]244pub enum BindSpec {245 Field {246 into: Destruct,247 value: LocExpr,248 },249 Function {250 name: IStr,251 params: ParamsDesc,252 value: LocExpr,253 },254}255impl BindSpec {256 pub fn capacity_hint(&self) -> usize {257 match self {258 BindSpec::Field { into, .. } => into.capacity_hint(),259 BindSpec::Function { .. } => 1,260 }261 }262}263264#[derive(Debug, PartialEq, Acyclic)]265pub struct IfSpecData(pub LocExpr);266267#[derive(Debug, PartialEq, Acyclic)]268pub struct ForSpecData(pub Destruct, pub LocExpr);269270#[derive(Debug, PartialEq, Acyclic)]271pub enum CompSpec {272 IfSpec(IfSpecData),273 ForSpec(ForSpecData),274}275276#[derive(Debug, PartialEq, Acyclic)]277pub struct ObjComp {278 pub pre_locals: Vec<BindSpec>,279 pub field: FieldMember,280 pub post_locals: Vec<BindSpec>,281 pub compspecs: Vec<CompSpec>,282}283284#[derive(Debug, PartialEq, Acyclic)]285pub enum ObjBody {286 MemberList(Vec<Member>),287 ObjComp(ObjComp),288}289290#[derive(Debug, PartialEq, Eq, Clone, Copy, Acyclic)]291pub enum LiteralType {292 This,293 Super,294 Dollar,295 Null,296 True,297 False,298}299300#[derive(Debug, PartialEq, Acyclic)]301pub struct SliceDesc {302 pub start: Option<LocExpr>,303 pub end: Option<LocExpr>,304 pub step: Option<LocExpr>,305}306307/// Syntax base308#[derive(Debug, PartialEq, Acyclic)]309pub enum Expr {310 Literal(LiteralType),311312 /// String value: "hello"313 Str(IStr),314 /// Number: 1, 2.0, 2e+20315 Num(f64),316 /// Variable name: test317 Var(IStr),318319 /// Array of expressions: [1, 2, "Hello"]320 Arr(Vec<LocExpr>),321 /// Array comprehension:322 /// ```jsonnet323 /// ingredients: [324 /// { kind: kind, qty: 4 / 3 }325 /// for kind in [326 /// 'Honey Syrup',327 /// 'Lemon Juice',328 /// 'Farmers Gin',329 /// ]330 /// ],331 /// ```332 ArrComp(LocExpr, Vec<CompSpec>),333334 /// Object: {a: 2}335 Obj(ObjBody),336 /// Object extension: var1 {b: 2}337 ObjExtend(LocExpr, ObjBody),338339 /// -2340 UnaryOp(UnaryOpType, LocExpr),341 /// 2 - 2342 BinaryOp(LocExpr, BinaryOpType, LocExpr),343 /// assert 2 == 2 : "Math is broken"344 AssertExpr(AssertStmt, LocExpr),345 /// local a = 2; { b: a }346 LocalExpr(Vec<BindSpec>, LocExpr),347348 /// import "hello"349 Import(LocExpr),350 /// importStr "file.txt"351 ImportStr(LocExpr),352 /// importBin "file.txt"353 ImportBin(LocExpr),354 /// error "I'm broken"355 ErrorStmt(LocExpr),356 /// a(b, c)357 Apply(LocExpr, ArgsDesc, bool),358 /// a[b], a.b, a?.b359 Index {360 indexable: LocExpr,361 parts: Vec<IndexPart>,362 },363 /// function(x) x364 Function(ParamsDesc, LocExpr),365 /// if true == false then 1 else 2366 IfElse {367 cond: IfSpecData,368 cond_then: LocExpr,369 cond_else: Option<LocExpr>,370 },371 Slice(LocExpr, SliceDesc),372}373374#[derive(Debug, PartialEq, Acyclic)]375pub struct IndexPart {376 pub value: LocExpr,377 #[cfg(feature = "exp-null-coaelse")]378 pub null_coaelse: bool,379}380381/// file, begin offset, end offset382#[derive(Clone, PartialEq, Eq, Acyclic)]383#[repr(C)]384pub struct Span(pub Source, pub u32, pub u32);385impl Span {386 pub fn belongs_to(&self, other: &Span) -> bool {387 other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2388 }389}390391static_assertions::assert_eq_size!(Span, (usize, usize));392393impl Debug for Span {394 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {395 write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)396 }397}398399/// Holds AST expression and its location in source file400#[derive(Clone, PartialEq, Acyclic)]401pub struct LocExpr(Rc<(Expr, Span)>);402impl LocExpr {403 pub fn new(expr: Expr, span: Span) -> Self {404 Self(Rc::new((expr, span)))405 }406 #[inline]407 pub fn span(&self) -> Span {408 self.0 .1.clone()409 }410 #[inline]411 pub fn expr(&self) -> &Expr {412 &self.0 .0413 }414}415416static_assertions::assert_eq_size!(LocExpr, usize);417418impl Debug for LocExpr {419 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {420 let expr = self.expr();421 if f.alternate() {422 write!(f, "{:#?}", expr)?;423 } else {424 write!(f, "{:?}", expr)?;425 }426 write!(f, " from {:?}", self.span())?;427 Ok(())428 }429}crates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-parser/src/lib.rs
+++ b/crates/jrsonnet-parser/src/lib.rs
@@ -313,6 +313,7 @@
use UnaryOpType::*;
rule expr(s: &ParserSettings) -> LocExpr
= precedence! {
+ "(" _ e:expr(s) _ ")" {e}
start:position!() v:@ end:position!() { LocExpr::new(v, Span(s.source.clone(), start as u32, end as u32)) }
--
a:(@) _ binop(<"||">) _ b:@ {expr_bin!(a Or b)}
@@ -359,7 +360,6 @@
a:(@) _ "{" _ body:objinside(s) _ "}" {Expr::ObjExtend(a, body)}
--
e:expr_basic(s) {e}
- "(" _ e:expr(s) _ ")" {Expr::Parened(e)}
}
pub rule index_part(s: &ParserSettings) -> IndexPart
= n:("?" _ ensure_null_coaelse())? "." _ value:id_loc(s) {IndexPart {
@@ -559,25 +559,21 @@
el!(Expr::Num(2.0), 0, 1),
Add,
el!(
- Expr::Parened(el!(
- Expr::BinaryOp(
- el!(Expr::Num(2.0), 3, 4),
- Add,
- el!(
- Expr::BinaryOp(
- el!(Expr::Num(2.0), 5, 6),
- Mul,
- el!(Expr::Num(2.0), 7, 8),
- ),
- 5,
- 8
+ Expr::BinaryOp(
+ el!(Expr::Num(2.0), 3, 4),
+ Add,
+ el!(
+ Expr::BinaryOp(
+ el!(Expr::Num(2.0), 5, 6),
+ Mul,
+ el!(Expr::Num(2.0), 7, 8),
),
+ 5,
+ 8
),
- 3,
- 8
- )),
- 2,
- 9
+ ),
+ 3,
+ 8
),
),
0,