diff options
| author | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
|---|---|---|
| committer | Martial Simon <msimon_fr@hotmail.com> | 2025-09-15 01:07:58 +0200 |
| commit | 967be9e750221ab2ab783f95df79bb26d290a45e (patch) | |
| tree | 6802900a5e975f9f68b169f0f503f040056d6952 /tiger-compiler/src/bind/binder.cc | |
Diffstat (limited to 'tiger-compiler/src/bind/binder.cc')
| -rw-r--r-- | tiger-compiler/src/bind/binder.cc | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/tiger-compiler/src/bind/binder.cc b/tiger-compiler/src/bind/binder.cc new file mode 100644 index 0000000..171e199 --- /dev/null +++ b/tiger-compiler/src/bind/binder.cc @@ -0,0 +1,183 @@ +/** + ** \file bind/binder.cc + ** \brief Implementation for bind/binder.hh. + */ + +#include <ast/all.hh> +#include <bind/binder.hh> + +#include <misc/contract.hh> + +namespace bind +{ + /*-----------------. + | Error handling. | + `-----------------*/ + + /// The error handler. + const misc::error& Binder::error_get() const { return error_; } + + // FIXME DONE: Some code was deleted here. + void Binder::operator()(ast::SimpleVar& e) + { + ast::VarDec* init = scoped_map_var_.get(e.name_get()); + if (init == nullptr) + { + err_undef(e.location_get(), e.name_get()); + return; + } + e.def_set(init); + } + + void Binder::operator()(ast::CallExp& e) + { + ast::FunctionDec* init = scoped_map_fun_.get(e.name_get()); + if (init == nullptr) + { + err_undef(e.location_get(), e.name_get()); + return; + } + e.def_set(init); + super_type::operator()(e); + } + + void Binder::operator()(ast::NameTy& e) + { + misc::symbol test_string("string"); + misc::symbol test_int("int"); + if (e.name_get() == test_int || e.name_get() == test_string) + { + auto init = scoped_map_ty_.get(e.name_get()); + e.def_set(init); + } + else + { + auto init = scoped_map_ty_.get(e.name_get()); + if (init == nullptr) + { + err_type_undef(e.location_get(), e.name_get()); + return; + } + e.def_set(init); + } + } + + void Binder::operator()(ast::WhileExp& e) + { + bool actual = in_a_while_; + e.test_get().accept(*this); + loop_.emplace_back(&e); + in_a_while_ = true; + begin_scope(); + e.body_get().accept(*this); + end_scope(); + loop_.pop_back(); + in_a_while_ = actual; + } + + void Binder::operator()(ast::ForExp& e) + { + bool actual = in_a_while_; + begin_scope(); + in_a_while_ = true; + e.vardec_get().accept(*this); + e.hi_get().accept(*this); + loop_.emplace_back(&e); + e.body_get().accept(*this); + end_scope(); + loop_.pop_back(); + in_a_while_ = actual; + } + + void Binder::operator()(ast::BreakExp& e) + { + if (loop_.empty() || !in_a_while_) + { + error_ << misc::error::error_type::bind; + error_ << e.location_get() << ": 'break' outside any loop\n"; + } + else + { + e.def_set(loop_.back()); + } + } + + //Declaration of function + + void Binder::operator()(ast::VarDec& e) + { + bool actual = in_a_while_; + scoped_map_var_.put(e.name_get(), &e); + in_a_while_ = false; + super_type::operator()(e); + in_a_while_ = actual; + } + + void Binder::operator()(ast::FunctionChunk& e) + { + chunk_visit<ast::FunctionDec>(e); + } + + void Binder::operator()(ast::TypeChunk& e) + { + chunk_visit<ast::TypeDec>(e); + } + + template <class D> void Binder::chunk_visit(ast::Chunk<D>& e) + { + misc::scoped_map<const misc::symbol, D*> def = misc::scoped_map<const misc::symbol, D*>(); + for (auto machala : e) + { + visit_dec_head<D>(*machala); + } + for (auto dec : e) + { + auto init = def.get(dec->name_get()); + if (init == nullptr) + { + def.put(dec->name_get(), dec); + visit_dec_bod<D>(*dec); + } + else + { + err_ddec(dec->location_get(), init->location_get(), dec->name_get()); + } + } + } + + void Binder::operator()(ast::FunctionDec& e) + { + if (e.name_get() == "_main") + { + if (is_main_already_) + { + error_ << misc::error::error_type::bind; + error_ << "Un deuxieme _main??????\n"; + return; + } + is_main_already_ = true; + if (in_a_scope_) + { + error_ << misc::error::error_type::bind; + error_ << "BRADDOCK, je vous préviens, attention ou vous mettez votre _main!!"; + return; + } + } + scoped_map_fun_.put(e.name_get(), &e); + bool scope = in_a_scope_; + bool actual = in_a_while_; + in_a_while_ = false; + in_a_scope_ = true; + this->accept(e.result_get()); + body_func(e); + in_a_while_ = actual; + in_a_scope_ = scope; + } + + void Binder::operator()(ast::TypeDec& e) + { + scoped_map_ty_.put(e.name_get(), &e); + super_type::operator()(e); + } + +} // namespace bind |
