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:
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:

View File

@ -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 <iostream>\n";
stream << "#include <cassert>\n";
stream << "#include <cstdlib>\n\n";
for (Module m: modules) {
m.emit(stream);
stream << "\n";
}
if (!modules.empty()) {
stream << "\n";
}
for (Function *f: functions) {
f->emitSignature(stream);

View File

@ -23,6 +23,8 @@
#include <vector>
#include <iostream>
#include <memory>
#include <functional>
#include <unordered_set>
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 {
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> main;
PointerList<Function> functions;
std::unordered_set<Module> modules;
};