@@ -226,29 +226,6 @@ impl<'e> Evaluator<'e> {
226
226
}
227
227
}
228
228
229
- /// Run an expression as far as possible.
230
- /// however, if an error is encountered, instead of error-ing, wrap the error
231
- /// in a call the `error` extension function.
232
- pub fn run_to_error (
233
- & self ,
234
- e : & Expr ,
235
- slots : & SlotEnv ,
236
- ) -> ( PartialValue , Option < EvaluationError > ) {
237
- match self . partial_interpret ( e, slots) {
238
- Ok ( e) => ( e, None ) ,
239
- Err ( err) => {
240
- let arg = Expr :: val ( format ! ( "{err}" ) ) ;
241
- // PANIC SAFETY: Input to `parse` is fully static and a valid extension function name
242
- #[ allow( clippy:: unwrap_used) ]
243
- let fn_name = "error" . parse ( ) . unwrap ( ) ;
244
- (
245
- PartialValue :: Residual ( Expr :: call_extension_fn ( fn_name, vec ! [ arg] ) ) ,
246
- Some ( err) ,
247
- )
248
- }
249
- }
250
- }
251
-
252
229
/// Interpret an `Expr` into a `Value` in this evaluation environment.
253
230
///
254
231
/// Ensures the result is not a residual.
@@ -317,10 +294,9 @@ impl<'e> Evaluator<'e> {
317
294
ExprKind :: And { left, right } => {
318
295
match self . partial_interpret ( left, slots) ? {
319
296
// PE Case
320
- PartialValue :: Residual ( e) => Ok ( PartialValue :: Residual ( Expr :: and (
321
- e,
322
- self . run_to_error ( right. as_ref ( ) , slots) . 0 . into ( ) ,
323
- ) ) ) ,
297
+ PartialValue :: Residual ( e) => {
298
+ Ok ( PartialValue :: Residual ( Expr :: and ( e, right. as_ref ( ) . clone ( ) ) ) )
299
+ }
324
300
// Full eval case
325
301
PartialValue :: Value ( v) => {
326
302
if v. get_as_bool ( ) ? {
@@ -344,10 +320,9 @@ impl<'e> Evaluator<'e> {
344
320
ExprKind :: Or { left, right } => {
345
321
match self . partial_interpret ( left, slots) ? {
346
322
// PE cases
347
- PartialValue :: Residual ( r) => Ok ( PartialValue :: Residual ( Expr :: or (
348
- r,
349
- self . run_to_error ( right, slots) . 0 . into ( ) ,
350
- ) ) ) ,
323
+ PartialValue :: Residual ( r) => {
324
+ Ok ( PartialValue :: Residual ( Expr :: or ( r, right. as_ref ( ) . clone ( ) ) ) )
325
+ }
351
326
// Full eval case
352
327
PartialValue :: Value ( lhs) => {
353
328
if lhs. get_as_bool ( ) ? {
@@ -695,8 +670,8 @@ impl<'e> Evaluator<'e> {
695
670
fn eval_if (
696
671
& self ,
697
672
guard : & Expr ,
698
- consequent : & Expr ,
699
- alternative : & Expr ,
673
+ consequent : & Arc < Expr > ,
674
+ alternative : & Arc < Expr > ,
700
675
slots : & SlotEnv ,
701
676
) -> Result < PartialValue > {
702
677
match self . partial_interpret ( guard, slots) ? {
@@ -708,13 +683,7 @@ impl<'e> Evaluator<'e> {
708
683
}
709
684
}
710
685
PartialValue :: Residual ( guard) => {
711
- let ( consequent, consequent_errored) = self . run_to_error ( consequent, slots) ;
712
- let ( alternative, alternative_errored) = self . run_to_error ( alternative, slots) ;
713
- // If both branches errored, the expression will always error
714
- match ( consequent_errored, alternative_errored) {
715
- ( Some ( e) , Some ( _) ) => Err ( e) ,
716
- _ => Ok ( Expr :: ite ( guard, consequent. into ( ) , alternative. into ( ) ) . into ( ) ) ,
717
- }
686
+ Ok ( Expr :: ite_arc ( Arc :: new ( guard) , consequent. clone ( ) , alternative. clone ( ) ) . into ( ) )
718
687
}
719
688
}
720
689
}
@@ -4755,7 +4724,7 @@ pub mod test {
4755
4724
let b = Expr :: and ( Expr :: val ( 1 ) , Expr :: val ( 2 ) ) ;
4756
4725
let c = Expr :: val ( true ) ;
4757
4726
4758
- let e = Expr :: ite ( a, b, c) ;
4727
+ let e = Expr :: ite ( a, b. clone ( ) , c) ;
4759
4728
4760
4729
let es = Entities :: new ( ) ;
4761
4730
@@ -4768,10 +4737,7 @@ pub mod test {
4768
4737
r,
4769
4738
PartialValue :: Residual ( Expr :: ite(
4770
4739
Expr :: unknown( Unknown :: new_untyped( "guard" ) ) ,
4771
- Expr :: call_extension_fn(
4772
- "error" . parse( ) . unwrap( ) ,
4773
- vec![ Expr :: val( "type error: expected bool, got long" ) ]
4774
- ) ,
4740
+ b,
4775
4741
Expr :: val( true )
4776
4742
) )
4777
4743
)
@@ -4836,14 +4802,21 @@ pub mod test {
4836
4802
let b = Expr :: and ( Expr :: val ( 1 ) , Expr :: val ( 2 ) ) ;
4837
4803
let c = Expr :: or ( Expr :: val ( 1 ) , Expr :: val ( 3 ) ) ;
4838
4804
4839
- let e = Expr :: ite ( a, b, c) ;
4805
+ let e = Expr :: ite ( a, b. clone ( ) , c. clone ( ) ) ;
4840
4806
4841
4807
let es = Entities :: new ( ) ;
4842
4808
4843
4809
let exts = Extensions :: none ( ) ;
4844
4810
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
4845
4811
4846
- assert_matches ! ( eval. partial_interpret( & e, & HashMap :: new( ) ) , Err ( _) ) ;
4812
+ assert_eq ! (
4813
+ eval. partial_interpret( & e, & HashMap :: new( ) ) . unwrap( ) ,
4814
+ PartialValue :: Residual ( Expr :: ite(
4815
+ Expr :: unknown( Unknown :: new_untyped( "guard" ) ) ,
4816
+ b,
4817
+ c
4818
+ ) )
4819
+ ) ;
4847
4820
}
4848
4821
4849
4822
#[ test]
@@ -5090,22 +5063,15 @@ pub mod test {
5090
5063
let guard = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "a" ) ) , "field" . into ( ) ) ;
5091
5064
let cons = Expr :: binary_app ( BinaryOp :: Add , Expr :: val ( 1 ) , Expr :: val ( true ) ) ;
5092
5065
let alt = Expr :: val ( 2 ) ;
5093
- let e = Expr :: ite ( guard. clone ( ) , cons, alt) ;
5066
+ let e = Expr :: ite ( guard. clone ( ) , cons. clone ( ) , alt) ;
5094
5067
5095
5068
let es = Entities :: new ( ) ;
5096
5069
let exts = Extensions :: none ( ) ;
5097
5070
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5098
5071
5099
5072
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5100
5073
5101
- let expected = Expr :: ite (
5102
- guard,
5103
- Expr :: call_extension_fn (
5104
- "error" . parse ( ) . unwrap ( ) ,
5105
- vec ! [ Expr :: val( "type error: expected long, got bool" ) ] ,
5106
- ) ,
5107
- Expr :: val ( 2 ) ,
5108
- ) ;
5074
+ let expected = Expr :: ite ( guard, cons, Expr :: val ( 2 ) ) ;
5109
5075
5110
5076
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5111
5077
}
@@ -5115,22 +5081,15 @@ pub mod test {
5115
5081
let guard = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "a" ) ) , "field" . into ( ) ) ;
5116
5082
let cons = Expr :: val ( 2 ) ;
5117
5083
let alt = Expr :: binary_app ( BinaryOp :: Add , Expr :: val ( 1 ) , Expr :: val ( true ) ) ;
5118
- let e = Expr :: ite ( guard. clone ( ) , cons, alt) ;
5084
+ let e = Expr :: ite ( guard. clone ( ) , cons, alt. clone ( ) ) ;
5119
5085
5120
5086
let es = Entities :: new ( ) ;
5121
5087
let exts = Extensions :: none ( ) ;
5122
5088
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5123
5089
5124
5090
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5125
5091
5126
- let expected = Expr :: ite (
5127
- guard,
5128
- Expr :: val ( 2 ) ,
5129
- Expr :: call_extension_fn (
5130
- "error" . parse ( ) . unwrap ( ) ,
5131
- vec ! [ Expr :: val( "type error: expected long, got bool" ) ] ,
5132
- ) ,
5133
- ) ;
5092
+ let expected = Expr :: ite ( guard, Expr :: val ( 2 ) , alt) ;
5134
5093
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5135
5094
}
5136
5095
@@ -5139,13 +5098,16 @@ pub mod test {
5139
5098
let guard = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "a" ) ) , "field" . into ( ) ) ;
5140
5099
let cons = Expr :: binary_app ( BinaryOp :: Add , Expr :: val ( 1 ) , Expr :: val ( true ) ) ;
5141
5100
let alt = Expr :: less ( Expr :: val ( "hello" ) , Expr :: val ( "bye" ) ) ;
5142
- let e = Expr :: ite ( guard, cons, alt) ;
5101
+ let e = Expr :: ite ( guard. clone ( ) , cons. clone ( ) , alt. clone ( ) ) ;
5143
5102
5144
5103
let es = Entities :: new ( ) ;
5145
5104
let exts = Extensions :: none ( ) ;
5146
5105
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5147
5106
5148
- assert_matches ! ( eval. partial_interpret( & e, & HashMap :: new( ) ) , Err ( _) ) ;
5107
+ assert_eq ! (
5108
+ eval. partial_interpret( & e, & HashMap :: new( ) ) . unwrap( ) ,
5109
+ PartialValue :: Residual ( Expr :: ite( guard, cons, alt) )
5110
+ ) ;
5149
5111
}
5150
5112
5151
5113
// err && res -> err
@@ -5212,27 +5174,27 @@ pub mod test {
5212
5174
fn partial_and_res_true ( ) {
5213
5175
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5214
5176
let rhs = Expr :: binary_app ( BinaryOp :: Eq , Expr :: val ( 2 ) , Expr :: val ( 2 ) ) ;
5215
- let e = Expr :: and ( lhs. clone ( ) , rhs) ;
5177
+ let e = Expr :: and ( lhs. clone ( ) , rhs. clone ( ) ) ;
5216
5178
let es = Entities :: new ( ) ;
5217
5179
let exts = Extensions :: none ( ) ;
5218
5180
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5219
5181
5220
5182
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5221
- let expected = Expr :: and ( lhs, Expr :: val ( true ) ) ;
5183
+ let expected = Expr :: and ( lhs, rhs ) ;
5222
5184
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5223
5185
}
5224
5186
5225
5187
#[ test]
5226
5188
fn partial_and_res_false ( ) {
5227
5189
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5228
5190
let rhs = Expr :: binary_app ( BinaryOp :: Eq , Expr :: val ( 2 ) , Expr :: val ( 1 ) ) ;
5229
- let e = Expr :: and ( lhs. clone ( ) , rhs) ;
5191
+ let e = Expr :: and ( lhs. clone ( ) , rhs. clone ( ) ) ;
5230
5192
let es = Entities :: new ( ) ;
5231
5193
let exts = Extensions :: none ( ) ;
5232
5194
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5233
5195
5234
5196
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5235
- let expected = Expr :: and ( lhs, Expr :: val ( false ) ) ;
5197
+ let expected = Expr :: and ( lhs, rhs ) ;
5236
5198
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5237
5199
}
5238
5200
@@ -5260,7 +5222,7 @@ pub mod test {
5260
5222
fn partial_and_res_err ( ) {
5261
5223
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5262
5224
let rhs = Expr :: binary_app ( BinaryOp :: Add , Expr :: val ( 1 ) , Expr :: val ( "oops" ) ) ;
5263
- let e = Expr :: and ( lhs, rhs) ;
5225
+ let e = Expr :: and ( lhs, rhs. clone ( ) ) ;
5264
5226
let es = Entities :: new ( ) ;
5265
5227
let exts = Extensions :: none ( ) ;
5266
5228
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
@@ -5269,10 +5231,7 @@ pub mod test {
5269
5231
5270
5232
let expected = Expr :: and (
5271
5233
Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ,
5272
- Expr :: call_extension_fn (
5273
- "error" . parse ( ) . unwrap ( ) ,
5274
- vec ! [ Expr :: val( "type error: expected long, got string" ) ] ,
5275
- ) ,
5234
+ rhs,
5276
5235
) ;
5277
5236
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5278
5237
}
@@ -5314,27 +5273,27 @@ pub mod test {
5314
5273
fn partial_or_res_true ( ) {
5315
5274
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5316
5275
let rhs = Expr :: binary_app ( BinaryOp :: Eq , Expr :: val ( 2 ) , Expr :: val ( 2 ) ) ;
5317
- let e = Expr :: or ( lhs. clone ( ) , rhs) ;
5276
+ let e = Expr :: or ( lhs. clone ( ) , rhs. clone ( ) ) ;
5318
5277
let es = Entities :: new ( ) ;
5319
5278
let exts = Extensions :: none ( ) ;
5320
5279
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5321
5280
5322
5281
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5323
- let expected = Expr :: or ( lhs, Expr :: val ( true ) ) ;
5282
+ let expected = Expr :: or ( lhs, rhs ) ;
5324
5283
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5325
5284
}
5326
5285
5327
5286
#[ test]
5328
5287
fn partial_or_res_false ( ) {
5329
5288
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5330
5289
let rhs = Expr :: binary_app ( BinaryOp :: Eq , Expr :: val ( 2 ) , Expr :: val ( 1 ) ) ;
5331
- let e = Expr :: or ( lhs. clone ( ) , rhs) ;
5290
+ let e = Expr :: or ( lhs. clone ( ) , rhs. clone ( ) ) ;
5332
5291
let es = Entities :: new ( ) ;
5333
5292
let exts = Extensions :: none ( ) ;
5334
5293
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5335
5294
5336
5295
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5337
- let expected = Expr :: or ( lhs, Expr :: val ( false ) ) ;
5296
+ let expected = Expr :: or ( lhs, rhs ) ;
5338
5297
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5339
5298
}
5340
5299
@@ -5362,7 +5321,7 @@ pub mod test {
5362
5321
fn partial_or_res_err ( ) {
5363
5322
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5364
5323
let rhs = Expr :: binary_app ( BinaryOp :: Add , Expr :: val ( 1 ) , Expr :: val ( "oops" ) ) ;
5365
- let e = Expr :: or ( lhs, rhs) ;
5324
+ let e = Expr :: or ( lhs, rhs. clone ( ) ) ;
5366
5325
let es = Entities :: new ( ) ;
5367
5326
let exts = Extensions :: none ( ) ;
5368
5327
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
@@ -5371,10 +5330,7 @@ pub mod test {
5371
5330
5372
5331
let expected = Expr :: or (
5373
5332
Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ,
5374
- Expr :: call_extension_fn (
5375
- "error" . parse ( ) . unwrap ( ) ,
5376
- vec ! [ Expr :: val( "type error: expected long, got string" ) ] ,
5377
- ) ,
5333
+ rhs,
5378
5334
) ;
5379
5335
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5380
5336
}
0 commit comments