@@ -223,29 +223,6 @@ impl<'e> Evaluator<'e> {
223
223
}
224
224
}
225
225
226
- /// Run an expression as far as possible.
227
- /// however, if an error is encountered, instead of error-ing, wrap the error
228
- /// in a call the `error` extension function.
229
- pub fn run_to_error (
230
- & self ,
231
- e : & Expr ,
232
- slots : & SlotEnv ,
233
- ) -> ( PartialValue , Option < EvaluationError > ) {
234
- match self . partial_interpret ( e, slots) {
235
- Ok ( e) => ( e, None ) ,
236
- Err ( err) => {
237
- let arg = Expr :: val ( format ! ( "{err}" ) ) ;
238
- // PANIC SAFETY: Input to `parse` is fully static and a valid extension function name
239
- #[ allow( clippy:: unwrap_used) ]
240
- let fn_name = "error" . parse ( ) . unwrap ( ) ;
241
- (
242
- PartialValue :: Residual ( Expr :: call_extension_fn ( fn_name, vec ! [ arg] ) ) ,
243
- Some ( err) ,
244
- )
245
- }
246
- }
247
- }
248
-
249
226
/// Interpret an `Expr` into a `Value` in this evaluation environment.
250
227
///
251
228
/// Ensures the result is not a residual.
@@ -314,10 +291,9 @@ impl<'e> Evaluator<'e> {
314
291
ExprKind :: And { left, right } => {
315
292
match self . partial_interpret ( left, slots) ? {
316
293
// PE Case
317
- PartialValue :: Residual ( e) => Ok ( PartialValue :: Residual ( Expr :: and (
318
- e,
319
- self . run_to_error ( right. as_ref ( ) , slots) . 0 . into ( ) ,
320
- ) ) ) ,
294
+ PartialValue :: Residual ( e) => {
295
+ Ok ( PartialValue :: Residual ( Expr :: and ( e, right. as_ref ( ) . clone ( ) ) ) )
296
+ }
321
297
// Full eval case
322
298
PartialValue :: Value ( v) => {
323
299
if v. get_as_bool ( ) ? {
@@ -341,10 +317,9 @@ impl<'e> Evaluator<'e> {
341
317
ExprKind :: Or { left, right } => {
342
318
match self . partial_interpret ( left, slots) ? {
343
319
// PE cases
344
- PartialValue :: Residual ( r) => Ok ( PartialValue :: Residual ( Expr :: or (
345
- r,
346
- self . run_to_error ( right, slots) . 0 . into ( ) ,
347
- ) ) ) ,
320
+ PartialValue :: Residual ( r) => {
321
+ Ok ( PartialValue :: Residual ( Expr :: or ( r, right. as_ref ( ) . clone ( ) ) ) )
322
+ }
348
323
// Full eval case
349
324
PartialValue :: Value ( lhs) => {
350
325
if lhs. get_as_bool ( ) ? {
@@ -686,8 +661,8 @@ impl<'e> Evaluator<'e> {
686
661
fn eval_if (
687
662
& self ,
688
663
guard : & Expr ,
689
- consequent : & Expr ,
690
- alternative : & Expr ,
664
+ consequent : & Arc < Expr > ,
665
+ alternative : & Arc < Expr > ,
691
666
slots : & SlotEnv ,
692
667
) -> Result < PartialValue > {
693
668
match self . partial_interpret ( guard, slots) ? {
@@ -699,13 +674,7 @@ impl<'e> Evaluator<'e> {
699
674
}
700
675
}
701
676
PartialValue :: Residual ( guard) => {
702
- let ( consequent, consequent_errored) = self . run_to_error ( consequent, slots) ;
703
- let ( alternative, alternative_errored) = self . run_to_error ( alternative, slots) ;
704
- // If both branches errored, the expression will always error
705
- match ( consequent_errored, alternative_errored) {
706
- ( Some ( e) , Some ( _) ) => Err ( e) ,
707
- _ => Ok ( Expr :: ite ( guard, consequent. into ( ) , alternative. into ( ) ) . into ( ) ) ,
708
- }
677
+ Ok ( Expr :: ite_arc ( Arc :: new ( guard) , consequent. clone ( ) , alternative. clone ( ) ) . into ( ) )
709
678
}
710
679
}
711
680
}
@@ -4885,7 +4854,7 @@ pub mod test {
4885
4854
let b = Expr :: and ( Expr :: val ( 1 ) , Expr :: val ( 2 ) ) ;
4886
4855
let c = Expr :: val ( true ) ;
4887
4856
4888
- let e = Expr :: ite ( a, b, c) ;
4857
+ let e = Expr :: ite ( a, b. clone ( ) , c) ;
4889
4858
4890
4859
let es = Entities :: new ( ) ;
4891
4860
@@ -4898,10 +4867,7 @@ pub mod test {
4898
4867
r,
4899
4868
PartialValue :: Residual ( Expr :: ite(
4900
4869
Expr :: unknown( Unknown :: new_untyped( "guard" ) ) ,
4901
- Expr :: call_extension_fn(
4902
- "error" . parse( ) . unwrap( ) ,
4903
- vec![ Expr :: val( "type error: expected bool, got long" ) ]
4904
- ) ,
4870
+ b,
4905
4871
Expr :: val( true )
4906
4872
) )
4907
4873
)
@@ -4966,14 +4932,21 @@ pub mod test {
4966
4932
let b = Expr :: and ( Expr :: val ( 1 ) , Expr :: val ( 2 ) ) ;
4967
4933
let c = Expr :: or ( Expr :: val ( 1 ) , Expr :: val ( 3 ) ) ;
4968
4934
4969
- let e = Expr :: ite ( a, b, c) ;
4935
+ let e = Expr :: ite ( a, b. clone ( ) , c. clone ( ) ) ;
4970
4936
4971
4937
let es = Entities :: new ( ) ;
4972
4938
4973
4939
let exts = Extensions :: none ( ) ;
4974
4940
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
4975
4941
4976
- assert_matches ! ( eval. partial_interpret( & e, & HashMap :: new( ) ) , Err ( _) ) ;
4942
+ assert_eq ! (
4943
+ eval. partial_interpret( & e, & HashMap :: new( ) ) . unwrap( ) ,
4944
+ PartialValue :: Residual ( Expr :: ite(
4945
+ Expr :: unknown( Unknown :: new_untyped( "guard" ) ) ,
4946
+ b,
4947
+ c
4948
+ ) )
4949
+ ) ;
4977
4950
}
4978
4951
4979
4952
#[ test]
@@ -5220,22 +5193,15 @@ pub mod test {
5220
5193
let guard = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "a" ) ) , "field" . into ( ) ) ;
5221
5194
let cons = Expr :: binary_app ( BinaryOp :: Add , Expr :: val ( 1 ) , Expr :: val ( true ) ) ;
5222
5195
let alt = Expr :: val ( 2 ) ;
5223
- let e = Expr :: ite ( guard. clone ( ) , cons, alt) ;
5196
+ let e = Expr :: ite ( guard. clone ( ) , cons. clone ( ) , alt) ;
5224
5197
5225
5198
let es = Entities :: new ( ) ;
5226
5199
let exts = Extensions :: none ( ) ;
5227
5200
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5228
5201
5229
5202
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5230
5203
5231
- let expected = Expr :: ite (
5232
- guard,
5233
- Expr :: call_extension_fn (
5234
- "error" . parse ( ) . unwrap ( ) ,
5235
- vec ! [ Expr :: val( "type error: expected long, got bool" ) ] ,
5236
- ) ,
5237
- Expr :: val ( 2 ) ,
5238
- ) ;
5204
+ let expected = Expr :: ite ( guard, cons, Expr :: val ( 2 ) ) ;
5239
5205
5240
5206
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5241
5207
}
@@ -5245,22 +5211,15 @@ pub mod test {
5245
5211
let guard = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "a" ) ) , "field" . into ( ) ) ;
5246
5212
let cons = Expr :: val ( 2 ) ;
5247
5213
let alt = Expr :: binary_app ( BinaryOp :: Add , Expr :: val ( 1 ) , Expr :: val ( true ) ) ;
5248
- let e = Expr :: ite ( guard. clone ( ) , cons, alt) ;
5214
+ let e = Expr :: ite ( guard. clone ( ) , cons, alt. clone ( ) ) ;
5249
5215
5250
5216
let es = Entities :: new ( ) ;
5251
5217
let exts = Extensions :: none ( ) ;
5252
5218
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5253
5219
5254
5220
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5255
5221
5256
- let expected = Expr :: ite (
5257
- guard,
5258
- Expr :: val ( 2 ) ,
5259
- Expr :: call_extension_fn (
5260
- "error" . parse ( ) . unwrap ( ) ,
5261
- vec ! [ Expr :: val( "type error: expected long, got bool" ) ] ,
5262
- ) ,
5263
- ) ;
5222
+ let expected = Expr :: ite ( guard, Expr :: val ( 2 ) , alt) ;
5264
5223
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5265
5224
}
5266
5225
@@ -5269,13 +5228,16 @@ pub mod test {
5269
5228
let guard = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "a" ) ) , "field" . into ( ) ) ;
5270
5229
let cons = Expr :: binary_app ( BinaryOp :: Add , Expr :: val ( 1 ) , Expr :: val ( true ) ) ;
5271
5230
let alt = Expr :: less ( Expr :: val ( "hello" ) , Expr :: val ( "bye" ) ) ;
5272
- let e = Expr :: ite ( guard, cons, alt) ;
5231
+ let e = Expr :: ite ( guard. clone ( ) , cons. clone ( ) , alt. clone ( ) ) ;
5273
5232
5274
5233
let es = Entities :: new ( ) ;
5275
5234
let exts = Extensions :: none ( ) ;
5276
5235
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5277
5236
5278
- assert_matches ! ( eval. partial_interpret( & e, & HashMap :: new( ) ) , Err ( _) ) ;
5237
+ assert_eq ! (
5238
+ eval. partial_interpret( & e, & HashMap :: new( ) ) . unwrap( ) ,
5239
+ PartialValue :: Residual ( Expr :: ite( guard, cons, alt) )
5240
+ ) ;
5279
5241
}
5280
5242
5281
5243
// err && res -> err
@@ -5342,27 +5304,27 @@ pub mod test {
5342
5304
fn partial_and_res_true ( ) {
5343
5305
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5344
5306
let rhs = Expr :: binary_app ( BinaryOp :: Eq , Expr :: val ( 2 ) , Expr :: val ( 2 ) ) ;
5345
- let e = Expr :: and ( lhs. clone ( ) , rhs) ;
5307
+ let e = Expr :: and ( lhs. clone ( ) , rhs. clone ( ) ) ;
5346
5308
let es = Entities :: new ( ) ;
5347
5309
let exts = Extensions :: none ( ) ;
5348
5310
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5349
5311
5350
5312
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5351
- let expected = Expr :: and ( lhs, Expr :: val ( true ) ) ;
5313
+ let expected = Expr :: and ( lhs, rhs ) ;
5352
5314
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5353
5315
}
5354
5316
5355
5317
#[ test]
5356
5318
fn partial_and_res_false ( ) {
5357
5319
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5358
5320
let rhs = Expr :: binary_app ( BinaryOp :: Eq , Expr :: val ( 2 ) , Expr :: val ( 1 ) ) ;
5359
- let e = Expr :: and ( lhs. clone ( ) , rhs) ;
5321
+ let e = Expr :: and ( lhs. clone ( ) , rhs. clone ( ) ) ;
5360
5322
let es = Entities :: new ( ) ;
5361
5323
let exts = Extensions :: none ( ) ;
5362
5324
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5363
5325
5364
5326
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5365
- let expected = Expr :: and ( lhs, Expr :: val ( false ) ) ;
5327
+ let expected = Expr :: and ( lhs, rhs ) ;
5366
5328
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5367
5329
}
5368
5330
@@ -5390,7 +5352,7 @@ pub mod test {
5390
5352
fn partial_and_res_err ( ) {
5391
5353
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5392
5354
let rhs = Expr :: binary_app ( BinaryOp :: Add , Expr :: val ( 1 ) , Expr :: val ( "oops" ) ) ;
5393
- let e = Expr :: and ( lhs, rhs) ;
5355
+ let e = Expr :: and ( lhs, rhs. clone ( ) ) ;
5394
5356
let es = Entities :: new ( ) ;
5395
5357
let exts = Extensions :: none ( ) ;
5396
5358
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
@@ -5399,10 +5361,7 @@ pub mod test {
5399
5361
5400
5362
let expected = Expr :: and (
5401
5363
Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ,
5402
- Expr :: call_extension_fn (
5403
- "error" . parse ( ) . unwrap ( ) ,
5404
- vec ! [ Expr :: val( "type error: expected long, got string" ) ] ,
5405
- ) ,
5364
+ rhs,
5406
5365
) ;
5407
5366
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5408
5367
}
@@ -5444,27 +5403,27 @@ pub mod test {
5444
5403
fn partial_or_res_true ( ) {
5445
5404
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5446
5405
let rhs = Expr :: binary_app ( BinaryOp :: Eq , Expr :: val ( 2 ) , Expr :: val ( 2 ) ) ;
5447
- let e = Expr :: or ( lhs. clone ( ) , rhs) ;
5406
+ let e = Expr :: or ( lhs. clone ( ) , rhs. clone ( ) ) ;
5448
5407
let es = Entities :: new ( ) ;
5449
5408
let exts = Extensions :: none ( ) ;
5450
5409
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5451
5410
5452
5411
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5453
- let expected = Expr :: or ( lhs, Expr :: val ( true ) ) ;
5412
+ let expected = Expr :: or ( lhs, rhs ) ;
5454
5413
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5455
5414
}
5456
5415
5457
5416
#[ test]
5458
5417
fn partial_or_res_false ( ) {
5459
5418
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5460
5419
let rhs = Expr :: binary_app ( BinaryOp :: Eq , Expr :: val ( 2 ) , Expr :: val ( 1 ) ) ;
5461
- let e = Expr :: or ( lhs. clone ( ) , rhs) ;
5420
+ let e = Expr :: or ( lhs. clone ( ) , rhs. clone ( ) ) ;
5462
5421
let es = Entities :: new ( ) ;
5463
5422
let exts = Extensions :: none ( ) ;
5464
5423
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
5465
5424
5466
5425
let r = eval. partial_interpret ( & e, & HashMap :: new ( ) ) . unwrap ( ) ;
5467
- let expected = Expr :: or ( lhs, Expr :: val ( false ) ) ;
5426
+ let expected = Expr :: or ( lhs, rhs ) ;
5468
5427
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5469
5428
}
5470
5429
@@ -5492,7 +5451,7 @@ pub mod test {
5492
5451
fn partial_or_res_err ( ) {
5493
5452
let lhs = Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ;
5494
5453
let rhs = Expr :: binary_app ( BinaryOp :: Add , Expr :: val ( 1 ) , Expr :: val ( "oops" ) ) ;
5495
- let e = Expr :: or ( lhs, rhs) ;
5454
+ let e = Expr :: or ( lhs, rhs. clone ( ) ) ;
5496
5455
let es = Entities :: new ( ) ;
5497
5456
let exts = Extensions :: none ( ) ;
5498
5457
let eval = Evaluator :: new ( empty_request ( ) , & es, & exts) ;
@@ -5501,10 +5460,7 @@ pub mod test {
5501
5460
5502
5461
let expected = Expr :: or (
5503
5462
Expr :: get_attr ( Expr :: unknown ( Unknown :: new_untyped ( "test" ) ) , "field" . into ( ) ) ,
5504
- Expr :: call_extension_fn (
5505
- "error" . parse ( ) . unwrap ( ) ,
5506
- vec ! [ Expr :: val( "type error: expected long, got string" ) ] ,
5507
- ) ,
5463
+ rhs,
5508
5464
) ;
5509
5465
assert_eq ! ( r, PartialValue :: Residual ( expected) ) ;
5510
5466
}
0 commit comments