@@ -437,3 +437,83 @@ TEST_F(LLVMCodeBuilderTest, WhileLoop)
437437 code->run (ctx.get ());
438438 ASSERT_EQ (testing::internal::GetCapturedStdout (), expected);
439439}
440+
441+ TEST_F (LLVMCodeBuilderTest, RepeatUntilLoop)
442+ {
443+ // Const condition
444+ m_builder->beginLoopCondition ();
445+ m_builder->addConstValue (" true" );
446+ m_builder->beginRepeatUntilLoop ();
447+ m_builder->addFunctionCall (" test_unreachable" , 0 , false );
448+ m_builder->endLoop ();
449+
450+ m_builder->beginLoopCondition ();
451+ m_builder->addConstValue (true );
452+ m_builder->beginRepeatUntilLoop ();
453+ m_builder->addFunctionCall (" test_unreachable" , 0 , false );
454+ m_builder->endLoop ();
455+
456+ // Condition returned by function
457+ m_builder->addFunctionCall (" test_reset_counter" , 0 , false );
458+ m_builder->beginLoopCondition ();
459+ m_builder->addFunctionCall (" test_get_counter" , 0 , true );
460+ m_builder->addConstValue (2 );
461+ m_builder->addFunctionCall (" test_lower_than" , 2 , true );
462+ m_builder->addFunctionCall (" test_not" , 1 , true );
463+ m_builder->beginRepeatUntilLoop ();
464+ m_builder->addConstValue (0 );
465+ m_builder->addFunctionCall (" test_function_1_arg" , 1 , false );
466+ m_builder->addFunctionCall (" test_increment_counter" , 0 , false );
467+ m_builder->endLoop ();
468+
469+ // Nested
470+ m_builder->addFunctionCall (" test_reset_counter" , 0 , false );
471+ m_builder->beginLoopCondition ();
472+ m_builder->addFunctionCall (" test_get_counter" , 0 , true );
473+ m_builder->addConstValue (3 );
474+ m_builder->addFunctionCall (" test_lower_than" , 2 , true );
475+ m_builder->addFunctionCall (" test_not" , 1 , true );
476+ m_builder->beginRepeatUntilLoop ();
477+ {
478+ m_builder->beginLoopCondition ();
479+ m_builder->addFunctionCall (" test_get_counter" , 0 , true );
480+ m_builder->addConstValue (3 );
481+ m_builder->addFunctionCall (" test_lower_than" , 2 , true );
482+ m_builder->addFunctionCall (" test_not" , 1 , true );
483+ m_builder->beginRepeatUntilLoop ();
484+ {
485+ m_builder->addConstValue (1 );
486+ m_builder->addFunctionCall (" test_function_1_arg" , 1 , false );
487+ m_builder->addFunctionCall (" test_increment_counter" , 0 , false );
488+ }
489+ m_builder->endLoop ();
490+
491+ m_builder->addConstValue (2 );
492+ m_builder->addFunctionCall (" test_function_1_arg" , 1 , false );
493+
494+ m_builder->beginLoopCondition ();
495+ m_builder->addConstValue (true );
496+ m_builder->beginRepeatUntilLoop ();
497+ {
498+ m_builder->addFunctionCall (" test_unreachable" , 0 , false );
499+ }
500+ m_builder->endLoop ();
501+ }
502+ m_builder->endLoop ();
503+
504+ auto code = m_builder->finalize ();
505+ auto ctx = code->createExecutionContext (&m_target);
506+
507+ static const std::string expected =
508+ " 1_arg 0\n "
509+ " 1_arg 0\n "
510+ " 1_arg 1\n "
511+ " 1_arg 1\n "
512+ " 1_arg 1\n "
513+ " 1_arg 2\n " ;
514+
515+ EXPECT_CALL (m_target, isStage).WillRepeatedly (Return (false ));
516+ testing::internal::CaptureStdout ();
517+ code->run (ctx.get ());
518+ ASSERT_EQ (testing::internal::GetCapturedStdout (), expected);
519+ }
0 commit comments