ValueBase* NIfElseStatement::codeGen(CodeGenContext& context) { ValueBase* test = condExpr->codeGen( context ); BasicBlock *btrue = BasicBlock::Create(getGlobalContext(), "thenBlock", context.currentFunction); BasicBlock *bfalse = BasicBlock::Create(getGlobalContext(), "elseBlock", context.currentFunction); BasicBlock *bmerge = BasicBlock::Create(getGlobalContext(), "mergeStmt", context.currentFunction); auto ret = llvm::BranchInst::Create(btrue,bfalse,test->getValue(), context.currentBlock()); auto oldBlock = context.currentBlock(); context.pushBlock(btrue); auto retThen = thenBlock->codeGen(context); if (retThen == NULL){ llvm::BranchInst::Create(bmerge,context.currentBlock()); } while (context.currentBlock() != oldBlock){ context.popBlock(); } oldBlock = context.currentBlock(); context.pushBlock(bfalse); ValueBase * retElse = NULL; if (elseBlock != NULL) { retElse = elseBlock->codeGen(context); } if (retElse == NULL){ llvm::BranchInst::Create(bmerge,context.currentBlock()); } while (context.currentBlock() != oldBlock){ context.popBlock(); } context.pushBlock(bmerge); return NULL; }
ValueBase* NFunctionDeclaration::codeGen(CodeGenContext& context, const std::vector<llvm::Type*> &argTypes) { FunctionType *ftype = FunctionType::get(typeOf(type), makeArrayRef(argTypes), false); Function *function = Function::Create(ftype, GlobalValue::InternalLinkage, id.name.c_str(), context.module); BasicBlock *bblock = BasicBlock::Create(getGlobalContext(), "entry", function, 0); Function *oldFunction = context.currentFunction; context.currentFunction = function; auto oldBlock = context.currentBlock(); context.pushBlock(bblock); Function::arg_iterator argsValues = function->arg_begin(); Value* argumentValue; VariableList::const_iterator it; std::vector<llvm::Type*>::const_iterator itType = argTypes.begin(); for (it = arguments.begin(); it != arguments.end(); it++) { argumentValue = argsValues++; itType = itType ++; AllocaInst *alloc = new AllocaInst(*itType, (*it)->name.c_str(), context.currentBlock()); ValueBase* value = new LongValue(alloc); context.locals()[(*it)->name] = value; new StoreInst(argumentValue, value->getValue(), false, context.currentBlock()); } block.codeGen(context); while (context.currentBlock() != oldBlock) context.popBlock(); context.currentFunction = oldFunction; return new FunctionValue(function); }
ValueBase* NIdentifier::codeGen(CodeGenContext& context) { //std::cout << "Creating identifier reference: " << name << endl; ValueBase *value = context.getVar(name); if (value == NULL) { return NULL; } return createValue(value->getType(), new LoadInst(value->getValue(), "", false, context.currentBlock())); }
ValueBase* NMethodCall::callScriptFunc(CodeGenContext& context) { ValueBase * functionInfo = context.getVar(id.name); if (functionInfo->getType() != ValueType::VT_FUNCTION){ std::cerr<< id.name <<" is not a function" <<endl; return NULL; } std::vector<Value*> args; std::vector<Type*> argsTypes; ExpressionList::const_iterator it; for (it = arguments.begin(); it != arguments.end(); it++) { ValueBase* arg = (**it).codeGen(context); argsTypes.push_back(arg->getRealType()); args.push_back(arg->getValue()); } ValueBase *value = ((FunctionValue*)functionInfo)->getFunctionInfo()->codeGen(context, argsTypes); CallInst *call = CallInst::Create(value->getValue(), makeArrayRef(args), "", context.currentBlock()); //std::cout << "Creating method call: " << id.name << endl; return new LongValue(call); }
ValueBase* NAssignment::codeGen(CodeGenContext& context) { //std::cout << "Creating assignment for " << lhs.name << endl; ValueBase * value = context.getVar(lhs.name); if (value == NULL) { auto type = rhs.codeGen(context)->getRealType(); AllocaInst *alloc = new AllocaInst(type, lhs.name.c_str(), context.currentBlock()); value = new LongValue(alloc); context.locals()[lhs.name] = value; } ValueBase* _target = rhs.codeGen(context); new StoreInst(_target->getValue(), value->getValue(), false, context.currentBlock()); return _target; }
ValueBase* NBlock::codeGen(CodeGenContext& context) { StatementList::const_iterator it; ValueBase *last = NULL; for (it = statements.begin(); it != statements.end(); it++) { //std::cout << "Generating code for " << typeid(**it).name() << endl; last = (**it).codeGen(context); if (strcmp(typeid(**it).name(), "16NReturnStatement") == 0){ BasicBlock *retStmt = BasicBlock::Create(getGlobalContext(), "retStmt", context.currentFunction); Value *value = last->getValue(); ReturnInst::Create(getGlobalContext(), value, retStmt); llvm::BranchInst::Create(retStmt,context.currentBlock()); return (ValueBase*)0xff; } } //std::cout << "Creating block" << endl; return NULL; }