abstractpass.h
No OneTemporary

File Metadata

Created
Wed, Jul 8, 7:06 AM

abstractpass.h

#ifndef ABSTRACTPASS_H
#define ABSTRACTPASS_H
#include "ast.h"
#include "passmanager.h"
#include<iostream>
namespace xreate
{
struct PassContext
{
CodeScope* scope = 0;
ManagedFnPtr function;
ManagedRulePtr rule;
std::string varDecl;
PassContext()
{}
PassContext&& updateScope(CodeScope* scopeNew) {
PassContext context2{*this};
context2.scope = scopeNew;
return std::move(context2);
}
~PassContext(){}
};
class AbstractPassBase {
public:
AbstractPassBase(PassManager* manager);
virtual void run()=0;
virtual void finish();
PassManager* man;
};
template<class Output>
Output defaultValue();
template<>
void defaultValue<void>();
template<class Output>
class SymbolCache: private std::map<Symbol, Output>{
public:
bool isCached(const Symbol& symbol){
return this->count(symbol);
}
Output setCachedValue(const Symbol& symbol, Output&& value){
(*this)[symbol] = value;
return value;
}
Output getCachedValue(const Symbol& symbol){
assert(this->count(symbol));
return this->at(symbol);
}
};
template<>
class SymbolCache<void>: private std::set<Symbol>{
public:
bool isCached(const Symbol& symbol){
bool result = this->count(symbol) > 0;
return result;
}
void setCachedValue(const Symbol& symbol){
this->insert(symbol);
}
void getCachedValue(const Symbol& symbol){
}
};
template<class Output>
class AbstractPass: public AbstractPassBase {
SymbolCache<Output> __visitedSymbols;
protected:
Output processSymbol(const Symbol& symbol, PassContext context, std::string hintSymbol=""){
if (__visitedSymbols.isCached(symbol))
return __visitedSymbols.getCachedValue(symbol);
const Expression& declaration = CodeScope::findDeclaration(symbol);
if (declaration.isDefined()){
PassContext context2 = context.updateScope(symbol.scope);
Output&& result = process(declaration, context2, ident);
return __visitedSymbols.setCachedValue(symbol, std::move(result));
}
return defaultValue<Output>();
}
Output processExpressionCall(const Expression& expression, PassContext context){
const std::string &calleeName = expression.getValueString();
std::list<ManagedFnPtr> callees = man->root->getFunctionVariants(calleeName);
if (callees.size() == 1 && callees.front()){
return processFnCall(callees.front(), context);
} else {
for (const ManagedFnPtr& callee: callees){
processFnCallUncertain(callee, context);
}
return defaultValue<Output>();
}
}
SymbolCache<Output>& getSymbolCache(){
return __visitedSymbols;
}
public:
AbstractPass(PassManager* manager)
: AbstractPassBase(manager){}
virtual Output processFnCall(ManagedFnPtr function, PassContext context){
return defaultValue<Output>();
}
virtual void processFnCallUncertain(ManagedFnPtr function, PassContext context)
{}
virtual void process(ManagedRulePtr rule)
{}
virtual Output process(ManagedFnPtr function)
{
PassContext context;
context.function = function;
return process(function->getEntryScope(), context);
}
virtual Output process(CodeScope* scope, PassContext context, const std::string& hintBlockDecl=""){
context.scope = scope;
return processSymbol(Symbol{ScopedSymbol::RetSymbol, scope}, context);
}
virtual Output process(const Expression& expression, PassContext context, const std::string& varDecl=""){
if (expression.__state == Expression::IDENT){
assert(context.scope);
return processSymbol(Attachments::get<Symbol>(expression), context, expression.getValueString());
}
assert(false);
return defaultValue<Output>();
}
void run() {
ManagedRulePtr rule = man->root->begin<MetaRuleAbstract>();
while (rule.isValid()) {
process(rule);
++rule;
}
ManagedFnPtr f = man->root->begin<Function>();
while (f.isValid()) {
process(f);
++f;
}
}
private:
template<>
void
AbstractPass<void>::processSymbol(const Symbol& symbol, PassContext context);
}
#endif
//PROCESS FUNCTION:
// const Symbol& symbolFunction{0, function->getEntryScope()};
//
// if (__visitedSymbols.isCached(symbolFunction))
// return __visitedSymbols.getCachedValue(symbolFunction);
//
// PassContext context;
// context.function = function;
//
// Output&& result = process(function->getEntryScope(), context);
// return __visitedSymbols.setCachedValue(symbolFunction, std::move(result));

Event Timeline