Project

General

Profile

/**
*
* OOAS Compiler - C++ AST
*
* Copyright 2015, AIT Austrian Institute of Technology.
* All rights reserved.
*
* SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
*
* If you modify the file please update the list of contributors below to in-
* clude your name. Please also stick to the coding convention of using TABs
* to do the basic (block-level) indentation and spaces for anything after
* that. (Enable the display of special chars and it should be pretty obvious
* what this means.) Also, remove all trailing whitespace.
*
* Contributors:
* Willibald Krenn (AIT)
* Stephan Zimmerer (AIT)
* Christoph Czurda (AIT)
*
*/



/*
* CompleteAstTraversalVisitor.cpp
*
* Created on: Dec 28, 2013
* Author: willibald
*/

#include "CompleteAstTraversalVisitor.hpp"
#include <ast/identifiers/EnumIdentifier.hpp>
#include <ast/identifiers/AttributeIdentifier.hpp>
#include <ast/identifiers/ExpressionVariableIdentifier.hpp>
#include <ast/identifiers/MethodIdentifier.hpp>
#include <ast/identifiers/ConstantIdentifier.hpp>
#include <ast/identifiers/NamedActionIdentifier.hpp>
#include <ast/identifiers/MainModule.hpp>
#include <ast/identifiers/IdentifierBlock.hpp>
#include <ast/statements/NondetBlock.hpp>
#include <ast/statements/PrioBlock.hpp>
#include <ast/statements/SeqBlock.hpp>
#include <ast/statements/Assignment.hpp>
#include <ast/statements/GuardedCommand.hpp>
#include <ast/statements/Call.hpp>
#include <ast/expressions/IdentifierExpression.hpp>
#include <ast/expressions/TypeExpression.hpp>
#include <ast/expressions/ListConstructor.hpp>
#include <ast/expressions/SetConstructor.hpp>
#include <ast/expressions/TupleConstructor.hpp>
#include <ast/expressions/AccessExpression.hpp>
#include <ast/expressions/BinaryOperator.hpp>
#include <ast/expressions/TernaryOperator.hpp>
#include <ast/expressions/TupleMapAccessExpression.hpp>
#include <ast/expressions/CallExpression.hpp>
#include <ast/expressions/ForallQuantifier.hpp>
#include <ast/expressions/ExistsQuantifier.hpp>
#include <ast/expressions/UnaryOperator.hpp>
#include <ast/types/EnumType.hpp>
#include <ast/types/ListType.hpp>
#include <ast/types/TupleType.hpp>
#include <ast/types/FunctionType.hpp>
#include <ast/types/ActionSystemType.hpp>
#include <ast/expressions/ObjectConstructor.hpp>


