Implementing abort/assert/input/output bitcode generation.

This commit is contained in:
Stefano Sanfilippo 2015-03-07 14:02:29 +01:00
parent 4321fa5dbf
commit 754485e40b

View File

@ -268,18 +268,91 @@ bool BitcodeEmitter::emit(Assignment const& node) {
} }
bool BitcodeEmitter::emit(Print const& node) { bool BitcodeEmitter::emit(Print const& node) {
std::vector<llvm::Value*> callargs;
GUARDED(node.getExpression().emit(this));
callargs.push_back(d->retval);
Type printType = MonicelliType(d->retval->getType());
if (printType == Type::UNKNOWN) {
return reportError({"Attempting to print unknown type"});
}
auto toCall = PUT_NAMES.find(printType);
if (toCall == PUT_NAMES.end()) {
return reportError({"Unknown print function for type"});
}
llvm::Function *callee = module->getFunction(toCall->second);
if (callee == nullptr) {
return reportError({"Print function was not registered"});
}
d->builder.CreateCall(callee, callargs);
return true; return true;
} }
bool BitcodeEmitter::emit(Input const& node) { bool BitcodeEmitter::emit(Input const& node) {
auto lookupResult = d->scope.lookup(node.getVariable().getValue());
if (!lookupResult) {
return reportError({"Attempting to read undefined variable"});
}
llvm::AllocaInst *variable = *lookupResult;
Type inputType = MonicelliType(variable->getAllocatedType());
if (inputType == Type::UNKNOWN) {
return reportError({"Attempting to read unknown type"});
}
auto toCall = GET_NAMES.find(inputType);
if (toCall == GET_NAMES.end()) {
return reportError({
"Unknown input function for type"
});
}
llvm::Function *callee = module->getFunction(toCall->second);
if (callee == nullptr) {
return reportError({
"Input function was not registered for type"
});
}
llvm::Value *readval = d->builder.CreateCall(callee);
d->builder.CreateStore(readval, variable);
return true; return true;
} }
bool BitcodeEmitter::emit(Abort const& node) { bool BitcodeEmitter::emit(Abort const& node) {
llvm::Function *callee = module->getFunction(ABORT_NAME);
if (callee == nullptr) {
return reportError({"Abort function was not registered"});
}
d->builder.CreateCall(callee);
return true; return true;
} }
bool BitcodeEmitter::emit(Assert const& node) { bool BitcodeEmitter::emit(Assert const& node) {
llvm::Function *callee = module->getFunction(ASSERT_NAME);
if (callee == nullptr) {
return reportError({"Assert function was not registered"});
}
node.getExpression().emit(this);
d->builder.CreateCall(callee, {coerce(d, d->retval, LLVMType(Type::BOOL))});
return true; return true;
} }