From 9c0a2573c3b43da8b38592ff7f4df65139c25c19 Mon Sep 17 00:00:00 2001 From: Stefano Sanfilippo Date: Wed, 10 Dec 2014 20:38:32 +0100 Subject: [PATCH] Adding simple module dependency analysis. Addresses #14 --- Monicelli.ypp | 4 ++++ Nodes.cpp | 16 +++++++++++++--- Nodes.hpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/Monicelli.ypp b/Monicelli.ypp index 23e2ba0..07c343c 100644 --- a/Monicelli.ypp +++ b/Monicelli.ypp @@ -234,11 +234,13 @@ assign_stmt: print_stmt: expression PRINT { $$ = new Print($1); + program.addModule(new Module("iostream", Module::SYSTEM)); } ; input_stmt: INPUT variable { $$ = new Input($2); + program.addModule(new Module("iostream", Module::SYSTEM)); } ; return_stmt: @@ -307,11 +309,13 @@ call_arglist: abort_stmt: ABORT { $$ = new Abort(); + program.addModule(new Module("cstdlib", Module::SYSTEM)); } ; assert_stmt: ASSERT expression BANG { $$ = new Assert($2); + program.addModule(new Module("cassert", Module::SYSTEM)); } ; expression: diff --git a/Nodes.cpp b/Nodes.cpp index 9cc0b63..a499221 100644 --- a/Nodes.cpp +++ b/Nodes.cpp @@ -224,6 +224,11 @@ void Function::emitSignature(std::ostream &stream, int indent) { stream << ")"; } +void Module::emit(std::ostream &stream, int indent) { + bool system = (type == Module::SYSTEM); + stream << "#include " << (system? '<': '"') << name << (system? '>': '"'); +} + void Main::emit(std::ostream &stream, int indent) { emitIndent(stream, indent); @@ -233,9 +238,14 @@ void Main::emit(std::ostream &stream, int indent) { } void Program::emit(std::ostream &stream, int indent) { - stream << "#include \n"; - stream << "#include \n"; - stream << "#include \n\n"; + for (Module m: modules) { + m.emit(stream); + stream << "\n"; + } + + if (!modules.empty()) { + stream << "\n"; + } for (Function *f: functions) { f->emitSignature(stream); diff --git a/Nodes.hpp b/Nodes.hpp index 572fa54..7b95f79 100644 --- a/Nodes.hpp +++ b/Nodes.hpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include namespace monicelli { @@ -332,6 +334,46 @@ private: }; +class Module: public Emittable { +public: + enum Type { + SYSTEM, USER + }; + + Module(const std::string &n, Type s): name(n), type(s) {} + virtual ~Module() {} + + bool operator==(const Module &other) const noexcept { + return (name == other.name) && (type == other.type); + } + + size_t hash() const noexcept { + return std::hash()(name) ^ std::hash()(type); + } + + virtual void emit(std::ostream &stream, int indent = 0); + +private: + std::string name; + Type type; +}; + +} // namespace + +namespace std { + +template<> +class hash { +public: + size_t operator ()(const monicelli::Module &e) const noexcept { + return e.hash(); + } +}; + +} + +namespace monicelli { + class Program: public Emittable { public: virtual void emit(std::ostream &stream, int indent = 0); @@ -344,9 +386,15 @@ public: functions.push_back(f); } + void addModule(Module *m) { + modules.insert(std::move(*m)); + delete m; + } + private: Pointer
main; PointerList functions; + std::unordered_set modules; };