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:
parent
2ce76a1dfd
commit
b7be4dc37f
|
@ -29,6 +29,14 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#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;
|
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() {
|
BitcodeEmitter::BitcodeEmitter() {
|
||||||
module = std::unique_ptr<llvm::Module>(new llvm::Module("monicelli", getGlobalContext()));
|
module = std::unique_ptr<llvm::Module>(new llvm::Module("monicelli", getGlobalContext()));
|
||||||
d = new Private;
|
d = new Private;
|
||||||
|
@ -84,16 +102,18 @@ BitcodeEmitter::~BitcodeEmitter() {
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcodeEmitter::emit(Return const& node) {
|
bool BitcodeEmitter::emit(Return const& node) {
|
||||||
if (node.getExpression()) {
|
if (node.getExpression()) {
|
||||||
node.getExpression()->emit(this);
|
GUARDED(node.getExpression()->emit(this));
|
||||||
d->builder.CreateRet(d->retval);
|
d->builder.CreateRet(d->retval);
|
||||||
} else {
|
} else {
|
||||||
d->builder.CreateRetVoid();
|
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::Function *father = d->builder.GetInsertBlock()->getParent();
|
||||||
|
|
||||||
llvm::BasicBlock *body = llvm::BasicBlock::Create(
|
llvm::BasicBlock *body = llvm::BasicBlock::Create(
|
||||||
|
@ -105,11 +125,11 @@ void BitcodeEmitter::emit(Loop const& node) {
|
||||||
|
|
||||||
d->scope.enter();
|
d->scope.enter();
|
||||||
for (Statement const* statement: node.getBody()) {
|
for (Statement const* statement: node.getBody()) {
|
||||||
statement->emit(this);
|
GUARDED(statement->emit(this));
|
||||||
}
|
}
|
||||||
d->scope.leave();
|
d->scope.leave();
|
||||||
|
|
||||||
node.getCondition().emit(this);
|
GUARDED(node.getCondition().emit(this));
|
||||||
|
|
||||||
llvm::Value *loopTest = isTrue(d->builder, d->retval, "looptest");
|
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.CreateCondBr(loopTest, body, after);
|
||||||
d->builder.SetInsertPoint(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::Function *father = d->builder.GetInsertBlock()->getParent();
|
||||||
llvm::AllocaInst *alloc = allocateVar(
|
llvm::AllocaInst *alloc = allocateVar(
|
||||||
father, node.getId(), LLVMType(node.getType())
|
father, node.getId(), LLVMType(node.getType())
|
||||||
);
|
);
|
||||||
|
|
||||||
if (node.getInitializer()) {
|
if (node.getInitializer()) {
|
||||||
node.getInitializer()->emit(this);
|
GUARDED(node.getInitializer()->emit(this));
|
||||||
d->builder.CreateStore(d->retval, alloc);
|
d->builder.CreateStore(d->retval, alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO pointers
|
// TODO pointers
|
||||||
|
|
||||||
d->scope.push(node.getId().getValue(), alloc);
|
d->scope.push(node.getId().getValue(), alloc);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcodeEmitter::emit(Assignment const& node) {
|
bool BitcodeEmitter::emit(Assignment const& node) {
|
||||||
node.getValue().emit(this);
|
GUARDED(node.getValue().emit(this));
|
||||||
auto var = d->scope.lookup(node.getName().getValue());
|
auto var = d->scope.lookup(node.getName().getValue());
|
||||||
|
|
||||||
if (!var) {
|
if (!var) {
|
||||||
// TODO undefined var
|
return reportError({
|
||||||
|
"Attempting assignment to undefined var", node.getName().getValue()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
d->builder.CreateStore(d->retval, *var);
|
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());
|
llvm::Function *callee = module->getFunction(node.getName().getValue());
|
||||||
|
|
||||||
if (callee == 0) {
|
if (callee == 0) {
|
||||||
// TODO Error
|
return reportError({
|
||||||
|
"Attempting to call undefined function", node.getName().getValue()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callee->arg_size() != node.getArgs().size()) {
|
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;
|
std::vector<llvm::Value*> callargs;
|
||||||
for (Expression const* arg: node.getArgs()) {
|
for (Expression const* arg: node.getArgs()) {
|
||||||
arg->emit(this);
|
GUARDED(arg->emit(this));
|
||||||
callargs.push_back(d->retval);
|
callargs.push_back(d->retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
d->retval = d->builder.CreateCall(callee, callargs);
|
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();
|
Branch::Body const& body = node.getBody();
|
||||||
llvm::Function *func = d->builder.GetInsertBlock()->getParent();
|
llvm::Function *func = d->builder.GetInsertBlock()->getParent();
|
||||||
|
|
||||||
|
@ -204,7 +244,7 @@ void BitcodeEmitter::emit(Branch const& node) {
|
||||||
d->builder.SetInsertPoint(thenbb);
|
d->builder.SetInsertPoint(thenbb);
|
||||||
d->scope.enter();
|
d->scope.enter();
|
||||||
for (Statement const* statement: cas->getBody()) {
|
for (Statement const* statement: cas->getBody()) {
|
||||||
statement->emit(this);
|
GUARDED(statement->emit(this));
|
||||||
}
|
}
|
||||||
d->scope.leave();
|
d->scope.leave();
|
||||||
d->builder.CreateBr(mergebb);
|
d->builder.CreateBr(mergebb);
|
||||||
|
@ -221,7 +261,7 @@ void BitcodeEmitter::emit(Branch const& node) {
|
||||||
if (body.getElse()) {
|
if (body.getElse()) {
|
||||||
d->scope.enter();
|
d->scope.enter();
|
||||||
for (Statement const* statement: *body.getElse()) {
|
for (Statement const* statement: *body.getElse()) {
|
||||||
statement->emit(this);
|
GUARDED(statement->emit(this));
|
||||||
}
|
}
|
||||||
d->scope.leave();
|
d->scope.leave();
|
||||||
d->builder.CreateBr(mergebb);
|
d->builder.CreateBr(mergebb);
|
||||||
|
@ -229,19 +269,33 @@ void BitcodeEmitter::emit(Branch const& node) {
|
||||||
|
|
||||||
func->getBasicBlockList().push_back(mergebb);
|
func->getBasicBlockList().push_back(mergebb);
|
||||||
d->builder.SetInsertPoint(mergebb);
|
d->builder.SetInsertPoint(mergebb);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcodeEmitter::emit(Function const& node) {
|
bool BitcodeEmitter::emit(Function const& node) {
|
||||||
d->scope.enter();
|
d->scope.enter();
|
||||||
|
|
||||||
std::vector<llvm::Type*> argtypes;
|
std::vector<llvm::Type*> argTypes;
|
||||||
|
|
||||||
for (FunArg const* arg: node.getArgs()) {
|
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(
|
llvm::FunctionType *ftype = llvm::FunctionType::get(
|
||||||
LLVMType(node.getType()), argtypes, false
|
LLVMType(node.getType()), argTypes, false
|
||||||
);
|
);
|
||||||
|
|
||||||
llvm::Function *func = llvm::Function::Create(
|
llvm::Function *func = llvm::Function::Create(
|
||||||
|
@ -253,11 +307,17 @@ void BitcodeEmitter::emit(Function const& node) {
|
||||||
func = module->getFunction(node.getName().getValue());
|
func = module->getFunction(node.getName().getValue());
|
||||||
|
|
||||||
if (!func->empty()) {
|
if (!func->empty()) {
|
||||||
// TODO redefinition
|
return reportError({
|
||||||
|
"Redefining function", node.getName().getValue()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (func->arg_size() != node.getArgs().size()) {
|
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;
|
++argToEmit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check repeated arg names
|
|
||||||
|
|
||||||
llvm::BasicBlock *bb = llvm::BasicBlock::Create(
|
llvm::BasicBlock *bb = llvm::BasicBlock::Create(
|
||||||
getGlobalContext(), "entry", func
|
getGlobalContext(), "entry", func
|
||||||
);
|
);
|
||||||
|
@ -284,48 +342,60 @@ void BitcodeEmitter::emit(Function const& node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Statement const* stat: node.getBody()) {
|
for (Statement const* stat: node.getBody()) {
|
||||||
stat->emit(this);
|
GUARDED(stat->emit(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyFunction(*func);
|
verifyFunction(*func);
|
||||||
|
|
||||||
d->scope.leave();
|
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()) {
|
for (Function const* function: program.getFunctions()) {
|
||||||
function->emit(this);
|
GUARDED(function->emit(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program.getMain()) {
|
if (program.getMain()) {
|
||||||
program.getMain()->emit(this);
|
GUARDED(program.getMain()->emit(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO modules
|
// TODO modules
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcodeEmitter::emit(Id const& node) {
|
bool BitcodeEmitter::emit(Id const& node) {
|
||||||
auto value = d->scope.lookup(node.getValue());
|
auto value = d->scope.lookup(node.getValue());
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
// TODO variable not defined
|
return reportError({
|
||||||
|
"Undefined variable", node.getValue()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
d->retval = d->builder.CreateLoad(*value, node.getValue().c_str());
|
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(
|
d->retval = llvm::ConstantInt::get(
|
||||||
getGlobalContext(), llvm::APInt(64, node.getValue(), true)
|
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(
|
d->retval = llvm::ConstantFP::get(
|
||||||
getGlobalContext(), llvm::APFloat(node.getValue())
|
getGlobalContext(), llvm::APFloat(node.getValue())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
|
@ -394,23 +464,27 @@ void createOp(BitcodeEmitter::Private *d, llvm::Value *left, Operator op, llvm::
|
||||||
#undef HANDLE
|
#undef HANDLE
|
||||||
#undef HANDLE_INT_ONLY
|
#undef HANDLE_INT_ONLY
|
||||||
|
|
||||||
void BitcodeEmitter::emit(BinaryExpression const& expression) {
|
bool BitcodeEmitter::emit(BinaryExpression const& expression) {
|
||||||
expression.getLeft().emit(this);
|
GUARDED(expression.getLeft().emit(this));
|
||||||
llvm::Value *left = d->retval;
|
llvm::Value *left = d->retval;
|
||||||
|
|
||||||
expression.getRight().emit(this);
|
GUARDED(expression.getRight().emit(this));
|
||||||
llvm::Value *right = d->retval;
|
llvm::Value *right = d->retval;
|
||||||
|
|
||||||
createOp(d, left, expression.getOperator(), right);
|
createOp(d, left, expression.getOperator(), right);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcodeEmitter::emitSemiExpression(Id const& left, SemiExpression const& right) {
|
bool BitcodeEmitter::emitSemiExpression(Id const& left, SemiExpression const& right) {
|
||||||
left.emit(this);
|
GUARDED(left.emit(this));
|
||||||
llvm::Value *lhs = d->retval;
|
llvm::Value *lhs = d->retval;
|
||||||
|
|
||||||
right.getLeft().emit(this);
|
GUARDED(right.getLeft().emit(this));
|
||||||
llvm::Value *rhs = d->retval;
|
llvm::Value *rhs = d->retval;
|
||||||
|
|
||||||
createOp(d, lhs, right.getOperator(), rhs);
|
createOp(d, lhs, right.getOperator(), rhs);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,24 +38,24 @@ public:
|
||||||
BitcodeEmitter(BitcodeEmitter &) = delete;
|
BitcodeEmitter(BitcodeEmitter &) = delete;
|
||||||
virtual ~BitcodeEmitter();
|
virtual ~BitcodeEmitter();
|
||||||
|
|
||||||
virtual void emit(Return const&) override;
|
virtual bool emit(Return const&) override;
|
||||||
virtual void emit(Loop const&) override;
|
virtual bool emit(Loop const&) override;
|
||||||
virtual void emit(VarDeclaration const&) override;
|
virtual bool emit(VarDeclaration const&) override;
|
||||||
virtual void emit(Assignment const&) override;
|
virtual bool emit(Assignment const&) override;
|
||||||
virtual void emit(Print const&) override;
|
virtual bool emit(Print const&) override;
|
||||||
virtual void emit(Input const&) override;
|
virtual bool emit(Input const&) override;
|
||||||
virtual void emit(Abort const&) override;
|
virtual bool emit(Abort const&) override;
|
||||||
virtual void emit(Assert const&) override;
|
virtual bool emit(Assert const&) override;
|
||||||
virtual void emit(Branch const&) override;
|
virtual bool emit(Branch const&) override;
|
||||||
virtual void emit(Function const&) override;
|
virtual bool emit(Function const&) override;
|
||||||
virtual void emit(Module const&) override;
|
virtual bool emit(Module const&) override;
|
||||||
virtual void emit(Program const&) override;
|
virtual bool emit(Program const&) override;
|
||||||
|
|
||||||
virtual void emit(Id const&) override;
|
virtual bool emit(Id const&) override;
|
||||||
virtual void emit(Integer const&) override;
|
virtual bool emit(Integer const&) override;
|
||||||
virtual void emit(Float const&) override;
|
virtual bool emit(Float const&) override;
|
||||||
virtual void emit(FunctionCall const&) override;
|
virtual bool emit(FunctionCall const&) override;
|
||||||
virtual void emit(BinaryExpression const&) override;
|
virtual bool emit(BinaryExpression const&) override;
|
||||||
|
|
||||||
llvm::Module const& getModule() const {
|
llvm::Module const& getModule() const {
|
||||||
return *module;
|
return *module;
|
||||||
|
@ -64,7 +64,7 @@ public:
|
||||||
struct Private;
|
struct Private;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void emitSemiExpression(Id const& left, SemiExpression const& right);
|
bool emitSemiExpression(Id const& left, SemiExpression const& right);
|
||||||
|
|
||||||
std::unique_ptr<llvm::Module> module;
|
std::unique_ptr<llvm::Module> module;
|
||||||
Private *d;
|
Private *d;
|
||||||
|
|
149
CppEmitter.cpp
149
CppEmitter.cpp
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
using namespace monicelli;
|
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 STATEMENT_TERMINATOR = ";\n";
|
||||||
static const std::string BLOCK = " ";
|
static const std::string BLOCK = " ";
|
||||||
|
@ -38,15 +40,17 @@ void CppEmitter::dedent() {
|
||||||
indent_chars -= 1;
|
indent_chars -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emitIndent() {
|
bool CppEmitter::emitIndent() {
|
||||||
for (int i = 0; i < indent_chars; ++i) {
|
for (int i = 0; i < indent_chars; ++i) {
|
||||||
stream << BLOCK;
|
stream << BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Program const& program) {
|
bool CppEmitter::emit(Program const& program) {
|
||||||
for (Module m: program.getModules()) {
|
for (Module m: program.getModules()) {
|
||||||
m.emit(this);
|
GUARDED(m.emit(this));
|
||||||
stream << "\n";
|
stream << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,52 +68,61 @@ void CppEmitter::emit(Program const& program) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Function *function: program.getFunctions()) {
|
for (Function *function: program.getFunctions()) {
|
||||||
function->emit(this);
|
GUARDED(function->emit(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program.getMain()) {
|
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) {
|
for (Statement *s: node) {
|
||||||
emitIndent();
|
emitIndent();
|
||||||
s->emit(this);
|
GUARDED(s->emit(this));
|
||||||
stream << STATEMENT_TERMINATOR;
|
stream << STATEMENT_TERMINATOR;
|
||||||
}
|
}
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emitMain(Function const& main) {
|
bool CppEmitter::emitMain(Function const& main) {
|
||||||
stream << "int main() {\n";
|
stream << "int main() {\n";
|
||||||
indent();
|
indent();
|
||||||
emitStatements(main.getBody());
|
emitStatements(main.getBody());
|
||||||
dedent();
|
dedent();
|
||||||
stream << "}\n";
|
stream << "}\n";
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Id const& id) {
|
bool CppEmitter::emit(Id const& id) {
|
||||||
stream << id.getValue();
|
stream << id.getValue();
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Integer const& num) {
|
bool CppEmitter::emit(Integer const& num) {
|
||||||
stream << num.getValue();
|
stream << num.getValue();
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Float const& num) {
|
bool CppEmitter::emit(Float const& num) {
|
||||||
stream << num.getValue();
|
stream << num.getValue();
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Return const& node) {
|
bool CppEmitter::emit(Return const& node) {
|
||||||
stream << "return";
|
stream << "return";
|
||||||
|
|
||||||
if (node.getExpression()) {
|
if (node.getExpression()) {
|
||||||
stream << ' ';
|
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 =
|
bool needsBraces =
|
||||||
(dynamic_cast<SimpleExpression const*>(&node.getExpression()) == nullptr)
|
(dynamic_cast<SimpleExpression const*>(&node.getExpression()) == nullptr)
|
||||||
&&
|
&&
|
||||||
|
@ -121,45 +134,55 @@ void CppEmitter::emit(Print const& node) {
|
||||||
stream << '(';
|
stream << '(';
|
||||||
}
|
}
|
||||||
|
|
||||||
node.getExpression().emit(this);
|
GUARDED(node.getExpression().emit(this));
|
||||||
|
|
||||||
if (needsBraces) {
|
if (needsBraces) {
|
||||||
stream << ')';
|
stream << ')';
|
||||||
}
|
}
|
||||||
stream << " << std::endl";
|
stream << " << std::endl";
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Input const& node) {
|
bool CppEmitter::emit(Input const& node) {
|
||||||
stream << "std::cout << \"";
|
stream << "std::cout << \"";
|
||||||
node.getVariable().emit(this);
|
GUARDED(node.getVariable().emit(this));
|
||||||
stream << "? \";\n";
|
stream << "? \";\n";
|
||||||
emitIndent();
|
emitIndent();
|
||||||
stream << "std::cin >> ";
|
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)";
|
stream << "std::exit(1)";
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Assert const& node) {
|
bool CppEmitter::emit(Assert const& node) {
|
||||||
stream << "assert(";
|
stream << "assert(";
|
||||||
node.getExpression().emit(this);
|
GUARDED(node.getExpression().emit(this));
|
||||||
stream << ")";
|
stream << ")";
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Loop const& loop) {
|
bool CppEmitter::emit(Loop const& loop) {
|
||||||
stream << "do {\n";
|
stream << "do {\n";
|
||||||
indent();
|
indent();
|
||||||
emitStatements(loop.getBody());
|
emitStatements(loop.getBody());
|
||||||
dedent();
|
dedent();
|
||||||
emitIndent();
|
emitIndent();
|
||||||
stream << "} while (";
|
stream << "} while (";
|
||||||
loop.getCondition().emit(this);
|
GUARDED(loop.getCondition().emit(this));
|
||||||
stream << ")";
|
stream << ")";
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emitBranchCase(BranchCase const& node) {
|
bool CppEmitter::emitBranchCase(BranchCase const& node) {
|
||||||
emitBranchCondition(node.getCondition());
|
emitBranchCondition(node.getCondition());
|
||||||
stream << ") {\n";
|
stream << ") {\n";
|
||||||
indent();
|
indent();
|
||||||
|
@ -167,14 +190,16 @@ void CppEmitter::emitBranchCase(BranchCase const& node) {
|
||||||
dedent();
|
dedent();
|
||||||
emitIndent();
|
emitIndent();
|
||||||
stream << "}";
|
stream << "}";
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Branch const& branch) {
|
bool CppEmitter::emit(Branch const& branch) {
|
||||||
auto &body = branch.getBody();
|
auto &body = branch.getBody();
|
||||||
auto &var = branch.getVar();
|
auto &var = branch.getVar();
|
||||||
|
|
||||||
stream << "if (";
|
stream << "if (";
|
||||||
var.emit(this);
|
GUARDED(var.emit(this));
|
||||||
|
|
||||||
if (body.getCases().size() > 0) {
|
if (body.getCases().size() > 0) {
|
||||||
BranchCase *last = body.getCases().back();
|
BranchCase *last = body.getCases().back();
|
||||||
|
@ -182,13 +207,13 @@ void CppEmitter::emit(Branch const& branch) {
|
||||||
emitBranchCase(*cas);
|
emitBranchCase(*cas);
|
||||||
if (cas != last) {
|
if (cas != last) {
|
||||||
stream << " else if (";
|
stream << " else if (";
|
||||||
var.emit(this);
|
GUARDED(var.emit(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!body.getElse()) {
|
if (!body.getElse()) {
|
||||||
return;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream << " else {\n";
|
stream << " else {\n";
|
||||||
|
@ -197,40 +222,50 @@ void CppEmitter::emit(Branch const& branch) {
|
||||||
dedent();
|
dedent();
|
||||||
emitIndent();
|
emitIndent();
|
||||||
stream << "}";
|
stream << "}";
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Assignment const& assignment) {
|
bool CppEmitter::emit(Assignment const& assignment) {
|
||||||
assignment.getName().emit(this);
|
GUARDED(assignment.getName().emit(this));
|
||||||
stream << " = ";
|
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();
|
Expression *last = args.back();
|
||||||
for (Expression const* arg: args) {
|
for (Expression const* arg: args) {
|
||||||
arg->emit(this);
|
GUARDED(arg->emit(this));
|
||||||
if (arg != last) {
|
if (arg != last) {
|
||||||
stream << ", ";
|
stream << ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CppEmitter::emit(FunctionCall const& funcall) {
|
bool CppEmitter::emit(FunctionCall const& funcall) {
|
||||||
funcall.getName().emit(this);
|
GUARDED(funcall.getName().emit(this));
|
||||||
stream << "(";
|
stream << "(";
|
||||||
emitFunctionArglist(funcall.getArgs());
|
emitFunctionArglist(funcall.getArgs());
|
||||||
stream << ")";
|
stream << ")";
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Function const& function) {
|
bool CppEmitter::emit(Function const& function) {
|
||||||
emitFunctionSignature(function);
|
emitFunctionSignature(function);
|
||||||
stream << " {\n";
|
stream << " {\n";
|
||||||
indent();
|
indent();
|
||||||
emitStatements(function.getBody());
|
emitStatements(function.getBody());
|
||||||
dedent();
|
dedent();
|
||||||
stream << "}\n\n";
|
stream << "}\n\n";
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream &stream, Type const& type) {
|
std::ostream& operator<<(std::ostream &stream, Type const& type) {
|
||||||
|
@ -258,40 +293,48 @@ std::ostream& operator<<(std::ostream &stream, Type const& type) {
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emitFunctionParams(PointerList<FunArg> const& funargs) {
|
bool CppEmitter::emitFunctionParams(PointerList<FunArg> const& funargs) {
|
||||||
FunArg *last = funargs.back();
|
FunArg *last = funargs.back();
|
||||||
|
|
||||||
for (FunArg const* funarg: funargs) {
|
for (FunArg const* funarg: funargs) {
|
||||||
stream << funarg->getType() << (funarg->isPointer()? "* ": " ");
|
stream << funarg->getType() << (funarg->isPointer()? "* ": " ");
|
||||||
funarg->getName().emit(this);
|
GUARDED(funarg->getName().emit(this));
|
||||||
if (funarg != last) {
|
if (funarg != last) {
|
||||||
stream << ", ";
|
stream << ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(Module const& module) {
|
bool CppEmitter::emit(Module const& module) {
|
||||||
bool system = (module.getType() == Module::SYSTEM);
|
bool system = (module.getType() == Module::SYSTEM);
|
||||||
stream << "#include " << (system? '<': '"') << module.getName() << (system? '>': '"');
|
stream << "#include " << (system? '<': '"') << module.getName() << (system? '>': '"');
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emitFunctionSignature(Function const& function) {
|
bool CppEmitter::emitFunctionSignature(Function const& function) {
|
||||||
stream << function.getType() << ' ';
|
stream << function.getType() << ' ';
|
||||||
function.getName().emit(this);
|
GUARDED(function.getName().emit(this));
|
||||||
stream << "(";
|
stream << "(";
|
||||||
emitFunctionParams(function.getArgs());
|
emitFunctionParams(function.getArgs());
|
||||||
stream << ")";
|
stream << ")";
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(VarDeclaration const& decl) {
|
bool CppEmitter::emit(VarDeclaration const& decl) {
|
||||||
stream << decl.getType() << ' ';
|
stream << decl.getType() << ' ';
|
||||||
if (decl.isPointer()) stream << '*';
|
if (decl.isPointer()) stream << '*';
|
||||||
decl.getId().emit(this);
|
GUARDED(decl.getId().emit(this));
|
||||||
|
|
||||||
if (decl.getInitializer()) {
|
if (decl.getInitializer()) {
|
||||||
stream << " = ";
|
stream << " = ";
|
||||||
decl.getInitializer()->emit(this);
|
GUARDED(decl.getInitializer()->emit(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream &stream, Operator op) {
|
std::ostream& operator<<(std::ostream &stream, Operator op) {
|
||||||
|
@ -334,18 +377,22 @@ std::ostream& operator<<(std::ostream &stream, Operator op) {
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEmitter::emit(BinaryExpression const& node) {
|
bool CppEmitter::emit(BinaryExpression const& node) {
|
||||||
node.getLeft().emit(this);
|
GUARDED(node.getLeft().emit(this));
|
||||||
stream << ' ' << node.getOperator() << ' ';
|
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);
|
bool braces = (dynamic_cast<SimpleExpression const*>(&node.getLeft()) == nullptr);
|
||||||
|
|
||||||
stream << ' ' << node.getOperator() << ' ';
|
stream << ' ' << node.getOperator() << ' ';
|
||||||
if (braces) stream << "(";
|
if (braces) stream << "(";
|
||||||
node.getLeft().emit(this);
|
GUARDED(node.getLeft().emit(this));
|
||||||
if (braces) stream << ")";
|
if (braces) stream << ")";
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,34 +31,34 @@ class CppEmitter: public Emitter {
|
||||||
public:
|
public:
|
||||||
CppEmitter(std::ostream *stream): stream(*stream), indent_chars(0) {}
|
CppEmitter(std::ostream *stream): stream(*stream), indent_chars(0) {}
|
||||||
|
|
||||||
virtual void emit(Return const&) override;
|
virtual bool emit(Return const&) override;
|
||||||
virtual void emit(Loop const&) override;
|
virtual bool emit(Loop const&) override;
|
||||||
virtual void emit(VarDeclaration const&) override;
|
virtual bool emit(VarDeclaration const&) override;
|
||||||
virtual void emit(Assignment const&) override;
|
virtual bool emit(Assignment const&) override;
|
||||||
virtual void emit(Print const&) override;
|
virtual bool emit(Print const&) override;
|
||||||
virtual void emit(Input const&) override;
|
virtual bool emit(Input const&) override;
|
||||||
virtual void emit(Abort const&) override;
|
virtual bool emit(Abort const&) override;
|
||||||
virtual void emit(Assert const&) override;
|
virtual bool emit(Assert const&) override;
|
||||||
virtual void emit(Branch const&) override;
|
virtual bool emit(Branch const&) override;
|
||||||
virtual void emit(Function const&) override;
|
virtual bool emit(Function const&) override;
|
||||||
virtual void emit(Module const&) override;
|
virtual bool emit(Module const&) override;
|
||||||
virtual void emit(Program const&) override;
|
virtual bool emit(Program const&) override;
|
||||||
|
|
||||||
virtual void emit(FunctionCall const&) override;
|
virtual bool emit(FunctionCall const&) override;
|
||||||
virtual void emit(Id const&) override;
|
virtual bool emit(Id const&) override;
|
||||||
virtual void emit(Integer const&) override;
|
virtual bool emit(Integer const&) override;
|
||||||
virtual void emit(Float const&) override;
|
virtual bool emit(Float const&) override;
|
||||||
virtual void emit(BinaryExpression const&) override;
|
virtual bool emit(BinaryExpression const&) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void emitIndent();
|
bool emitIndent();
|
||||||
void emitFunctionSignature(Function const& function);
|
bool emitFunctionSignature(Function const& function);
|
||||||
void emitFunctionParams(PointerList<FunArg> const& funargs);
|
bool emitFunctionParams(PointerList<FunArg> const& funargs);
|
||||||
void emitFunctionArglist(PointerList<Expression> const& args);
|
bool emitFunctionArglist(PointerList<Expression> const& args);
|
||||||
void emitStatements(PointerList<Statement> const& node);
|
bool emitStatements(PointerList<Statement> const& node);
|
||||||
void emitBranchCondition(SemiExpression const& node);
|
bool emitBranchCondition(SemiExpression const& node);
|
||||||
void emitBranchCase(BranchCase const& node);
|
bool emitBranchCase(BranchCase const& node);
|
||||||
void emitMain(Function const& main);
|
bool emitMain(Function const& main);
|
||||||
|
|
||||||
void indent();
|
void indent();
|
||||||
void dedent();
|
void dedent();
|
||||||
|
|
34
Emitter.hpp
34
Emitter.hpp
|
@ -45,24 +45,24 @@ class BinaryExpression;
|
||||||
|
|
||||||
class Emitter {
|
class Emitter {
|
||||||
public:
|
public:
|
||||||
virtual void emit(Return const&) = 0;
|
virtual bool emit(Return const&) = 0;
|
||||||
virtual void emit(Loop const&) = 0;
|
virtual bool emit(Loop const&) = 0;
|
||||||
virtual void emit(VarDeclaration const&) = 0;
|
virtual bool emit(VarDeclaration const&) = 0;
|
||||||
virtual void emit(Assignment const&) = 0;
|
virtual bool emit(Assignment const&) = 0;
|
||||||
virtual void emit(Print const&) = 0;
|
virtual bool emit(Print const&) = 0;
|
||||||
virtual void emit(Input const&) = 0;
|
virtual bool emit(Input const&) = 0;
|
||||||
virtual void emit(Abort const&) = 0;
|
virtual bool emit(Abort const&) = 0;
|
||||||
virtual void emit(Assert const&) = 0;
|
virtual bool emit(Assert const&) = 0;
|
||||||
virtual void emit(Branch const&) = 0;
|
virtual bool emit(Branch const&) = 0;
|
||||||
virtual void emit(Function const&) = 0;
|
virtual bool emit(Function const&) = 0;
|
||||||
virtual void emit(Module const&) = 0;
|
virtual bool emit(Module const&) = 0;
|
||||||
virtual void emit(Program const&) = 0;
|
virtual bool emit(Program const&) = 0;
|
||||||
|
|
||||||
virtual void emit(Id const&) = 0;
|
virtual bool emit(Id const&) = 0;
|
||||||
virtual void emit(Integer const&) = 0;
|
virtual bool emit(Integer const&) = 0;
|
||||||
virtual void emit(Float const&) = 0;
|
virtual bool emit(Float const&) = 0;
|
||||||
virtual void emit(FunctionCall const&) = 0;
|
virtual bool emit(FunctionCall const&) = 0;
|
||||||
virtual void emit(BinaryExpression const&) = 0;
|
virtual bool emit(BinaryExpression const&) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
83
Nodes.hpp
83
Nodes.hpp
|
@ -50,22 +50,15 @@ enum class Operator {
|
||||||
class Emittable {
|
class Emittable {
|
||||||
public:
|
public:
|
||||||
virtual ~Emittable() {}
|
virtual ~Emittable() {}
|
||||||
virtual void emit(Emitter *emitter) const = 0;
|
virtual bool emit(Emitter *emitter) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Statement: public Emittable {
|
class Statement: public Emittable {};
|
||||||
public:
|
|
||||||
virtual void emit(Emitter *) const {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Expression: public Emittable {
|
class Expression: public Emittable {};
|
||||||
public:
|
|
||||||
virtual void emit(Emitter *) const {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SimpleExpression: public Expression {
|
class SimpleExpression: public Expression {};
|
||||||
};
|
|
||||||
|
|
||||||
class SemiExpression {
|
class SemiExpression {
|
||||||
public:
|
public:
|
||||||
|
@ -89,8 +82,8 @@ class Id: public SimpleExpression {
|
||||||
public:
|
public:
|
||||||
explicit Id(std::string *c): value(c) {}
|
explicit Id(std::string *c): value(c) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const& getValue() const {
|
std::string const& getValue() const {
|
||||||
|
@ -109,8 +102,8 @@ class Integer: public Number {
|
||||||
public:
|
public:
|
||||||
Integer(long i): value(i) {}
|
Integer(long i): value(i) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
long getValue() const {
|
long getValue() const {
|
||||||
|
@ -126,8 +119,8 @@ class Float: public Number {
|
||||||
public:
|
public:
|
||||||
Float(double f): value(f) {}
|
Float(double f): value(f) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
double getValue() const {
|
double getValue() const {
|
||||||
|
@ -143,8 +136,8 @@ class Return: public Statement {
|
||||||
public:
|
public:
|
||||||
explicit Return(Expression *e): expression(e) {}
|
explicit Return(Expression *e): expression(e) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<Expression const&> getExpression() const {
|
boost::optional<Expression const&> getExpression() const {
|
||||||
|
@ -160,8 +153,8 @@ class Loop: public Statement {
|
||||||
public:
|
public:
|
||||||
Loop(PointerList<Statement> *b, Expression *c): body(b), condition(c) {}
|
Loop(PointerList<Statement> *b, Expression *c): body(b), condition(c) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerList<Statement> const& getBody() const {
|
PointerList<Statement> const& getBody() const {
|
||||||
|
@ -183,8 +176,8 @@ public:
|
||||||
VarDeclaration(Id *n, Type t, bool p, Expression *i):
|
VarDeclaration(Id *n, Type t, bool p, Expression *i):
|
||||||
name(n), point(p), init(i), type(t) {}
|
name(n), point(p), init(i), type(t) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id const& getId() const {
|
Id const& getId() const {
|
||||||
|
@ -215,8 +208,8 @@ class Assignment: public Statement {
|
||||||
public:
|
public:
|
||||||
Assignment(Id *n, Expression *v): name(n), value(v) {}
|
Assignment(Id *n, Expression *v): name(n), value(v) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id const& getName() const {
|
Id const& getName() const {
|
||||||
|
@ -237,8 +230,8 @@ class Print: public Statement {
|
||||||
public:
|
public:
|
||||||
explicit Print(Expression *e): expression(e) {}
|
explicit Print(Expression *e): expression(e) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression const& getExpression() const {
|
Expression const& getExpression() const {
|
||||||
|
@ -254,8 +247,8 @@ class Input: public Statement {
|
||||||
public:
|
public:
|
||||||
explicit Input(Id *v): variable(v) {}
|
explicit Input(Id *v): variable(v) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id const& getVariable() const {
|
Id const& getVariable() const {
|
||||||
|
@ -269,8 +262,8 @@ private:
|
||||||
|
|
||||||
class Abort: public Statement {
|
class Abort: public Statement {
|
||||||
public:
|
public:
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -279,8 +272,8 @@ class Assert: public Statement {
|
||||||
public:
|
public:
|
||||||
explicit Assert(Expression *e): expression(e) {}
|
explicit Assert(Expression *e): expression(e) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression const& getExpression() const {
|
Expression const& getExpression() const {
|
||||||
|
@ -296,8 +289,8 @@ class FunctionCall: public Statement, public Expression {
|
||||||
public:
|
public:
|
||||||
FunctionCall(Id *n, PointerList<Expression> *a): name(n), args(a) {}
|
FunctionCall(Id *n, PointerList<Expression> *a): name(n), args(a) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id const& getName() const {
|
Id const& getName() const {
|
||||||
|
@ -353,8 +346,8 @@ public:
|
||||||
|
|
||||||
Branch(Id *v, Branch::Body *b): var(v), body(b) {}
|
Branch(Id *v, Branch::Body *b): var(v), body(b) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id const& getVar() const {
|
Id const& getVar() const {
|
||||||
|
@ -401,8 +394,8 @@ public:
|
||||||
Function(Id *n, Type r, PointerList<FunArg> *a, PointerList<Statement> *b):
|
Function(Id *n, Type r, PointerList<FunArg> *a, PointerList<Statement> *b):
|
||||||
name(n), type(r), args(a), body(b) {}
|
name(n), type(r), args(a), body(b) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id const& getName() const {
|
Id const& getName() const {
|
||||||
|
@ -437,8 +430,8 @@ public:
|
||||||
|
|
||||||
Module(const std::string &n, Type s): name(n), type(s) {}
|
Module(const std::string &n, Type s): name(n), type(s) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const Module &other) const noexcept {
|
bool operator==(const Module &other) const noexcept {
|
||||||
|
@ -480,8 +473,8 @@ namespace monicelli {
|
||||||
|
|
||||||
class Program: public Emittable {
|
class Program: public Emittable {
|
||||||
public:
|
public:
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMain(Function *m) {
|
void setMain(Function *m) {
|
||||||
|
@ -521,8 +514,8 @@ public:
|
||||||
BinaryExpression(Expression *l, Operator op, Expression *r):
|
BinaryExpression(Expression *l, Operator op, Expression *r):
|
||||||
left(l), op(op), right(r) {}
|
left(l), op(op), right(r) {}
|
||||||
|
|
||||||
virtual void emit(Emitter *emitter) const {
|
virtual bool emit(Emitter *emitter) const {
|
||||||
emitter->emit(*this);
|
return emitter->emit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression const& getLeft() const {
|
Expression const& getLeft() const {
|
||||||
|
|
Reference in New Issue
Block a user