abstractpass.h
No OneTemporary

File Metadata

Created
Wed, Jul 8, 9:14 AM

abstractpass.h

#ifndef ABSTRACTPASS_H
#define ABSTRACTPASS_H
#include "ast.h"
#include "passmanager.h"
#include<iostream>
using namespace std;
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 PassManager;
class AbstractPassBase {
public:
AbstractPassBase(PassManager* manager);
virtual void run()=0;
virtual void finish();
PassManager* man;
};
template<class Output>
class AbstractPass: public AbstractPassBase {
private:
std::set<Symbol> __visitedSymbols;
public:
AbstractPass(PassManager* manager): AbstractPassBase(manager) {}
//NOTE implement processFnCall
virtual void processFnCall(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 process(scope->__body, context);
}
virtual Output process(const Expression& expression, PassContext context, const std::string& varDecl=""){
switch (expression.__state) {
case Expression::COMPOUND:
for (const Expression &op: expression.getOperands()) {
process(op, context);
}
assert(expression.op != Operator::MAP || expression.op == Operator::MAP && expression.blocks.size());
for (CodeScope* scope: expression.blocks) {
process(scope, context);
}
/*
if (expression.op == Operator::CALL) {
const std::string &calleeName = expression.getValueString();
ManagedFnPtr callee = root->findFunction(calleeName);
}
*/
break;
case Expression::IDENT:
assert(context.scope);
std::string ident = expression.getValueString();
const Symbol& symbol = context.scope->findSymbol(ident);
if (__visitedSymbols.count(symbol)) {break;}
__visitedSymbols.insert(symbol);
PassContext context2 = context;
context2.scope = symbol.scope;
if (CodeScope::hasDeclaration(symbol)) {
process(CodeScope::findDeclaration(symbol), context2, ident);
}
break;
}
}
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;
}
}
};
}
#endif

Event Timeline