@@ -253,65 +253,6 @@ impl CustomExecute for CaptureOp {
253253 }
254254}
255255
256- #[ derive( Clone , Debug ) ]
257- pub struct CaseOp {
258- space : DynSpace ,
259- settings : PragmaSettings ,
260- }
261-
262- grounded_op ! ( CaseOp , "case" ) ;
263-
264- impl CaseOp {
265- pub fn new ( space : DynSpace , settings : PragmaSettings ) -> Self {
266- Self { space, settings }
267- }
268- }
269-
270- impl Grounded for CaseOp {
271- fn type_ ( & self ) -> Atom {
272- Atom :: expr ( [ ARROW_SYMBOL , ATOM_TYPE_ATOM , ATOM_TYPE_EXPRESSION , ATOM_TYPE_UNDEFINED ] )
273- }
274-
275- fn as_execute ( & self ) -> Option < & dyn CustomExecute > {
276- Some ( self )
277- }
278- }
279-
280- impl CustomExecute for CaseOp {
281- fn execute ( & self , args : & [ Atom ] ) -> Result < Vec < Atom > , ExecError > {
282- let arg_error = || ExecError :: from ( "case expects two arguments: atom and expression of cases" ) ;
283- let cases = args. get ( 1 ) . ok_or_else ( arg_error) ?;
284- let atom = args. get ( 0 ) . ok_or_else ( arg_error) ?;
285- log:: debug!( "CaseOp::execute: atom: {}, cases: {:?}" , atom, cases) ;
286-
287- let switch = |interpreted : Atom | -> Atom {
288- Atom :: expr ( [ sym ! ( "switch" ) , interpreted, cases. clone ( ) ] )
289- } ;
290-
291- // Interpreting argument inside CaseOp is required because otherwise `Empty` result
292- // calculated inside interpreter cuts the whole branch of the interpretation. Also we
293- // cannot use `unify` in a unit test because after interpreting `(chain... (chain
294- // (metta (unify ...) Atom <space>)) ...)` `chain` executes `unify` and also gets
295- // `Empty` even if we have `Atom` as a resulting type. It can be solved by different ways.
296- // One way is to invent new type `EmptyType` (type of the `Empty` atom) and use this type
297- // in a function to allow `Empty` atoms as an input. `EmptyType` type should not be
298- // casted to the `%Undefined%` thus one cannot pass `Empty` to the function which accepts
299- // `%Undefined%`. Another way is to introduce "call" level. Thus if function called
300- // returned the result to the `chain` it should stop reducing it and insert it into the
301- // last argument.
302- let results = interpret ( self . space . clone ( ) , atom, self . settings . clone ( ) ) ;
303- log:: debug!( "CaseOp::execute: atom results: {:?}" , results) ;
304- let results = match results {
305- Ok ( results) if results. is_empty ( ) =>
306- vec ! [ switch( EMPTY_SYMBOL ) ] ,
307- Ok ( results) =>
308- results. into_iter ( ) . map ( |atom| switch ( atom) ) . collect ( ) ,
309- Err ( err) => vec ! [ Atom :: expr( [ ERROR_SYMBOL , atom. clone( ) , Atom :: sym( err) ] ) ] ,
310- } ;
311- Ok ( results)
312- }
313- }
314-
315256fn collapse_add_next_atom_from_collapse_bind_result ( args : & [ Atom ] ) -> Result < Vec < Atom > , ExecError > {
316257 let arg0_error = || ExecError :: from ( "Expression is expected as a first argument" ) ;
317258 let list = TryInto :: < & ExpressionAtom > :: try_into ( args. get ( 0 ) . ok_or_else ( arg0_error) ?) . map_err ( |_| arg0_error ( ) ) ?;
@@ -347,8 +288,6 @@ pub(super) fn register_context_independent_tokens(tref: &mut Tokenizer) {
347288}
348289
349290pub ( super ) fn register_context_dependent_tokens ( tref : & mut Tokenizer , space : & DynSpace , metta : & Metta ) {
350- let case_op = Atom :: gnd ( CaseOp :: new ( space. clone ( ) , metta. settings ( ) . clone ( ) ) ) ;
351- tref. register_token ( regex ( r"case" ) , move |_| { case_op. clone ( ) } ) ;
352291 let capture_op = Atom :: gnd ( CaptureOp :: new ( space. clone ( ) , metta. settings ( ) . clone ( ) ) ) ;
353292 tref. register_token ( regex ( r"capture" ) , move |_| { capture_op. clone ( ) } ) ;
354293 let pragma_op = Atom :: gnd ( PragmaOp :: new ( metta. settings ( ) . clone ( ) ) ) ;
@@ -409,6 +348,18 @@ mod tests {
409348 assert_eq ! ( result, Ok ( vec![ vec![ expr!( "nok" ) ] ] ) ) ;
410349 }
411350
351+ #[ test]
352+ fn metta_case_error ( ) {
353+ let program = "
354+ (= (err) (Error (err) \" Test error\" ))
355+ !(case (err) (
356+ ((Error $a \" Test error\" ) ())
357+ ($_ (Error $_ \" Error is expected\" ))
358+ ))
359+ " ;
360+ assert_eq ! ( run_program( program) , Ok ( vec![ vec![ UNIT_ATOM ] ] ) ) ;
361+ }
362+
412363 #[ test]
413364 fn test_pragma_interpreter_bare_minimal ( ) {
414365 let program = "
@@ -503,8 +454,8 @@ mod tests {
503454 let nested = run_program ( "!(sealed ($c) (quote (= ($a $x $c) ($b))))" ) ;
504455 let simple_replace = run_program ( "!(sealed ($z $x) (quote (= ($y $z))))" ) ;
505456
506- assert ! ( hyperon_atom :: matcher :: atoms_are_equivalent( & nested. unwrap( ) [ 0 ] [ 0 ] , & expr!( "quote" ( "=" ( a b c) ( z) ) ) ) ) ;
507- assert ! ( hyperon_atom :: matcher :: atoms_are_equivalent( & simple_replace. unwrap( ) [ 0 ] [ 0 ] , & expr!( "quote" ( "=" ( y z) ) ) ) ) ;
457+ assert ! ( atoms_are_equivalent( & nested. unwrap( ) [ 0 ] [ 0 ] , & expr!( "quote" ( "=" ( a b c) ( z) ) ) ) ) ;
458+ assert ! ( atoms_are_equivalent( & simple_replace. unwrap( ) [ 0 ] [ 0 ] , & expr!( "quote" ( "=" ( y z) ) ) ) ) ;
508459 }
509460
510461 #[ test]
0 commit comments