/* * ASTInspector.cpp * * Created on: Dec 17, 2012 * Author: att */ #include "ASTInspector.h" ASTInspector::ASTInspector() : number_of_visits(0), depth_level(0) { } ASTInspector::~ASTInspector() { } unsigned int ASTInspector::how_many_occurences_of(std::string type) { return this->occurences[type]; } void ASTInspector::visit(Visitable * node) { number_of_visits++; if(node->type == "ConstantExpression") { visit(static_cast(node)); } else if (node->type == "BasicExpression") { visit(static_cast(node)); } else if (node->type == "PostfixExpression") { visit(static_cast(node)); } else if (node->type == "WhileNode") { visit(static_cast(node)); } else if (node->type == "ProgramNode") { visit(static_cast(node)); } else if (node->type == "BasicStatement") { visit(static_cast(node)); } else if (node->type == "DeclarationStatement") { visit(static_cast(node)); } else if (node->type == "VariableExpression") { visit(static_cast(node)); } else if (node->type == "Assignment") { visit(static_cast(node)); } else if (node->type == "IfNode") { visit(static_cast(node)); } else if (node->type == "RepeatStatement") { visit(static_cast(node)); } else if (node->type == "IncorrectExpression") { visit(static_cast(node)); } else { std::cout << "Visiting unknown node" << std::endl; } } void ASTInspector::visit(ConstantExpression * constant_expression) { this->occurences["ConstantExpression"]++; depth_level++; std::string visit_notes = ""; visit_notes += "Constant expression of value:\n"; visit_notes += constant_expression->value.repr() + "\n"; visit_notes += "End of ConstantExpression"; write_report(visit_notes); depth_level--; } void ASTInspector::forget_everything() { depth_level = 0; inspection_report = ""; occurences.clear(); number_of_visits = 0; } void ASTInspector::visit(BasicExpression * basic_expression) { this->occurences["BasicExpression"]++; depth_level++; std::string visit_notes = ""; visit_notes += "Basic expression:\n"; visit_notes += "Executing " + basic_expression->get_operator() + " on:\n"; write_report(visit_notes); basic_expression->children[0]->accept(this); basic_expression->children[1]->accept(this); write_report("End of BasicExpression\n"); depth_level--; } void ASTInspector::visit(PostfixExpression * postfix_expression) { this->occurences["PostfixExpression"]++; depth_level++; std::string visit_notes = ""; visit_notes += "Postfix expression:\n"; visit_notes += postfix_expression->name; visit_notes += " operating on arguments:\n"; write_report(visit_notes); for(auto argument : postfix_expression->arguments) { argument->accept(this); } write_report("End of postfix expression\n"); depth_level--; } void ASTInspector::visit(WhileNode * while_node) { this->occurences["WhileNode"]++; depth_level++; std::string visit_notes = ""; visit_notes += "WhileNode:\n"; write_report(visit_notes); for(auto child: while_node->children) { child->accept(this); } while_node->body->accept(this); write_report("End of while node\n"); depth_level--; } void ASTInspector::visit(ProgramNode * program) { this->occurences["ProgramNode"]++; std::cout << "Visiting ProgramNode" << std::endl; depth_level++; std::string visit_notes = ""; visit_notes += "ProgramNode:\n"; write_report(visit_notes); for(auto child: program->children) { child->accept(this); } write_report("End of ProgramNode\n"); depth_level--; } void ASTInspector::visit(BasicStatement * basic_statement) { this->occurences["BasicStatement"]++; depth_level++; std::string visit_notes = ""; visit_notes += "BasicStatement:\n"; write_report(visit_notes); for(auto child: basic_statement->children) { child->accept(this); } write_report("End of BasicStatement\n"); depth_level--; } void ASTInspector::visit(DeclarationStatement * declaration_statement) { this->occurences["DeclarationStatement"]++; depth_level++; std::string visit_notes = ""; visit_notes += "DeclarationStatement:\n"; visit_notes += "It declares: " + declaration_statement->name + "to be:\n"; visit_notes += declaration_statement->right_value.repr(); write_report(visit_notes); write_report("End of DeclarationStatement\n"); depth_level--; } void ASTInspector::visit(Assignment * assignment) { this->occurences["Assignment"]++; depth_level++; std::string visit_notes = ""; visit_notes += "Assignment:\n"; visit_notes += "It assigns to: " + assignment->name + " expression:\n"; write_report(visit_notes); assignment->children[1]->accept(this); write_report("End of DeclarationStatement\n"); depth_level--; } void ASTInspector::visit(IfNode * if_node) { this->occurences["IfNode"]++; depth_level++; std::string visit_notes = ""; visit_notes += "IfNode:\n"; visit_notes += "checks condition:"; write_report(visit_notes); if_node->condition()->accept(this); write_report("if above is true, it executes:"); if_node->then_block()->accept(this); if(if_node->is_else) { write_report("if it's not, it executes:"); if_node->else_block()->accept(this); } write_report("End of IfNode\n"); depth_level--; } void ASTInspector::visit(IncorrectExpression * incorrect_expression) { this->occurences["IncorrectExpression"]++; depth_level++; std::string visit_notes = ""; visit_notes += "IncorrectExpression:\n"; visit_notes += incorrect_expression->error_message; write_report(visit_notes); write_report("End of IncorrectExpression\n"); depth_level--; } void ASTInspector::visit(RepeatStatement * repeat_statement) { this->occurences["RepeatStatement"]++; depth_level++; std::string visit_notes = ""; visit_notes += "RepeatStatement:\n"; visit_notes += "It executes " + to_string(repeat_statement->how_many_times) + "times\n"; write_report(visit_notes); repeat_statement->body->accept(this); write_report("End of RepeatStatement\n"); depth_level--; } void ASTInspector::visit(VariableExpression * variable) { this->occurences["VariableExpression"]++; depth_level++; std::string visit_notes = ""; visit_notes += "VariableExpression:\n"; visit_notes += "Name: " + variable->name + "\n"; write_report(visit_notes); write_report("End of VariableExpression\n"); depth_level--; } void ASTInspector::write_report(std::string visit_notes) { std::istringstream stream(visit_notes); std::string line; std::string correct_indentation = compute_indent(); while(std::getline(stream, line)) { inspection_report += correct_indentation + line + "\n"; } } std::string ASTInspector::compute_indent() { std::string indentation = ""; std::string basic_indent = " "; for(unsigned int i = 0; i < depth_level; i++) { indentation += basic_indent; } return indentation; }