namespace Ast {

CompleteAstTraversalVisitor::CompleteAstTraversalVisitor(CallContext* context, bool duplicateVisit):
m_visited(),
m_context(context),
m_DuplicateVisit(duplicateVisit)
{}

CompleteAstTraversalVisitor::~CompleteAstTraversalVisitor()
{}


void CompleteAstTraversalVisitor::visitSub(AstElement* subElement, AstElement* parent) {
if (subElement == nullptr)
return;
if (m_visited.count(subElement) > 0)
return;
if (!m_DuplicateVisit)
m_visited[subElement] = true;
visitAstElement(subElement, parent);
}

void CompleteAstTraversalVisitor::visitAstElement(AstElement* element, AstElement* parent){
switch (element->nodeType()) {
case AstNodeTypeEnum::type:
visitType(static_cast<Type*>(element), parent);
break;
case AstNodeTypeEnum::identifier:
visitIdentifier((Identifier*)element, parent);
break;
case AstNodeTypeEnum::expression:
visitExpression((Expression*)element, parent);
break;
case AstNodeTypeEnum::statement:
visitStatement((Statement*)element, parent);
break;
default:
m_context->logError("Internal error. Unknown AST type.");
abort();
}
}


void CompleteAstTraversalVisitor::visitType(Type* element, AstElement* ) {
element->accept(*this); // could be replaced by direct switch here..
}

void CompleteAstTraversalVisitor::visitIdentifier(Identifier* element, AstElement* ) {
element->accept(*this); // could be replaced by direct switch here..
}

void CompleteAstTraversalVisitor::visitExpression(Expression* element, AstElement* ) {
element->accept(*this); // could be replaced by direct switch here..
}

void CompleteAstTraversalVisitor::visitStatement(Statement* element, AstElement* ) {
element->accept(*this); // could be replaced by direct switch here..
}

void CompleteAstTraversalVisitor::visit(TypeIdentifier* typeIdentifier) {
visitSub(typeIdentifier->type(), typeIdentifier);
};

void CompleteAstTraversalVisitor::visit(EnumIdentifier* enumIdentifier) {
visitSub(enumIdentifier->type(), enumIdentifier);
};

//void CompleteAstTraversalVisitor::visit(ValuedEnumIdentifier* enumIdentifier) {};

void CompleteAstTraversalVisitor::visit(AttributeIdentifier* attributeIdentifier) {
visitSub(attributeIdentifier->type(), attributeIdentifier);
visitSub(attributeIdentifier->initializer(), attributeIdentifier);
};

void CompleteAstTraversalVisitor::visit(LocalVariableIdentifier* localVariableIdentifier) {
visitSub(localVariableIdentifier->type(), localVariableIdentifier);
};

void CompleteAstTraversalVisitor::visit(ParameterIdentifier* parameterIdentifier) {
visitSub(parameterIdentifier->type(), parameterIdentifier);
};

void CompleteAstTraversalVisitor::visit(ExpressionVariableIdentifier* expressionVariableIdentifier) {
visitSub(expressionVariableIdentifier->type(), expressionVariableIdentifier);
};

void CompleteAstTraversalVisitor::visit(MethodIdentifier* methodIdentifier) {
visitSub(methodIdentifier->type(), methodIdentifier);
for (auto& sym: *(methodIdentifier->symbolTable()))
visitSub(sym.second, methodIdentifier);
for (auto& par: methodIdentifier->parameter())
visitSub(par, methodIdentifier);
visitSub(methodIdentifier->body(), methodIdentifier);
};

void CompleteAstTraversalVisitor::visit(NamedActionIdentifier* namedActionIdentifier) {
visitSub(namedActionIdentifier->type(), namedActionIdentifier);
for (auto& sym : *namedActionIdentifier->symbolTable())
visitSub(sym.second, namedActionIdentifier);
for (auto& par: namedActionIdentifier->parameter())
visitSub(par, namedActionIdentifier);
visitSub(namedActionIdentifier->body(), namedActionIdentifier);
};

void CompleteAstTraversalVisitor::visit(Module* module) {
for (auto& sym: *module->symbolTable())
visitSub(sym.second, module);
};

void CompleteAstTraversalVisitor::visit(ConstantIdentifier* constantIdentifier) {
visitSub(constantIdentifier->type(), constantIdentifier);
visitSub(constantIdentifier->value(), constantIdentifier);
};

void CompleteAstTraversalVisitor::visit(UnspecIdentifierBlock* unspecIdentifierList) {
for (auto& id: unspecIdentifierList->identifiers())
visitSub(id, unspecIdentifierList);
};

void CompleteAstTraversalVisitor::visit(SeqIdentifierBlock* seqIdentifierList) {
for (auto& id: seqIdentifierList->identifiers())
visitSub(id, seqIdentifierList);
};

void CompleteAstTraversalVisitor::visit(NondetIdentifierBlock* nondetIdentifierList) {
for (auto& id: nondetIdentifierList->identifiers())
visitSub(id, nondetIdentifierList);
};

void CompleteAstTraversalVisitor::visit(PrioIdentifierBlock* prioIdentifierList) {
for (auto& id: prioIdentifierList->identifiers())
visitSub(id, prioIdentifierList);
};

void CompleteAstTraversalVisitor::visit(MainModule* mainModule) {
for (auto& sym: *mainModule->symbolTable())
visitSub(sym.second, mainModule);
visitSub(mainModule->systemDescription(), mainModule);
};

void CompleteAstTraversalVisitor::visit(IntType* ) {};
void CompleteAstTraversalVisitor::visit(BoolType* ) {};

void CompleteAstTraversalVisitor::visit(EnumType* enumType) {
for (auto& sym: enumType->listOfEnumSymbols())
visitSub(sym, enumType);
};

void CompleteAstTraversalVisitor::visit(ListType* listType) {
visitSub(listType->innerType(), listType);
};

void CompleteAstTraversalVisitor::visit(TupleType* tupleType) {
for (auto& t: tupleType->innerTypes())
visitSub(t, tupleType);
};

void CompleteAstTraversalVisitor::visit(NullType* ) {};

void CompleteAstTraversalVisitor::visit(FunctionType* functionType) {
for (auto& a: functionType->parameter())
visitSub(a, functionType);
visitSub(functionType->returnType(), functionType);
};

void CompleteAstTraversalVisitor::visit(ActionSystemType* actionSystemType) {
for (auto& s: *actionSystemType->symbols())
visitSub(s.second, actionSystemType);

visitSub(actionSystemType->doodBlock(), actionSystemType);
};

void CompleteAstTraversalVisitor::visit(GuardedCommand* guardedCommand) {
visitSub(guardedCommand->guard(), guardedCommand);
visitSub(guardedCommand->body(), guardedCommand);
};

void CompleteAstTraversalVisitor::visit(Call* call) {
visitSub(call->callExpression(), call);
};

void CompleteAstTraversalVisitor::visit(Assignment* assignment) {
for (auto& vexp: assignment->places())
visitSub(vexp, assignment);
for (auto& expr: assignment->values())
visitSub(expr, assignment);

visitSub(assignment->nondetExpression(), assignment);
};

void CompleteAstTraversalVisitor::visit(SeqBlock* seqBlock) {
for (auto& id: *seqBlock->symbols())
visitSub(id.second, seqBlock);

if (seqBlock->filter() != nullptr)
visitSub(seqBlock->filter(), seqBlock);

for (auto& stmnt: seqBlock->statements())
visitSub(stmnt, seqBlock);
};

void CompleteAstTraversalVisitor::visit(NondetBlock* nondetBlock) {
for (auto& id: *nondetBlock->symbols())
visitSub(id.second, nondetBlock);

for (auto& stmnt: nondetBlock->statements())
visitSub(stmnt, nondetBlock);
};

void CompleteAstTraversalVisitor::visit(PrioBlock* prioBlock) {
for (auto& id: *prioBlock->symbols())
visitSub(id.second, prioBlock);

for (auto& stmnt: prioBlock->statements())
visitSub(stmnt, prioBlock);
};

void CompleteAstTraversalVisitor::visit(Skip* ) {};
void CompleteAstTraversalVisitor::visit(Break* ) {};
void CompleteAstTraversalVisitor::visit(Abort* ) {};

void CompleteAstTraversalVisitor::visit(TernaryOperator* ternaryOperator) {
visitSub(ternaryOperator->left(), ternaryOperator);
visitSub(ternaryOperator->mid(), ternaryOperator);
visitSub(ternaryOperator->right(), ternaryOperator);
};

void CompleteAstTraversalVisitor::visit(BinaryOperator* binaryOperator) {
visitSub(binaryOperator->left(), binaryOperator);
visitSub(binaryOperator->right(), binaryOperator);
};

void CompleteAstTraversalVisitor::visit(UnaryOperator* unaryOperator) {
visitSub(unaryOperator->child(), unaryOperator);
if (unaryOperator->kind() == ExpressionKind::Cast)
visitSub(unaryOperator->type(), unaryOperator);
};

void CompleteAstTraversalVisitor::visit(ExistsQuantifier* quantifier) {
for (auto& lvar: *quantifier->symbols())
visitSub(lvar.second, quantifier);

visitSub(quantifier->child(), quantifier);
};

void CompleteAstTraversalVisitor::visit(ForallQuantifier* quantifier) {
for (auto& lvar: *quantifier->symbols())
visitSub(lvar.second, quantifier);

visitSub(quantifier->child(), quantifier);
};

void CompleteAstTraversalVisitor::visit(ListConstructor* listConstructor) {
for (auto& lvar: *listConstructor->comprehensionVariables())
visitSub(lvar.second, listConstructor);

for (auto& elems: listConstructor->elements())
visitSub(elems, listConstructor);

visitSub(listConstructor->comprehension(), listConstructor);
};

void CompleteAstTraversalVisitor::visit(SetConstructor* setConstructor) {
for (auto& svar: *setConstructor->comprehensionVariables())
visitSub(svar.second, setConstructor);

for (auto& elems: setConstructor->items())
visitSub(elems, setConstructor);

visitSub(setConstructor->comprehension(), setConstructor);
};

void CompleteAstTraversalVisitor::visit(TupleConstructor* tupleConstructor) {
for (auto& elem: tupleConstructor->values())
visitSub(elem, tupleConstructor);
};

void CompleteAstTraversalVisitor::visit(ObjectConstructor* objectConstructor) {
visitSub(objectConstructor->type(), objectConstructor);
};

void CompleteAstTraversalVisitor::visit(BoolValueExpression* ) {};
void CompleteAstTraversalVisitor::visit(IntValueExpression* ) {};
void CompleteAstTraversalVisitor::visit(RefValueExpression* ) {};

void CompleteAstTraversalVisitor::visit(IdentifierExpression* identifierExpression) {
visitSub(identifierExpression->type(), identifierExpression);
visitSub(identifierExpression->identifier(), identifierExpression);
};

void CompleteAstTraversalVisitor::visit(TypeExpression* typeExpression) {
visitSub(typeExpression->type(), typeExpression);
};

void CompleteAstTraversalVisitor::visit(TupleMapAccessExpression* tupleMapAccessExpression) {
visitSub(tupleMapAccessExpression->argument(), tupleMapAccessExpression);
visitSub(tupleMapAccessExpression->child(), tupleMapAccessExpression);
};

void CompleteAstTraversalVisitor::visit(CallExpression* callExpression) {
for (auto& arg: callExpression->arguments())
visitSub(arg, callExpression);
visitSub(callExpression->child(), callExpression);
};

void CompleteAstTraversalVisitor::visit(AccessExpression* accessExpression) {
visitSub(accessExpression->left(), accessExpression);
visitSub(accessExpression->right(), accessExpression);
};

void CompleteAstTraversalVisitor::visit(PointerType* ) {

}

} /* namespace Ast */
(7-7/23)