From 734537a528031a5a4448a3dc0affd9f4bb83a7ce Mon Sep 17 00:00:00 2001 From: apio Date: Fri, 26 Aug 2022 17:29:20 +0200 Subject: [PATCH] implicit casts between integer/floating point types yay!! --- src/AST/FunctionNode.cpp | 24 ++++++++++++++++++++++++ src/Parser.cpp | 3 ++- tests/float-expr.json | 9 +++++++-- tests/unmatched-integer-type.json | 14 ++++++++++++++ tests/unmatched-integer-type.sp | 3 +++ tests/unmatched-type.json | 2 +- 6 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 tests/unmatched-integer-type.json create mode 100644 tests/unmatched-integer-type.sp diff --git a/src/AST/FunctionNode.cpp b/src/AST/FunctionNode.cpp index de89f27..ed21a3b 100644 --- a/src/AST/FunctionNode.cpp +++ b/src/AST/FunctionNode.cpp @@ -40,6 +40,30 @@ void FunctionNode::codegen(IRBuilder* builder, llvm::Module* module) if (llvm::Value* retVal = body->codegen(builder)) { + if (retVal->getType() != prototype.returnType) + { + if (retVal->getType()->isIntegerTy() && prototype.returnType->isIntegerTy()) + { + retVal = builder->getBuilder()->CreateIntCast(retVal, prototype.returnType, true); + } + else if (retVal->getType()->isFloatingPointTy() && prototype.returnType->isFloatingPointTy()) + { + retVal = builder->getBuilder()->CreateFPCast(retVal, prototype.returnType); + } + else if (retVal->getType()->isIntegerTy() && prototype.returnType->isFloatingPointTy()) + { + retVal = builder->getBuilder()->CreateCast(llvm::Instruction::SIToFP, retVal, prototype.returnType); + } + else if (retVal->getType()->isFloatingPointTy() && prototype.returnType->isIntegerTy()) + { + retVal = builder->getBuilder()->CreateCast(llvm::Instruction::FPToSI, retVal, prototype.returnType); + } + else + { + Error::throw_error_without_location( + format_string("The %s function's body type does not match its return type", prototype.name)); + } + } builder->getBuilder()->CreateRet(retVal); if (llvm::verifyFunction(*Function)) diff --git a/src/Parser.cpp b/src/Parser.cpp index ed3fcdc..ab61b63 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -10,7 +10,8 @@ Parser::Parser(const TokenStream& tokens) : tokens(tokens) { m_type_map = {{"void", llvm::Type::getVoidTy(*globalContext)}, {"bool", llvm::Type::getInt1Ty(*globalContext)}, {"i8", llvm::Type::getInt8Ty(*globalContext)}, {"i16", llvm::Type::getInt16Ty(*globalContext)}, - {"i32", llvm::Type::getInt32Ty(*globalContext)}, {"i64", llvm::Type::getInt64Ty(*globalContext)}}; + {"i32", llvm::Type::getInt32Ty(*globalContext)}, {"i64", llvm::Type::getInt64Ty(*globalContext)}, + {"f32", llvm::Type::getFloatTy(*globalContext)}, {"f64", llvm::Type::getDoubleTy(*globalContext)}}; } std::shared_ptr Parser::new_parser(const TokenStream& tokens) diff --git a/tests/float-expr.json b/tests/float-expr.json index 86a75d7..c2b751b 100644 --- a/tests/float-expr.json +++ b/tests/float-expr.json @@ -2,8 +2,13 @@ "file": "float-expr.sp", "compile": { "flags": [], - "exit-code": 1, + "exit-code": 0, "stdout": "", - "stderr": "\u001b[1;1m\u001b[31;49merror: \u001b[0;0mInvalid function main\n" + "stderr": "" + }, + "run": { + "exit-code": 3, + "stdout": "", + "stderr": "" } } \ No newline at end of file diff --git a/tests/unmatched-integer-type.json b/tests/unmatched-integer-type.json new file mode 100644 index 0000000..81d9b70 --- /dev/null +++ b/tests/unmatched-integer-type.json @@ -0,0 +1,14 @@ +{ + "file": "unmatched-integer-type.sp", + "compile": { + "flags": [], + "exit-code": 0, + "stdout": "", + "stderr": "" + }, + "run": { + "exit-code": 0, + "stdout": "", + "stderr": "" + } +} \ No newline at end of file diff --git a/tests/unmatched-integer-type.sp b/tests/unmatched-integer-type.sp new file mode 100644 index 0000000..3967d81 --- /dev/null +++ b/tests/unmatched-integer-type.sp @@ -0,0 +1,3 @@ +let @main : i64 in { + 0 +} \ No newline at end of file diff --git a/tests/unmatched-type.json b/tests/unmatched-type.json index ccb71b3..b61c877 100644 --- a/tests/unmatched-type.json +++ b/tests/unmatched-type.json @@ -4,6 +4,6 @@ "flags": [], "exit-code": 1, "stdout": "", - "stderr": "\u001b[1;1m\u001b[31;49merror: \u001b[0;0mInvalid function main\n" + "stderr": "\u001b[1;1m\u001b[31;49merror: \u001b[0;0mThe main function's body type does not match its return type\n" } } \ No newline at end of file