targetinterpretation.cpp
No OneTemporary

File Metadata

Created
Tue, Jul 7, 7:32 AM

targetinterpretation.cpp

/*
* File: targetinterpretation.cpp
* Author: pgess
*
* Created on June 29, 2016, 6:45 PM
*/
#include "compilation/targetinterpretation.h"
#include "pass/interpretationpass.h"
using namespace std;
namespace xreate{ namespace compilation {
const Expression EXPRESSION_FALSE = Expression(Atom<Number_t>(0));
const Expression EXPRESSION_TRUE = Expression(Atom<Number_t>(1));
//Expression
//InterpretationScope::compile(const Expression& expression){}
CodeScope*
InterpretationScope::processOperatorIf(const Expression& expression){
const Expression& exprCondition = process(expression.getOperands()[0]);
if (exprCondition == EXPRESSION_TRUE){
return expression.blocks.front();
}
return expression.blocks.back();
}
CodeScope*
InterpretationScope::processOperatorSwitch(const Expression& expression) {
const Expression& exprCondition = process(expression.operands[0]);
bool flagHasDefault = expression.operands[1].op == Operator::CASE_DEFAULT;
//TODO check that one and only one case variant is appropriate
for (size_t size = expression.operands.size(), i= flagHasDefault? 2: 1; i<size; ++i){
const Expression& exprCase = process(expression.operands[i]);
if (function->getScope(exprCase.blocks.front())->processScope() == exprCondition){
return exprCase.blocks.back();
}
}
if (flagHasDefault){
const Expression& exprCaseDefault = expression.operands[1];
return exprCaseDefault.blocks.front();
}
assert(false && "Switch has no appropriate variant");
return nullptr;
}
llvm::Value*
InterpretationScope::compileHybrid(const InterpretationOperator& op, const Expression& expression, const Context& context){
switch(op){
case IF_INTERPRET_CONDITION: {
CodeScope* scopeResult = processOperatorIf(expression);
llvm::Value* result = context.function->getScopeUnit(scopeResult)->compile();
return result;
}
case SWITCH_INTERPRET_CONDITION:{
CodeScope* scopeResult = processOperatorSwitch(expression);
llvm::Value* result = context.function->getScopeUnit(scopeResult)->compile();
return result;
}
case FOLD_INTERPRET_INPUT: {
//initialization
const Expression& exprInput = process(expression.getOperands()[0]);
assert(exprInput.op == Operator::LIST);
CodeScope* scopeBody = expression.blocks.front();
const string& nameEl = expression.bindings[0];
const Symbol& symbolEl = scopeBody->findSymbol(nameEl);
const std::string& idAccum = expression.bindings[1];
llvm::Value* rawAccum = context.scope->process(expression.getOperands()[1]);
compilation::CodeScopeUnit* unitBody = context.function->getScopeUnit(scopeBody);
InterpretationScope* intrBody = function->getScope(scopeBody);
const std::vector<Expression> elementsInput= exprInput.getOperands();
for (size_t i=0; i<elementsInput.size(); ++i){
Expression exprElement = elementsInput[i];
unitBody->reset();
intrBody->bindArg(exprElement, nameEl);
unitBody->overrideDeclaration(symbolEl, move(exprElement));
unitBody->bindArg(rawAccum, string(idAccum));
rawAccum = unitBody->compile();
}
return rawAccum;
}
default: break;
}
assert(false&& "Unknown hybrid operator");
return nullptr;
}
llvm::Value*
InterpretationScope::compile(const Expression& expression, const Context& context){
const InterpretationData& data = Attachments::get<Expression, InterpretationData>(expression);
if (data.op != InterpretationOperator::NONE){
return compileHybrid(data.op, expression, context);
}
Expression result = process(expression);
return context.scope->processLowlevel(result);
}
Expression
InterpretationScope::process(const Expression& expression){
switch (expression.__state){
case Expression::VARIANT:
case Expression::INVALID:
assert(false);
case Expression::NUMBER:
case Expression::STRING:
return expression;
case Expression::IDENT:{
const std::string &ident = expression.getValueString();
Symbol s = scope->findSymbol(ident);
return Parent::processSymbol(s);
}
case Expression::COMPOUND:
break;
default: assert(false);
}
switch (expression.op) {
case Operator::EQU: {
const Expression& left = process(expression.operands[0]);
const Expression& right = process(expression.operands[1]);
if (left == right) return EXPRESSION_TRUE;
return EXPRESSION_FALSE;
}
case Operator::NE: {
const Expression& left = process(expression.operands[0]);
const Expression& right = process(expression.operands[1]);
if (left == right) return EXPRESSION_FALSE;
return EXPRESSION_TRUE;
}
case Operator::LOGIC_AND: {
assert(expression.operands.size() == 1);
return process (expression.operands[0]);
}
// case Operator::LOGIC_OR:
case Operator::CALL: {
const std::string &fnName = expression.getValueString();
ManagedFnPtr fnAst = this->function->man->ast->findFunction(fnName);
InterpretatonFunction* fnUnit = this->function->man->getFunction(fnAst);
vector<Expression> args;
args.reserve(expression.getOperands().size());
for(size_t i=0, size = expression.getOperands().size(); i<size; ++i) {
args.push_back(process(expression.getOperands()[i]));
}
return fnUnit->process(args);
}
case Operator::IF:{
CodeScope* scopeResult = processOperatorIf(expression);
return function->getScope(scopeResult)->processScope();
}
case Operator::SWITCH: {
CodeScope* scopeResult = processOperatorSwitch(expression);
return function->getScope(scopeResult)->processScope();
}
case Operator::INDEX: {
const Expression& exprKey = process(expression.operands[0]);
const Expression& exprData = processSymbol(scope->findSymbol(expression.getValueString()));
if (exprKey.__state == Expression::STRING){
const string& key = exprKey.getValueString();
assert(exprData.__indexBindings.count(key));
return exprData.operands[exprData.__indexBindings.at(key)];
}
if (exprKey.__state == Expression::NUMBER){
int key = exprKey.getValueDouble();
return exprData.operands[key];
}
assert(false);
}
case Operator::FOLD: {
const Expression& exprInput = process(expression.getOperands()[0]);
const Expression& exprInit = process(expression.getOperands()[1]);
const std::string& argEl = expression.bindings[0];
const std::string& argAccum = expression.bindings[1];
InterpretationScope* body = function->getScope(expression.blocks.front());
Expression accum = exprInit;
for(size_t size=exprInput.getOperands().size(), i=0; i<size; ++i){
body->bindArg(exprInput.getOperands()[i], argEl);
body->bindArg(accum, argAccum);
accum = body->processScope();
}
return accum;
}
// case Operator::MAP: {
// break;
// }
default: break;
}
return expression;
}
InterpretatonFunction::InterpretatonFunction(const ManagedFnPtr& function, Target<TargetInterpretation>* target)
: Function<TargetInterpretation>(function, target)
{}
Expression
InterpretatonFunction::process(const std::vector<Expression>& args){
InterpretationScope* body = getScope(__function->__entry);
for(size_t i=0, size = args.size(); i<size; ++i) {
body->bindArg(args.at(i), string(body->scope->__bindings.at(i)));
}
return body->processScope();
}
InterpretatonFunction*
TargetInterpretation::getFunction(const PIFSignature& sig){
return __functions.find(sig);
}
InterpretationScope*
TargetInterpretation::transformContext(const Context& c){
return this->getFunction(c.function->function)->getScope(c.scope->scope);
}
llvm::Value*
TargetInterpretation::transform(const Expression& expression, llvm::Value* raw, const Context& ctx){
return raw;
}
Expression
TargetInterpretation::transform(const Expression& expression, const Context& ctx){
return transformContext(ctx)->process(expression);
}
llvm::Value*
TargetInterpretation::compile(const Expression& expression, const Context& ctx){
return transformContext(ctx)->compile(expression, ctx);
}
bool
TargetInterpretation::isAcceptable(const Expression& expression){
const InterpretationData& data = Attachments::get<Expression, InterpretationData>(expression, {BOTH, NONE});
return (data.resolution == INTR_ONLY || data.op != InterpretationOperator::NONE);
}
}}
//Partial function interpretation
llvm::Value*
InterpretationScope::compilePartialFnCall(const Expression& expression, const Context& context){
const std::string &fnName = expression.getValueString();
ManagedFnPtr fnAst = this->function->man->ast->findFunction(fnName);
context.pass->getFunctionUnit(fnAst)
intrBody->bindArg(exprElement, nameEl);
unitBody->overrideDeclaration(symbolEl, move(exprElement));
}
class PartialInterpretationScopeDecorator(){
void compile(){
}
void findFunction(){
}
};
template<class Parent>
class PartialInterpretationFunctionDecorator: public Parent{
protected:
void recognizeArguments(){
argsReal.reserve(entry->__bindings.size());
for(size_t no=0, size=entry->__bindings.size(); no < size; ++no){
const std::string& argName = entry->__bindings[no];
const Expression& arg = entry->findDeclaration(entry->findSymbol(argName));
InterpretationResolution res = recognizeTags(arg.tags);
if (res != INTR_ONLY){
argsReal.push_back(arg);
}
}
}
std::vector<llvm::Type*> prepareArguments(){
std::vector<llvm::Type*> signature;
for(size_t no=0, size=argsReal.size(); no < size; ++no){
signature.push_back(llvm->toLLVMType(ast->expandType(argsReal[no].type)));
}
}
void prepareBindings(){
// bindings from argsReal
}
private:
std::vector<Expression> argsReal;
};
template<class Parent>
class PartialInterpretationCallStatement: public Parent {
PartialInterpretationCallStatement(){
}
}

Event Timeline