Adding simple module dependency analysis.

Addresses #14
This commit is contained in:
Stefano Sanfilippo 2014-12-10 20:38:32 +01:00
parent eb072a063d
commit 9c0a2573c3
3 changed files with 65 additions and 3 deletions

View File

@ -234,11 +234,13 @@ assign_stmt:
print_stmt: print_stmt:
expression PRINT { expression PRINT {
$$ = new Print($1); $$ = new Print($1);
program.addModule(new Module("iostream", Module::SYSTEM));
} }
; ;
input_stmt: input_stmt:
INPUT variable { INPUT variable {
$$ = new Input($2); $$ = new Input($2);
program.addModule(new Module("iostream", Module::SYSTEM));
} }
; ;
return_stmt: return_stmt:
@ -307,11 +309,13 @@ call_arglist:
abort_stmt: abort_stmt:
ABORT { ABORT {
$$ = new Abort(); $$ = new Abort();
program.addModule(new Module("cstdlib", Module::SYSTEM));
} }
; ;
assert_stmt: assert_stmt:
ASSERT expression BANG { ASSERT expression BANG {
$$ = new Assert($2); $$ = new Assert($2);
program.addModule(new Module("cassert", Module::SYSTEM));
} }
; ;
expression: expression:

View File

@ -224,6 +224,11 @@ void Function::emitSignature(std::ostream &stream, int indent) {
stream << ")"; 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) { void Main::emit(std::ostream &stream, int indent) {
emitIndent(stream, indent); emitIndent(stream, indent);
@ -233,9 +238,14 @@ void Main::emit(std::ostream &stream, int indent) {
} }
void Program::emit(std::ostream &stream, int indent) { void Program::emit(std::ostream &stream, int indent) {
stream << "#include <iostream>\n"; for (Module m: modules) {
stream << "#include <cassert>\n"; m.emit(stream);
stream << "#include <cstdlib>\n\n"; stream << "\n";
}
if (!modules.empty()) {
stream << "\n";
}
for (Function *f: functions) { for (Function *f: functions) {
f->emitSignature(stream); f->emitSignature(stream);

View File

@ -23,6 +23,8 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <memory> #include <memory>
#include <functional>
#include <unordered_set>
namespace monicelli { 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<std::string>()(name) ^ std::hash<bool>()(type);
}
virtual void emit(std::ostream &stream, int indent = 0);
private:
std::string name;
Type type;
};
} // namespace
namespace std {
template<>
class hash<monicelli::Module> {
public:
size_t operator ()(const monicelli::Module &e) const noexcept {
return e.hash();
}
};
}
namespace monicelli {
class Program: public Emittable { class Program: public Emittable {
public: public:
virtual void emit(std::ostream &stream, int indent = 0); virtual void emit(std::ostream &stream, int indent = 0);
@ -344,9 +386,15 @@ public:
functions.push_back(f); functions.push_back(f);
} }
void addModule(Module *m) {
modules.insert(std::move(*m));
delete m;
}
private: private:
Pointer<Main> main; Pointer<Main> main;
PointerList<Function> functions; PointerList<Function> functions;
std::unordered_set<Module> modules;
}; };