Extracting a FunctionPrototype node.
This will allow more flexibility in defining externed functions.
This commit is contained in:
parent
3f19125574
commit
f933cc3163
|
@ -468,7 +468,7 @@ bool BitcodeEmitter::emit(Branch const& node) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BitcodeEmitter::emitFunctionPrototype(Function const& node, llvm::Function **proto) {
|
||||
bool BitcodeEmitter::emit(FunctionPrototype const& node) {
|
||||
std::vector<llvm::Type*> argTypes;
|
||||
|
||||
for (FunArg const* arg: node.getArgs()) {
|
||||
|
@ -521,14 +521,14 @@ bool BitcodeEmitter::emitFunctionPrototype(Function const& node, llvm::Function
|
|||
++argToEmit;
|
||||
}
|
||||
|
||||
*proto = func;
|
||||
d->retval = func;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BitcodeEmitter::emit(Function const& node) {
|
||||
llvm::Function *func = nullptr;
|
||||
GUARDED(emitFunctionPrototype(node, &func));
|
||||
GUARDED(node.getPrototype().emit(this));
|
||||
llvm::Function *func = dynamic_cast<llvm::Function*>(d->retval);
|
||||
|
||||
d->scope.enter();
|
||||
|
||||
|
@ -538,7 +538,7 @@ bool BitcodeEmitter::emit(Function const& node) {
|
|||
d->builder.SetInsertPoint(bb);
|
||||
|
||||
auto argToAlloc = func->arg_begin();
|
||||
for (FunArg const* arg: node.getArgs()) {
|
||||
for (FunArg const* arg: node.getPrototype().getArgs()) {
|
||||
llvm::AllocaInst *alloc = allocateVar(
|
||||
func, arg->getName(), LLVMType(arg->getType())
|
||||
);
|
||||
|
@ -558,8 +558,6 @@ bool BitcodeEmitter::emit(Function const& node) {
|
|||
}
|
||||
|
||||
bool BitcodeEmitter::emit(Module const& node) {
|
||||
llvm::Function *dummy;
|
||||
|
||||
if (node.getType() == Module::SYSTEM) {
|
||||
auto module = STANDARD_MODULES.find(node.getName());
|
||||
|
||||
|
@ -569,8 +567,8 @@ bool BitcodeEmitter::emit(Module const& node) {
|
|||
});
|
||||
}
|
||||
|
||||
for (Function const* func: module->second) {
|
||||
if (!emitFunctionPrototype(*func, &dummy)) return false;
|
||||
for (FunctionPrototype const* proto: module->second) {
|
||||
GUARDED(proto->emit(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
virtual bool emit(Abort const&) override;
|
||||
virtual bool emit(Assert const&) override;
|
||||
virtual bool emit(Branch const&) override;
|
||||
virtual bool emit(FunctionPrototype const&) override;
|
||||
virtual bool emit(Function const&) override;
|
||||
virtual bool emit(Module const&) override;
|
||||
virtual bool emit(Program const&) override;
|
||||
|
@ -66,7 +67,6 @@ public:
|
|||
|
||||
private:
|
||||
bool emitSemiExpression(Id const& left, SemiExpression const& right);
|
||||
bool emitFunctionPrototype(Function const& node, llvm::Function **proto);
|
||||
|
||||
std::unique_ptr<llvm::Module> module;
|
||||
Private *d;
|
||||
|
|
|
@ -59,7 +59,7 @@ bool CppEmitter::emit(Program const& program) {
|
|||
}
|
||||
|
||||
for (Function *function: program.getFunctions()) {
|
||||
emitFunctionSignature(*function);
|
||||
emit(function->getPrototype());
|
||||
stream << ";\n";
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,7 @@ bool CppEmitter::emit(FunctionCall const& funcall) {
|
|||
}
|
||||
|
||||
bool CppEmitter::emit(Function const& function) {
|
||||
emitFunctionSignature(function);
|
||||
emit(function.getPrototype());
|
||||
stream << " {\n";
|
||||
indent();
|
||||
emitStatements(function.getBody());
|
||||
|
@ -317,11 +317,11 @@ bool CppEmitter::emit(Module const& module) {
|
|||
return stream;
|
||||
}
|
||||
|
||||
bool CppEmitter::emitFunctionSignature(Function const& function) {
|
||||
stream << function.getType() << ' ';
|
||||
GUARDED(function.getName().emit(this));
|
||||
bool CppEmitter::emit(FunctionPrototype const& proto) {
|
||||
stream << proto.getType() << ' ';
|
||||
GUARDED(proto.getName().emit(this));
|
||||
stream << "(";
|
||||
emitFunctionParams(function.getArgs());
|
||||
emitFunctionParams(proto.getArgs());
|
||||
stream << ")";
|
||||
|
||||
return stream;
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
virtual bool emit(Abort const&) override;
|
||||
virtual bool emit(Assert const&) override;
|
||||
virtual bool emit(Branch const&) override;
|
||||
virtual bool emit(FunctionPrototype const&) override;
|
||||
virtual bool emit(Function const&) override;
|
||||
virtual bool emit(Module const&) override;
|
||||
virtual bool emit(Program const&) override;
|
||||
|
@ -52,7 +53,6 @@ public:
|
|||
|
||||
private:
|
||||
bool emitIndent();
|
||||
bool emitFunctionSignature(Function const& function);
|
||||
bool emitFunctionParams(PointerList<FunArg> const& funargs);
|
||||
bool emitFunctionArglist(PointerList<Expression> const& args);
|
||||
bool emitStatements(PointerList<Statement> const& node);
|
||||
|
|
|
@ -37,6 +37,7 @@ class Assert;
|
|||
class FunctionCall;
|
||||
class Branch;
|
||||
class Main;
|
||||
class FunctionPrototype;
|
||||
class Function;
|
||||
class Module;
|
||||
class Program;
|
||||
|
@ -53,6 +54,7 @@ public:
|
|||
virtual bool emit(Input const&) = 0;
|
||||
virtual bool emit(Abort const&) = 0;
|
||||
virtual bool emit(Assert const&) = 0;
|
||||
virtual bool emit(FunctionPrototype const&) = 0;
|
||||
virtual bool emit(Branch const&) = 0;
|
||||
virtual bool emit(Function const&) = 0;
|
||||
virtual bool emit(Module const&) = 0;
|
||||
|
|
|
@ -150,7 +150,7 @@ fun_decls:
|
|||
;
|
||||
fun_decl:
|
||||
FUN_DECL fun_return ID args FUN_END statements {
|
||||
$$ = new Function(new Id($3), $2, $4, $6);
|
||||
$$ = new Function(new FunctionPrototype(new Id($3), $2, $4), $6);
|
||||
}
|
||||
;
|
||||
fun_return:
|
||||
|
|
|
@ -26,9 +26,10 @@ using namespace monicelli;
|
|||
Function *monicelli::makeMain(PointerList<Statement> *body) {
|
||||
PointerList<FunArg> *noargs = new PointerList<FunArg>();
|
||||
|
||||
return new Function(
|
||||
new Id(new std::string(ENTRYPOINT_NAME)),
|
||||
Type::VOID, noargs, body
|
||||
FunctionPrototype *proto = new FunctionPrototype(
|
||||
new Id(new std::string(ENTRYPOINT_NAME)), Type::VOID, noargs
|
||||
);
|
||||
|
||||
return new Function(proto, body);
|
||||
}
|
||||
|
||||
|
|
30
Nodes.hpp
30
Nodes.hpp
|
@ -392,10 +392,10 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class Function: public Emittable {
|
||||
class FunctionPrototype: public Emittable {
|
||||
public:
|
||||
Function(Id *n, Type r, PointerList<FunArg> *a, PointerList<Statement> *b):
|
||||
name(n), type(r), args(a), body(b) {}
|
||||
FunctionPrototype(Id *n, Type r, PointerList<FunArg> *a):
|
||||
name(n), type(r), args(a) {}
|
||||
|
||||
virtual bool emit(Emitter *emitter) const {
|
||||
return emitter->emit(*this);
|
||||
|
@ -413,14 +413,32 @@ public:
|
|||
return *args;
|
||||
}
|
||||
|
||||
private:
|
||||
Pointer<Id> name;
|
||||
Type type;
|
||||
Pointer<PointerList<FunArg>> args;
|
||||
};
|
||||
|
||||
|
||||
class Function: public Emittable {
|
||||
public:
|
||||
Function(FunctionPrototype *p, PointerList<Statement> *b):
|
||||
prototype(p), body(b) {}
|
||||
|
||||
virtual bool emit(Emitter *emitter) const {
|
||||
return emitter->emit(*this);
|
||||
}
|
||||
|
||||
FunctionPrototype const& getPrototype() const {
|
||||
return *prototype;
|
||||
}
|
||||
|
||||
PointerList<Statement> const& getBody() const {
|
||||
return *body;
|
||||
}
|
||||
|
||||
private:
|
||||
Pointer<Id> name;
|
||||
Type type;
|
||||
Pointer<PointerList<FunArg>> args;
|
||||
Pointer<FunctionPrototype> prototype;
|
||||
Pointer<PointerList<Statement>> body;
|
||||
};
|
||||
|
||||
|
|
|
@ -26,19 +26,17 @@
|
|||
#include <vector>
|
||||
|
||||
#define PUT(type, funcname) \
|
||||
new Function { \
|
||||
new FunctionPrototype { \
|
||||
new Id {#funcname}, Type::VOID, \
|
||||
new PointerList<FunArg> { \
|
||||
new FunArg {new Id {"value"}, type, false} \
|
||||
}, \
|
||||
new PointerList<Statement>{} \
|
||||
}
|
||||
|
||||
#define GET(type, funcname) \
|
||||
new Function { \
|
||||
new FunctionPrototype { \
|
||||
new Id {#funcname}, type, \
|
||||
new PointerList<FunArg> {}, \
|
||||
new PointerList<Statement>{} \
|
||||
}
|
||||
|
||||
namespace monicelli {
|
||||
|
@ -64,7 +62,7 @@ static const std::string ASSERT_NAME = "__Monicelli_assert";
|
|||
static const std::string ENTRYPOINT_NAME = "__Monicelli_main";
|
||||
|
||||
|
||||
static const std::map<std::string, std::vector<Function const*>> STANDARD_MODULES = {
|
||||
static const std::map<std::string, std::vector<FunctionPrototype const*>> STANDARD_MODULES = {
|
||||
{"iostream", {
|
||||
PUT(Type::BOOL, __Monicelli_putBool),
|
||||
PUT(Type::CHAR, __Monicelli_putChar),
|
||||
|
@ -77,17 +75,15 @@ static const std::map<std::string, std::vector<Function const*>> STANDARD_MODULE
|
|||
GET(Type::DOUBLE, __Monicelli_getDouble),
|
||||
GET(Type::INT, __Monicelli_getInt)
|
||||
}},
|
||||
{"cassert", { new Function{
|
||||
{"cassert", { new FunctionPrototype {
|
||||
new Id("__Monicelli_assert"), Type::VOID,
|
||||
new PointerList<FunArg> {
|
||||
new FunArg {new Id("condition"), Type::BOOL, false}
|
||||
},
|
||||
new PointerList<Statement>{}
|
||||
}}},
|
||||
{"cstdlib", { new Function{
|
||||
{"cstdlib", { new FunctionPrototype {
|
||||
new Id("__Monicelli_abort"), Type::VOID,
|
||||
new PointerList<FunArg> {},
|
||||
new PointerList<Statement>{}
|
||||
}}}
|
||||
};
|
||||
|
||||
|
|
Reference in New Issue
Block a user