view codenodes.c @ 2:ff5e493bc9cb default tip

2003-01-29
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sat, 13 Oct 2012 21:14:50 +0200
parents
children
line wrap: on
line source

/* Zestaw procedur do zamieniania na tekst roznych rodzajow wezlow. */

#include <glib.h>
#include "symbols.h"
#include "node.h"
#include "codetext.h"
#include "codetools.h"
#include "codenodes.h"
#include "pascal.tab.h"

void printNamespace(CodeText *text, Namespace *nam);

/* Wyświetla dany symbol (nazwę) lub jego zawartość, jeśli nie ma nazwy. */
void
printSymbolNode(CodeText *text, SymbolNode * node)
{
    if (node == NULL)
        return;

    if (node->parent != NULL) {
        switch (node->kind) {
            case SYM_TYPE_POINTER:
            case SYM_TYPE_STRING:
            case SYM_TYPE_ARRAY:
            case SYM_TYPE_SET:
            case SYM_TYPE_SUBRANGE:
            case SYM_TYPE_ENUM:
            case SYM_TYPE_RECORD:
            case SYM_TYPE_FILE:
                codeBeginTag(text, HG_TYPE, node);
                break;
            case SYM_LABEL:
                codeBeginTag(text, HG_LABEL, node);
                break;
            case SYM_CONST:
                codeBeginTag(text, HG_CONST, node);
                break;
            default:
                codeBeginTag(text, HG_IDENT, node);
        }
        codePrint(text, node->name->str);
        codeEndTag(text);
    } else {
        printSymbolNodeContents(text, node);
    }

}

/* Wyświetla treść danego symbolu. */
void
printSymbolNodeContents(CodeText *text, SymbolNode * node)
{
    GList          *iter;

    if (node == NULL)
        return;

    switch (node->kind) {
        case SYM_TAG_FIELD:
            for (iter = node->list; iter != NULL; iter = iter->next) {
                if (iter->data!=NULL) {
                    printExprNode(text, iter->data);
                    codeBeginTag(text, HG_PUNCT, NULL);
                    codePrint(text, ";");
                    codeEndTag(text);
                    codeNewLine(text);
                }
            }
            break;
        case SYM_TYPE_POINTER:
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, "^");
            codeEndTag(text);
            printSymbolNode(text, node->type);
            break;
        case SYM_TYPE_STRING:
            codeBeginTag(text, HG_TYPE, NULL);
            codePrint(text, "STRING");
            codeEndTag(text);
            if (node->expr != NULL) {
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, "[");
                codeEndTag(text);
                printExprNode(text, node->expr);
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, "]");
                codeEndTag(text);
            }
            break;
        case SYM_TYPE_ARRAY:
            codeBeginTag(text, HG_TYPE, NULL);
            codePrint(text, "ARRAY");
            codeEndTag(text);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, "[");
            codeEndTag(text);
            for (iter = node->list; iter != NULL; iter = iter->next) {
                printSymbolNode(text, iter->data);
                if (iter->next != NULL) {
                    codeBeginTag(text, HG_PUNCT, NULL);
                    codePrint(text, ", ");
                    codeEndTag(text);
                }
            }
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, "] ");
            codeEndTag(text);
            codeBeginTag(text, HG_TYPE, NULL);
            codePrint(text, "OF ");
            codeEndTag(text);
            printSymbolNode(text, node->type);
            break;
        case SYM_TYPE_SET:
            codeBeginTag(text, HG_TYPE, NULL);
            codePrint(text, "SET OF ");
            codeEndTag(text);
            printSymbolNode(text, node->type);
            break;
        case SYM_TYPE_SUBRANGE:
            printExprNode(text, node->expr);
            break;
        case SYM_TYPE_ENUM:
            codePrint(text, "enumeraton");
            break;
        case SYM_TYPE_RECORD:
            codeBeginTag(text, HG_TYPE, NULL);
            codePrint(text, "RECORD");
            codeEndTag(text);
            codeNewLine(text);
            codeIndent(text);
            for (iter = node->list; iter != NULL; iter = iter->next) {
                if (iter->data!=NULL) {
                    printSymbolNodeDef(text, iter->data);
                    codeBeginTag(text, HG_PUNCT, NULL);
                    codePrint(text, ";");
                    codeEndTag(text);
                    codeNewLine(text);
                }
            }
            /* printNamespace(text, node->symbols); */
            printSymbolNodeDef(text, node->base);
            codeUnindent(text);
            codeBeginTag(text, HG_TYPE, NULL);
            codePrint(text, "END");
            codeEndTag(text);
            break;
        case SYM_TYPE_FILE:
            codeBeginTag(text, HG_TYPE, NULL);
            codePrint(text, "FILE OF ");
            codeEndTag(text);
            printSymbolNode(text, node->type);
            break;
        case SYM_VAR_LOCAL:
        case SYM_VAR_PARAM:
        case SYM_VAR_VARPARAM:
        case SYM_VAR_DEARR:
        case SYM_VAR_DEREF:
        case SYM_VAR_CAST:
        case SYM_UNIT:
            printSymbolNode(text, node);
