summaryrefslogblamecommitdiffstats
path: root/src/ast.c
blob: 2ba1e7dee51db55d18220bc0ef1f95d07bf81a9b (plain) (tree)
1
2
3
4
5
6
7
8
9
10



                    
                
                   
 


                   
 
 
                                                                       
 




                                    
                                                             



                                            
                                    
                

 
                                                                     
 





                                        
 





                                                           
     
                   

 
                                                                   
 
                      
                      
                        
                                                       
            
                                        


                                   
                                         




                  

                                                 
 







                                                             
     
                          


                  
                                                                              
 
                                                                   



                                              

 
                                                                    
 
                                                                     

                                 

 
                                                                    
 
                                                                     

                                 

 
                                                                                 
 
                                                                     








                                                                                    
 

                               
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "ast.h"
#include "common.h"

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>


CcmmcAst *ccmmc_ast_new(CcmmcAstNodeType type_node, size_t line_number)
{
    CcmmcAst *node;
    node = malloc(sizeof(CcmmcAst));
    ERR_FATAL_CHECK(node, malloc);
    node->parent = NULL;
    node->child = NULL;
    // Notice that leftmostSibling is not initialized as NULL
    node->leftmost_sibling = node;
    node->right_sibling = NULL;
    node->type_node = type_node;
    node->type_value = CCMMC_AST_VALUE_NONE;
    node->line_number = line_number;
    return node;
}

CcmmcAst *ccmmc_ast_append_sibling(CcmmcAst *node, CcmmcAst *sibling)
{
    while (node->right_sibling)
        node = node->right_sibling;
    if (sibling == NULL)
        return node;
    sibling = sibling->leftmost_sibling;
    node->right_sibling = sibling;

    sibling->leftmost_sibling = node->leftmost_sibling;
    sibling->parent = node->parent;
    while (sibling->right_sibling) {
        sibling = sibling->right_sibling;
        sibling->leftmost_sibling = node->leftmost_sibling;
        sibling->parent = node->parent;
    }
    return sibling;
}

CcmmcAst *ccmmc_ast_append_child(CcmmcAst *parent, CcmmcAst *child)
{
    if (child == NULL)
        return parent;
    if (parent->child) {
        ccmmc_ast_append_sibling(parent->child, child);
    } else {
        child = child->leftmost_sibling;
        parent->child = child;
        while (child) {
            child->parent = parent;
            child = child->right_sibling;
        }
    }
    return parent;
}

CcmmcAst *ccmmc_ast_append_children(
    CcmmcAst *parent, size_t children_count, ...)
{
    va_list children_list;
    va_start(children_list, children_count);
    CcmmcAst *child = va_arg(children_list, CcmmcAst*);
    ccmmc_ast_append_child(parent, child);
    CcmmcAst *tmp = child;
    for (size_t index = 1; index < children_count; ++index) {
        child = va_arg(children_list, CcmmcAst*);
        tmp = ccmmc_ast_append_sibling(tmp, child);
    }
    va_end(children_list);
    return parent;
}

CcmmcAst *ccmmc_ast_new_id(char *lexeme, CcmmcKindId kind, size_t line_number)
{
    CcmmcAst *node = ccmmc_ast_new(CCMMC_AST_NODE_ID, line_number);
    node->value_id.kind = kind;
    node->value_id.name = lexeme;
    // node->value_id.symbolTableEntry = NULL;
    return node;
}

CcmmcAst *ccmmc_ast_new_stmt(CcmmcKindStmt kind, size_t line_number)
{
    CcmmcAst *node = ccmmc_ast_new(CCMMC_AST_NODE_STMT, line_number);
    node->value_stmt.kind = kind;
    return node;
}

CcmmcAst *ccmmc_ast_new_decl(CcmmcKindDecl kind, size_t line_number)
{
    CcmmcAst *node = ccmmc_ast_new(CCMMC_AST_NODE_DECL, line_number);
    node->value_decl.kind = kind;
    return node;
}

CcmmcAst *ccmmc_ast_new_expr(CcmmcKindExpr kind, int op_kind, size_t line_number)
{
    CcmmcAst *node = ccmmc_ast_new(CCMMC_AST_NODE_EXPR, line_number);
    node->value_expr.kind = kind;
    node->value_expr.is_const_eval = false;
    if (kind == CCMMC_KIND_EXPR_BINARY_OP)
        node->value_expr.op_binary = op_kind;
    else if (kind == CCMMC_KIND_EXPR_UNARY_OP)
        node->value_expr.op_unary = op_kind;
    else
        fprintf(stderr, "%s: invalid expression kind in %s\n", prog_name, __func__);
    return node;
}

// vim: set sw=4 ts=4 sts=4 et: