From f933cc3163e619f07d88d9dc85c87389e4c789c6 Mon Sep 17 00:00:00 2001 From: Stefano Sanfilippo Date: Sun, 8 Mar 2015 11:25:41 +0100 Subject: [PATCH] Extracting a FunctionPrototype node. This will allow more flexibility in defining externed functions. --- BitcodeEmitter.cpp | 16 +++++++--------- BitcodeEmitter.hpp | 2 +- CppEmitter.cpp | 12 ++++++------ CppEmitter.hpp | 2 +- Emitter.hpp | 2 ++ Monicelli.ypp | 2 +- Nodes.cpp | 7 ++++--- Nodes.hpp | 30 ++++++++++++++++++++++++------ RuntimePrototypes.hpp | 14 +++++--------- 9 files changed, 51 insertions(+), 36 deletions(-) diff --git a/BitcodeEmitter.cpp b/BitcodeEmitter.cpp index c0a9188..54aef2e 100644 --- a/BitcodeEmitter.cpp +++ b/BitcodeEmitter.cpp @@ -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 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(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)); } } diff --git a/BitcodeEmitter.hpp b/BitcodeEmitter.hpp index 49823cb..53a2d42 100644 --- a/BitcodeEmitter.hpp +++ b/BitcodeEmitter.hpp @@ -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 module; Private *d; diff --git a/CppEmitter.cpp b/CppEmitter.cpp index 3fec1fa..ef14faa 100644 --- a/CppEmitter.cpp +++ b/CppEmitter.cpp @@ -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; diff --git a/CppEmitter.hpp b/CppEmitter.hpp index c4fcb6f..85a760a 100644 --- a/CppEmitter.hpp +++ b/CppEmitter.hpp @@ -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 const& funargs); bool emitFunctionArglist(PointerList const& args); bool emitStatements(PointerList const& node); diff --git a/Emitter.hpp b/Emitter.hpp index e96b2d6..53d7cc3 100644 --- a/Emitter.hpp +++ b/Emitter.hpp @@ -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; diff --git a/Monicelli.ypp b/Monicelli.ypp index 6399ba7..c2dfc8b 100644 --- a/Monicelli.ypp +++ b/Monicelli.ypp @@ -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: diff --git a/Nodes.cpp b/Nodes.cpp index 907de41..1c5cbe1 100644 --- a/Nodes.cpp +++ b/Nodes.cpp @@ -26,9 +26,10 @@ using namespace monicelli; Function *monicelli::makeMain(PointerList *body) { PointerList *noargs = new PointerList(); - 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); } diff --git a/Nodes.hpp b/Nodes.hpp index e380297..70b7bdb 100644 --- a/Nodes.hpp +++ b/Nodes.hpp @@ -392,10 +392,10 @@ private: }; -class Function: public Emittable { +class FunctionPrototype: public Emittable { public: - Function(Id *n, Type r, PointerList *a, PointerList *b): - name(n), type(r), args(a), body(b) {} + FunctionPrototype(Id *n, Type r, PointerList *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 name; + Type type; + Pointer> args; +}; + + +class Function: public Emittable { +public: + Function(FunctionPrototype *p, PointerList *b): + prototype(p), body(b) {} + + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); + } + + FunctionPrototype const& getPrototype() const { + return *prototype; + } + PointerList const& getBody() const { return *body; } private: - Pointer name; - Type type; - Pointer> args; + Pointer prototype; Pointer> body; }; diff --git a/RuntimePrototypes.hpp b/RuntimePrototypes.hpp index a2405ba..6da0ad7 100644 --- a/RuntimePrototypes.hpp +++ b/RuntimePrototypes.hpp @@ -26,19 +26,17 @@ #include #define PUT(type, funcname) \ - new Function { \ + new FunctionPrototype { \ new Id {#funcname}, Type::VOID, \ new PointerList { \ new FunArg {new Id {"value"}, type, false} \ }, \ - new PointerList{} \ } #define GET(type, funcname) \ - new Function { \ + new FunctionPrototype { \ new Id {#funcname}, type, \ new PointerList {}, \ - new PointerList{} \ } 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> STANDARD_MODULES = { +static const std::map> STANDARD_MODULES = { {"iostream", { PUT(Type::BOOL, __Monicelli_putBool), PUT(Type::CHAR, __Monicelli_putChar), @@ -77,17 +75,15 @@ static const std::map> 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 { new FunArg {new Id("condition"), Type::BOOL, false} }, - new PointerList{} }}}, - {"cstdlib", { new Function{ + {"cstdlib", { new FunctionPrototype { new Id("__Monicelli_abort"), Type::VOID, new PointerList {}, - new PointerList{} }}} };