#if 0
            codeBeginTag(text, HG_IDENT, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
#endif
            break;
        case SYM_LABEL:
            printSymbolNode(text, node);
#if 0
            codeBeginTag(text, HG_LABEL, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
#endif
            break;
        case SYM_CONST:
            printSymbolNode(text, node);
#if 0
            codeBeginTag(text, HG_CONST, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
#endif
            break;
        case SYM_VAR_FIELD:
            if (node->base == node) {
                codeBeginTag(text, HG_IDENT, node);
                codePrint(text, node->name->str);
                codeEndTag(text);
            } else {
                printSymbolNode(text, node->base);
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, ".");
                codeEndTag(text);
                codeBeginTag(text, HG_IDENT, node);
                codePrint(text, node->name->str);
                codeEndTag(text);
            }
            break;
        case SYM_PROC:
        case SYM_FUNC:
            codeIndent(text);
            printNamespace(text, node->symbols);
            printStmtNode(text, node->stmt);
            codeUnindent(text);
            break;
        case SYM_PROG:
            codeIndent(text);
            printNamespace(text, node->symbols);

            printStmtNode(text, node->stmt);
            codeUnindent(text);
            break;
        default:
            codeBeginTag(text, HG_ERROR, NULL);
            codePrint(text, "?symbol?");
            codeEndTag(text);
    }
}

/* Wyświetla definicję danego symbolu. */
void
printSymbolNodeDef(CodeText *text, SymbolNode * node)
{
    GList          *iter;

    if (node == NULL)
        return;

    if (node->bcomm != NULL) {
        codeBeginTag(text, HG_COMMENT, NULL);
        codePrint(text, node->bcomm->str);
        codeEndTag(text);
        codeNewLine(text);   
    }

    if (node->ccomm!=NULL) {
        codeComment(text, node->ccomm->str);
    }

    switch (node->kind) {
        case SYM_TAG_FIELD:
            codeBeginTag(text, HG_TYPE, NULL);
            codePrint(text, "CASE ");
            codeEndTag(text);
            codeBeginTag(text, HG_IDENT, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
            if (node->type!=NULL) {
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, ": ");
                codeEndTag(text);
                printSymbolNode(text, node->type);
            }
            codeBeginTag(text, HG_TYPE, NULL);
            codePrint(text, " OF");
            codeEndTag(text);
            codeNewLine(text);
            codeIndent(text);
            printSymbolNodeContents(text, node);
            codeUnindent(text);
            break;
        case SYM_TYPE_POINTER:
        case SYM_TYPE_STRING:
        case SYM_TYPE_ARRAY:
        case SYM_TYPE_SET:
        case SYM_TYPE_SUBRANGE:
        case SYM_TYPE_ENUM:
        case SYM_TYPE_RECORD:
        case SYM_TYPE_FILE:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "TYPE ");
            codeEndTag(text);
#if 0
            codeBeginTag(text, HG_IDENT, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
#endif
            printSymbolNode(text, node);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, " = ");
            codeEndTag(text);
            printSymbolNodeContents(text, node);
            break;
        case SYM_VAR_PARAM:
#if 0
            codeBeginTag(text, HG_IDENT, node);
            codePrint(text, node->name->str); 
            codeEndTag(text);
#endif
            printSymbolNode(text, node);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ": ");
            codeEndTag(text);
            printSymbolNode(text, node->type);
            break;
        case SYM_VAR_VARPARAM:
            codeBeginTag(text, HG_TYPE, NULL);
            codePrint(text, "VAR ");
            codeEndTag(text);
