Example #1
0
/// Read-Eval-Print-Loop
static void repl(CEnv& cenv, ExecutionEngine* engine)
{
	while (1) {
		std::cout << "> ";
		std::cout.flush();
		SExp exp = readExpression(std::cin);

		try {
			AST* ast = parseExpression(exp);
			if (ast->evaluatable()) {
				ASTPrototype* proto = new ASTPrototype(false, "", vector<string>());
				ASTFunction*  func  = new ASTFunction(proto, ast);
				Function*     code  = func->Funcgen(cenv);
				void*         fp    = engine->getPointerToFunction(code);
				double (*f)() = (double (*)())fp;
				std::cout << f() << endl;
			} else {
				Value* code = ast->Codegen(cenv); 
				std::cout << "Generated code:" << endl;
				code->dump();
			}
		} catch (SyntaxError e) {
			std::cerr << "Syntax error: " << e.what() << endl;
		}
	}
}
Example #2
0
Value* ASTIf::Codegen(CEnv& cenv)
{
	Value* condV = _cond->Codegen(cenv);

	// Convert condition to a bool by comparing equal to 0.0.
	condV = cenv.builder.CreateFCmpONE(
			condV, ConstantFP::get(APFloat(0.0)), "ifcond");

	Function* parent = cenv.builder.GetInsertBlock()->getParent();

	// Create blocks for the then and else cases.
	// Insert the 'then' block at the end of the function.
	BasicBlock* thenBB = BasicBlock::Create("then", parent);
	BasicBlock* elseBB = BasicBlock::Create("else");
	BasicBlock* mergeBB = BasicBlock::Create("ifcont");

	cenv.builder.CreateCondBr(condV, thenBB, elseBB);

	// Emit then value.
	cenv.builder.SetInsertPoint(thenBB);
	Value* thenV = _then->Codegen(cenv);

	cenv.builder.CreateBr(mergeBB);
	// Codegen of 'Then' can change the current block, update thenBB
	thenBB = cenv.builder.GetInsertBlock();

	// Emit else block.
	parent->getBasicBlockList().push_back(elseBB);
	cenv.builder.SetInsertPoint(elseBB);
	Value* elseV = _else->Codegen(cenv);

	cenv.builder.CreateBr(mergeBB);
	// Codegen of 'Else' can change the current block, update elseBB
	elseBB = cenv.builder.GetInsertBlock();

	// Emit merge block.
	parent->getBasicBlockList().push_back(mergeBB);
	cenv.builder.SetInsertPoint(mergeBB);
	PHINode* pn = cenv.builder.CreatePHI(Type::DoubleTy, "iftmp");

	pn->addIncoming(thenV, thenBB);
	pn->addIncoming(elseV, elseBB);
	return pn;
}
Example #3
0
Function* ASTFunction::Funcgen(CEnv& cenv)
{
	cenv.env.clear();

	Function* f = _proto->Funcgen(cenv);

	// Create a new basic block to start insertion into.
	BasicBlock* bb = BasicBlock::Create("entry", f);
	cenv.builder.SetInsertPoint(bb);

	try {
		Value* retVal = _body->Codegen(cenv);
		cenv.builder.CreateRet(retVal); // Finish function
		verifyFunction(*f); // Validate generated code
		cenv.fpm.run(*f); // Optimize function
		return f;
	} catch (SyntaxError e) {
		f->eraseFromParent(); // Error reading body, remove function
		throw e;
	}

	return 0; // Never reached
}