diff --git a/CMakeLists.txt b/CMakeLists.txt index d80eba3..d9df42c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project( LANGUAGES CXX C) set(CMAKE_CXX_STANDARD 20) -set(CMAKE_COLOR_DIAGNOSTICS ON) +set(CMAKE_COLOR_DIAGNOSTICS OFF) set(CMAKE_VERBOSE_MAKEFILE ON) find_package(LLVM REQUIRED CONFIG) diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index dd66e44..88b9935 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -127,25 +127,45 @@ void ModuleBuilder::buildReturn(shared_ptr statement) { void ModuleBuilder::buildLoop(shared_ptr statement) { shared_ptr initStatement = statement->getInitStatement(); + shared_ptr bodyStatement= statement->getBodyBlockStatement(); shared_ptr preExpression = statement->getPreConditionExpression(); shared_ptr postExpression = statement->getPostConditionExpression(); - shared_ptr bodyStatement= statement->getBodyBlockStatement(); - llvm::BasicBlock *parentBlock = builder->GetInsertBlock(); + llvm::Function *fun = builder->GetInsertBlock()->getParent(); + llvm::BasicBlock *preBlock = llvm::BasicBlock::Create(*context, "loopPre", fun); + llvm::BasicBlock *bodyBlock = llvm::BasicBlock::Create(*context, "loopBody"); + llvm::BasicBlock *afterBlock = llvm::BasicBlock::Create(*context, "loopPost"); - + // loop init if (initStatement != nullptr) buildStatement(statement->getInitStatement()); - llvm::Function *fun = builder->GetInsertBlock()->getParent(); + builder->CreateBr(preBlock); - llvm::BasicBlock *bodyBlock = llvm::BasicBlock::Create(*context, "loopBody", fun); + // pre condition + builder->SetInsertPoint(preBlock); + if (preExpression != nullptr) { + llvm::Value *preConditionValue = valueForExpression(preExpression); + builder->CreateCondBr(preConditionValue, bodyBlock, afterBlock); + } else { + builder->CreateBr(bodyBlock); + } + + // body + fun->insert(fun->end(), bodyBlock); builder->SetInsertPoint(bodyBlock); buildBlock(bodyStatement); - builder->CreateBr(bodyBlock); - //llvm::BasicBlock *loopEndBlock = builder->GetInsertBlock() + // post condition + if (postExpression != nullptr) { + llvm::Value *postConditionValue = valueForExpression(postExpression); + builder->CreateCondBr(postConditionValue, preBlock, afterBlock); + } else { + builder->CreateBr(preBlock); + } - builder->SetInsertPoint(parentBlock); + // loop post + fun->insert(fun->end(), afterBlock); + builder->SetInsertPoint(afterBlock); } void ModuleBuilder::buildMetaExternFunction(shared_ptr statement) { diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 7c4e25d..1a7625c 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -183,32 +183,41 @@ shared_ptr Parser::matchStatementLoop() { if (!tryMatchingTokenKinds({TokenKind::REPEAT}, true, true)) return nullptr; + shared_ptr initStatement; + shared_ptr preConditionExpression; + shared_ptr postConditionExpression; + // initial - shared_ptr initStatement = matchStatementVariable(); + initStatement = matchStatementVariable(); if (initStatement != nullptr && !initStatement->isValid()) initStatement = nullptr; - // got initial, expect comma - if (initStatement != nullptr && !tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) - return matchStatementInvalid("Expected comma after initial statement"); + if (tokens.at(currentIndex-1)->getKind() != TokenKind::NEW_LINE) { + // got initial, expect comma + if (initStatement != nullptr && !tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) + return matchStatementInvalid("Expected comma after initial statement"); - // pre condition - shared_ptr preConditionExpression = nextExpression(); - if (preConditionExpression != nullptr && !preConditionExpression->isValid()) - return matchStatementInvalid("Expected pre-condition expression"); + // pre condition + preConditionExpression = nextExpression(); + if (preConditionExpression != nullptr && !preConditionExpression->isValid()) + return matchStatementInvalid("Expected pre-condition expression"); - // post condition - shared_ptr postConditionExpression; - if (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) { - postConditionExpression = nextExpression(); - if (postConditionExpression == nullptr || !postConditionExpression->isValid()) - return matchStatementInvalid("Expected post-condition expression"); + if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) { + // got pre-condition, expect comma + if (!tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) + return matchStatementInvalid("Expected comma after pre-condition statement"); + + // post condition + postConditionExpression = nextExpression(); + if (postConditionExpression == nullptr || !postConditionExpression->isValid()) + return matchStatementInvalid("Expected post-condition expression"); + + // epxect new line + if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) + return matchStatementInvalid("Expected new line"); + } } - // epxect new line - if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) - return matchStatementInvalid("Expected new line"); - // body shared_ptr bodyBlockStatement = matchStatementBlock({TokenKind::SEMICOLON}, true); if (bodyBlockStatement == nullptr) diff --git a/test.brc b/test.brc index b0d395e..b9cd580 100644 --- a/test.brc +++ b/test.brc @@ -1,8 +1,5 @@ -test fun - /*rep i sint32 <- 0, i < 10 - //i sint32 <- i + 1 - ;*/ - rep i sint32 <- 13 +test fun: num1 sint32, num2 sint32 + rep num3 sint32 <- 5, true, num1 < num2 abc sint32 <- 5 ; ; \ No newline at end of file