targets.h
No OneTemporary

File Metadata

Created
Thu, Jul 9, 8:10 AM

targets.h

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* File: targetabstract.h
* Author: pgess <v.melnychenko@xreate.org>
*
* Created on July 2, 2016, 1:25 PM
*/
/**
* \file
* \brief Compilation targets infrastructure
*/
#ifndef TARGETABSTRACT_H
#define TARGETABSTRACT_H
class Function;
#include "ast.h"
#include "pass/ipass.h"
//#include "targetinterpretation.h"
#include <boost/optional.hpp>
#include <map>
#include <list>
namespace xreate{
namespace compilation{
template <typename ConcreteTargetTag>
struct TargetInfo{
//public:
// typedef Result
// typedef Function
// typedef Scope
};
template<typename ConcreteTarget>
class Function;
template<typename ConcreteTarget>
class Target;
template<typename ConcreteTargetTag>
class Scope{
typedef typename TargetInfo<ConcreteTargetTag>::Scope Self;
public:
const CodeScope* scope;
Function<ConcreteTargetTag>* function = 0;
typename TargetInfo<ConcreteTargetTag>::Result
processSymbol(const Symbol& s){
const CodeScope* scope = s.scope;
Self* self = function->getScope(scope);
if(self->__bindings.count(s.identifier)){
return self->__bindings[s.identifier];
}
const Expression& declaration = CodeScope::getDefinition(s, true);
if(!declaration.isDefined()){
assert(false); //for bindings there should be result already
}
return self->__bindings[s.identifier] = self->process(declaration);
}
typename TargetInfo<ConcreteTargetTag>::Result
processScope(){
return process(scope->getBody());
}
virtual typename TargetInfo<ConcreteTargetTag>::Result
process(const Expression& expression) = 0;
Scope(const CodeScope* codeScope, Function<ConcreteTargetTag>* f)
: scope(codeScope), function(f){ }
virtual
~Scope(){ }
void
overrideBindings(std::list<std::pair<typename TargetInfo<ConcreteTargetTag>::Result, std::string>> bindings){
std::list < std::pair<typename TargetInfo<ConcreteTargetTag>::Result, ScopedSymbol>> bindingsSymbols;
for(auto entry: bindings){
assert(scope->__identifiers.count(entry.second));
ScopedSymbol id{scope->__identifiers.at(entry.second), versions::VERSION_NONE};
bindingsSymbols.push_back(std::make_pair(entry.first, id));
}
overrideBindings(bindingsSymbols);
}
void
overrideBindings(std::list<std::pair<typename TargetInfo<ConcreteTargetTag>::Result, ScopedSymbol>> bindings){
reset();
for(auto entry: bindings){
__bindings[entry.second] = entry.first;
}
}
bool
isBindingDefined(const ScopedSymbol& id){
return __bindings.count(id);
}
void
registerChildScope(std::shared_ptr<Self> scope){
__childScopes.push_back(scope);
}
void
reset(){
__bindings.clear();
__childScopes.clear();
}
protected:
std::map<ScopedSymbol, typename TargetInfo<ConcreteTargetTag>::Result> __bindings;
std::list<std::shared_ptr<Self>> __childScopes;
};
template<typename ConcreteTargetTag>
class Function{
typedef typename TargetInfo<ConcreteTargetTag>::Result Result;
typedef typename TargetInfo<ConcreteTargetTag>::Scope ConcreteScope;
public:
Function(const ManagedFnPtr& function, Target<ConcreteTargetTag>* target)
: __pass(target), __function(function){ }
virtual ~Function(){ };
virtual Result process(const std::vector<Result>& args) = 0;
ConcreteScope*
getScope(const CodeScope * const scope){
if(__scopes.count(scope)){
auto result = __scopes.at(scope).lock();
if(result){
return result.get();
}
}
std::shared_ptr<ConcreteScope> unit(new ConcreteScope(scope, this));
if(scope->__parent != nullptr){
getScope(scope->__parent)->registerChildScope(unit);
} else{
assert(!__entryScope);
__entryScope = unit;
}
if(!__scopes.emplace(scope, unit).second){
__scopes[scope] = unit;
}
return unit.get();
}
Target<ConcreteTargetTag>* __pass = 0;
protected:
ManagedFnPtr __function;
std::map<const CodeScope*, std::weak_ptr<ConcreteScope>> __scopes;
std::shared_ptr<ConcreteScope> __entryScope;
};
/** \brief Similar to xreate::IPass */
template<typename ConcreteTargetTag>
class Target: public IPass{
typedef typename TargetInfo<ConcreteTargetTag>::Function ConcreteFunction;
public:
Target(PassManager *manager): IPass(manager){ }
virtual ~Target(){
for(const auto& entry: __functions){
delete entry.second;
}
}
virtual void run() override {}
ConcreteFunction* getFunction(const ManagedFnPtr& function){
unsigned int id = function.id();
if(!__functions.count(id)){
ConcreteFunction* unit = new ConcreteFunction(function, this);
__functions.emplace(id, unit);
return unit;
}
return __functions.at(id);
}
protected:
std::map<unsigned int, ConcreteFunction*> __functions;
};
}
}
#endif /* TARGETABSTRACT_H */

Event Timeline