Files
bits-runner-builder/src/ModuleBuilder.cpp
2025-06-05 15:26:19 +09:00

115 lines
4.7 KiB
C++

#include "ModuleBuilder.h"
ModuleBuilder::ModuleBuilder(vector<shared_ptr<Statement>> statements): statements(statements) {
context = make_shared<llvm::LLVMContext>();
module = make_shared<llvm::Module>("dummy", *context);
builder = make_shared<llvm::IRBuilder<>>(*context);
voidType = llvm::Type::getVoidTy(*context);
int32Type = llvm::Type::getInt32Ty(*context);
}
shared_ptr<llvm::Module> ModuleBuilder::getModule() {
for (shared_ptr<Statement> &statement : statements) {
buildStatement(statement);
}
return module;
}
void ModuleBuilder::buildStatement(shared_ptr<Statement> statement) {
switch (statement->getKind()) {
case Statement::Kind::FUNCTION_DECLARATION:
buildFunctionDeclaration(dynamic_pointer_cast<StatementFunctionDeclaration>(statement));
break;
case Statement::Kind::BLOCK:
buildBlock(dynamic_pointer_cast<StatementBlock>(statement));
break;
case Statement::Kind::RETURN:
buildReturn(dynamic_pointer_cast<StatementReturn>(statement));
break;
case Statement::Kind::EXPRESSION:
buildExpression(dynamic_pointer_cast<StatementExpression>(statement));
return;
default:
exit(1);
}
}
void ModuleBuilder::buildFunctionDeclaration(shared_ptr<StatementFunctionDeclaration> statement) {
llvm::FunctionType *funType = llvm::FunctionType::get(int32Type, false);
llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::InternalLinkage, statement->getName(), module.get());
llvm::BasicBlock *block = llvm::BasicBlock::Create(*context, statement->getName(), fun);
builder->SetInsertPoint(block);
buildStatement(statement->getStatementBlock());
}
void ModuleBuilder::buildBlock(shared_ptr<StatementBlock> statement) {
for (shared_ptr<Statement> &innerStatement : statement->getStatements()) {
buildStatement(innerStatement);
}
}
void ModuleBuilder::buildReturn(shared_ptr<StatementReturn> statement) {
if (statement->getExpression() != nullptr) {
llvm::Value *value = valueForExpression(statement->getExpression());
builder->CreateRet(value);
} else {
builder->CreateRetVoid();
}
}
void ModuleBuilder::buildExpression(shared_ptr<StatementExpression> statement) {
valueForExpression(statement->getExpression());
}
llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression) {
switch (expression->getKind()) {
case Expression::Kind::LITERAL:
return valueForLiteral(dynamic_pointer_cast<ExpressionLiteral>(expression));
case Expression::Kind::GROUPING:
return valueForExpression(dynamic_pointer_cast<ExpressionGrouping>(expression)->getExpression());
case Expression::Kind::BINARY:
return valueForBinary(dynamic_pointer_cast<ExpressionBinary>(expression));
default:
exit(1);
}
}
llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr<ExpressionLiteral> expression) {
return llvm::ConstantInt::get(int32Type, expression->getInteger(), true);
}
llvm::Value *ModuleBuilder::valueForGrouping(shared_ptr<ExpressionGrouping> expression) {
return valueForExpression(expression->getExpression());
}
llvm::Value *ModuleBuilder::valueForBinary(shared_ptr<ExpressionBinary> expression) {
llvm::Value *leftValue = valueForExpression(expression->getLeft());
llvm::Value *rightValue = valueForExpression(expression->getRight());
switch (expression->getOperation()) {
case ExpressionBinary::Operation::EQUAL:
return builder->CreateICmpEQ(leftValue, rightValue);
case ExpressionBinary::Operation::NOT_EQUAL:
return builder->CreateICmpNE(leftValue, rightValue);
case ExpressionBinary::Operation::LESS:
return builder->CreateICmpSLT(leftValue, rightValue);
case ExpressionBinary::Operation::LESS_EQUAL:
return builder->CreateICmpSLE(leftValue, rightValue);
case ExpressionBinary::Operation::GREATER:
return builder->CreateICmpSGT(leftValue, rightValue);
case ExpressionBinary::Operation::GREATER_EQUAL:
return builder->CreateICmpSGE(leftValue, rightValue);
case ExpressionBinary::Operation::ADD:
return builder->CreateNSWAdd(leftValue, rightValue);
case ExpressionBinary::Operation::SUB:
return builder->CreateNSWSub(leftValue, rightValue);
case ExpressionBinary::Operation::MUL:
return builder->CreateNSWMul(leftValue, rightValue);
case ExpressionBinary::Operation::DIV:
return builder->CreateSDiv(leftValue, rightValue);
case ExpressionBinary::Operation::MOD:
return builder->CreateSRem(leftValue, rightValue);
}
}