#if 0
            codeBeginTag(text, HG_IDENT, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
#endif
            printSymbolNode(text, node);
            if (node->type!=NULL) {
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, ": ");
                codeEndTag(text);
                printSymbolNode(text, node->type);
            }
            break;
        case SYM_VAR_LOCAL:
        case SYM_VAR_DEARR:
        case SYM_VAR_DEREF:
        case SYM_VAR_CAST:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "VAR ");
            codeEndTag(text);
#if 0
            codeBeginTag(text, HG_IDENT, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
#endif
            printSymbolNode(text, node);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ": ");
            codeEndTag(text);
            printSymbolNode(text, node->type);
            break;
        case SYM_VAR_FIELD:
            for (iter = node->list; iter != NULL; iter = iter->next) {
                if (iter->data != NULL) {
                    printExprNode(text, iter->data);
                }
                codeBeginTag(text, HG_PUNCT, NULL);
                if (iter->next != NULL) {
                    codePrint(text, ", ");
                } else {
                    codePrint(text, ": ");
                }
                codeEndTag(text);
            }
            codeBeginTag(text, HG_IDENT, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ": ");
            codeEndTag(text);
            printSymbolNode(text, node->type);
            break;
        case SYM_LABEL:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "LABEL ");
            codeEndTag(text);
#if 0
            codeBeginTag(text, HG_LABEL, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
#endif
            printSymbolNode(text, node);
            break;
        case SYM_PROC:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "PROCEDURE ");
            codeEndTag(text);
#if 0
            codeBeginTag(text, HG_IDENT, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
#endif
            printSymbolNode(text, node);
            if (node->list != NULL) {
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, "(");
                codeEndTag(text);
                for (iter = node->list; iter != NULL; iter = iter->next) {
                    printSymbolNodeDef(text, iter->data);
                    if (iter->next != NULL) {
                        codeBeginTag(text, HG_PUNCT, NULL);
                        codePrint(text, "; ");
                        codeEndTag(text);
                    }
                }
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, ")");
                codeEndTag(text);
            }
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ";");
            codeEndTag(text);
            codeNewLine(text);
            printSymbolNodeContents(text, node);
            break;
        case SYM_FUNC:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "FUNCTION ");
            codeEndTag(text);
#if 0
            codeBeginTag(text, HG_IDENT, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
#endif
            printSymbolNode(text, node);
            if (node->list != NULL) {
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, "(");
                codeEndTag(text);
                for (iter = node->list; iter != NULL; iter = iter->next) {
                    node = ((SymbolNode *) iter->data);
                    printSymbolNodeDef(text, node);
                    if (iter->next != NULL) {
                        codeBeginTag(text, HG_PUNCT, NULL);
                        codePrint(text, "; ");
                        codeEndTag(text);
                    }
                }
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, ")");
                codeEndTag(text);
            }
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ": ");
            codeEndTag(text);
            printSymbolNode(text, node->type);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ";");
            codeEndTag(text);
            codeNewLine(text);
            printSymbolNodeContents(text, node);
            break;
        case SYM_CONST:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "CONST ");
            codeEndTag(text);
#if 0
            codeBeginTag(text, HG_CONST, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
#endif
            printSymbolNode(text, node);
            if (node->type != NULL) {
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, ": ");
                codeEndTag(text);
                printSymbolNode(text, node->type);
            }
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, " = ");
            codeEndTag(text);
            printExprNode(text, node->expr);
            break;
        case SYM_UNIT:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "USES ");
            codeEndTag(text);
