Build function call
This commit is contained in:
@@ -38,13 +38,14 @@ void ModuleBuilder::buildStatement(shared_ptr<Statement> statement) {
|
|||||||
buildExpression(dynamic_pointer_cast<StatementExpression>(statement));
|
buildExpression(dynamic_pointer_cast<StatementExpression>(statement));
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
exit(1);
|
failed("Unexpected statement");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleBuilder::buildFunctionDeclaration(shared_ptr<StatementFunctionDeclaration> statement) {
|
void ModuleBuilder::buildFunctionDeclaration(shared_ptr<StatementFunctionDeclaration> statement) {
|
||||||
llvm::FunctionType *funType = llvm::FunctionType::get(typeForValueType(statement->getReturnValueType()), false);
|
llvm::FunctionType *funType = llvm::FunctionType::get(typeForValueType(statement->getReturnValueType()), false);
|
||||||
llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::InternalLinkage, statement->getName(), module.get());
|
llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::InternalLinkage, statement->getName(), module.get());
|
||||||
|
funMap[statement->getName()] = fun;
|
||||||
llvm::BasicBlock *block = llvm::BasicBlock::Create(*context, statement->getName(), fun);
|
llvm::BasicBlock *block = llvm::BasicBlock::Create(*context, statement->getName(), fun);
|
||||||
builder->SetInsertPoint(block);
|
builder->SetInsertPoint(block);
|
||||||
buildStatement(statement->getStatementBlock());
|
buildStatement(statement->getStatementBlock());
|
||||||
@@ -90,8 +91,10 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression
|
|||||||
return valueForIfElse(dynamic_pointer_cast<ExpressionIfElse>(expression));
|
return valueForIfElse(dynamic_pointer_cast<ExpressionIfElse>(expression));
|
||||||
case ExpressionKind::VAR:
|
case ExpressionKind::VAR:
|
||||||
return valueForVar(dynamic_pointer_cast<ExpressionVar>(expression));
|
return valueForVar(dynamic_pointer_cast<ExpressionVar>(expression));
|
||||||
|
case ExpressionKind::CALL:
|
||||||
|
return valueForCall(dynamic_pointer_cast<ExpressionCall>(expression));
|
||||||
default:
|
default:
|
||||||
exit(1);
|
failed("Unexpected expression");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,8 +123,10 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr<ExpressionBinary> expressi
|
|||||||
return valueForBinaryInteger(expression);
|
return valueForBinaryInteger(expression);
|
||||||
case ValueType::REAL32:
|
case ValueType::REAL32:
|
||||||
return valueForBinaryReal(expression);
|
return valueForBinaryReal(expression);
|
||||||
|
case ValueType::NONE:
|
||||||
|
return valueForBinaryInteger(expression);
|
||||||
default:
|
default:
|
||||||
exit(1);
|
failed("Unexpected operation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +140,7 @@ llvm::Value *ModuleBuilder::valueForBinaryBool(shared_ptr<ExpressionBinary> expr
|
|||||||
case ExpressionBinary::Operation::NOT_EQUAL:
|
case ExpressionBinary::Operation::NOT_EQUAL:
|
||||||
return builder->CreateICmpNE(leftValue, rightValue);
|
return builder->CreateICmpNE(leftValue, rightValue);
|
||||||
default:
|
default:
|
||||||
exit(1);
|
failed("Undefined operation for boolean operands");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +208,6 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr<ExpressionIfElse> expressi
|
|||||||
shared_ptr<Expression> conditionExpression = expression->getCondition();
|
shared_ptr<Expression> conditionExpression = expression->getCondition();
|
||||||
|
|
||||||
llvm::Function *fun = builder->GetInsertBlock()->getParent();
|
llvm::Function *fun = builder->GetInsertBlock()->getParent();
|
||||||
//llvm::Value *conditionValue = valueForBinary(conditionExpression);
|
|
||||||
llvm::Value *conditionValue = valueForExpression(conditionExpression);
|
llvm::Value *conditionValue = valueForExpression(conditionExpression);
|
||||||
|
|
||||||
llvm::BasicBlock *thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", fun);
|
llvm::BasicBlock *thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", fun);
|
||||||
@@ -217,14 +221,11 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr<ExpressionIfElse> expressi
|
|||||||
builder->SetInsertPoint(thenBlock);
|
builder->SetInsertPoint(thenBlock);
|
||||||
llvm::Value *thenValue = valueForExpression(expression->getThenBlock()->getStatementExpression()->getExpression());
|
llvm::Value *thenValue = valueForExpression(expression->getThenBlock()->getStatementExpression()->getExpression());
|
||||||
buildStatement(expression->getThenBlock());
|
buildStatement(expression->getThenBlock());
|
||||||
//llvm::Value *thenValue = llvm::ConstantInt::get(typeSInt32, 11, true);
|
|
||||||
//buildStatement(expression->getThenBlock());
|
|
||||||
builder->CreateBr(mergeBlock);
|
builder->CreateBr(mergeBlock);
|
||||||
thenBlock = builder->GetInsertBlock();
|
thenBlock = builder->GetInsertBlock();
|
||||||
|
|
||||||
// Else
|
// Else
|
||||||
fun->insert(fun->end(), elseBlock);
|
fun->insert(fun->end(), elseBlock);
|
||||||
//llvm::Value *elseValue = llvm::ConstantInt::get(typeSInt32, 22, true);
|
|
||||||
builder->SetInsertPoint(elseBlock);
|
builder->SetInsertPoint(elseBlock);
|
||||||
llvm::Value *elseValue = nullptr;
|
llvm::Value *elseValue = nullptr;
|
||||||
if (expression->getElseBlock() != nullptr) {
|
if (expression->getElseBlock() != nullptr) {
|
||||||
@@ -243,18 +244,29 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr<ExpressionIfElse> expressi
|
|||||||
if (elseValue != nullptr)
|
if (elseValue != nullptr)
|
||||||
phi->addIncoming(elseValue, elseBlock);
|
phi->addIncoming(elseValue, elseBlock);
|
||||||
|
|
||||||
//return llvm::ConstantInt::get(int32Type, 42, true);
|
|
||||||
return phi;
|
return phi;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value *ModuleBuilder::valueForVar(shared_ptr<ExpressionVar> expression) {
|
llvm::Value *ModuleBuilder::valueForVar(shared_ptr<ExpressionVar> expression) {
|
||||||
llvm::AllocaInst *alloca = allocaMap[expression->getName()];
|
llvm::AllocaInst *alloca = allocaMap[expression->getName()];
|
||||||
if (alloca == nullptr)
|
if (alloca == nullptr)
|
||||||
exit(1);
|
failed("Variable " + expression->getName() + " not defined");
|
||||||
|
|
||||||
return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getName());
|
return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
llvm::Value *ModuleBuilder::valueForCall(shared_ptr<ExpressionCall> expression) {
|
||||||
|
llvm::Function *fun = funMap[expression->getName()];
|
||||||
|
failed("Function " + expression->getName() + " not defined");
|
||||||
|
llvm::FunctionType *funType = fun->getFunctionType();
|
||||||
|
vector<llvm::Value*> argValues;
|
||||||
|
for (shared_ptr<Expression> &argumentExpression : expression->getArgumentExpressions()) {
|
||||||
|
llvm::Value *argValue = valueForExpression(argumentExpression);
|
||||||
|
argValues.push_back(argValue);
|
||||||
|
}
|
||||||
|
builder->CreateCall(funType, fun, llvm::ArrayRef(argValues));
|
||||||
|
}
|
||||||
|
|
||||||
llvm::Type *ModuleBuilder::typeForValueType(ValueType valueType) {
|
llvm::Type *ModuleBuilder::typeForValueType(ValueType valueType) {
|
||||||
switch (valueType) {
|
switch (valueType) {
|
||||||
case ValueType::NONE:
|
case ValueType::NONE:
|
||||||
@@ -267,3 +279,8 @@ llvm::Type *ModuleBuilder::typeForValueType(ValueType valueType) {
|
|||||||
return typeReal32;
|
return typeReal32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModuleBuilder::failed(string message) {
|
||||||
|
cerr << "Building module " << moduleName << " failed: " << message << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ private:
|
|||||||
|
|
||||||
vector<shared_ptr<Statement>> statements;
|
vector<shared_ptr<Statement>> statements;
|
||||||
map<string, llvm::AllocaInst*> allocaMap;
|
map<string, llvm::AllocaInst*> allocaMap;
|
||||||
|
map<string, llvm::Function*> funMap;
|
||||||
|
|
||||||
void buildStatement(shared_ptr<Statement> statement);
|
void buildStatement(shared_ptr<Statement> statement);
|
||||||
void buildFunctionDeclaration(shared_ptr<StatementFunctionDeclaration> statement);
|
void buildFunctionDeclaration(shared_ptr<StatementFunctionDeclaration> statement);
|
||||||
@@ -47,8 +48,10 @@ private:
|
|||||||
llvm::Value *valueForBinaryReal(shared_ptr<ExpressionBinary> expression);
|
llvm::Value *valueForBinaryReal(shared_ptr<ExpressionBinary> expression);
|
||||||
llvm::Value *valueForIfElse(shared_ptr<ExpressionIfElse> expression);
|
llvm::Value *valueForIfElse(shared_ptr<ExpressionIfElse> expression);
|
||||||
llvm::Value *valueForVar(shared_ptr<ExpressionVar> expression);
|
llvm::Value *valueForVar(shared_ptr<ExpressionVar> expression);
|
||||||
|
llvm::Value *valueForCall(shared_ptr<ExpressionCall> expression);
|
||||||
|
|
||||||
llvm::Type *typeForValueType(ValueType valueType);
|
llvm::Type *typeForValueType(ValueType valueType);
|
||||||
|
void failed(string message);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModuleBuilder(string moduleName, string sourceFileName, vector<shared_ptr<Statement>> statements);
|
ModuleBuilder(string moduleName, string sourceFileName, vector<shared_ptr<Statement>> statements);
|
||||||
|
|||||||
Reference in New Issue
Block a user