latereasoningpass.h
No OneTemporary

File Metadata

Created
Tue, Jul 7, 10:00 AM

latereasoningpass.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/.
*/
/*
* Author: pgess <v.melnychenko@xreate.org>
* Created on June 7, 2018, 7:20 PM
*
* \file latereasoningpass.h
* \brief latereasoningpass
*/
#ifndef LATEREASONINGPASS_H
#define LATEREASONINGPASS_H
#include "pass/dfapass.h"
namespace xreate { namespace latereasoning {
class LateReasoningScope{
public:
LateReasoningScope(LateReasoningScope* parent): __parent(parent){ }
boost::optional<LateSymbolRecognized>
recognizeIdentifier(const std::string& identifier){
//Search identifier in the current scope
if(__identifiers.count(identifier)){
return make_pair(identifier, __identifiers.at(identifier));
}
//Search in the parent scope
if(__parent){
return __parent->recognizeIdentifier(identifier);
}
return boost::none;
}
void
addIdentifier(std::string idenName, const SymbolPacked& identSymbol){
__identifiers.emplace(idenName, identSymbol);
}
private:
std::map<std::string, SymbolPacked> __identifiers;
LateReasoningScope *__parent;
};
/**
* \note Limitation: Produces late annotation with target as a symbol to which annotation is attached
*/
template<class Parent>
class LateReasoningDFAPassDecorator: public Parent{
public:
LateReasoningDFAPassDecorator(PassManager* manager): Parent(manager){ }
void
registerLateScope(CodeScope* scope, LateReasoningScope* scopeLate){
__dictScopes.emplace(scope, scopeLate);
}
private:
LateReasoningScope*
liftScope(const CodeScope* scope){
while(scope){
if(__dictScopes.count(scope)) return __dictScopes.at(scope);
scope = scope->__parent;
}
return nullptr;
}
std::list<LateSymbolRecognized>
recognizeLateIdentifiers(const Expression& expression, LateReasoningScope* scope){
std::list<LateSymbolRecognized> result;
switch(expression.op){
case Operator::CALL:
{
for(const auto& op: expression.operands){
std::list<LateSymbolRecognized> opResult = recognizeLateIdentifiers(op, scope);
result.insert(result.end(), opResult.begin(), opResult.end());
}
if(!expression.operands.size()){
if(auto symbolRecognized = scope->recognizeIdentifier(expression.getValueString())){
result.push_back(*symbolRecognized);
}
}
break;
}
case Operator::NEG:
{
assert(expression.operands.size() == 1);
const Expression &op = expression.operands.at(0);
std::list<LateSymbolRecognized> opResult = recognizeLateIdentifiers(op, scope);
result.insert(result.end(), opResult.begin(), opResult.end());
};
case Operator::INVALID:
{
switch(expression.__state){
case Expression::NUMBER:
break;
default:
assert(true);
}
break;
}
default: break;
}
return result;
}
protected:
virtual SymbolNode process(const Expression& expression, PassContext context, const std::string& varDecl="") override{
if(expression.__state == Expression::COMPOUND && expression.op == Operator::SWITCH_LATE){
//Reserve late scope:
LateReasoningScope* scopeLate = new LateReasoningScope(liftScope(context.scope));
CodeScope* scopeBody = expression.blocks.front();
registerLateScope(scopeBody, scopeLate);
//Assign late identifiers
for(const std::string& identLate: expression.bindings){
ScopedSymbol identLateS = scopeBody->getSymbol(identLate);
SymbolPacked identLateSP = Parent::man->transcend->pack(Symbol{identLateS, scopeBody});
scopeLate->addIdentifier(identLate, identLateSP);
}
}
return Parent::process(expression, context, varDecl);
}
virtual void
processAnnotations(const Expression& expression,
PassContext context,
const SymbolNode& ident){
LateReasoningScope* scopeLate = liftScope(context.scope);
if(!expression.tags.size() || !scopeLate)
return Parent::processAnnotations(expression, context, ident);
for(const std::pair<std::string, Expression>& tag: expression.tags){
std::list<LateSymbolRecognized> symbols = recognizeLateIdentifiers(tag.second, scopeLate);
if(!symbols.size()){
//Standard compilation
Parent::graph->printInplaceAnnotation(ident, tag.second);
} else{
//Late compilation
std::list<std::string> domains;
for(const auto& symbol: symbols){
Symbol symbolUnpacked = Parent::man->transcend->unpack(symbol.second);
ExpandedType typSymbol = Parent::man->root->getType(CodeScope::getDefinition(symbolUnpacked));
assert(typSymbol->__operator == TypeOperator::SLAVE);
domains.push_back(typSymbol->__valueCustom);
}
Parent::graph->printLateAnnotation(ident, tag.second, symbols, domains);
}
}
}
private:
std::unordered_map<const CodeScope*, LateReasoningScope*> __dictScopes;
};
}}
#endif /* LATEREASONINGPASS_H */

Event Timeline