#if 0
            codeBeginTag(text, HG_IDENT, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
#endif
            printSymbolNode(text, node);
            break;
        case SYM_PROG:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "PROGRAM ");
            codeEndTag(text);
            codeBeginTag(text, HG_IDENT, node);
            codePrint(text, node->name->str);
            codeEndTag(text);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, "(");
            codeEndTag(text);
            for (iter = node->list; iter != NULL; iter = iter->next) {
                codePrint(text, (char *)(iter->data));
                if (iter->next != NULL) {
                    codeBeginTag(text, HG_PUNCT, NULL);
                    codePrint(text, ", ");
                    codeEndTag(text);
                }
            }
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ");");
            codeEndTag(text);
            codeNewLine(text);
            printSymbolNodeContents(text, node);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ".");
            codeEndTag(text);
            break;
        default:
            codeBeginTag(text, HG_ERROR, NULL);
            codePrint(text, "?symbol?");
            codeEndTag(text);
    }
}

/* Wyświetla węzeł rozkazu. */
void
printStmtNode(CodeText *text, StmtNode * node)
{
    GList          *iter;

    if (node == NULL)
        return;

    if (node->bcomm != NULL) {
        codeBeginTag(text, HG_COMMENT, NULL);
        codePrint(text, node->bcomm->str);
        codeEndTag(text);
        codeNewLine(text);   
    }

    if (node->label!=NULL) {
        codeLabel(text, node->label->name->str);
        codeLabel(text, ": ");
    }
    
    if (node->ccomm!=NULL) {
        codeComment(text, node->ccomm->str);
    }

    switch (node->kind) {
        case STMT_CASE_CASE:
            for (iter = node->list; iter != NULL; iter = iter->next) {
                printExprNode(text, iter->data);
                if (iter->next != NULL) {
                    codeBeginTag(text, HG_PUNCT, NULL);
                    codePrint(text, ", ");
                    codeEndTag(text);
                }
            }
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ": ");
            codeEndTag(text);
            printStmtNode(text, node->stmt);
            break;
        case STMT_CASE_HEAD:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "CASE ");
            codeEndTag(text);
            printExprNode(text, node->expr);
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, " OF");
            codeEndTag(text);
            codeNewLine(text);
            codeIndent(text);
            for (iter = node->list; iter != NULL; iter = iter->next) {
                if (iter->data != NULL) {
                    printStmtNode(text, iter->data);
                    codeBeginTag(text, HG_PUNCT, NULL);
                    codePrint(text, ";");
                    codeEndTag(text);
                    codeNewLine(text);
                }
            }
            if (node->stmt != NULL) {
                codeBeginTag(text, HG_KEYWORD, NULL);
                codePrint(text, "ELSE ");
                codeEndTag(text);
                printStmtNode(text, node->stmt);
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, ";");
                codeEndTag(text);
                codeNewLine(text);
            }
            codeUnindent(text);
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "END");
            codeEndTag(text);
            break;
        case STMT_REPEAT:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "REPEAT");
            codeEndTag(text);
            codeNewLine(text);
            codeIndent(text);
            for (iter = node->list; iter != NULL; iter = iter->next) {
                printStmtNode(text, iter->data);
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, ";");
                codeEndTag(text);
                codeNewLine(text);
            }
            codeUnindent(text);
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "UNTIL ");
            codeEndTag(text);
            printExprNode(text, node->expr);
            break;
        case STMT_WHILE:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "WHILE ");
            codeEndTag(text);
            printExprNode(text, node->expr);
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, " DO ");
            codeEndTag(text);
            printStmtNode(text, node->stmt);
            break;
        case STMT_WITH:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "WITH ");
            codeEndTag(text);
            for (iter = node->list; iter != NULL; iter = iter->next) {
                if (iter->data != NULL) {
                    printSymbolNode(text, (SymbolNode *)iter->data);
                    if (iter->next != NULL) {
                        codeBeginTag(text, HG_PUNCT, NULL);
                        codePrint(text, ", ");
                        codeEndTag(text);
                    }
                }
            }
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, " DO ");
            codeEndTag(text);
            printStmtNode(text, node->stmt);
            break;
        case STMT_GOTO:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "GOTO ");
            codeEndTag(text);
            printSymbolNode(text, node->symbol);
            break;
        case STMT_BLOCK:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "BEGIN");
            codeEndTag(text);
            codeNewLine(text);
            codeIndent(text);
            for (iter = node->list; iter != NULL; iter = iter->next) {
                if (iter->data != NULL) {
                    printStmtNode(text, iter->data);
                    codeBeginTag(text, HG_PUNCT, NULL);
                    codePrint(text, ";");
                    codeEndTag(text);
                    codeNewLine(text);
                }
            }
            codeUnindent(text);
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "END");
            codeEndTag(text);
            break;
        case STMT_IF:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "IF ");
            codeEndTag(text);
            printExprNode(text, node->expr);
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, " THEN ");
            codeEndTag(text);
            printStmtNode(text, node->stmt);
            if (node->stmt2 != NULL) {
                codeBeginTag(text, HG_KEYWORD, NULL);
                codePrint(text, " ELSE ");
                codeEndTag(text);
                printStmtNode(text, node->stmt2);
            }
            break;
        case STMT_ASSIGN:
            printSymbolNode(text, node->symbol);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ":= ");
            codeEndTag(text);
            printExprNode(text, node->expr);
            break;
        case STMT_PROC:
            printSymbolNode(text, node->symbol);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, "(");
            codeEndTag(text);
            for (iter = node->list; iter != NULL; iter = iter->next) {
                printExprNode(text, iter->data);
                if (iter->next != NULL) {
                    codeBeginTag(text, HG_PUNCT, NULL);
                    codePrint(text, ", ");
                    codeEndTag(text);
                }
            }
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ")");
            codeEndTag(text);
            break;
        case STMT_FOR:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "FOR ");
            codeEndTag(text);
            printSymbolNode(text, node->symbol);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ":= ");
            codeEndTag(text);
            printExprNode(text, node->expr);
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, " TO ");
            codeEndTag(text);
            printExprNode(text, node->expr2);
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, " DO ");
            codeEndTag(text);
            printStmtNode(text, node->stmt);
            break;
        case STMT_FOR_DOWN:
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, "FOR ");
            codeEndTag(text);
            printSymbolNode(text, node->symbol);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ":= ");
            codeEndTag(text);
            printExprNode(text, node->expr);
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, " DOWNTO ");
            codeEndTag(text);
            printExprNode(text, node->expr2);
            codeBeginTag(text, HG_KEYWORD, NULL);
            codePrint(text, " DO ");
            codeEndTag(text);
            printStmtNode(text, node->stmt);
            break;
        default:
            codeBeginTag(text, HG_ERROR, NULL);
            codePrint(text, "?stmt?");
            codeEndTag(text);
    }
}

