Skip to content

Commit

Permalink
Merge pull request #106 from czgdp1807/while_loop_01
Browse files Browse the repository at this point in the history
Ported ``integration_tests/loop_02.py`` from LPython and improve LC to compile it
  • Loading branch information
czgdp1807 authored Mar 11, 2024
2 parents 2222724 + 467fed5 commit 33a4fde
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 1 deletion.
2 changes: 2 additions & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,5 @@ RUN(NAME union_01.cpp LABELS gcc llvm NOFAST)
RUN(NAME union_02.cpp LABELS gcc llvm NOFAST)

RUN(NAME vector_01.cpp LABELS gcc llvm NOFAST)

RUN(NAME loop_01.cpp LABELS gcc llvm NOFAST)
142 changes: 142 additions & 0 deletions integration_tests/loop_01.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#include <iostream>

#define assert(cond) if( !(cond) ) { \
exit(2); \
} \

void test_loop_01() {
int32_t i = 0;
int32_t j = 0;

while( false ) {
assert( false );
}

while( i < 0 ) {
assert( false );
}

while( i < 10 ) {
i += 1;
}
std::cout<<i<<std::endl;
assert( i == 10 );

while( i < 20 ) {
while( i < 15 ) {
i += 1;
}
i += 1;
}
std::cout<<i<<std::endl;
assert( i == 20 );

for( i = 0; i < 5; i++ ) {
std::cout<<i<<" "<<j<<std::endl;
assert( i == j );
j += 1;
}
}

void test_loop_02() {
int32_t i = 0;
int32_t j = 0;

j = 0;
for( i = 10; i > 0; i-- ) {
j = j + i;
}
std::cout<<j<<std::endl;
assert( j == 55 );

for( i = 0; i < 5; i++ ) {
if( i == 3 ) {
break;
}
}
std::cout<<i<<std::endl;
assert( i == 3 );

j = 0;
for( i = 0; i < 5; i++ ) {
if( i == 3 ) {
continue;
}
j += 1;
}
std::cout<<j<<std::endl;
assert( j == 4 );
}

void test_loop_03() {
int32_t i = 0;
int32_t j = 0;
int32_t k = 0;
while( i < 10 ) {
j = 0;
while( j < 10 ) {
k += 1;
if( i == 0 ) {
if( j == 3 ) {
continue;
} else {
j += 1;
}
}
j += 1;
}
i += 1;
}
std::cout<<k<<std::endl;
assert( k == 95 );

i = 0; j = 0; k = 0;
while( i < 10 ) {
j = 0;
while( j < 10 ) {
k += i + j;
if( i == 5 ) {
if( j == 4 ) {
break;
} else {
j += 1;
}
}
j += 1;
}
i += 1;
}
std::cout<<k<<std::endl;
assert( k == 826 );

i = 0;
if( i == 0 ) {
while( i < 10 ) {
j = 0;
if( j == 0 ) {
while( j < 10 ) {
k += 1;
if( i == 9 ) {
break;
}
j += 1;
}
i += 1;
}
}
}
std::cout<<k<<std::endl;
assert( k == 917 );
}

void verify() {
test_loop_01();
test_loop_02();
test_loop_03();
}

int main() {

verify();

}
61 changes: 60 additions & 1 deletion src/lc/clang_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
bool enable_fall_through;
std::map<ASR::symbol_t*, std::map<std::string, ASR::expr_t*>> struct2member_inits;
std::map<SymbolTable*, std::vector<ASR::symbol_t*>> scope2enums;
clang::ForStmt* for_loop;
bool inside_loop;

explicit ClangASTtoASRVisitor(clang::ASTContext *Context_,
Allocator& al_, ASR::asr_t*& tu_):
Expand All @@ -173,7 +175,8 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
assignment_target{nullptr}, print_args{nullptr},
is_all_called{false}, is_range_called{false},
current_switch_case{nullptr}, default_stmt{nullptr},
interpret_init_list_expr_as_list{false}, enable_fall_through{false} {}
interpret_init_list_expr_as_list{false}, enable_fall_through{false},
for_loop{nullptr}, inside_loop{false} {}

template <typename T>
Location Lloc(T *x) {
Expand Down Expand Up @@ -2290,10 +2293,26 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit

bool TraverseBreakStmt(clang::BreakStmt* x) {
clang::RecursiveASTVisitor<ClangASTtoASRVisitor>::TraverseBreakStmt(x);
if( inside_loop ) {
tmp = ASR::make_Exit_t(al, Lloc(x), nullptr);
is_stmt_created = true;
}
is_break_stmt_present.set(true);
return true;
}

bool TraverseContinueStmt(clang::ContinueStmt* x) {
if( for_loop != nullptr ) {
clang::Stmt* inc_stmt = for_loop->getInc();
TraverseStmt(inc_stmt);
LCOMPILERS_ASSERT(tmp != nullptr && is_stmt_created);
current_body->push_back(al, ASRUtils::STMT(tmp.get()));
}
tmp = ASR::make_Cycle_t(al, Lloc(x), nullptr);
is_stmt_created = true;
return true;
}

bool TraverseCaseStmt(clang::CaseStmt* x) {
if ( x->caseStmtIsGNURange() ) {
throw std::runtime_error("Ranges not supported in case.");
Expand Down Expand Up @@ -2437,6 +2456,16 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
is_stmt_created = true;
break;
}
case clang::UnaryOperatorKind::UO_PostDec: {
ASR::expr_t* decbyone = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(
al, Lloc(x), var, ASR::binopType::Sub,
ASRUtils::EXPR(ASR::make_IntegerConstant_t(
al, Lloc(x), 1, ASRUtils::expr_type(var))),
ASRUtils::expr_type(var), nullptr));
tmp = ASR::make_Assignment_t(al, Lloc(x), var, decbyone, nullptr);
is_stmt_created = true;
break;
}
case clang::UnaryOperatorKind::UO_Minus: {
CreateUnaryMinus(var, Lloc(x));
break;
Expand All @@ -2452,7 +2481,35 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
return true;
}

bool TraverseWhileStmt(clang::WhileStmt* x) {
bool inside_loop_copy = inside_loop;
inside_loop = true;
std::map<std::string, std::string> alias;
scopes.push_back(alias);

clang::Expr* loop_cond = x->getCond();
TraverseStmt(loop_cond);
ASR::expr_t* test = ASRUtils::EXPR(tmp.get());

Vec<ASR::stmt_t*> body; body.reserve(al, 1);
Vec<ASR::stmt_t*>*current_body_copy = current_body;
current_body = &body;
clang::Stmt* loop_body = x->getBody();
TraverseStmt(loop_body);
current_body = current_body_copy;

tmp = ASR::make_WhileLoop_t(al, Lloc(x), nullptr, test, body.p, body.size());
is_stmt_created = true;
scopes.pop_back();
inside_loop = inside_loop_copy;
return true;
}

bool TraverseForStmt(clang::ForStmt* x) {
bool inside_loop_copy = inside_loop;
inside_loop = true;
clang::ForStmt* for_loop_copy = for_loop;
for_loop = x;
std::map<std::string, std::string> alias;
scopes.push_back(alias);
clang::Stmt* init_stmt = x->getInit();
Expand All @@ -2478,6 +2535,8 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
tmp = ASR::make_WhileLoop_t(al, Lloc(x), nullptr, test, body.p, body.size());
is_stmt_created = true;
scopes.pop_back();
for_loop = for_loop_copy;
inside_loop = inside_loop_copy;
return true;
}

Expand Down

0 comments on commit 33a4fde

Please sign in to comment.