Implemented loops
This commit is contained in:
@@ -5,7 +5,7 @@ project(
|
|||||||
LANGUAGES CXX C)
|
LANGUAGES CXX C)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_COLOR_DIAGNOSTICS ON)
|
set(CMAKE_COLOR_DIAGNOSTICS OFF)
|
||||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||||
|
|
||||||
find_package(LLVM REQUIRED CONFIG)
|
find_package(LLVM REQUIRED CONFIG)
|
||||||
|
|||||||
@@ -127,25 +127,45 @@ void ModuleBuilder::buildReturn(shared_ptr<StatementReturn> statement) {
|
|||||||
|
|
||||||
void ModuleBuilder::buildLoop(shared_ptr<StatementLoop> statement) {
|
void ModuleBuilder::buildLoop(shared_ptr<StatementLoop> statement) {
|
||||||
shared_ptr<Statement> initStatement = statement->getInitStatement();
|
shared_ptr<Statement> initStatement = statement->getInitStatement();
|
||||||
|
shared_ptr<StatementBlock> bodyStatement= statement->getBodyBlockStatement();
|
||||||
shared_ptr<Expression> preExpression = statement->getPreConditionExpression();
|
shared_ptr<Expression> preExpression = statement->getPreConditionExpression();
|
||||||
shared_ptr<Expression> postExpression = statement->getPostConditionExpression();
|
shared_ptr<Expression> postExpression = statement->getPostConditionExpression();
|
||||||
shared_ptr<StatementBlock> 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)
|
if (initStatement != nullptr)
|
||||||
buildStatement(statement->getInitStatement());
|
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);
|
builder->SetInsertPoint(bodyBlock);
|
||||||
buildBlock(bodyStatement);
|
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<StatementMetaExternFunction> statement) {
|
void ModuleBuilder::buildMetaExternFunction(shared_ptr<StatementMetaExternFunction> statement) {
|
||||||
|
|||||||
@@ -183,32 +183,41 @@ shared_ptr<Statement> Parser::matchStatementLoop() {
|
|||||||
if (!tryMatchingTokenKinds({TokenKind::REPEAT}, true, true))
|
if (!tryMatchingTokenKinds({TokenKind::REPEAT}, true, true))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
shared_ptr<Statement> initStatement;
|
||||||
|
shared_ptr<Expression> preConditionExpression;
|
||||||
|
shared_ptr<Expression> postConditionExpression;
|
||||||
|
|
||||||
// initial
|
// initial
|
||||||
shared_ptr<Statement> initStatement = matchStatementVariable();
|
initStatement = matchStatementVariable();
|
||||||
if (initStatement != nullptr && !initStatement->isValid())
|
if (initStatement != nullptr && !initStatement->isValid())
|
||||||
initStatement = nullptr;
|
initStatement = nullptr;
|
||||||
|
|
||||||
// got initial, expect comma
|
if (tokens.at(currentIndex-1)->getKind() != TokenKind::NEW_LINE) {
|
||||||
if (initStatement != nullptr && !tryMatchingTokenKinds({TokenKind::COMMA}, true, true))
|
// got initial, expect comma
|
||||||
return matchStatementInvalid("Expected comma after initial statement");
|
if (initStatement != nullptr && !tryMatchingTokenKinds({TokenKind::COMMA}, true, true))
|
||||||
|
return matchStatementInvalid("Expected comma after initial statement");
|
||||||
|
|
||||||
// pre condition
|
// pre condition
|
||||||
shared_ptr<Expression> preConditionExpression = nextExpression();
|
preConditionExpression = nextExpression();
|
||||||
if (preConditionExpression != nullptr && !preConditionExpression->isValid())
|
if (preConditionExpression != nullptr && !preConditionExpression->isValid())
|
||||||
return matchStatementInvalid("Expected pre-condition expression");
|
return matchStatementInvalid("Expected pre-condition expression");
|
||||||
|
|
||||||
// post condition
|
if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) {
|
||||||
shared_ptr<Expression> postConditionExpression;
|
// got pre-condition, expect comma
|
||||||
if (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)) {
|
if (!tryMatchingTokenKinds({TokenKind::COMMA}, true, true))
|
||||||
postConditionExpression = nextExpression();
|
return matchStatementInvalid("Expected comma after pre-condition statement");
|
||||||
if (postConditionExpression == nullptr || !postConditionExpression->isValid())
|
|
||||||
return matchStatementInvalid("Expected post-condition expression");
|
// 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
|
// body
|
||||||
shared_ptr<Statement> bodyBlockStatement = matchStatementBlock({TokenKind::SEMICOLON}, true);
|
shared_ptr<Statement> bodyBlockStatement = matchStatementBlock({TokenKind::SEMICOLON}, true);
|
||||||
if (bodyBlockStatement == nullptr)
|
if (bodyBlockStatement == nullptr)
|
||||||
|
|||||||
Reference in New Issue
Block a user