const char     *
getOper(enum OperKind oper)
{
    switch (oper) {
        case OPER_PLUS:
            return "+";
        case OPER_MINUS:
            return "-";
        case OPER_STAR:
            return "*";
        case OPER_SLASH:
            return "/";
        case OPER_DIV:
            return "DIV";
        case OPER_MOD:
            return "MOD";
        case OPER_SHL:
            return "SHL";
        case OPER_SHR:
            return "SHR";
        case OPER_EQ:
            return "=";
        case OPER_NEQ:
            return "<>";
        case OPER_GT:
            return ">";
        case OPER_LT:
            return "<";
        case OPER_GEQ:
            return ">=";
        case OPER_LEQ:
            return "<=";
        case OPER_IN:
            return "IN";
        case OPER_XOR:
            return "XOR";
        case OPER_OR:
            return "OR";
        case OPER_AND:
            return "AND";
        case OPER_NOT:
            return "NOT";
        case OPER_NONE:
        default:
            return " ";

    }
}

void
printExprNode(CodeText *text, ExprNode * node)
{
    GList          *iter;

    if (node == NULL)
        return;

    switch (node->kind) {
        case EXPR_VARIANT:
            printExprNode(text, node->expr);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text,"(");
            codeEndTag(text);
            codeIndent(text);
            codeNewLine(text);
            for (iter = node->list; iter != NULL; iter = iter->next) {
                if (iter->data!=NULL) {
                    printSymbolNodeDef(text, iter->data);
                    codeBeginTag(text, HG_PUNCT, NULL);
                    codePrint(text, ";");
                    codeEndTag(text);
                    codeNewLine(text);
                }
            }
            printSymbolNodeDef(text, node->symbol);
            codeUnindent(text);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text,")");
            codeEndTag(text);
            break;
        case EXPR_CASES:
            for (iter = node->list; iter != NULL; iter = iter->next) {
                printExprNode(text, iter->data);
                codeBeginTag(text, HG_PUNCT, NULL);
                if (iter->next != NULL)
                    codePrint(text, ", ");
                else
                    codePrint(text, ": ");
                codeEndTag(text);
            }
            break;
        case EXPR_ADDR:
            if (node->symbol != NULL) {
                codePrint(text, "@");
                printSymbolNode(text, node->symbol);
            } else {
                printExprNode(text, node->expr);
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, ":");
                codeEndTag(text);
                printExprNode(text, node->expr2);
            }
            break;
        case EXPR_NUMBER:
            codeBeginTag(text, HG_NUMBER, node);
            codePrint(text, node->value->str);
            codeEndTag(text);
            break;
        case EXPR_STRING:
            codeBeginTag(text, HG_STRING, node);
            codePrint(text, node->value->str);
            codeEndTag(text);
            break;
        case EXPR_CONST:
        case EXPR_VAR:
            printSymbolNode(text, node->symbol);
            break;
        case EXPR_PAREN:
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, "( ");
            codeEndTag(text);
            printExprNode(text, node->expr);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, " )");
            codeEndTag(text);
            break;
        case EXPR_UN:
            codeBeginTag(text, HG_OPER, node);
            codePrint(text, getOper(node->oper));
            codeEndTag(text);
            printExprNode(text, node->expr);
            break;
        case EXPR_BIN:
        case EXPR_EQ:
            printExprNode(text, node->expr);
            codePrint(text, " ");
            codeBeginTag(text, HG_OPER, node);
            codePrint(text, getOper(node->oper));
            codeEndTag(text);
            codePrint(text, " ");
            printExprNode(text, node->expr2);
            break;
        case EXPR_SET:
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, "[");
            codeEndTag(text);
            if (node->list != NULL) {
                for (iter = node->list; iter != NULL; iter = iter->next) {
                    printExprNode(text, iter->data);
                    if (iter->next != NULL) {
                        codeBeginTag(text, HG_PUNCT, NULL);
                        codePrint(text, ", ");
                        codeEndTag(text);
                    }
                }
            }
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, "]");
            codeEndTag(text);
            break;
        case EXPR_ARRAY:
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, "(");
            codeEndTag(text);
            if (node->list != NULL) {
                for (iter = node->list; iter != NULL; iter = iter->next) {
                    printExprNode(text, iter->data);
                    if (iter->next != NULL) {
                        codeBeginTag(text, HG_PUNCT, NULL);
                        codePrint(text, ", ");
                        codeEndTag(text);
                    }
                }
            }
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ")");
            codeEndTag(text);
            break;
        case EXPR_NIL:
            codeBeginTag(text, HG_CONST, node);
            codePrint(text, "NIL");
            codeEndTag(text);
            break;
        case EXPR_RANGE:
            printExprNode(text, node->expr);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, "..");
            codeEndTag(text);
            printExprNode(text, node->expr2);
            break;
        case EXPR_FUNC:
            printSymbolNode(text, node->symbol);
            if (node->list != NULL) {
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, "(");
                codeEndTag(text);
                for (iter = node->list; iter != NULL; iter = iter->next) {
                    printExprNode(text, iter->data);
                    if (iter->next != NULL) {
                        codeBeginTag(text, HG_PUNCT, NULL);
                        codePrint(text, ", ");
                        codeEndTag(text);
                    }
                }
                codeBeginTag(text, HG_PUNCT, NULL);
                codePrint(text, ")");
                codeEndTag(text);
            }
        default:
            codeBeginTag(text, HG_ERROR, NULL);
            codePrint(text, "?expr?");
            codeEndTag(text);
    }
}

void
printNamespace(CodeText *text, Namespace * nam)
{
    GList          *iter;
    SymbolNode     *node;

    if (nam == NULL)
        return;
    for (iter = nam->list; iter != NULL; iter = iter->next) {
        node = ((SymbolNode *) iter->data);
        if ((node->kind != SYM_VAR_PARAM) && (node->kind != SYM_VAR_VARPARAM)) {
            printSymbolNodeDef(text, node);
            codeBeginTag(text, HG_PUNCT, NULL);
            codePrint(text, ";");
            codeEndTag(text);
            codeNewLine(text);
        }
    }
}