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