From b7be4dc37f3a823b35a60ddb933fa7c6f8da28de Mon Sep 17 00:00:00 2001 From: Stefano Sanfilippo Date: Fri, 6 Mar 2015 14:29:52 +0100 Subject: [PATCH] Implementing error handling in emitters. As a result, Emitter iface changes by providing a bool retval. False means failure and should be managed as such. --- BitcodeEmitter.cpp | 162 +++++++++++++++++++++++++++++++++------------ BitcodeEmitter.hpp | 36 +++++----- CppEmitter.cpp | 145 ++++++++++++++++++++++++++-------------- CppEmitter.hpp | 50 +++++++------- Emitter.hpp | 34 +++++----- Nodes.hpp | 83 +++++++++++------------ 6 files changed, 312 insertions(+), 198 deletions(-) diff --git a/BitcodeEmitter.cpp b/BitcodeEmitter.cpp index d2ac3e3..a88ffdc 100644 --- a/BitcodeEmitter.cpp +++ b/BitcodeEmitter.cpp @@ -29,6 +29,14 @@ #include #include +#include +#include + +//TODO remove +#include + +// Yes, that's right, no ending ; +#define GUARDED(call) if (!(call)) return false using namespace monicelli; @@ -75,6 +83,16 @@ llvm::Value* isTrue(llvm::IRBuilder<> &builder, llvm::Value* test, llvm::Twine c ); } +static +bool reportError(std::initializer_list const& what) { + for (std::string const& chunk: what) { + std::cerr << chunk << ' '; + } + std::cerr << std::endl; + + return false; +} + BitcodeEmitter::BitcodeEmitter() { module = std::unique_ptr(new llvm::Module("monicelli", getGlobalContext())); d = new Private; @@ -84,16 +102,18 @@ BitcodeEmitter::~BitcodeEmitter() { delete d; } -void BitcodeEmitter::emit(Return const& node) { +bool BitcodeEmitter::emit(Return const& node) { if (node.getExpression()) { - node.getExpression()->emit(this); + GUARDED(node.getExpression()->emit(this)); d->builder.CreateRet(d->retval); } else { d->builder.CreateRetVoid(); } + + return true; } -void BitcodeEmitter::emit(Loop const& node) { +bool BitcodeEmitter::emit(Loop const& node) { llvm::Function *father = d->builder.GetInsertBlock()->getParent(); llvm::BasicBlock *body = llvm::BasicBlock::Create( @@ -105,11 +125,11 @@ void BitcodeEmitter::emit(Loop const& node) { d->scope.enter(); for (Statement const* statement: node.getBody()) { - statement->emit(this); + GUARDED(statement->emit(this)); } d->scope.leave(); - node.getCondition().emit(this); + GUARDED(node.getCondition().emit(this)); llvm::Value *loopTest = isTrue(d->builder, d->retval, "looptest"); @@ -119,68 +139,88 @@ void BitcodeEmitter::emit(Loop const& node) { d->builder.CreateCondBr(loopTest, body, after); d->builder.SetInsertPoint(after); + + return true; } -void BitcodeEmitter::emit(VarDeclaration const& node) { +bool BitcodeEmitter::emit(VarDeclaration const& node) { llvm::Function *father = d->builder.GetInsertBlock()->getParent(); llvm::AllocaInst *alloc = allocateVar( father, node.getId(), LLVMType(node.getType()) ); if (node.getInitializer()) { - node.getInitializer()->emit(this); + GUARDED(node.getInitializer()->emit(this)); d->builder.CreateStore(d->retval, alloc); } // TODO pointers d->scope.push(node.getId().getValue(), alloc); + + return true; } -void BitcodeEmitter::emit(Assignment const& node) { - node.getValue().emit(this); +bool BitcodeEmitter::emit(Assignment const& node) { + GUARDED(node.getValue().emit(this)); auto var = d->scope.lookup(node.getName().getValue()); if (!var) { - // TODO undefined var + return reportError({ + "Attempting assignment to undefined var", node.getName().getValue() + }); } d->builder.CreateStore(d->retval, *var); + + return true; } -void BitcodeEmitter::emit(Print const& node) { +bool BitcodeEmitter::emit(Print const& node) { + return true; } -void BitcodeEmitter::emit(Input const& node) { +bool BitcodeEmitter::emit(Input const& node) { + return true; } -void BitcodeEmitter::emit(Abort const& node) { +bool BitcodeEmitter::emit(Abort const& node) { + return true; } -void BitcodeEmitter::emit(Assert const& node) { +bool BitcodeEmitter::emit(Assert const& node) { + return true; } -void BitcodeEmitter::emit(FunctionCall const& node) { +bool BitcodeEmitter::emit(FunctionCall const& node) { llvm::Function *callee = module->getFunction(node.getName().getValue()); if (callee == 0) { - // TODO Error + return reportError({ + "Attempting to call undefined function", node.getName().getValue() + }); } if (callee->arg_size() != node.getArgs().size()) { - // TODO Error + return reportError({ + "Argument number mismatch, expected", + std::to_string(callee->arg_size()), + "given", std::to_string(node.getArgs().size()) + }); } std::vector callargs; for (Expression const* arg: node.getArgs()) { - arg->emit(this); + GUARDED(arg->emit(this)); callargs.push_back(d->retval); } d->retval = d->builder.CreateCall(callee, callargs); + + return true; } -void BitcodeEmitter::emit(Branch const& node) { +bool BitcodeEmitter::emit(Branch const& node) { Branch::Body const& body = node.getBody(); llvm::Function *func = d->builder.GetInsertBlock()->getParent(); @@ -204,7 +244,7 @@ void BitcodeEmitter::emit(Branch const& node) { d->builder.SetInsertPoint(thenbb); d->scope.enter(); for (Statement const* statement: cas->getBody()) { - statement->emit(this); + GUARDED(statement->emit(this)); } d->scope.leave(); d->builder.CreateBr(mergebb); @@ -221,7 +261,7 @@ void BitcodeEmitter::emit(Branch const& node) { if (body.getElse()) { d->scope.enter(); for (Statement const* statement: *body.getElse()) { - statement->emit(this); + GUARDED(statement->emit(this)); } d->scope.leave(); d->builder.CreateBr(mergebb); @@ -229,19 +269,33 @@ void BitcodeEmitter::emit(Branch const& node) { func->getBasicBlockList().push_back(mergebb); d->builder.SetInsertPoint(mergebb); + + return true; } -void BitcodeEmitter::emit(Function const& node) { +bool BitcodeEmitter::emit(Function const& node) { d->scope.enter(); - std::vector argtypes; + std::vector argTypes; for (FunArg const* arg: node.getArgs()) { - argtypes.emplace_back(LLVMType(arg->getType())); + argTypes.emplace_back(LLVMType(arg->getType())); + } + + std::unordered_set argsSet; + 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", + node.getName().getValue(), ":", name + }); + } + argsSet.insert(name); } llvm::FunctionType *ftype = llvm::FunctionType::get( - LLVMType(node.getType()), argtypes, false + LLVMType(node.getType()), argTypes, false ); llvm::Function *func = llvm::Function::Create( @@ -253,11 +307,17 @@ void BitcodeEmitter::emit(Function const& node) { func = module->getFunction(node.getName().getValue()); if (!func->empty()) { - // TODO redefinition + return reportError({ + "Redefining function", node.getName().getValue() + }); } if (func->arg_size() != node.getArgs().size()) { - // TODO different args + return reportError({ + "Argument number mismatch in definition vs declaration,", + "expected", std::to_string(func->arg_size()), + "given", std::to_string(node.getArgs().size()) + }); } } @@ -267,8 +327,6 @@ void BitcodeEmitter::emit(Function const& node) { ++argToEmit; } - // TODO check repeated arg names - llvm::BasicBlock *bb = llvm::BasicBlock::Create( getGlobalContext(), "entry", func ); @@ -284,48 +342,60 @@ void BitcodeEmitter::emit(Function const& node) { } for (Statement const* stat: node.getBody()) { - stat->emit(this); + GUARDED(stat->emit(this)); } verifyFunction(*func); d->scope.leave(); + + return true; } -void BitcodeEmitter::emit(Module const& node) {} +bool BitcodeEmitter::emit(Module const& node) { + return true; +} -void BitcodeEmitter::emit(Program const& program) { +bool BitcodeEmitter::emit(Program const& program) { for (Function const* function: program.getFunctions()) { - function->emit(this); + GUARDED(function->emit(this)); } if (program.getMain()) { - program.getMain()->emit(this); + GUARDED(program.getMain()->emit(this)); } // TODO modules } -void BitcodeEmitter::emit(Id const& node) { +bool BitcodeEmitter::emit(Id const& node) { auto value = d->scope.lookup(node.getValue()); if (!value) { - // TODO variable not defined + return reportError({ + "Undefined variable", node.getValue() + }); } d->retval = d->builder.CreateLoad(*value, node.getValue().c_str()); + + return true; } -void BitcodeEmitter::emit(Integer const& node) { +bool BitcodeEmitter::emit(Integer const& node) { d->retval = llvm::ConstantInt::get( getGlobalContext(), llvm::APInt(64, node.getValue(), true) ); + + return true; } -void BitcodeEmitter::emit(Float const& node) { +bool BitcodeEmitter::emit(Float const& node) { d->retval = llvm::ConstantFP::get( getGlobalContext(), llvm::APFloat(node.getValue()) ); + + return true; } static inline @@ -394,23 +464,27 @@ void createOp(BitcodeEmitter::Private *d, llvm::Value *left, Operator op, llvm:: #undef HANDLE #undef HANDLE_INT_ONLY -void BitcodeEmitter::emit(BinaryExpression const& expression) { - expression.getLeft().emit(this); +bool BitcodeEmitter::emit(BinaryExpression const& expression) { + GUARDED(expression.getLeft().emit(this)); llvm::Value *left = d->retval; - expression.getRight().emit(this); + GUARDED(expression.getRight().emit(this)); llvm::Value *right = d->retval; createOp(d, left, expression.getOperator(), right); + + return true; } -void BitcodeEmitter::emitSemiExpression(Id const& left, SemiExpression const& right) { - left.emit(this); +bool BitcodeEmitter::emitSemiExpression(Id const& left, SemiExpression const& right) { + GUARDED(left.emit(this)); llvm::Value *lhs = d->retval; - right.getLeft().emit(this); + GUARDED(right.getLeft().emit(this)); llvm::Value *rhs = d->retval; createOp(d, lhs, right.getOperator(), rhs); + + return true; } diff --git a/BitcodeEmitter.hpp b/BitcodeEmitter.hpp index aff599f..b8b427f 100644 --- a/BitcodeEmitter.hpp +++ b/BitcodeEmitter.hpp @@ -38,24 +38,24 @@ public: BitcodeEmitter(BitcodeEmitter &) = delete; virtual ~BitcodeEmitter(); - virtual void emit(Return const&) override; - virtual void emit(Loop const&) override; - virtual void emit(VarDeclaration const&) override; - virtual void emit(Assignment const&) override; - virtual void emit(Print const&) override; - virtual void emit(Input const&) override; - virtual void emit(Abort const&) override; - virtual void emit(Assert const&) override; - virtual void emit(Branch const&) override; - virtual void emit(Function const&) override; - virtual void emit(Module const&) override; - virtual void emit(Program const&) override; + virtual bool emit(Return const&) override; + virtual bool emit(Loop const&) override; + virtual bool emit(VarDeclaration const&) override; + virtual bool emit(Assignment const&) override; + virtual bool emit(Print const&) override; + virtual bool emit(Input const&) override; + virtual bool emit(Abort const&) override; + virtual bool emit(Assert const&) override; + virtual bool emit(Branch const&) override; + virtual bool emit(Function const&) override; + virtual bool emit(Module const&) override; + virtual bool emit(Program const&) override; - virtual void emit(Id const&) override; - virtual void emit(Integer const&) override; - virtual void emit(Float const&) override; - virtual void emit(FunctionCall const&) override; - virtual void emit(BinaryExpression const&) override; + virtual bool emit(Id const&) override; + virtual bool emit(Integer const&) override; + virtual bool emit(Float const&) override; + virtual bool emit(FunctionCall const&) override; + virtual bool emit(BinaryExpression const&) override; llvm::Module const& getModule() const { return *module; @@ -64,7 +64,7 @@ public: struct Private; private: - void emitSemiExpression(Id const& left, SemiExpression const& right); + bool emitSemiExpression(Id const& left, SemiExpression const& right); std::unique_ptr module; Private *d; diff --git a/CppEmitter.cpp b/CppEmitter.cpp index 2119136..0a9145d 100644 --- a/CppEmitter.cpp +++ b/CppEmitter.cpp @@ -25,6 +25,8 @@ using namespace monicelli; +// Yes, that's right, no ending ; +#define GUARDED(call) if (!(call)) return false static const std::string STATEMENT_TERMINATOR = ";\n"; static const std::string BLOCK = " "; @@ -38,15 +40,17 @@ void CppEmitter::dedent() { indent_chars -= 1; } -void CppEmitter::emitIndent() { +bool CppEmitter::emitIndent() { for (int i = 0; i < indent_chars; ++i) { stream << BLOCK; } + + return stream; } -void CppEmitter::emit(Program const& program) { +bool CppEmitter::emit(Program const& program) { for (Module m: program.getModules()) { - m.emit(this); + GUARDED(m.emit(this)); stream << "\n"; } @@ -64,52 +68,61 @@ void CppEmitter::emit(Program const& program) { } for (Function *function: program.getFunctions()) { - function->emit(this); + GUARDED(function->emit(this)); } if (program.getMain()) { - program.getMain()->emit(this); + GUARDED(program.getMain()->emit(this)); } + + return stream; } -void CppEmitter::emitStatements(PointerList const& node) { +bool CppEmitter::emitStatements(PointerList const& node) { for (Statement *s: node) { emitIndent(); - s->emit(this); + GUARDED(s->emit(this)); stream << STATEMENT_TERMINATOR; } + return stream; } -void CppEmitter::emitMain(Function const& main) { +bool CppEmitter::emitMain(Function const& main) { stream << "int main() {\n"; indent(); emitStatements(main.getBody()); dedent(); stream << "}\n"; + return stream; } -void CppEmitter::emit(Id const& id) { +bool CppEmitter::emit(Id const& id) { stream << id.getValue(); + return stream; } -void CppEmitter::emit(Integer const& num) { +bool CppEmitter::emit(Integer const& num) { stream << num.getValue(); + return stream; } -void CppEmitter::emit(Float const& num) { +bool CppEmitter::emit(Float const& num) { stream << num.getValue(); + return stream; } -void CppEmitter::emit(Return const& node) { +bool CppEmitter::emit(Return const& node) { stream << "return"; if (node.getExpression()) { stream << ' '; - node.getExpression()->emit(this); + GUARDED(node.getExpression()->emit(this)); } + + return stream; } -void CppEmitter::emit(Print const& node) { +bool CppEmitter::emit(Print const& node) { bool needsBraces = (dynamic_cast(&node.getExpression()) == nullptr) && @@ -121,45 +134,55 @@ void CppEmitter::emit(Print const& node) { stream << '('; } - node.getExpression().emit(this); + GUARDED(node.getExpression().emit(this)); if (needsBraces) { stream << ')'; } stream << " << std::endl"; + + return stream; } -void CppEmitter::emit(Input const& node) { +bool CppEmitter::emit(Input const& node) { stream << "std::cout << \""; - node.getVariable().emit(this); + GUARDED(node.getVariable().emit(this)); stream << "? \";\n"; emitIndent(); stream << "std::cin >> "; - node.getVariable().emit(this); + GUARDED(node.getVariable().emit(this)); + + return stream; } -void CppEmitter::emit(Abort const&) { +bool CppEmitter::emit(Abort const&) { stream << "std::exit(1)"; + + return stream; } -void CppEmitter::emit(Assert const& node) { +bool CppEmitter::emit(Assert const& node) { stream << "assert("; - node.getExpression().emit(this); + GUARDED(node.getExpression().emit(this)); stream << ")"; + + return stream; } -void CppEmitter::emit(Loop const& loop) { +bool CppEmitter::emit(Loop const& loop) { stream << "do {\n"; indent(); emitStatements(loop.getBody()); dedent(); emitIndent(); stream << "} while ("; - loop.getCondition().emit(this); + GUARDED(loop.getCondition().emit(this)); stream << ")"; + + return stream; } -void CppEmitter::emitBranchCase(BranchCase const& node) { +bool CppEmitter::emitBranchCase(BranchCase const& node) { emitBranchCondition(node.getCondition()); stream << ") {\n"; indent(); @@ -167,14 +190,16 @@ void CppEmitter::emitBranchCase(BranchCase const& node) { dedent(); emitIndent(); stream << "}"; + + return stream; } -void CppEmitter::emit(Branch const& branch) { +bool CppEmitter::emit(Branch const& branch) { auto &body = branch.getBody(); auto &var = branch.getVar(); stream << "if ("; - var.emit(this); + GUARDED(var.emit(this)); if (body.getCases().size() > 0) { BranchCase *last = body.getCases().back(); @@ -182,13 +207,13 @@ void CppEmitter::emit(Branch const& branch) { emitBranchCase(*cas); if (cas != last) { stream << " else if ("; - var.emit(this); + GUARDED(var.emit(this)); } } } if (!body.getElse()) { - return; + return stream; } stream << " else {\n"; @@ -197,40 +222,50 @@ void CppEmitter::emit(Branch const& branch) { dedent(); emitIndent(); stream << "}"; + + return stream; } -void CppEmitter::emit(Assignment const& assignment) { - assignment.getName().emit(this); +bool CppEmitter::emit(Assignment const& assignment) { + GUARDED(assignment.getName().emit(this)); stream << " = "; - assignment.getValue().emit(this); + GUARDED(assignment.getValue().emit(this)); + + return stream; } -void CppEmitter::emitFunctionArglist(PointerList const& args) { +bool CppEmitter::emitFunctionArglist(PointerList const& args) { Expression *last = args.back(); for (Expression const* arg: args) { - arg->emit(this); + GUARDED(arg->emit(this)); if (arg != last) { stream << ", "; } } + + return stream; } -void CppEmitter::emit(FunctionCall const& funcall) { - funcall.getName().emit(this); +bool CppEmitter::emit(FunctionCall const& funcall) { + GUARDED(funcall.getName().emit(this)); stream << "("; emitFunctionArglist(funcall.getArgs()); stream << ")"; + + return stream; } -void CppEmitter::emit(Function const& function) { +bool CppEmitter::emit(Function const& function) { emitFunctionSignature(function); stream << " {\n"; indent(); emitStatements(function.getBody()); dedent(); stream << "}\n\n"; + + return stream; } std::ostream& operator<<(std::ostream &stream, Type const& type) { @@ -258,40 +293,48 @@ std::ostream& operator<<(std::ostream &stream, Type const& type) { return stream; } -void CppEmitter::emitFunctionParams(PointerList const& funargs) { +bool CppEmitter::emitFunctionParams(PointerList const& funargs) { FunArg *last = funargs.back(); for (FunArg const* funarg: funargs) { stream << funarg->getType() << (funarg->isPointer()? "* ": " "); - funarg->getName().emit(this); + GUARDED(funarg->getName().emit(this)); if (funarg != last) { stream << ", "; } } + + return stream; } -void CppEmitter::emit(Module const& module) { +bool CppEmitter::emit(Module const& module) { bool system = (module.getType() == Module::SYSTEM); stream << "#include " << (system? '<': '"') << module.getName() << (system? '>': '"'); + + return stream; } -void CppEmitter::emitFunctionSignature(Function const& function) { +bool CppEmitter::emitFunctionSignature(Function const& function) { stream << function.getType() << ' '; - function.getName().emit(this); + GUARDED(function.getName().emit(this)); stream << "("; emitFunctionParams(function.getArgs()); stream << ")"; + + return stream; } -void CppEmitter::emit(VarDeclaration const& decl) { +bool CppEmitter::emit(VarDeclaration const& decl) { stream << decl.getType() << ' '; if (decl.isPointer()) stream << '*'; - decl.getId().emit(this); + GUARDED(decl.getId().emit(this)); if (decl.getInitializer()) { stream << " = "; - decl.getInitializer()->emit(this); + GUARDED(decl.getInitializer()->emit(this)); } + + return stream; } std::ostream& operator<<(std::ostream &stream, Operator op) { @@ -334,18 +377,22 @@ std::ostream& operator<<(std::ostream &stream, Operator op) { return stream; } -void CppEmitter::emit(BinaryExpression const& node) { - node.getLeft().emit(this); +bool CppEmitter::emit(BinaryExpression const& node) { + GUARDED(node.getLeft().emit(this)); stream << ' ' << node.getOperator() << ' '; - node.getRight().emit(this); + GUARDED(node.getRight().emit(this)); + + return stream; } -void CppEmitter::emitBranchCondition(SemiExpression const& node) { +bool CppEmitter::emitBranchCondition(SemiExpression const& node) { bool braces = (dynamic_cast(&node.getLeft()) == nullptr); stream << ' ' << node.getOperator() << ' '; if (braces) stream << "("; - node.getLeft().emit(this); + GUARDED(node.getLeft().emit(this)); if (braces) stream << ")"; + + return stream; } diff --git a/CppEmitter.hpp b/CppEmitter.hpp index 0e5b14c..c4fcb6f 100644 --- a/CppEmitter.hpp +++ b/CppEmitter.hpp @@ -31,34 +31,34 @@ class CppEmitter: public Emitter { public: CppEmitter(std::ostream *stream): stream(*stream), indent_chars(0) {} - virtual void emit(Return const&) override; - virtual void emit(Loop const&) override; - virtual void emit(VarDeclaration const&) override; - virtual void emit(Assignment const&) override; - virtual void emit(Print const&) override; - virtual void emit(Input const&) override; - virtual void emit(Abort const&) override; - virtual void emit(Assert const&) override; - virtual void emit(Branch const&) override; - virtual void emit(Function const&) override; - virtual void emit(Module const&) override; - virtual void emit(Program const&) override; + virtual bool emit(Return const&) override; + virtual bool emit(Loop const&) override; + virtual bool emit(VarDeclaration const&) override; + virtual bool emit(Assignment const&) override; + virtual bool emit(Print const&) override; + virtual bool emit(Input const&) override; + virtual bool emit(Abort const&) override; + virtual bool emit(Assert const&) override; + virtual bool emit(Branch const&) override; + virtual bool emit(Function const&) override; + virtual bool emit(Module const&) override; + virtual bool emit(Program const&) override; - virtual void emit(FunctionCall const&) override; - virtual void emit(Id const&) override; - virtual void emit(Integer const&) override; - virtual void emit(Float const&) override; - virtual void emit(BinaryExpression const&) override; + virtual bool emit(FunctionCall const&) override; + virtual bool emit(Id const&) override; + virtual bool emit(Integer const&) override; + virtual bool emit(Float const&) override; + virtual bool emit(BinaryExpression const&) override; private: - void emitIndent(); - void emitFunctionSignature(Function const& function); - void emitFunctionParams(PointerList const& funargs); - void emitFunctionArglist(PointerList const& args); - void emitStatements(PointerList const& node); - void emitBranchCondition(SemiExpression const& node); - void emitBranchCase(BranchCase const& node); - void emitMain(Function const& main); + bool emitIndent(); + bool emitFunctionSignature(Function const& function); + bool emitFunctionParams(PointerList const& funargs); + bool emitFunctionArglist(PointerList const& args); + bool emitStatements(PointerList const& node); + bool emitBranchCondition(SemiExpression const& node); + bool emitBranchCase(BranchCase const& node); + bool emitMain(Function const& main); void indent(); void dedent(); diff --git a/Emitter.hpp b/Emitter.hpp index 7c8f21b..e96b2d6 100644 --- a/Emitter.hpp +++ b/Emitter.hpp @@ -45,24 +45,24 @@ class BinaryExpression; class Emitter { public: - virtual void emit(Return const&) = 0; - virtual void emit(Loop const&) = 0; - virtual void emit(VarDeclaration const&) = 0; - virtual void emit(Assignment const&) = 0; - virtual void emit(Print const&) = 0; - virtual void emit(Input const&) = 0; - virtual void emit(Abort const&) = 0; - virtual void emit(Assert const&) = 0; - virtual void emit(Branch const&) = 0; - virtual void emit(Function const&) = 0; - virtual void emit(Module const&) = 0; - virtual void emit(Program const&) = 0; + virtual bool emit(Return const&) = 0; + virtual bool emit(Loop const&) = 0; + virtual bool emit(VarDeclaration const&) = 0; + virtual bool emit(Assignment const&) = 0; + virtual bool emit(Print const&) = 0; + virtual bool emit(Input const&) = 0; + virtual bool emit(Abort const&) = 0; + virtual bool emit(Assert const&) = 0; + virtual bool emit(Branch const&) = 0; + virtual bool emit(Function const&) = 0; + virtual bool emit(Module const&) = 0; + virtual bool emit(Program const&) = 0; - virtual void emit(Id const&) = 0; - virtual void emit(Integer const&) = 0; - virtual void emit(Float const&) = 0; - virtual void emit(FunctionCall const&) = 0; - virtual void emit(BinaryExpression const&) = 0; + virtual bool emit(Id const&) = 0; + virtual bool emit(Integer const&) = 0; + virtual bool emit(Float const&) = 0; + virtual bool emit(FunctionCall const&) = 0; + virtual bool emit(BinaryExpression const&) = 0; }; } diff --git a/Nodes.hpp b/Nodes.hpp index 1f621e5..1e086f5 100644 --- a/Nodes.hpp +++ b/Nodes.hpp @@ -50,22 +50,15 @@ enum class Operator { class Emittable { public: virtual ~Emittable() {} - virtual void emit(Emitter *emitter) const = 0; + virtual bool emit(Emitter *emitter) const = 0; }; -class Statement: public Emittable { -public: - virtual void emit(Emitter *) const {} -}; +class Statement: public Emittable {}; -class Expression: public Emittable { -public: - virtual void emit(Emitter *) const {} -}; +class Expression: public Emittable {}; -class SimpleExpression: public Expression { -}; +class SimpleExpression: public Expression {}; class SemiExpression { public: @@ -89,8 +82,8 @@ class Id: public SimpleExpression { public: explicit Id(std::string *c): value(c) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } std::string const& getValue() const { @@ -109,8 +102,8 @@ class Integer: public Number { public: Integer(long i): value(i) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } long getValue() const { @@ -126,8 +119,8 @@ class Float: public Number { public: Float(double f): value(f) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } double getValue() const { @@ -143,8 +136,8 @@ class Return: public Statement { public: explicit Return(Expression *e): expression(e) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } boost::optional getExpression() const { @@ -160,8 +153,8 @@ class Loop: public Statement { public: Loop(PointerList *b, Expression *c): body(b), condition(c) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } PointerList const& getBody() const { @@ -183,8 +176,8 @@ public: VarDeclaration(Id *n, Type t, bool p, Expression *i): name(n), point(p), init(i), type(t) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } Id const& getId() const { @@ -215,8 +208,8 @@ class Assignment: public Statement { public: Assignment(Id *n, Expression *v): name(n), value(v) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } Id const& getName() const { @@ -237,8 +230,8 @@ class Print: public Statement { public: explicit Print(Expression *e): expression(e) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } Expression const& getExpression() const { @@ -254,8 +247,8 @@ class Input: public Statement { public: explicit Input(Id *v): variable(v) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } Id const& getVariable() const { @@ -269,8 +262,8 @@ private: class Abort: public Statement { public: - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } }; @@ -279,8 +272,8 @@ class Assert: public Statement { public: explicit Assert(Expression *e): expression(e) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } Expression const& getExpression() const { @@ -296,8 +289,8 @@ class FunctionCall: public Statement, public Expression { public: FunctionCall(Id *n, PointerList *a): name(n), args(a) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } Id const& getName() const { @@ -353,8 +346,8 @@ public: Branch(Id *v, Branch::Body *b): var(v), body(b) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } Id const& getVar() const { @@ -401,8 +394,8 @@ public: Function(Id *n, Type r, PointerList *a, PointerList *b): name(n), type(r), args(a), body(b) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } Id const& getName() const { @@ -437,8 +430,8 @@ public: Module(const std::string &n, Type s): name(n), type(s) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } bool operator==(const Module &other) const noexcept { @@ -480,8 +473,8 @@ namespace monicelli { class Program: public Emittable { public: - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } void setMain(Function *m) { @@ -521,8 +514,8 @@ public: BinaryExpression(Expression *l, Operator op, Expression *r): left(l), op(op), right(r) {} - virtual void emit(Emitter *emitter) const { - emitter->emit(*this); + virtual bool emit(Emitter *emitter) const { + return emitter->emit(*this); } Expression const& getLeft() const {