mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-25 11:22:55 +00:00
907 lines
18 KiB
C++
907 lines
18 KiB
C++
/*
|
|
Copyright 2008 Hamish Rodda <rodda@kde.org>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "codegenerator.h"
|
|
|
|
#include "tokens.h"
|
|
#include "lexer.h"
|
|
#include "parsesession.h"
|
|
|
|
/*
|
|
|
|
Thoughts.
|
|
- tokens are actually the position in the token stream, whose position can be determined, and thus replaced.
|
|
- we need to be able to make changes where there are changes [todo], or generate directly when it's a new node [done]
|
|
|
|
*/
|
|
|
|
CodeGenerator::CodeGenerator(ParseSession* session)
|
|
: m_output(&m_outputString)
|
|
, m_session(session)
|
|
{
|
|
}
|
|
|
|
CodeGenerator::~CodeGenerator()
|
|
{
|
|
}
|
|
|
|
QString CodeGenerator::output()
|
|
{
|
|
m_output.flush();
|
|
return m_outputString;
|
|
}
|
|
|
|
void CodeGenerator::outputToken(uint tokenPosition)
|
|
{
|
|
if (tokenPosition) {
|
|
const Token& t = m_session->token_stream->token(tokenPosition);
|
|
m_output << m_session->token_stream->symbolString(t);
|
|
|
|
/* if (t.kind == Token_identifier || t.kind == Token_string_literal || t.kind == Token_number_literal || t.kind == Token_char_literal)
|
|
m_output << t.symbolString().str();
|
|
else
|
|
m_output << token_text( t.kind );*/
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::print(const ListNode<uint>* tokenList, bool followingSpace)
|
|
{
|
|
if (!tokenList)
|
|
return;
|
|
|
|
const ListNode<uint>* it = tokenList->toFront(), *end = it;
|
|
bool first = true;
|
|
do {
|
|
if (first) first = false; else m_output << " ";
|
|
outputToken(it->element);
|
|
it = it->next;
|
|
} while (it != end);
|
|
|
|
if (followingSpace)
|
|
m_output << " ";
|
|
}
|
|
|
|
void CodeGenerator::print(uint token, bool followingSpace)
|
|
{
|
|
if (!token)
|
|
return;
|
|
|
|
outputToken(token);
|
|
if (followingSpace)
|
|
m_output << " ";
|
|
}
|
|
|
|
void CodeGenerator::printToken(int token, bool followingSpace)
|
|
{
|
|
m_output << token_text(token);
|
|
if (followingSpace)
|
|
m_output << " ";
|
|
}
|
|
|
|
|
|
void CodeGenerator::visitAccessSpecifier(AccessSpecifierAST* node)
|
|
{
|
|
print(node->specs);
|
|
m_output << ":";
|
|
}
|
|
|
|
void CodeGenerator::visitAsmDefinition(AsmDefinitionAST* node)
|
|
{
|
|
print(node->cv);
|
|
|
|
DefaultVisitor::visitAsmDefinition(node);
|
|
}
|
|
|
|
void CodeGenerator::visitBaseClause(BaseClauseAST* node)
|
|
{
|
|
m_output << ":";
|
|
|
|
commaPrintNodes(this, node->base_specifiers);
|
|
}
|
|
|
|
void CodeGenerator::visitBaseSpecifier(BaseSpecifierAST* node)
|
|
{
|
|
if (node->virt) {
|
|
print(node->virt, true);
|
|
}
|
|
|
|
print(node->access_specifier, true);
|
|
|
|
DefaultVisitor::visitBaseSpecifier(node);
|
|
}
|
|
|
|
void CodeGenerator::visitBinaryExpression(BinaryExpressionAST* node)
|
|
{
|
|
visit(node->left_expression);
|
|
|
|
// TODO whitespace
|
|
print(node->op);
|
|
|
|
visit(node->right_expression);
|
|
}
|
|
|
|
void CodeGenerator::visitBracedInitList(BracedInitListAST* node)
|
|
{
|
|
m_output << "{";
|
|
visit(node->list);
|
|
m_output << "}";
|
|
}
|
|
|
|
void CodeGenerator::visitCastExpression(CastExpressionAST* node)
|
|
{
|
|
m_output << "(";
|
|
visit(node->type_id);
|
|
m_output << ")";
|
|
visit(node->expression);
|
|
}
|
|
|
|
void CodeGenerator::visitClassMemberAccess(ClassMemberAccessAST* node)
|
|
{
|
|
print(node->op);
|
|
DefaultVisitor::visitClassMemberAccess(node);
|
|
}
|
|
|
|
void CodeGenerator::visitClassSpecifier(ClassSpecifierAST* node)
|
|
{
|
|
print(node->class_key, true);
|
|
|
|
visit(node->win_decl_specifiers);
|
|
visit(node->name);
|
|
visit(node->base_clause);
|
|
|
|
m_output << "{";
|
|
|
|
visitNodes(this, node->member_specs);
|
|
|
|
m_output << "}";
|
|
}
|
|
|
|
void CodeGenerator::visitCompoundStatement(CompoundStatementAST* node)
|
|
{
|
|
m_output << "{";
|
|
|
|
DefaultVisitor::visitCompoundStatement(node);
|
|
|
|
m_output << "}";
|
|
}
|
|
|
|
void CodeGenerator::visitCondition(ConditionAST* node)
|
|
{
|
|
if (node->declarator) {
|
|
visit(node->type_specifier);
|
|
visit(node->declarator);
|
|
|
|
m_output << "=";
|
|
}
|
|
|
|
visit(node->expression);
|
|
}
|
|
|
|
void CodeGenerator::visitConditionalExpression(ConditionalExpressionAST* node)
|
|
{
|
|
visit(node->condition);
|
|
|
|
m_output << "?";
|
|
|
|
visit(node->left_expression);
|
|
|
|
m_output << ":";
|
|
|
|
visit(node->right_expression);
|
|
}
|
|
|
|
void CodeGenerator::visitCppCastExpression(CppCastExpressionAST* node)
|
|
{
|
|
print(node->op);
|
|
|
|
m_output << "<";
|
|
|
|
visit(node->type_id);
|
|
|
|
m_output << ">(";
|
|
|
|
visit(node->expression);
|
|
|
|
m_output << ")";
|
|
|
|
visitNodes(this, node->sub_expressions);
|
|
}
|
|
|
|
void CodeGenerator::visitCtorInitializer(CtorInitializerAST* node)
|
|
{
|
|
m_output << ":";
|
|
|
|
visitCommaPrint(node->member_initializers);
|
|
}
|
|
|
|
void CodeGenerator::visitDeclarationStatement(DeclarationStatementAST* node)
|
|
{
|
|
DefaultVisitor::visitDeclarationStatement(node);
|
|
}
|
|
|
|
void CodeGenerator::visitDeclarator(DeclaratorAST* node)
|
|
{
|
|
if (node->sub_declarator) {
|
|
m_output << "(";
|
|
visit(node->sub_declarator);
|
|
m_output << ")";
|
|
}
|
|
|
|
visitNodes(this, node->ptr_ops);
|
|
visit(node->id);
|
|
|
|
if (node->bit_expression) {
|
|
m_output << ":";
|
|
visit(node->bit_expression);
|
|
}
|
|
|
|
surroundPrintNodes(this, node->array_dimensions, "[", "]");
|
|
|
|
if (node->parameter_declaration_clause) {
|
|
m_output << "(";
|
|
visit(node->parameter_declaration_clause);
|
|
m_output << ")";
|
|
}
|
|
|
|
print(node->fun_cv, true);
|
|
|
|
visit(node->exception_spec);
|
|
}
|
|
|
|
void CodeGenerator::visitDeleteExpression(DeleteExpressionAST* node)
|
|
{
|
|
print( node->scope_token );
|
|
print( node->delete_token );
|
|
print( node->lbracket_token );
|
|
print( node->rbracket_token );
|
|
|
|
m_output << " ";
|
|
|
|
DefaultVisitor::visitDeleteExpression(node);
|
|
}
|
|
|
|
void CodeGenerator::visitDoStatement(DoStatementAST* node)
|
|
{
|
|
printToken( Token_do, true );
|
|
|
|
visit(node->statement);
|
|
|
|
printToken( Token_while );
|
|
m_output << "(";
|
|
|
|
visit(node->expression);
|
|
|
|
m_output << ");";
|
|
}
|
|
|
|
void CodeGenerator::visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST* node)
|
|
{
|
|
print(node->type, true);
|
|
|
|
DefaultVisitor::visitElaboratedTypeSpecifier(node);
|
|
}
|
|
|
|
void CodeGenerator::visitEnumSpecifier(EnumSpecifierAST* node)
|
|
{
|
|
printToken(Token_enum, true);
|
|
|
|
visit(node->name);
|
|
|
|
if (node->enumerators) {
|
|
m_output << "{";
|
|
visitCommaPrint(node->enumerators);
|
|
m_output << "}";
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitEnumerator(EnumeratorAST* node)
|
|
{
|
|
print(node->id);
|
|
|
|
if (node->expression) {
|
|
m_output << "=";
|
|
|
|
visit(node->expression);
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitExceptionSpecification(ExceptionSpecificationAST* node)
|
|
{
|
|
if (node->no_except)
|
|
{
|
|
printToken(Token_noexcept);
|
|
|
|
if (node->noexcept_expression)
|
|
{
|
|
m_output << "(";
|
|
|
|
DefaultVisitor::visitExceptionSpecification(node);
|
|
|
|
m_output << ")";
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
printToken(Token_throw);
|
|
|
|
m_output << "(";
|
|
|
|
print(node->ellipsis);
|
|
|
|
DefaultVisitor::visitExceptionSpecification(node);
|
|
|
|
m_output << ")";
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitExpressionOrDeclarationStatement(ExpressionOrDeclarationStatementAST* node)
|
|
{
|
|
DefaultVisitor::visitExpressionOrDeclarationStatement(node);
|
|
}
|
|
|
|
void CodeGenerator::visitExpressionStatement(ExpressionStatementAST* node)
|
|
{
|
|
DefaultVisitor::visitExpressionStatement(node);
|
|
m_output << ";";
|
|
}
|
|
|
|
void CodeGenerator::visitForStatement(ForStatementAST* node)
|
|
{
|
|
printToken(Token_for);
|
|
m_output << "(";
|
|
if (node->range_declaration) {
|
|
visit(node->range_declaration);
|
|
m_output << " : ";
|
|
} else {
|
|
if (node->init_statement) {
|
|
visit(node->init_statement);
|
|
// Init statement gives its own ;
|
|
} else {
|
|
m_output << ";";
|
|
}
|
|
|
|
visit(node->condition);
|
|
m_output << ";";
|
|
}
|
|
|
|
visit(node->expression);
|
|
m_output << ")";
|
|
visit(node->statement);
|
|
}
|
|
|
|
void CodeGenerator::visitFunctionCall(FunctionCallAST* node)
|
|
{
|
|
m_output << "(";
|
|
DefaultVisitor::visitFunctionCall(node);
|
|
m_output << ")";
|
|
}
|
|
|
|
void CodeGenerator::visitFunctionDefinition(FunctionDefinitionAST* node)
|
|
{
|
|
visit(node->type_specifier);
|
|
visit(node->declarator);
|
|
visit(node->constructor_initializers);
|
|
visit(node->function_body);
|
|
visit(node->win_decl_specifiers);
|
|
}
|
|
|
|
void CodeGenerator::visitIfStatement(IfStatementAST* node)
|
|
{
|
|
printToken(Token_if);
|
|
|
|
m_output << "(";
|
|
visit(node->condition);
|
|
m_output << ")";
|
|
|
|
visit(node->statement);
|
|
|
|
if (node->else_statement) {
|
|
printToken(Token_else, true);
|
|
visit(node->else_statement);
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitIncrDecrExpression(IncrDecrExpressionAST* node)
|
|
{
|
|
print(node->op);
|
|
}
|
|
|
|
void CodeGenerator::visitInitDeclarator(InitDeclaratorAST* node)
|
|
{
|
|
DefaultVisitor::visitInitDeclarator(node);
|
|
}
|
|
|
|
void CodeGenerator::visitInitializer(InitializerAST* node)
|
|
{
|
|
if (node->initializer_clause) {
|
|
m_output << "=";
|
|
visit(node->initializer_clause);
|
|
|
|
} else if (node->expression) {
|
|
m_output << "(";
|
|
visit(node->expression);
|
|
m_output << ")";
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitInitializerClause(InitializerClauseAST* node)
|
|
{
|
|
visit(node->expression);
|
|
}
|
|
|
|
void CodeGenerator::visitInitializerList(InitializerListAST* node)
|
|
{
|
|
visitCommaPrint(node->clauses);
|
|
if (node->isVariadic) {
|
|
m_output << "...";
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitJumpStatement(JumpStatementAST* node)
|
|
{
|
|
print(node->op, true);
|
|
print(node->identifier);
|
|
m_output << ";";
|
|
}
|
|
|
|
void CodeGenerator::visitLabeledStatement(LabeledStatementAST* node)
|
|
{
|
|
print(node->label, true);
|
|
|
|
visit(node->expression);
|
|
|
|
m_output << ":";
|
|
|
|
visit(node->statement);
|
|
}
|
|
|
|
void CodeGenerator::visitLinkageBody(LinkageBodyAST* node)
|
|
{
|
|
m_output << "{";
|
|
|
|
DefaultVisitor::visitLinkageBody(node);
|
|
|
|
m_output << "}";
|
|
}
|
|
|
|
void CodeGenerator::visitLinkageSpecification(LinkageSpecificationAST* node)
|
|
{
|
|
printToken(Token_extern, true);
|
|
print(node->extern_type, true);
|
|
|
|
DefaultVisitor::visitLinkageSpecification(node);
|
|
}
|
|
|
|
void CodeGenerator::visitMemInitializer(MemInitializerAST* node)
|
|
{
|
|
visit(node->initializer_id);
|
|
|
|
m_output << "(";
|
|
visit(node->expression);
|
|
m_output << ")";
|
|
}
|
|
|
|
void CodeGenerator::visitName(NameAST* node)
|
|
{
|
|
if (node->global)
|
|
printToken( Token_scope );
|
|
|
|
if (node->qualified_names) {
|
|
commaPrintNodes( this, node->qualified_names, token_text( Token_scope ) );
|
|
printToken( Token_scope );
|
|
}
|
|
|
|
visit(node->unqualified_name);
|
|
}
|
|
|
|
void CodeGenerator::visitNamespace(NamespaceAST* node)
|
|
{
|
|
printToken( Token_namespace, true );
|
|
|
|
print(node->namespace_name);
|
|
|
|
DefaultVisitor::visitNamespace(node);
|
|
}
|
|
|
|
void CodeGenerator::visitNamespaceAliasDefinition(NamespaceAliasDefinitionAST* node)
|
|
{
|
|
printToken( Token_namespace, true );
|
|
|
|
print(node->namespace_name);
|
|
|
|
m_output << "=";
|
|
|
|
DefaultVisitor::visitNamespaceAliasDefinition(node);
|
|
|
|
m_output << ";";
|
|
}
|
|
|
|
void CodeGenerator::visitNewDeclarator(NewDeclaratorAST* node)
|
|
{
|
|
visit(node->ptr_op);
|
|
visit(node->sub_declarator);
|
|
surroundPrintNodes(this, node->expressions, "[", "]");
|
|
}
|
|
|
|
void CodeGenerator::visitNewExpression(NewExpressionAST* node)
|
|
{
|
|
print(node->scope_token);
|
|
print(node->new_token, true);
|
|
|
|
if (node->expression) {
|
|
m_output << "(";
|
|
visit(node->expression);
|
|
m_output << ")";
|
|
}
|
|
|
|
if (node->type_id) {
|
|
m_output << "(";
|
|
visit(node->type_id);
|
|
m_output << ")";
|
|
}
|
|
|
|
visit(node->new_type_id);
|
|
visit(node->new_initializer);
|
|
}
|
|
|
|
void CodeGenerator::visitNewInitializer(NewInitializerAST* node)
|
|
{
|
|
m_output << "(";
|
|
DefaultVisitor::visitNewInitializer(node);
|
|
m_output << ")";
|
|
}
|
|
|
|
void CodeGenerator::visitNewTypeId(NewTypeIdAST* node)
|
|
{
|
|
DefaultVisitor::visitNewTypeId(node);
|
|
}
|
|
|
|
void CodeGenerator::visitOperator(OperatorAST* node)
|
|
{
|
|
print(node->op);
|
|
|
|
if (node->op != node->open)
|
|
print(node->open);
|
|
|
|
print(node->close);
|
|
|
|
DefaultVisitor::visitOperator(node);
|
|
}
|
|
|
|
void CodeGenerator::visitOperatorFunctionId(OperatorFunctionIdAST* node)
|
|
{
|
|
printToken(Token_operator, true);
|
|
|
|
DefaultVisitor::visitOperatorFunctionId( node );
|
|
}
|
|
|
|
void CodeGenerator::visitParameterDeclaration(ParameterDeclarationAST* node)
|
|
{
|
|
if (node->type_specifier) {
|
|
visit(node->type_specifier);
|
|
m_output << " ";
|
|
}
|
|
visit(node->declarator);
|
|
|
|
if (node->expression) {
|
|
m_output << "=";
|
|
visit(node->expression);
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitParameterDeclarationClause(ParameterDeclarationClauseAST* node)
|
|
{
|
|
commaPrintNodes(this, node->parameter_declarations);
|
|
|
|
// TODO add elipsis
|
|
}
|
|
|
|
void CodeGenerator::visitPostfixExpression(PostfixExpressionAST* node)
|
|
{
|
|
DefaultVisitor::visitPostfixExpression(node);
|
|
}
|
|
|
|
void CodeGenerator::visitPrimaryExpression(PrimaryExpressionAST* node)
|
|
{
|
|
if (node->type == PrimaryExpressionAST::Token) {
|
|
print(node->token);
|
|
} else if (node->type == PrimaryExpressionAST::Literal) {
|
|
visit(node->literal);
|
|
} else if (node->type == PrimaryExpressionAST::Name) {
|
|
visit(node->name);
|
|
} else if (node->type == PrimaryExpressionAST::Statement || node->type == PrimaryExpressionAST::SubExpression) {
|
|
m_output << "(";
|
|
if (node->type == PrimaryExpressionAST::Statement) {
|
|
visit(node->expression_statement);
|
|
} else {
|
|
visit(node->sub_expression);
|
|
}
|
|
m_output << ")";
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitPtrOperator(PtrOperatorAST* node)
|
|
{
|
|
print(node->op);
|
|
|
|
DefaultVisitor::visitPtrOperator(node);
|
|
|
|
print(node->cv);
|
|
}
|
|
|
|
void CodeGenerator::visitPtrToMember(PtrToMemberAST* node)
|
|
{
|
|
visit(node->class_type);
|
|
printToken(Token_scope);
|
|
m_output << "*";
|
|
}
|
|
|
|
void CodeGenerator::visitReturnStatement(ReturnStatementAST* node)
|
|
{
|
|
printToken(Token_return, true);
|
|
|
|
DefaultVisitor::visitReturnStatement(node);
|
|
|
|
m_output << ";";
|
|
}
|
|
|
|
void CodeGenerator::visitSimpleDeclaration(SimpleDeclarationAST* node)
|
|
{
|
|
print(node->storage_specifiers, true);
|
|
print(node->function_specifiers, true);
|
|
visit(node->type_specifier);
|
|
commaPrintNodes(this, node->init_declarators);
|
|
visit(node->win_decl_specifiers);
|
|
|
|
m_output << ";";
|
|
}
|
|
|
|
void CodeGenerator::visitSimpleTypeSpecifier(SimpleTypeSpecifierAST* node)
|
|
{
|
|
print(node->cv, true);
|
|
|
|
print(node->integrals, true);
|
|
|
|
if (node->name) {
|
|
visit(node->name);
|
|
m_output << " ";
|
|
}
|
|
|
|
if (node->isTypeof) {
|
|
m_output << "typeof";
|
|
///TODO: expression in parens?
|
|
if (node->type_id) {
|
|
m_output << "(";
|
|
visit(node->type_id);
|
|
m_output << ")";
|
|
}
|
|
visit(node->expression);
|
|
} else if (node->isDecltype) {
|
|
m_output << "decltype(";
|
|
visit(node->expression);
|
|
m_output << ")";
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitSizeofExpression(SizeofExpressionAST* node)
|
|
{
|
|
printToken(Token_sizeof);
|
|
|
|
if (node->type_id) {
|
|
m_output << "(";
|
|
visit(node->type_id);
|
|
m_output << ")";
|
|
}
|
|
|
|
visit(node->expression);
|
|
}
|
|
|
|
void CodeGenerator::visitStringLiteral(StringLiteralAST* node)
|
|
{
|
|
print(node->literals);
|
|
}
|
|
|
|
void CodeGenerator::visitSubscriptExpression(SubscriptExpressionAST* node)
|
|
{
|
|
m_output << "[";
|
|
DefaultVisitor::visitSubscriptExpression(node);
|
|
m_output << "]";
|
|
}
|
|
|
|
void CodeGenerator::visitSwitchStatement(SwitchStatementAST* node)
|
|
{
|
|
printToken(Token_switch);
|
|
|
|
m_output << "(";
|
|
visit(node->condition);
|
|
m_output << ")";
|
|
|
|
visit(node->statement);
|
|
}
|
|
|
|
void CodeGenerator::visitTemplateArgument(TemplateArgumentAST* node)
|
|
{
|
|
DefaultVisitor::visitTemplateArgument(node);
|
|
}
|
|
|
|
void CodeGenerator::visitTemplateDeclaration(TemplateDeclarationAST* node)
|
|
{
|
|
if (node->exported) {
|
|
printToken(Token_export, true);
|
|
}
|
|
|
|
printToken(Token_template, true);
|
|
|
|
if (node->template_parameters) {
|
|
m_output << "< ";
|
|
commaPrintNodes(this, node->template_parameters);
|
|
m_output << " >";
|
|
}
|
|
|
|
visit(node->declaration);
|
|
}
|
|
|
|
void CodeGenerator::visitTemplateParameter(TemplateParameterAST* node)
|
|
{
|
|
DefaultVisitor::visitTemplateParameter(node);
|
|
}
|
|
|
|
void CodeGenerator::visitThrowExpression(ThrowExpressionAST* node)
|
|
{
|
|
printToken(Token_throw);
|
|
|
|
DefaultVisitor::visitThrowExpression(node);
|
|
}
|
|
|
|
void CodeGenerator::visitTranslationUnit(TranslationUnitAST* node)
|
|
{
|
|
DefaultVisitor::visitTranslationUnit(node);
|
|
}
|
|
|
|
void CodeGenerator::visitTryBlockStatement(TryBlockStatementAST* node)
|
|
{
|
|
printToken(Token_try);
|
|
visit(node->try_block);
|
|
visitNodes(this, node->catch_blocks);
|
|
}
|
|
|
|
void CodeGenerator::visitCatchStatement(CatchStatementAST* node)
|
|
{
|
|
printToken(Token_catch);
|
|
|
|
m_output << "(";
|
|
visit(node->condition);
|
|
m_output << ")";
|
|
|
|
visit(node->statement);
|
|
}
|
|
|
|
void CodeGenerator::visitTypeId(TypeIdAST* node)
|
|
{
|
|
DefaultVisitor::visitTypeId(node);
|
|
}
|
|
|
|
void CodeGenerator::visitTypeIdentification(TypeIdentificationAST* node)
|
|
{
|
|
print(node->typename_token);
|
|
|
|
visit(node->name);
|
|
|
|
if (node->expression) {
|
|
m_output << "(";
|
|
visit(node->expression);
|
|
m_output << ")";
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitTypeParameter(TypeParameterAST* node)
|
|
{
|
|
print(node->type, true);
|
|
|
|
visit(node->name);
|
|
|
|
if (node->type_id) {
|
|
m_output << "=";
|
|
visit(node->type_id);
|
|
}
|
|
|
|
if (node->template_parameters) {
|
|
m_output << "<";
|
|
commaPrintNodes(this, node->template_parameters);
|
|
m_output << ">";
|
|
|
|
// TODO when AST ready: if (node->template_class_token) printToken(Token_class);
|
|
}
|
|
|
|
if (node->template_name) {
|
|
m_output << "=";
|
|
visit(node->template_name);
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitTypedef(TypedefAST* node)
|
|
{
|
|
printToken( Token_typedef );
|
|
|
|
visit(node->type_specifier);
|
|
|
|
commaPrintNodes(this, node->init_declarators);
|
|
|
|
m_output << ";";
|
|
}
|
|
|
|
void CodeGenerator::visitUnaryExpression(UnaryExpressionAST* node)
|
|
{
|
|
print(node->op);
|
|
|
|
DefaultVisitor::visitUnaryExpression(node);
|
|
}
|
|
|
|
void CodeGenerator::visitUnqualifiedName(UnqualifiedNameAST* node)
|
|
{
|
|
print(node->tilde);
|
|
print(node->id);
|
|
|
|
visit(node->operator_id);
|
|
|
|
if (node->template_arguments) {
|
|
m_output << "< ";
|
|
visitNodes(this, node->template_arguments);
|
|
m_output << " >";
|
|
}
|
|
}
|
|
|
|
void CodeGenerator::visitUsing(UsingAST* node)
|
|
{
|
|
printToken(Token_using, true);
|
|
print(node->type_name);
|
|
|
|
DefaultVisitor::visitUsing(node);
|
|
|
|
m_output << ";";
|
|
}
|
|
|
|
void CodeGenerator::visitUsingDirective(UsingDirectiveAST* node)
|
|
{
|
|
printToken(Token_using, true);
|
|
printToken(Token_namespace, true);
|
|
|
|
DefaultVisitor::visitUsingDirective(node);
|
|
|
|
m_output << ";";
|
|
}
|
|
|
|
void CodeGenerator::visitWhileStatement(WhileStatementAST* node)
|
|
{
|
|
printToken(Token_while);
|
|
m_output << "(";
|
|
visit(node->condition);
|
|
m_output << ")";
|
|
|
|
visit(node->statement);
|
|
}
|
|
|
|
void CodeGenerator::visitWinDeclSpec(WinDeclSpecAST* node)
|
|
{
|
|
print(node->specifier);
|
|
m_output << "(";
|
|
print(node->modifier);
|
|
m_output << ")";
|
|
}
|
|
|