Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <codegen.h>
- #include "syntaxtree.h"
- // grammar files
- #include "grammar.hpp"
- #include <llvm/Module.h>
- #include <llvm/Function.h>
- #include <llvm/Type.h>
- #include <llvm/DerivedTypes.h>
- #include <llvm/LLVMContext.h>
- #include <llvm/PassManager.h>
- #include <llvm/Instructions.h>
- #include <llvm/CallingConv.h>
- #include <llvm/Bitcode/ReaderWriter.h>
- #include <llvm/Analysis/Verifier.h>
- #include <llvm/Assembly/PrintModulePass.h>
- #include <llvm/Support/IRBuilder.h>
- #include <llvm/Target/TargetSelect.h>
- #include <llvm/ExecutionEngine/GenericValue.h>
- #include <llvm/ExecutionEngine/JIT.h>
- #include <llvm/Support/raw_ostream.h>
- #include <iostream>
- using namespace llvm;
- bool CodeGenerator::generate(Program *program)
- {
- m_module = new Module(program->name(), getGlobalContext());
- std::vector<const Type *> args;
- FunctionType *mainType = FunctionType::get(Type::getVoidTy(getGlobalContext()), args, false);
- m_mainFunction = Function::Create(mainType, GlobalValue::InternalLinkage, program->name(), m_module);
- BasicBlock *mainBlock = BasicBlock::Create(getGlobalContext(), "main", m_mainFunction);
- pushScope(new CodeScope(mainBlock));
- program->codeGen(*this);
- ReturnInst::Create(getGlobalContext(), mainBlock);
- popScope();
- // if (m_error)
- // return false;
- PassManager pm;
- pm.add(createPrintModulePass(&outs()));
- return pm.run(*m_module);
- }
- void CodeGenerator::error(const std::string &msg, unsigned int line)
- {
- m_error = true;
- std::cerr << "ERROR:" << msg << std::endl;
- }
- void CodeGenerator::warning(const std::string &msg, unsigned int line)
- {
- std::cerr << "WARNING:" << msg << std::endl;
- }
- void CodeGenerator::run()
- {
- InitializeNativeTarget();
- ExecutionEngine *ee = ExecutionEngine::create(m_module, false);
- if (ee == NULL)
- {
- std::cerr << "can't create execution engine" << std::endl;
- return;
- }
- std::vector<GenericValue> noargs;
- GenericValue v = ee->runFunction(m_mainFunction, noargs);
- }
- const Type *typeById(Identifier *tp)
- {
- if (tp->name() == "integer")
- return Type::getInt32Ty(getGlobalContext());
- else if (tp->name() == "float")
- return Type::getFloatTy(getGlobalContext());
- return Type::getVoidTy(getGlobalContext());
- }
- //llvm::Value *Node::codeGen(CodeGenerator &gen)
- //{
- // std::cout << "generating Node" << std::endl;
- // return NULL;
- //}
- Value *Program::codeGen(CodeGenerator &gen)
- {
- std::cout << "generating Program" << std::endl;
- return m_body->codeGen(gen);
- }
- llvm::Value *Block::codeGen(CodeGenerator &gen)
- {
- std::cout << "generating block" << std::endl;
- for (VariableList::iterator it = m_decls->begin(); it != m_decls->end(); ++it)
- {
- Value *val = (*it)->codeGen(gen);
- gen.local()->addDeclaration((*it)->name(), val);
- }
- Value *last = NULL;
- for (StatementList::iterator it = m_stmts->begin(); it != m_stmts->end(); ++it)
- last = (*it)->codeGen(gen);
- return last;
- }
- Value *Variable::codeGen(CodeGenerator &gen)
- {
- std::cout << "generating variable: " << m_var->name() << ": " << m_type->name() << std::endl;
- if (gen.local()->contains(m_var->name()))
- {
- gen.error("variable with name:" + m_var->name() + " is already declared");
- return NULL;
- }
- // variable declaration
- return new AllocaInst(typeById(m_type.get()), m_var->name(), gen.local()->block());
- }
- Value *Integer::codeGen(CodeGenerator &gen)
- {
- return ConstantInt::get(Type::getInt32Ty(getGlobalContext()), m_value);
- }
- Value *Float::codeGen(CodeGenerator &gen)
- {
- return ConstantFP::get(Type::getFloatTy(getGlobalContext()), m_value);
- }
- Value *String::codeGen(CodeGenerator &gen)
- {
- return ConstantArray::get(getGlobalContext(), m_value);
- }
- Value *Identifier::codeGen(CodeGenerator &gen)
- {
- if (!gen.local()->contains(m_name))
- {
- gen.error("undeclared variable:" + m_name);
- return NULL;
- }
- return new LoadInst(gen.local()->lookup(m_name), "", gen.local()->block());
- }
- Value *AssignStatement::codeGen(CodeGenerator &gen)
- {
- std::cout << "generating assignment:" << m_left->name() << ":" << std::endl;
- if (!gen.local()->contains(m_left->name()))
- {
- gen.error("undeclared variable:" + m_left->name());
- return NULL;
- }
- Value *variable = gen.local()->lookup(m_left->name());
- Value *value = m_right->codeGen(gen);
- return new StoreInst(value, variable, gen.local()->block());
- }
- Value *IfStatement::codeGen(CodeGenerator &gen)
- {
- gen.error("IF statement isn't implemented");
- BasicBlock *blockTrue = BasicBlock::Create(getGlobalContext(), "true", gen.function());
- BasicBlock *blockFalse = BasicBlock::Create(getGlobalContext(), "false");
- BasicBlock *blockAfter = BasicBlock::Create(getGlobalContext(), "after");
- gen.pushScope(new CodeScope(blockTrue, gen.local().get()));
- m_ifTrue->codeGen(gen);
- gen.popScope();
- gen.function()->getBasicBlockList().push_back(blockFalse);
- gen.function()->getBasicBlockList().push_back(blockAfter);
- gen.pushScope(new CodeScope(blockFalse, gen.local().get()));
- m_ifFalse->codeGen(gen);
- gen.popScope();
- return BranchInst::Create(blockTrue, blockFalse,
- m_cond->codeGen(gen),
- gen.local()->block());
- }
- Value *CompoundStatement::codeGen(CodeGenerator &gen)
- {
- gen.warning("compound statement isn't implemented");
- Value *last = NULL;
- for (StatementList::iterator it = m_stmts->begin(); it != m_stmts->end(); ++it)
- last = (*it)->codeGen(gen);
- return last;
- }
- Value *UnaryExpression::codeGen(CodeGenerator &gen)
- {
- gen.error("unary expression isn't implemented");
- return NULL;
- }
- Value *BinaryExpression::codeGen(CodeGenerator &gen)
- {
- gen.warning("binary expression isn't implemented");
- Instruction::BinaryOps op;
- switch (m_op)
- {
- /* add */
- // +
- case PLUS:
- op = Instruction::Add;
- break;
- // -
- case MINUS:
- op = Instruction::Sub;
- break;
- // or
- case OR:
- op = Instruction::Or;
- break;
- /* multiplication */
- case MULT:
- op = Instruction::Mul;
- break;
- case DIVIDE:
- op = Instruction::SDiv;
- break;
- case MOD:
- case DIV:
- case AND:
- op = Instruction::And;
- break;
- case NOTSYM:
- default:
- gen.error("unknown operator");
- return NULL;
- }
- return BinaryOperator::Create(op, m_left->codeGen(gen), m_right->codeGen(gen),
- "", gen.local()->block());
- }
- Value *CompareExpression::codeGen(CodeGenerator &gen)
- {
- gen.warning("comparing expression isn't implemented");
- Instruction::OtherOps op;
- // checking the types etc.
- op = CmpInst::ICmp;
- //
- CmpInst::Predicate pr;
- switch (m_op)
- {
- /* comparison */
- // ==
- case EQ:
- if (op == CmpInst::ICmp)
- pr = CmpInst::ICMP_EQ;
- else if (op == CmpInst::FCmp)
- pr = CmpInst::FCMP_OEQ;
- break;
- // <>
- case NE:
- if (op == CmpInst::ICmp)
- pr = CmpInst::ICMP_NE;
- else if (op == CmpInst::FCmp)
- pr = CmpInst::FCMP_ONE;
- break;
- // >
- case GT:
- if (op == CmpInst::ICmp)
- pr = CmpInst::ICMP_SGT;
- else if (op == CmpInst::FCmp)
- pr = CmpInst::FCMP_OGT;
- break;
- // >=
- case GE:
- if (op == CmpInst::ICmp)
- pr = CmpInst::ICMP_SGE;
- else if (op == CmpInst::FCmp)
- pr = CmpInst::FCMP_OGE;
- break;
- // <
- case LT:
- if (op == CmpInst::ICmp)
- pr = CmpInst::ICMP_SLT;
- else if (op == CmpInst::FCmp)
- pr = CmpInst::FCMP_OLT;
- break;
- // <=
- case LE:
- if (op == CmpInst::ICmp)
- pr = CmpInst::ICMP_SLE;
- else if (op == CmpInst::FCmp)
- pr = CmpInst::FCMP_OLE;
- break;
- default:
- gen.error("unknown compare operator");
- return NULL;
- }
- return CmpInst::Create(op, pr,
- m_left->codeGen(gen), m_right->codeGen(gen),
- "", gen.local()->block());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement