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.
This commit is contained in:
Stefano Sanfilippo 2015-03-06 14:29:52 +01:00
parent 2ce76a1dfd
commit b7be4dc37f
6 changed files with 312 additions and 198 deletions

View File

@ -29,6 +29,14 @@
#include <string>
#include <vector>
#include <unordered_set>
#include <initializer_list>
//TODO remove
#include <iostream>
// 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<std::string> const& what) {
for (std::string const& chunk: what) {
std::cerr << chunk << ' ';
}
std::cerr << std::endl;
return false;
}
BitcodeEmitter::BitcodeEmitter() {
module = std::unique_ptr<llvm::Module>(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<llvm::Value*> 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<llvm::Type*> argtypes;
std::vector<llvm::Type*> argTypes;
for (FunArg const* arg: node.getArgs()) {
argtypes.emplace_back(LLVMType(arg->getType()));
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();
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;
}

View File

@ -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<llvm::Module> module;
Private *d;

View File

@ -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));
}
void CppEmitter::emitStatements(PointerList<Statement> const& node) {
return stream;
}
bool CppEmitter::emitStatements(PointerList<Statement> 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));
}
void CppEmitter::emit(Print const& node) {
return stream;
}
bool CppEmitter::emit(Print const& node) {
bool needsBraces =
(dynamic_cast<SimpleExpression const*>(&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<Expression> const& args) {
bool CppEmitter::emitFunctionArglist(PointerList<Expression> 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<FunArg> const& funargs) {
bool CppEmitter::emitFunctionParams(PointerList<FunArg> 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<SimpleExpression const*>(&node.getLeft()) == nullptr);
stream << ' ' << node.getOperator() << ' ';
if (braces) stream << "(";
node.getLeft().emit(this);
GUARDED(node.getLeft().emit(this));
if (braces) stream << ")";
return stream;
}

View File

@ -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<FunArg> const& funargs);
void emitFunctionArglist(PointerList<Expression> const& args);
void emitStatements(PointerList<Statement> 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<FunArg> const& funargs);
bool emitFunctionArglist(PointerList<Expression> const& args);
bool emitStatements(PointerList<Statement> const& node);
bool emitBranchCondition(SemiExpression const& node);
bool emitBranchCase(BranchCase const& node);
bool emitMain(Function const& main);
void indent();
void dedent();

View File

@ -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;
};
}

View File

@ -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<Expression const&> getExpression() const {
@ -160,8 +153,8 @@ class Loop: public Statement {
public:
Loop(PointerList<Statement> *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<Statement> 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<Expression> *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<FunArg> *a, PointerList<Statement> *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 {