diff --git a/src/codegen.cpp b/src/codegen.cpp index 3654d5c..8eadfad 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -41,7 +41,7 @@ namespace AST { } } else { - throw std::runtime_error("Value " + this->m_name + " not found"); + throw codegen::Error("Value " + this->m_name + " not found", this->m_meta); } } @@ -49,32 +49,37 @@ namespace AST { auto lvalued = scope.with_lvalue(); auto lhs = this->m_lhs->codegen(builder, this->m_binop == types::BinOp::Assignment ? lvalued : scope); auto rhs = this->m_rhs->codegen(builder, scope); - switch (this->m_binop) { - case types::BinOp::Assignment: - builder.builder->CreateStore(rhs.value, lhs.value, false); - return rhs; - case types::BinOp::Add: - return codegen::StackValue{ - lhs.ty->add(builder, lhs.value, rhs.value), - lhs.ty - }; - case types::BinOp::Sub: - return codegen::StackValue{ - lhs.ty->sub(builder, lhs.value, rhs.value), - lhs.ty - }; - case types::BinOp::LessThan: - return codegen::StackValue{ - lhs.ty->lt(builder, lhs.value, rhs.value), - std::make_shared(types::FundamentalTypeKind::Bool), - }; - case types::BinOp::GreaterThan: - return codegen::StackValue{ - lhs.ty->gt(builder, lhs.value, rhs.value), - std::make_shared(types::FundamentalTypeKind::Bool), - }; - default: - throw std::runtime_error("invalid binop"); + try { + switch (this->m_binop) { + case types::BinOp::Assignment: + builder.builder->CreateStore(rhs.value, lhs.value, false); + return rhs; + case types::BinOp::Add: + return codegen::StackValue{ + lhs.ty->add(builder, lhs.value, rhs.value), + lhs.ty + }; + case types::BinOp::Sub: + return codegen::StackValue{ + lhs.ty->sub(builder, lhs.value, rhs.value), + lhs.ty + }; + case types::BinOp::LessThan: + return codegen::StackValue{ + lhs.ty->lt(builder, lhs.value, rhs.value), + std::make_shared(types::FundamentalTypeKind::Bool), + }; + case types::BinOp::GreaterThan: + return codegen::StackValue{ + lhs.ty->gt(builder, lhs.value, rhs.value), + std::make_shared(types::FundamentalTypeKind::Bool), + }; + default: + throw codegen::Error("invalid binop", this->m_meta); + } + } + catch (std::runtime_error& error) { + throw codegen::Error(error.what(), this->m_meta); } } diff --git a/src/codegen.h b/src/codegen.h index 93cbf9b..c5eb939 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -8,8 +8,16 @@ #include "builder.h" #include "types.h" +#include "tokens.h" namespace codegen { + class Error : public std::runtime_error { + public: + token::Metadata m_meta; + Error(std::string text, token::Metadata meta) + : std::runtime_error{ text }, m_meta{ meta } {} + }; + struct StackValue { llvm::Value* value = nullptr; std::shared_ptr ty = nullptr; diff --git a/src/main.cpp b/src/main.cpp index 1eb932c..db79527 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,8 +88,10 @@ int main() { tls->codegen(builder, scope); } } - catch (std::runtime_error& error) { + catch (codegen::Error& error) { std::cerr << "FATAL: " << error.what() << std::endl; + std::cerr << " at " << error.m_meta.start.line + 1 << ":" << error.m_meta.start.col + 1; + std::cerr << " to " << error.m_meta.end.line + 1 << ":" << error.m_meta.end.col + 1 << std::endl; return 1; } diff --git a/src/types.cpp b/src/types.cpp index 82c6d2e..decbdaf 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1,7 +1,8 @@ -#include "types.h" #include +#include "types.h" + namespace types { int operator_precedence(BinOp& op) { switch (op) {