Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F3995406
targetinterpretation.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Tue, Jul 7, 7:32 AM
Size
10 KB
Mime Type
text/x-c++
Expires
Thu, Jul 9, 7:32 AM (15 h, 47 m)
Engine
blob
Format
Raw Data
Handle
271584
Attached To
rXR Xreate
targetinterpretation.cpp
View Options
/*
* 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
Log In to Comment