targets.h
No OneTemporary

File Metadata

Created
Mon, Jul 6, 11:28 PM

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
#include "ast.h"
#include <boost/optional.hpp>
#include <map>
#include <list>
namespace xreate{
namespace compilation{
template <typename ConcreteTarget>
struct TargetInfo{
//typedef Result
//typedef Function
//typedef Scope
};
template<typename ConcreteTarget>
class Function;
template<typename ConcreteTarget>
class Target;
template<typename ConcreteTarget>
class Scope{
typedef typename TargetInfo<ConcreteTarget>::Scope Self;
public:
const CodeScope* scope;
Function<ConcreteTarget>* function = 0;
typename TargetInfo<ConcreteTarget>::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<ConcreteTarget>::Result
processScope(){
return process(scope->getBody());
}
// typename TargetInfo<ConcreteTarget>::Result
// processFunction(typename TargetInfo<ConcreteTarget>::Function* fnRemote, const std::vector<typename TargetInfo<ConcreteTarget>::Result>& args){
// Scope<ConcreteTarget> scopeRemote = fnRemote->getScope(fnRemote->__function->__entry);
//
// if (scopeRemote->raw){
// return scopeRemote->raw;
// }
//
// return fnRemote->process(args);
// }
virtual typename TargetInfo<ConcreteTarget>::Result
process(const Expression& expression) = 0;
Scope(const CodeScope* codeScope, Function<ConcreteTarget>* f)
: scope(codeScope), function(f){ }
virtual
~Scope(){ }
void
overrideBindings(std::list<std::pair<typename TargetInfo<ConcreteTarget>::Result, std::string>> bindings){
std::list < std::pair<typename TargetInfo<ConcreteTarget>::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<ConcreteTarget>::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<ConcreteTarget>::Result> __bindings;
std::list<std::shared_ptr<Self>> __childScopes;
};
template<typename ConcreteTarget>
class Function{
typedef typename TargetInfo<ConcreteTarget>::Result Result;
typedef typename TargetInfo<ConcreteTarget>::Scope ConcreteScope;
public:
Function(const ManagedFnPtr& function, Target<ConcreteTarget>* target)
: man(target), __function(function){ }
virtual
~Function(){ };
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();
}
virtual Result
process(const std::vector<Result>& args) = 0;
Target<ConcreteTarget>* man = 0;
ManagedFnPtr __function;
protected:
std::map<const CodeScope*, std::weak_ptr<ConcreteScope>> __scopes;
std::shared_ptr<ConcreteScope> __entryScope;
};
/** \brief Similar to xreate::IPass */
template<typename ConcreteTarget>
class Target{
typedef typename TargetInfo<ConcreteTarget>::Function ConcreteFunction;
public:
Target(AST* root): ast(root){ }
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);
}
AST* ast;
virtual
~Target(){
for(const auto& entry: __functions){
delete entry.second;
}
}
protected:
std::map<unsigned int, ConcreteFunction*> __functions;
};
}
}
#endif /* TARGETABSTRACT_H */

Event Timeline