Introducing boost::ptr_vector and boost::ptr_unordered_set.
This is an easy way to increase the uniformity of the API.
This commit is contained in:
parent
19a0c656f2
commit
b2e7a11b7a
|
@ -254,8 +254,8 @@ bool BitcodeEmitter::emit(Loop const& node) {
|
|||
d->builder.SetInsertPoint(body);
|
||||
|
||||
d->scope.enter();
|
||||
for (Statement const* statement: node.getBody()) {
|
||||
GUARDED(statement->emit(this));
|
||||
for (Statement const& statement: node.getBody()) {
|
||||
GUARDED(statement.emit(this));
|
||||
}
|
||||
d->scope.leave();
|
||||
|
||||
|
@ -424,8 +424,8 @@ bool BitcodeEmitter::emit(FunctionCall const& node) {
|
|||
|
||||
auto param = callee->getArgumentList().begin();
|
||||
std::vector<llvm::Value*> callargs;
|
||||
for (Expression const* arg: node.getArgs()) {
|
||||
GUARDED(arg->emit(this));
|
||||
for (Expression const& arg: node.getArgs()) {
|
||||
GUARDED(arg.emit(this));
|
||||
callargs.push_back(coerce(d, d->retval, param->getType()));
|
||||
++param;
|
||||
}
|
||||
|
@ -449,17 +449,17 @@ bool BitcodeEmitter::emit(Branch const& node) {
|
|||
getGlobalContext(), "endif"
|
||||
);
|
||||
|
||||
BranchCase const* last = body.getCases().back();
|
||||
BranchCase const& last = body.getCases().back();
|
||||
|
||||
for (BranchCase const* cas: body.getCases()) {
|
||||
emitSemiExpression(node.getVar(), cas->getCondition());
|
||||
for (BranchCase const& cas: body.getCases()) {
|
||||
emitSemiExpression(node.getVar(), cas.getCondition());
|
||||
d->builder.CreateCondBr(
|
||||
isTrue(d->builder, d->retval, "condition"), thenbb, elsebb
|
||||
);
|
||||
d->builder.SetInsertPoint(thenbb);
|
||||
d->scope.enter();
|
||||
for (Statement const* statement: cas->getBody()) {
|
||||
GUARDED(statement->emit(this));
|
||||
for (Statement const& statement: cas.getBody()) {
|
||||
GUARDED(statement.emit(this));
|
||||
}
|
||||
d->scope.leave();
|
||||
d->builder.CreateBr(mergebb);
|
||||
|
@ -467,7 +467,7 @@ bool BitcodeEmitter::emit(Branch const& node) {
|
|||
func->getBasicBlockList().push_back(elsebb);
|
||||
d->builder.SetInsertPoint(elsebb);
|
||||
|
||||
if (cas != last) {
|
||||
if (&cas != &last) {
|
||||
thenbb = llvm::BasicBlock::Create(getGlobalContext(), "then", func);
|
||||
elsebb = llvm::BasicBlock::Create(getGlobalContext(), "else");
|
||||
}
|
||||
|
@ -475,8 +475,8 @@ bool BitcodeEmitter::emit(Branch const& node) {
|
|||
|
||||
if (body.getElse()) {
|
||||
d->scope.enter();
|
||||
for (Statement const* statement: *body.getElse()) {
|
||||
GUARDED(statement->emit(this));
|
||||
for (Statement const& statement: *body.getElse()) {
|
||||
GUARDED(statement.emit(this));
|
||||
}
|
||||
d->scope.leave();
|
||||
d->builder.CreateBr(mergebb);
|
||||
|
@ -491,13 +491,13 @@ bool BitcodeEmitter::emit(Branch const& node) {
|
|||
bool BitcodeEmitter::emit(FunctionPrototype const& node) {
|
||||
std::vector<llvm::Type*> argTypes;
|
||||
|
||||
for (FunArg const* arg: node.getArgs()) {
|
||||
argTypes.emplace_back(LLVMType(arg->getType()));
|
||||
for (FunArg const& arg: node.getArgs()) {
|
||||
argTypes.emplace_back(LLVMType(arg.getType()));
|
||||
}
|
||||
|
||||
std::unordered_set<std::string> argsSet;
|
||||
for (FunArg const* arg: node.getArgs()) {
|
||||
std::string const& name = arg->getName().getValue();
|
||||
for (FunArg const& arg: node.getArgs()) {
|
||||
std::string const& name = arg.getName().getValue();
|
||||
if (argsSet.find(name) != argsSet.end()) {
|
||||
return reportError({
|
||||
"Two arguments with same name to function",
|
||||
|
@ -536,8 +536,8 @@ bool BitcodeEmitter::emit(FunctionPrototype const& node) {
|
|||
}
|
||||
|
||||
auto argToEmit = func->arg_begin();
|
||||
for (FunArg const* arg: node.getArgs()) {
|
||||
argToEmit->setName(arg->getName().getValue());
|
||||
for (FunArg const& arg: node.getArgs()) {
|
||||
argToEmit->setName(arg.getName().getValue());
|
||||
++argToEmit;
|
||||
}
|
||||
|
||||
|
@ -558,16 +558,16 @@ bool BitcodeEmitter::emit(Function const& node) {
|
|||
d->builder.SetInsertPoint(bb);
|
||||
|
||||
auto argToAlloc = func->arg_begin();
|
||||
for (FunArg const* arg: node.getPrototype().getArgs()) {
|
||||
for (FunArg const& arg: node.getPrototype().getArgs()) {
|
||||
llvm::AllocaInst *alloc = allocateVar(
|
||||
func, arg->getName(), LLVMType(arg->getType())
|
||||
func, arg.getName(), LLVMType(arg.getType())
|
||||
);
|
||||
d->builder.CreateStore(argToAlloc, alloc);
|
||||
d->scope.push(arg->getName().getValue(), alloc);
|
||||
d->scope.push(arg.getName().getValue(), alloc);
|
||||
}
|
||||
|
||||
for (Statement const* stat: node.getBody()) {
|
||||
GUARDED(stat->emit(this));
|
||||
for (Statement const& stat: node.getBody()) {
|
||||
GUARDED(stat.emit(this));
|
||||
}
|
||||
|
||||
verifyFunction(*func);
|
||||
|
@ -583,12 +583,12 @@ bool BitcodeEmitter::emit(Module const& node) {
|
|||
|
||||
bool BitcodeEmitter::emit(Program const& program) {
|
||||
auto const& externals = getModuleRegistry().getRegisteredFunctions();
|
||||
for (FunctionPrototype const* proto: externals) {
|
||||
GUARDED(proto->emit(this));
|
||||
for (FunctionPrototype const& proto: externals) {
|
||||
GUARDED(proto.emit(this));
|
||||
}
|
||||
|
||||
for (Function const* function: program.getFunctions()) {
|
||||
GUARDED(function->emit(this));
|
||||
for (Function const& function: program.getFunctions()) {
|
||||
GUARDED(function.emit(this));
|
||||
}
|
||||
|
||||
if (program.getMain()) {
|
||||
|
|
|
@ -58,8 +58,8 @@ bool CppEmitter::emit(Program const& program) {
|
|||
stream << "\n";
|
||||
}
|
||||
|
||||
for (Function *function: program.getFunctions()) {
|
||||
emit(function->getPrototype());
|
||||
for (Function const& function: program.getFunctions()) {
|
||||
emit(function.getPrototype());
|
||||
stream << ";\n";
|
||||
}
|
||||
|
||||
|
@ -67,8 +67,8 @@ bool CppEmitter::emit(Program const& program) {
|
|||
stream << "\n";
|
||||
}
|
||||
|
||||
for (Function *function: program.getFunctions()) {
|
||||
GUARDED(function->emit(this));
|
||||
for (Function const& function: program.getFunctions()) {
|
||||
GUARDED(function.emit(this));
|
||||
}
|
||||
|
||||
if (program.getMain()) {
|
||||
|
@ -79,9 +79,9 @@ bool CppEmitter::emit(Program const& program) {
|
|||
}
|
||||
|
||||
bool CppEmitter::emitStatements(PointerList<Statement> const& node) {
|
||||
for (Statement *s: node) {
|
||||
for (Statement const& s: node) {
|
||||
emitIndent();
|
||||
GUARDED(s->emit(this));
|
||||
GUARDED(s.emit(this));
|
||||
stream << STATEMENT_TERMINATOR;
|
||||
}
|
||||
return stream;
|
||||
|
@ -202,10 +202,10 @@ bool CppEmitter::emit(Branch const& branch) {
|
|||
GUARDED(var.emit(this));
|
||||
|
||||
if (body.getCases().size() > 0) {
|
||||
BranchCase *last = body.getCases().back();
|
||||
for (BranchCase *cas: body.getCases()) {
|
||||
emitBranchCase(*cas);
|
||||
if (cas != last) {
|
||||
BranchCase const& last = body.getCases().back();
|
||||
for (BranchCase const& cas: body.getCases()) {
|
||||
emitBranchCase(cas);
|
||||
if (&cas != &last) {
|
||||
stream << " else if (";
|
||||
GUARDED(var.emit(this));
|
||||
}
|
||||
|
@ -236,10 +236,10 @@ bool CppEmitter::emit(Assignment const& assignment) {
|
|||
|
||||
|
||||
bool CppEmitter::emitFunctionArglist(PointerList<Expression> const& args) {
|
||||
Expression *last = args.back();
|
||||
for (Expression const* arg: args) {
|
||||
GUARDED(arg->emit(this));
|
||||
if (arg != last) {
|
||||
Expression const& last = args.back();
|
||||
for (Expression const& arg: args) {
|
||||
GUARDED(arg.emit(this));
|
||||
if (&arg != &last) {
|
||||
stream << ", ";
|
||||
}
|
||||
}
|
||||
|
@ -297,12 +297,12 @@ std::ostream& operator<<(std::ostream &stream, Type const& type) {
|
|||
}
|
||||
|
||||
bool CppEmitter::emitFunctionParams(PointerList<FunArg> const& funargs) {
|
||||
FunArg *last = funargs.back();
|
||||
FunArg const& last = funargs.back();
|
||||
|
||||
for (FunArg const* funarg: funargs) {
|
||||
stream << funarg->getType() << (funarg->isPointer()? "* ": " ");
|
||||
GUARDED(funarg->getName().emit(this));
|
||||
if (funarg != last) {
|
||||
for (FunArg const& funarg: funargs) {
|
||||
stream << funarg.getType() << (funarg.isPointer()? "* ": " ");
|
||||
GUARDED(funarg.getName().emit(this));
|
||||
if (&funarg != &last) {
|
||||
stream << ", ";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
*/
|
||||
|
||||
#include "ModuleRegistry.hpp"
|
||||
#include "Pointers.hpp"
|
||||
#include "Nodes.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace monicelli;
|
||||
|
||||
|
@ -31,7 +31,7 @@ ModuleRegistry& monicelli::getModuleRegistry() {
|
|||
}
|
||||
|
||||
struct ModuleRegistry::Private {
|
||||
PointerList<FunctionPrototype> prototypes;
|
||||
boost::ptr_unordered_set<FunctionPrototype> prototypes;
|
||||
};
|
||||
|
||||
ModuleRegistry::ModuleRegistry() {
|
||||
|
@ -42,20 +42,20 @@ ModuleRegistry::~ModuleRegistry() {
|
|||
delete d;
|
||||
}
|
||||
|
||||
PointerList<FunctionPrototype> const& ModuleRegistry::getRegisteredFunctions() const {
|
||||
PointerSet<FunctionPrototype> const& ModuleRegistry::getRegisteredFunctions() const {
|
||||
return d->prototypes;
|
||||
}
|
||||
|
||||
void ModuleRegistry::registerFunction(FunctionPrototype *proto) {
|
||||
d->prototypes.push_back(proto);
|
||||
d->prototypes.insert(proto);
|
||||
}
|
||||
|
||||
#define PUT(type, funcname) \
|
||||
new FunctionPrototype { \
|
||||
new Id {#funcname}, Type::VOID, \
|
||||
new PointerList<FunArg> { \
|
||||
plist({ \
|
||||
new FunArg {new Id {"value"}, type, false} \
|
||||
}, \
|
||||
}), \
|
||||
}
|
||||
|
||||
#define GET(type, funcname) \
|
||||
|
@ -77,14 +77,15 @@ void monicelli::registerStdLib(ModuleRegistry &r) {
|
|||
r.registerFunction(GET(Type::INT, __Monicelli_getInt));
|
||||
r.registerFunction(new FunctionPrototype {
|
||||
new Id("__Monicelli_assert"), Type::VOID,
|
||||
new PointerList<FunArg> {
|
||||
plist({
|
||||
new FunArg {new Id("condition"), Type::CHAR, false}
|
||||
}
|
||||
})
|
||||
});
|
||||
r.registerFunction(new FunctionPrototype {
|
||||
new Id("__Monicelli_abort"), Type::VOID,
|
||||
new PointerList<FunArg> {}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
#undef PUT
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
ModuleRegistry(ModuleRegistry&) = delete;
|
||||
virtual ~ModuleRegistry();
|
||||
|
||||
PointerList<FunctionPrototype> const& getRegisteredFunctions() const;
|
||||
PointerSet<FunctionPrototype> const& getRegisteredFunctions() const;
|
||||
void registerFunction(FunctionPrototype *proto);
|
||||
|
||||
private:
|
||||
|
|
34
Pointers.hpp
34
Pointers.hpp
|
@ -21,33 +21,25 @@
|
|||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <initializer_list>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/ptr_container/ptr_unordered_set.hpp>
|
||||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
|
||||
namespace monicelli {
|
||||
|
||||
// We need these instead of an using decl for compatibility
|
||||
template <class T>
|
||||
class Pointer: public std::unique_ptr<T> {
|
||||
public:
|
||||
Pointer(T *p = nullptr): std::unique_ptr<T>(p) {}
|
||||
};
|
||||
template<typename T> using Pointer = std::unique_ptr<T>;
|
||||
template<typename T> using PointerList = boost::ptr_vector<T>;
|
||||
template<typename T> using PointerSet = boost::ptr_unordered_set<T>;
|
||||
|
||||
|
||||
template<class T>
|
||||
class PointerList: public std::vector<T*> {
|
||||
public:
|
||||
using std::vector<T*>::vector;
|
||||
PointerList() {}
|
||||
PointerList(PointerList&) = delete;
|
||||
|
||||
virtual ~PointerList() {
|
||||
for (T *element: *this) {
|
||||
delete element;
|
||||
}
|
||||
template<typename T>
|
||||
PointerList<T>* plist(std::initializer_list<T*> elements) {
|
||||
PointerList<T> *result = new PointerList<T>(elements.size());
|
||||
for (T *el: elements) {
|
||||
result->push_back(el);
|
||||
}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Reference in New Issue
Block a user