Replace throw 0 with real exceptions or assertions.
This commit is contained in:
parent
1f7a53ccf6
commit
92a9ec2021
|
@ -1,4 +1,5 @@
|
|||
#include "definition.hpp"
|
||||
#include <cassert>
|
||||
#include "error.hpp"
|
||||
#include "ast.hpp"
|
||||
#include "instruction.hpp"
|
||||
|
@ -62,7 +63,10 @@ void definition_data::insert_constructors() const {
|
|||
type_app* return_app = new type_app(std::move(this_type_ptr));
|
||||
type_ptr return_type(return_app);
|
||||
for(auto& var : vars) {
|
||||
if(var_set.find(var) != var_set.end()) throw 0;
|
||||
if(var_set.find(var) != var_set.end())
|
||||
throw std::runtime_error(
|
||||
std::string("type variable ") +
|
||||
var + std::string(" used twice in data type definition."));
|
||||
var_set.insert(var);
|
||||
return_app->arguments.push_back(type_ptr(new type_var(var)));
|
||||
}
|
||||
|
@ -121,8 +125,7 @@ void definition_group::typecheck(type_mgr& mgr, type_env_ptr& env) {
|
|||
dependency_graph.add_function(def_defn.second->name);
|
||||
|
||||
for(auto& dependency : def_defn.second->nearby_variables) {
|
||||
if(defs_defn.find(dependency) == defs_defn.end())
|
||||
throw 0;
|
||||
assert(defs_defn.find(dependency) != defs_defn.end());
|
||||
dependency_graph.add_edge(def_defn.second->name, dependency);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include "env.hpp"
|
||||
#include <cassert>
|
||||
|
||||
int env_var::get_offset(const std::string& name) const {
|
||||
if(name == this->name) return 0;
|
||||
if(parent) return parent->get_offset(name) + 1;
|
||||
throw 0;
|
||||
assert(parent);
|
||||
return parent->get_offset(name) + 1;
|
||||
}
|
||||
|
||||
bool env_var::has_variable(const std::string& name) const {
|
||||
|
@ -13,8 +14,8 @@ bool env_var::has_variable(const std::string& name) const {
|
|||
}
|
||||
|
||||
int env_offset::get_offset(const std::string& name) const {
|
||||
if(parent) return parent->get_offset(name) + offset;
|
||||
throw 0;
|
||||
assert(parent);
|
||||
return parent->get_offset(name) + offset;
|
||||
}
|
||||
|
||||
bool env_offset::has_variable(const std::string& name) const {
|
||||
|
|
17
13/main.cpp
17
13/main.cpp
|
@ -103,12 +103,12 @@ void output_llvm(llvm_context& ctx, const std::string& filename) {
|
|||
std::error_code ec;
|
||||
llvm::raw_fd_ostream file(filename, ec, llvm::sys::fs::F_None);
|
||||
if (ec) {
|
||||
throw 0;
|
||||
throw std::runtime_error("failed to open object file for writing");
|
||||
} else {
|
||||
llvm::CodeGenFileType type = llvm::CGFT_ObjectFile;
|
||||
llvm::legacy::PassManager pm;
|
||||
if (targetMachine->addPassesToEmitFile(pm, file, NULL, type)) {
|
||||
throw 0;
|
||||
throw std::runtime_error("failed to add passes to pass manager");
|
||||
} else {
|
||||
pm.run(ctx.module);
|
||||
file.close();
|
||||
|
@ -132,10 +132,13 @@ void gen_llvm(global_scope& scope) {
|
|||
|
||||
int main(int argc, char** argv) {
|
||||
if(argc != 2) {
|
||||
std::cout << "please enter a file to compile." << std::endl;
|
||||
std::cerr << "please enter a file to compile." << std::endl;
|
||||
}
|
||||
parse_driver driver(argv[1]);
|
||||
driver.run_parse();
|
||||
if(!driver.run_parse()) {
|
||||
std::cerr << "failed to open file " << argv[1] << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
type_mgr mgr;
|
||||
type_env_ptr env(new type_env);
|
||||
|
@ -154,8 +157,10 @@ int main(int argc, char** argv) {
|
|||
scope.compile();
|
||||
gen_llvm(scope);
|
||||
} catch(unification_error& err) {
|
||||
err.pretty_print(std::cout, driver, mgr);
|
||||
err.pretty_print(std::cerr, driver, mgr);
|
||||
} catch(type_error& err) {
|
||||
err.pretty_print(std::cout, driver);
|
||||
err.pretty_print(std::cerr, driver);
|
||||
} catch(std::runtime_error& err) {
|
||||
std::cerr << err.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,9 +26,9 @@ struct parse_driver {
|
|||
parse_driver(const std::string& file)
|
||||
: file_name(file), file_offset(0) {}
|
||||
|
||||
void run_parse() {
|
||||
bool run_parse() {
|
||||
file_stream.open(file_name);
|
||||
if(!file_stream.good()) throw 0;
|
||||
if(!file_stream.good()) return false;
|
||||
line_offsets.push_back(0);
|
||||
yyscan_t scanner;
|
||||
scanner_init(this, &scanner);
|
||||
|
@ -36,6 +36,7 @@ struct parse_driver {
|
|||
parser();
|
||||
scanner_destroy(&scanner);
|
||||
read_file = string_stream.str();
|
||||
return true;
|
||||
}
|
||||
|
||||
int get() {
|
||||
|
|
|
@ -1,15 +1,26 @@
|
|||
#include "parsed_type.hpp"
|
||||
#include <sstream>
|
||||
#include "type.hpp"
|
||||
#include "type_env.hpp"
|
||||
#include "error.hpp"
|
||||
|
||||
type_ptr parsed_type_app::to_type(
|
||||
const std::set<std::string>& vars,
|
||||
const type_env& e) const {
|
||||
auto parent_type = e.lookup_type(name);
|
||||
if(parent_type == nullptr) throw 0;
|
||||
if(parent_type == nullptr)
|
||||
throw type_error(std::string("no such type or type constructor ") + name);
|
||||
type_base* base_type;
|
||||
if(!(base_type = dynamic_cast<type_base*>(parent_type.get()))) throw 0;
|
||||
if(base_type->arity != arguments.size()) throw 0;
|
||||
if(!(base_type = dynamic_cast<type_base*>(parent_type.get())))
|
||||
throw type_error(std::string("invalid type ") + name);
|
||||
if(base_type->arity != arguments.size()) {
|
||||
std::ostringstream error_stream;
|
||||
error_stream << "invalid application of type ";
|
||||
error_stream << name;
|
||||
error_stream << "(" << base_type->arity << " arguments expected, ";
|
||||
error_stream << "but " << arguments.size() << " were provided)";
|
||||
throw type_error(error_stream.str());
|
||||
}
|
||||
|
||||
type_app* new_app = new type_app(std::move(parent_type));
|
||||
type_ptr to_return(new_app);
|
||||
|
@ -22,7 +33,8 @@ type_ptr parsed_type_app::to_type(
|
|||
type_ptr parsed_type_var::to_type(
|
||||
const std::set<std::string>& vars,
|
||||
const type_env& e) const {
|
||||
if(vars.find(var) == vars.end()) throw 0;
|
||||
if(vars.find(var) == vars.end())
|
||||
throw type_error(std::string("the type variable ") + var + std::string(" was not explicitly declared."));
|
||||
return type_ptr(new type_var(var));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "type_env.hpp"
|
||||
#include "type.hpp"
|
||||
#include "error.hpp"
|
||||
|
||||
void type_env::find_free(const type_mgr& mgr, std::set<std::string>& into) const {
|
||||
if(parent != nullptr) parent->find_free(mgr, into);
|
||||
|
@ -61,14 +62,15 @@ void type_env::bind(const std::string& name, type_scheme_ptr t, visibility v) {
|
|||
}
|
||||
|
||||
void type_env::bind_type(const std::string& type_name, type_ptr t) {
|
||||
if(lookup_type(type_name) != nullptr) throw 0;
|
||||
if(lookup_type(type_name) != nullptr)
|
||||
throw type_error("redefinition of type");
|
||||
type_names[type_name] = t;
|
||||
}
|
||||
|
||||
void type_env::generalize(const std::string& name, const group& grp, type_mgr& mgr) {
|
||||
auto names_it = names.find(name);
|
||||
if(names_it == names.end()) throw 0;
|
||||
if(names_it->second.type->forall.size() > 0) throw 0;
|
||||
assert(names_it != names.end());
|
||||
assert(names_it->second.type->forall.size() == 0);
|
||||
|
||||
std::set<std::string> free_in_type;
|
||||
std::set<std::string> free_in_env;
|
||||
|
|
Loading…
Reference in New Issue
Block a user