openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

cint_eval_asts.c (41896B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        cint_eval_asts.c
      8  * Purpose:     CINT AST evaluators
      9  */
     10 
     11 #include "cint_eval_asts.h"
     12 #include "cint_porting.h"
     13 #include "cint_variables.h"
     14 #include "cint_internal.h"
     15 #include "cint_error.h"
     16 #include "cint_debug.h"
     17 #include "cint_eval_ast_cint.h"
     18 #include "cint_eval_ast_print.h"
     19 #include <stdarg.h>
     20 
     21 
     22 static int __breakable = 0; 
     23 static int __returnable = 0; 
     24 
     25 #define CINT_BREAK()          CINT_ERRNO_IS(BREAK)
     26 #define CINT_CONTINUE()       CINT_ERRNO_IS(CONTINUE)
     27 #define CINT_RETURN()         CINT_ERRNO_IS(RETURN)
     28 #define CINT_EXIT()           CINT_ERRNO_IS(EXIT)
     29 
     30 typedef cint_variable_t* (*cint_vararg_f)(cint_ast_t* ast);
     31 
     32 static cint_variable_t* 
     33 __cint_eval_ast_Empty(cint_ast_t* ast)
     34 {
     35     return NULL; 
     36 }
     37 
     38 static cint_variable_t* 
     39 __cint_eval_ast_Integer(cint_ast_t* ast)
     40 {
     41     return cint_auto_integer(ast->utype.integer.i); 
     42 }
     43 
     44 #if CINT_CONFIG_INCLUDE_LONGLONGS == 1
     45 static cint_variable_t* 
     46 __cint_eval_ast_LongLong(cint_ast_t* ast)
     47 {
     48     return cint_auto_longlong(ast->utype._longlong.i); 
     49 }
     50 #endif
     51 
     52 static cint_variable_t* 
     53 __cint_eval_ast_String(cint_ast_t* ast)
     54 {
     55     cint_variable_t* rv; 
     56     rv = cint_auto_string(ast->utype.string.s); 
     57     return rv; 
     58 }
     59 
     60 #if CINT_CONFIG_INCLUDE_DOUBLES == 1
     61 static cint_variable_t*
     62 __cint_eval_ast_Double(cint_ast_t* ast)
     63 {
     64     return cint_auto_double(ast->utype._double.d); 
     65 }
     66 #endif
     67 
     68 static cint_variable_t* 
     69 __cint_eval_ast_Type(cint_ast_t* ast)
     70 {
     71     return NULL; 
     72 }
     73 
     74 static cint_variable_t*
     75 __cint_eval_ast_Initializer(cint_ast_t* ast)
     76 {
     77     return NULL; 
     78 }
     79 
     80 static cint_variable_t* 
     81 __cint_eval_ast_EnumDef(cint_ast_t* ast)
     82 {
     83     cint_enum_type_t* cet; 
     84     cint_enum_map_t* map; 
     85     cint_ast_t* e; 
     86     int ecount; 
     87     int evalue = 0; 
     88     int map_size;
     89 
     90     /*
     91      * Allocate a new cint_enum_type_t structure
     92      */
     93     cet = CINT_MALLOC(sizeof(*cet)); 
     94     if(cet == NULL) {
     95         cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 
     96         return NULL; 
     97     }
     98     CINT_MEMSET(cet, 0, sizeof(*cet));
     99 
    100     cet->name = CINT_STRDUP(ast->utype.enumdef.identifier->utype.identifier.s); 
    101     ecount = cint_ast_count(ast->utype.enumdef.enumerators); 
    102 
    103     /* Allocate the map array based on the enum count */
    104     map_size = sizeof(*map)*(ecount+1);
    105     map = CINT_MALLOC(map_size); 
    106 
    107     if(map == NULL) {
    108         cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 
    109         cint_datatype_clear_enumeration(cet); 
    110         return NULL; 
    111     }   
    112     CINT_MEMSET(map, 0, map_size);
    113 
    114     /* Initialize map array base on the enumerators */
    115     cet->enum_map = map; 
    116     for(e = ast->utype.enumdef.enumerators; e; e = e->next, map++) {
    117         map->name = CINT_STRDUP(e->utype.enumerator.identifier->utype.identifier.s); 
    118         if(e->utype.enumerator.value) {
    119             cint_variable_t* rv;
    120 
    121             rv = cint_eval_ast(e->utype.enumerator.value);
    122             if (rv) {
    123                 map->value = cint_integer_value(rv);
    124                 evalue = map->value;
    125             } else {
    126                 cint_ast_error(ast, CINT_E_BAD_AST, "illegal enum value"); 
    127                 cint_datatype_clear_enumeration(cet); 
    128                 return NULL; 
    129             }
    130         }
    131         else {
    132             map->value = evalue; 
    133         }       
    134         evalue++; 
    135     }
    136     map->name = NULL; 
    137 
    138     cint_datatype_add_enumeration(cet); 
    139 
    140     return NULL; 
    141 }
    142 
    143 static cint_variable_t*
    144 __cint_eval_ast_Enumerator(cint_ast_t* ast)
    145 {
    146     return NULL; 
    147 }
    148 
    149 
    150 static cint_variable_t* 
    151 __cint_eval_ast_Identifier(cint_ast_t* ast)
    152 {
    153     cint_variable_t* rv = NULL; 
    154     int c; 
    155     cint_datatype_t dt; 
    156     const char* id = ast->utype.identifier.s; 
    157 
    158     /* Special Command Identifiers */
    159     if(!CINT_STRCMP(id, "quit") ||  
    160        !CINT_STRCMP(id, "exit")) {
    161         cint_errno = CINT_E_EXIT; 
    162         return NULL; 
    163     }
    164 
    165     /* Variables */
    166     if((rv = cint_variable_find(id, 0))) {
    167         return rv; 
    168     }
    169 
    170     /* Enumerations */
    171     if(cint_datatype_enum_find(id, &dt, &c) == CINT_E_NONE) {
    172         if(cint_variable_create(&rv, NULL, &dt.desc, CINT_VARIABLE_F_AUTO | CINT_VARIABLE_F_CONST, NULL) != CINT_E_NONE) {
    173             cint_internal_error(__FILE__, __LINE__, "could not create enum autovar of type '%s'", dt.desc.basetype); 
    174             return NULL; 
    175         }
    176         else {
    177             *((int*)rv->data) = c; 
    178         }
    179         return rv; 
    180     }
    181 
    182     
    183     /* Enumerations and constants */
    184     if(cint_constant_find(id, &c) == CINT_E_NONE) {
    185         return cint_auto_integer(c); 
    186     }   
    187     
    188     /* Functions */
    189     if(cint_datatype_find(id, &dt) == CINT_E_NONE) {
    190         if(dt.flags & (CINT_DATATYPE_F_FUNC | CINT_DATATYPE_F_FUNC_DYNAMIC)) {
    191             cint_parameter_desc_t pdt = { NULL, 0, 0 }; 
    192             
    193             pdt.basetype = id; 
    194             cint_variable_create(&rv, 
    195                                  NULL, 
    196                                  &pdt, 
    197                                  CINT_VARIABLE_F_AUTO | CINT_VARIABLE_F_CONST, 
    198                                  NULL); 
    199             return rv; 
    200         }
    201     }   
    202 
    203     if(rv == NULL) {
    204         cint_ast_error(ast, CINT_E_BAD_VARIABLE, "identifier '%s' undeclared", ast->utype.identifier.s); 
    205     }
    206     return rv; 
    207 }
    208 
    209 static int
    210 _cint_eval_ast_declaration_parameter(cint_ast_t* ast,
    211                                      char *basetype,
    212                                      int basetype_len,
    213                                      unsigned* basetype_flags,
    214                                      int *pcount_p,
    215                                      int *array_dimension_count,
    216                                      int *array_dimensions)
    217 {
    218     int rc; 
    219     cint_variable_t* rv; 
    220     int pcount;
    221     int dim_index;
    222     int dimensions[CINT_CONFIG_ARRAY_DIMENSION_LIMIT];
    223 
    224     if (ast->ntype != cintAstDeclaration) {
    225         return cint_ast_error(ast,
    226             CINT_E_BAD_AST,
    227             "expected declaration"); 
    228     }
    229 
    230     pcount = ast->utype.declaration.pcount; 
    231 
    232     rc = cint_eval_type_list(ast->utype.declaration.type,
    233                              basetype, basetype_len,
    234                              basetype_flags, 1);
    235 
    236     if (rc != CINT_E_NONE) {
    237         return rc;
    238     }
    239 
    240     if(ast->utype.declaration.num_dimension_initializers) {
    241         for(dim_index = 0;
    242             dim_index < ast->utype.declaration.num_dimension_initializers;
    243             dim_index++) {
    244             rv = cint_eval_ast(
    245                 ast->utype.declaration.dimension_initializers[dim_index]); 
    246             if(rv == NULL || (cint_is_integer(rv) == 0)) {
    247                 return cint_ast_error(ast,
    248                     CINT_E_BAD_AST,
    249                     "illegal array definition"); 
    250             } 
    251             dimensions[dim_index] = cint_integer_value(rv); 
    252             if(dim_index > 0 && dimensions[dim_index] <= 0) {
    253                 return cint_ast_error(ast,
    254                     CINT_E_BAD_AST,
    255                     "illegal array definition"); 
    256             }
    257         }
    258 
    259         if(dimensions[0] <= 0) {
    260             if(dimensions[0] == -1 &&
    261                ast->utype.declaration.num_dimension_initializers == 1 &&
    262                ast->utype.declaration.init &&
    263                ast->utype.declaration.init->ntype == cintAstInitializer) {
    264                 /* 
    265                  * Determine the proper size for this initialized array. 
    266                  * based on the length of the initializer chain 
    267                  */
    268                 dimensions[0] =
    269                     cint_ast_count(ast->utype.declaration.init->
    270                                    utype.initializer.initializers); 
    271             }
    272             else {
    273                 return cint_ast_error(ast,
    274                                       CINT_E_BAD_AST,
    275                                       "illegal array definition"); 
    276             }
    277         }
    278     }
    279 
    280     if (rc == CINT_E_NONE) {
    281         *pcount_p = pcount;
    282         *array_dimension_count = 
    283             ast->utype.declaration.num_dimension_initializers;
    284         for(dim_index = 0; 
    285             dim_index < ast->utype.declaration.num_dimension_initializers;
    286             dim_index++) {
    287             array_dimensions[dim_index] = dimensions[dim_index];
    288         }
    289     }
    290     return rc; 
    291 }
    292 
    293 static cint_variable_t* 
    294 __cint_eval_ast_Declaration(cint_ast_t* ast)
    295 {    
    296     int rc; 
    297     cint_variable_t* rv; 
    298     cint_parameter_desc_t desc; 
    299     unsigned basetype_flags;
    300     char basetype[64];
    301     
    302     rc = _cint_eval_ast_declaration_parameter(ast,
    303                                               basetype,
    304                                               sizeof(basetype),
    305                                               &basetype_flags,
    306                                               &desc.pcount,
    307                                               &desc.num_dimensions,
    308                                               desc.dimensions);
    309 
    310     if (rc != CINT_E_NONE) {
    311         return NULL;
    312     }
    313 
    314     desc.name = ast->utype.declaration.identifier->utype.string.s;
    315     desc.basetype = basetype;
    316 
    317     if (CINT_STRLEN(desc.basetype) == 0) {
    318         cint_ast_error(ast, CINT_E_BAD_VARIABLE,
    319                        "identifier '%s' has unknown type", desc.name);
    320         return NULL; 
    321     }
    322 
    323     if((rv=cint_variable_find(desc.name, 1)) != NULL) {
    324         /* Variable already exists in current scope */
    325         cint_ast_error(ast, CINT_E_BAD_VARIABLE,
    326                        "identifier '%s' redeclared", desc.name); 
    327         return NULL; 
    328     }
    329 
    330     rc = cint_variable_create(&rv,      
    331                               desc.name,
    332                               &desc, 
    333                               0, 
    334                               NULL);
    335 
    336     if(rc < 0) {
    337         if(rc == CINT_E_BAD_TYPE) {
    338             cint_ast_error(ast, rc, "cannot declare variable of type '%s'",
    339                            desc.basetype); 
    340         }
    341         else {
    342             cint_ast_error(ast, rc, "variable create error: %s\n",
    343                            cint_error_name(rc)); 
    344         }
    345         return NULL; 
    346     }
    347     else {
    348 
    349         if(ast->utype.declaration.init) {
    350             /* New variable has an initialization expression */
    351             cint_ast_t *id; 
    352             cint_ast_t *assign; 
    353 
    354             /*
    355              * Identifier AST
    356              */
    357             id = cint_ast_identifier(rv->name);
    358 
    359             /*
    360              * Assignment AST
    361              */
    362             assign = cint_ast_operator(cintOpAssign,
    363                                        id,
    364                                        ast->utype.declaration.init);
    365             cint_eval_ast(assign);
    366 
    367             /* sdk-67627: free the two ast allocated in this scope */ 
    368             cint_ast_free_single(assign);
    369             cint_ast_free_single(id);
    370         }    
    371 
    372         if(basetype_flags & CINT_AST_TYPE_F_CONST || 
    373             (desc.num_dimensions != 0 && desc.pcount == 0))  {
    374             rv->flags |= CINT_VARIABLE_F_CONST; 
    375         }
    376         if(basetype_flags & CINT_AST_TYPE_F_VOLATILE) {
    377             rv->flags |= CINT_VARIABLE_F_VOLATILE; 
    378         }
    379                
    380     }       
    381     return rv; 
    382 }
    383 
    384 static cint_variable_t* 
    385 __cint_eval_ast_Operator(cint_ast_t* ast)
    386 {
    387     return cint_eval_operator(ast); 
    388 }
    389 
    390 
    391 static int 
    392 __cint_eval_ast_dimensions_equal(int length0,
    393                                  int length1,
    394                                  int *dimensions0,
    395                                  int *dimensions1)
    396 {
    397     int i;
    398     if(length0 != length1) {
    399         return 0;
    400     }
    401 
    402     for(i = 0; i < length0; i++) {
    403         if(dimensions0[i] != dimensions1[i]) {
    404             return 0;
    405         }
    406     }
    407 
    408     return 1;
    409 }
    410 
    411 
    412 static cint_variable_t* 
    413 __cint_eval_ast_Function(cint_ast_t* ast)
    414 {
    415     cint_error_t rc;    
    416     cint_datatype_t* dtp; 
    417     cint_variable_t* rv = NULL; 
    418     cint_fparams_t fparams; 
    419     cint_parameter_desc_t* pd; 
    420     cint_ast_t* p; 
    421     int count; 
    422     int fcount; 
    423     cint_function_t* fp; 
    424     char _rstr[256] = {0};
    425 
    426     /*
    427      * Find the function 
    428      */
    429     if((dtp = ast->utype.function.dtp) == NULL) {
    430         
    431         dtp = CINT_MALLOC(sizeof(*dtp)); 
    432         if(dtp == NULL) {
    433             cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 
    434             return NULL; 
    435         }
    436 
    437         
    438         if( ((rc = cint_datatype_find(ast->utype.function.name, dtp)) < 0) ||
    439             ((dtp->flags & CINT_DATATYPE_FLAGS_FUNC) == 0) ) {
    440             cint_ast_error(ast, CINT_E_NOT_FOUND, "identifier '%s' is not a function", ast->utype.function.name); 
    441 
    442             CINT_FREE(dtp); 
    443             return NULL; 
    444         }
    445         
    446         ast->utype.function.dtp = dtp; 
    447     }       
    448     
    449     fp = dtp->basetype.fp; 
    450     
    451     if(dtp->flags & CINT_DATATYPE_F_FUNC_VARARG) {
    452         cint_vararg_f func = (cint_vararg_f)fp->addr;
    453         return func(ast); 
    454     }   
    455 
    456     /* 
    457      * Return value?
    458      */
    459     if(!cint_parameter_void(fp->params)) {
    460         /* Allocate variable to hold return type */
    461         cint_variable_create(&rv, 
    462                              NULL, 
    463                              fp->params,
    464                              0, 0); 
    465         if(rv) {
    466             fparams.rv = rv->data; 
    467         }
    468         else {
    469             fparams.rv = NULL; 
    470         }
    471     }   
    472 
    473     /*
    474      * Check parameter count
    475      */
    476     count = cint_ast_count(ast->utype.function.parameters); 
    477     fcount = fp->params ? cint_parameter_count(fp->params) - 1   /* Return value doesn't count */ : 0; 
    478     
    479     if(fcount == 1 && cint_parameter_void(fp->params+1)) { 
    480         fcount = 0; 
    481     }
    482     
    483     if(count != fcount) {
    484         cint_ast_error(ast, CINT_E_PARAM, "wrong number of parameters to function '%s' (expected %d but received %d)", 
    485                        fp->name, fcount, count); 
    486         return NULL; 
    487     }   
    488 
    489     
    490     /*
    491      * Parameters
    492      */
    493     for(count = 0, p = ast->utype.function.parameters, pd = fp->params+1; 
    494         p; 
    495         count ++, p = p->next, pd++) {
    496 
    497         /* Given parameter value */
    498         cint_variable_t* v = cint_eval_ast(p); 
    499         cint_datatype_t pdt; 
    500 
    501         if(v == NULL) {
    502             cint_ast_error(ast, CINT_E_PARAM, "error evaluating argument %d to function '%s'", 
    503                            count+1, fp->name); 
    504             return NULL; 
    505         }
    506 
    507         CINT_MEMSET(&pdt, 0, sizeof(pdt));
    508         /* Parameter type */
    509         if(cint_datatype_find(pd->basetype, &pdt) != CINT_E_NONE) {
    510             return NULL; 
    511         }
    512 
    513         if(cint_array_combine_dimensions(&pdt.desc, pd) != CINT_E_NONE) {
    514             return NULL;
    515         }
    516         pdt.desc.pcount += pd->pcount;
    517 
    518         if(cint_type_check(&v->dt, &pdt) == 0) {
    519             
    520             int rc; 
    521             cint_variable_t* nv; 
    522 
    523             /*
    524              * Not the same type. Special pointer conversions, where
    525              * an extra level of indirection is added.
    526              */
    527 
    528             /*
    529              * There may be other type conversions (string to
    530              * bcm_mac_t, string to bcm_ip_t) that should be
    531              * allowable.
    532              */
    533             
    534             if((!CINT_STRCMP(v->dt.desc.basetype, pdt.desc.basetype) ||
    535                 cint_type_compatible(&v->dt, &pdt) ) && 
    536                v->dt.desc.pcount == (pdt.desc.pcount-1) &&
    537                v->dt.desc.num_dimensions == (pdt.desc.num_dimensions -1) &&
    538                __cint_eval_ast_dimensions_equal(
    539                    pdt.desc.num_dimensions - 1,
    540                    v->dt.desc.num_dimensions == 0 ? 
    541                         v->cached_num_dimensions : 
    542                         v->dt.desc.num_dimensions, 
    543                    pdt.desc.dimensions + 1,
    544                    v->dt.desc.dimensions)) {
    545                 
    546                 /*
    547                  * The function expects a pointer to the given argument type. 
    548                  * Enable conversion. 
    549                  */
    550                 v = cint_variable_address(v); 
    551                 v->flags &= ~CINT_VARIABLE_F_CONST; 
    552             }
    553             else {
    554                 
    555                 /*
    556                  * Can we convert the argument through assignment? 
    557                  */
    558                 if((rc = cint_variable_create(&nv, NULL, pd, CINT_VARIABLE_F_AUTO, NULL)) != CINT_E_NONE) {
    559                     cint_ast_error(ast, rc, "error creating temporary variables"); 
    560                     return NULL; 
    561                 }
    562             
    563                 if(cint_eval_operator_internal(ast, cintOpAssign, nv, v) == nv) {
    564                     /* Conversion successful */
    565                     v = nv; 
    566                 }   
    567                 else {
    568                     char* f1 = cint_datatype_format(&v->dt, _rstr, 1); 
    569                     cint_ast_error(ast, CINT_E_PARAM, "arg %d to function '%s' was wrong type: expected %s, received %s", 
    570                                    count+1, fp->name, cint_datatype_format(&pdt, _rstr, 0), f1); 
    571                     CINT_FREE(f1); 
    572                     return NULL; 
    573                 }       
    574             }   
    575         }       
    576         
    577         /* Parameter is good to go */
    578         if(dtp->flags & CINT_DATATYPE_F_FUNC) {
    579             /* Static function call */
    580             fparams.args[count] = v->data; 
    581         }
    582         else {
    583             /* Stored for later -- see dynamic function call below */
    584             fparams.args[count] = v; 
    585         }
    586     }   
    587 
    588 
    589     /*
    590      * Call function
    591      */
    592     if(dtp->flags & CINT_DATATYPE_F_FUNC) {
    593         cint_ftrace(fp->name, 1); 
    594         rc = fp->body.wrapper(&fparams); 
    595         cint_ftrace(fp->name, 0); 
    596     }   
    597     else {
    598 
    599         /*
    600          * Clone all function parameters into a new scope using the expected parameter names
    601          */
    602         int i; 
    603         cint_variable_scope_push(fp->name); 
    604 
    605         for(i = 0, pd = fp->params+1; 
    606             i < count; 
    607             i++, pd++) {        
    608 
    609             cint_variable_t* pv = cint_variable_clone((cint_variable_t*)fparams.args[i]); 
    610             cint_variable_rename(pv, pd->name);
    611             cint_variable_auto_save(pv); 
    612         }       
    613         
    614         /* 
    615          * Evaluate function body
    616          */
    617         cint_ftrace(fp->name, 1); 
    618         __returnable++; 
    619         rv = cint_eval_asts(fp->body.statements); 
    620         if(rv) rv = cint_variable_clone(rv); 
    621         if(cint_errno == CINT_E_RETURN) {
    622             cint_errno = CINT_E_NONE; 
    623         }       
    624         __returnable--; 
    625         cint_ftrace(fp->name, 0); 
    626 
    627         /* Do not destroy return value when scope is popped */
    628         if(rv) rv->flags |= CINT_VARIABLE_F_NODESTROY; 
    629 
    630         /* Pop function scope */
    631         cint_variable_scope_pop(fp->name); 
    632 
    633         /* Add return value back into the local scope list */
    634         if(rv) {
    635             rv->flags &= ~CINT_VARIABLE_F_NODESTROY; 
    636             rv->flags &= ~CINT_VARIABLE_F_AUTO; 
    637             cint_variable_add(rv); 
    638         }       
    639     }
    640     
    641     return rv; 
    642 }
    643 
    644 static cint_variable_t* 
    645 __cint_eval_ast_Elist(cint_ast_t* ast)
    646 {
    647     cint_ast_t* p; 
    648     cint_variable_t* rv = NULL; 
    649 
    650     for(p = ast->utype.elist.list; p; p = p->next) {
    651         rv = cint_eval_ast(p); 
    652     }
    653     return rv; 
    654 }
    655 
    656 static cint_variable_t* 
    657 __cint_eval_ast_While(cint_ast_t* ast)
    658 {
    659     cint_variable_t* rv; 
    660 
    661     __breakable++; 
    662 
    663 
    664     if(ast->utype._while.order) {       
    665 
    666         rv = cint_eval_asts(ast->utype._while.statements);    
    667 
    668         if(CINT_BREAK()) {
    669             cint_errno = CINT_E_NONE; 
    670             return rv;
    671         } else if(CINT_CONTINUE()) {
    672             cint_errno = CINT_E_NONE; 
    673         } else if(CINT_RETURN()) {
    674             cint_errno = CINT_E_RETURN;
    675             return rv;
    676         }       
    677     }   
    678     
    679     while(cint_logical_value(cint_eval_ast(ast->utype._while.condition))) {
    680 
    681         rv = cint_eval_asts(ast->utype._while.statements);
    682 
    683         if(CINT_BREAK()) {
    684             cint_errno = CINT_E_NONE; 
    685             break; 
    686         } else if(CINT_CONTINUE()) {
    687             cint_errno = CINT_E_NONE; 
    688             continue; 
    689         } else if(CINT_RETURN()) {
    690             cint_errno = CINT_E_RETURN;
    691             return rv;
    692         } else if (cint_errno != CINT_E_NONE) {
    693             break;
    694         }
    695     }
    696 
    697     __breakable--; 
    698     return NULL; 
    699 }
    700 
    701 static int
    702 _for_cond(cint_ast_t* ast)
    703 {
    704     int cond = 1;
    705 
    706     if (ast && ast->ntype != cintAstEmpty) {
    707         cond = cint_logical_value(cint_eval_ast(ast));
    708     }
    709 
    710     return cond;
    711 }
    712 
    713 static cint_variable_t* 
    714 __cint_eval_ast_For(cint_ast_t* ast)
    715 {
    716     cint_variable_t* rv = NULL; 
    717 
    718     __breakable++; 
    719     
    720     for(cint_eval_ast(ast->utype._for.pre); 
    721         _for_cond(ast->utype._for.condition); 
    722         cint_eval_ast(ast->utype._for.post)) {
    723         
    724         rv = cint_eval_asts(ast->utype._for.statements); 
    725 
    726         if(CINT_BREAK()) {
    727             cint_errno = CINT_E_NONE; 
    728             break; 
    729         }
    730 
    731         if(CINT_CONTINUE()) {
    732             cint_errno = CINT_E_NONE; 
    733             continue; 
    734         }
    735 
    736         if(CINT_RETURN()) {
    737             break;
    738         }       
    739 
    740         if(CINT_EXIT()) {
    741             break;
    742         }
    743     }
    744 
    745     __breakable--; 
    746 
    747     return rv; 
    748 }
    749 
    750 static cint_variable_t* 
    751 __cint_eval_ast_If(cint_ast_t* ast)
    752 {
    753     cint_variable_t* rv = NULL; 
    754 
    755     if(cint_logical_value(cint_eval_ast(ast->utype._if.condition))) {
    756         rv = cint_eval_asts(ast->utype._if.statements); 
    757     }
    758     else if(ast->utype._if._else) {
    759         rv = cint_eval_asts(ast->utype._if._else); 
    760     }   
    761     return rv; 
    762 }
    763 
    764 static cint_variable_t*
    765 __cint_eval_ast_Return(cint_ast_t* ast)
    766 {
    767     cint_variable_t* rv = NULL; 
    768     
    769     if(!__returnable) {
    770         cint_ast_error(ast, CINT_E_BAD_AST, "return statement not within function"); 
    771         return NULL; 
    772     }   
    773 
    774     if(ast->utype._return.expression) {
    775         rv = cint_eval_ast(ast->utype._return.expression); 
    776     }
    777 
    778     cint_errno = CINT_E_RETURN; 
    779     return rv;
    780 }
    781 
    782 static cint_variable_t*
    783 __cint_eval_ast_Continue(cint_ast_t* ast)
    784 {
    785     if(!__breakable) {
    786         cint_ast_error(ast, CINT_E_BAD_AST, "continue statement not within loop"); 
    787     }
    788     else {
    789         cint_errno = CINT_E_CONTINUE; 
    790     }   
    791     return NULL; 
    792 }
    793 
    794 static cint_variable_t*
    795 __cint_eval_ast_Break(cint_ast_t* ast)
    796 {
    797     if(!__breakable) {
    798         cint_ast_error(ast, CINT_E_BAD_AST, "break statement not within loop"); 
    799     }
    800     else {
    801         cint_errno = CINT_E_BREAK; 
    802     }   
    803     return NULL; 
    804 }
    805     
    806 static cint_variable_t*
    807 __cint_eval_ast_Switch(cint_ast_t* ast)
    808 {
    809     cint_ast_t* s; 
    810     cint_ast_t* _default = NULL; 
    811     cint_ast_t* eq = NULL; 
    812     cint_variable_t* rv = NULL;
    813     
    814     /*
    815      * If this is a compound statement the brace operators might not get paired properly. 
    816      * The first open brace will never get executed, since it is not part of a case label. 
    817      * The final open brace may get executed as we fall through the labels (including the default). 
    818      *
    819      * The trailing closing brace is disabled for this reason. 
    820      */
    821     s = cint_ast_last(ast->utype._switch.statements); 
    822     if(cint_operator_type(s) == cintOpCloseBrace) {
    823         s->noexec = 1; 
    824     }
    825 
    826     /* Find and validate default case */
    827     for(s = ast->utype._switch.statements; s; s = s->next) {
    828         if( (s->ntype == cintAstCase) &&
    829             s->utype._case.expression == NULL) {
    830             
    831             if(_default) {
    832                 cint_ast_error(ast, CINT_E_BAD_AST, "more than one default label in switch statement"); 
    833                 return NULL; 
    834             }
    835             else {
    836                 _default = s; 
    837             }
    838         }
    839     }
    840 
    841     eq = cint_ast_operator(cintOpEqual, ast->utype._switch.expression, NULL); 
    842     for(s = ast->utype._switch.statements; s; s = s->next) {
    843         if( (s->ntype == cintAstCase) &&
    844             (s->utype._case.expression) ) {
    845             
    846             cint_variable_t* v; 
    847 
    848             /* Check the switch expression against the case expression */
    849             eq->utype.operator.right = s->utype._case.expression; 
    850             v = cint_eval_ast(eq); 
    851             if(v == NULL) {
    852                 rv = NULL;
    853                 break;
    854             }
    855             
    856             if(cint_logical_value(v) == 1) {
    857                 /* Begin executing all statements starting here */
    858                 __breakable++; 
    859                 rv = cint_eval_asts(s);
    860                 __breakable--; 
    861                 if(CINT_BREAK()) {
    862                     cint_errno = CINT_E_NONE; 
    863                 }                
    864                 if(CINT_RETURN()) {
    865                     cint_errno = CINT_E_RETURN;
    866                 }
    867                 else {
    868                     rv = NULL;
    869                 }
    870                 break;
    871             }   
    872         }
    873     }
    874 
    875     /* Free up the AST as the switch evaluation is complete. */
    876     cint_ast_free_single(eq);
    877     if (s) {
    878         return rv;
    879     }
    880 
    881     if(_default) {
    882         /* Execute default case */
    883         __breakable++; 
    884         rv = cint_eval_asts(_default);
    885         __breakable--; 
    886         if(CINT_BREAK()) {
    887             cint_errno = CINT_E_NONE; 
    888         }
    889         if(CINT_RETURN()) {
    890             cint_errno = CINT_E_RETURN;
    891             return rv;
    892         }                
    893     }
    894     return NULL; 
    895 }
    896 
    897 static cint_variable_t*
    898 __cint_eval_ast_Case(cint_ast_t* ast)
    899 {
    900     /* Evaluate all statements in case label */
    901     return cint_eval_asts(ast->utype._case.statements); 
    902 }
    903 
    904 
    905 
    906 static cint_variable_t*
    907 __cint_eval_ast_Print(cint_ast_t* ast)
    908 {
    909     /* cint_eval_ast_print.c */
    910     return cint_eval_ast_Print(ast); 
    911 }
    912 
    913 static cint_variable_t*
    914 __cint_eval_ast_Cint(cint_ast_t* ast)
    915 {
    916     /* cint_eval_ast_debug.c */
    917     return cint_eval_ast_Cint(ast); 
    918 }
    919 
    920 static cint_variable_t*
    921 __cint_eval_ast_StructureDef(cint_ast_t* ast)
    922 {
    923     cint_struct_type_t* cst = CINT_MALLOC(sizeof(*cst)); 
    924     cint_ast_t* m; 
    925     cint_parameter_desc_t* p0; 
    926     cint_parameter_desc_t* p; 
    927     cint_datatype_t dt; 
    928     int mcount; 
    929     int ssize = 0;
    930     char basetype[64];
    931     int rv;
    932     int sm_size;
    933     int dim_index;
    934 
    935     if(cst == NULL) {
    936         cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 
    937         return NULL; 
    938     }
    939     CINT_MEMSET((void *)cst, 0, sizeof(*cst));     
    940 
    941     CINT_MEMSET(&dt, 0, sizeof(dt));
    942 
    943     if (ast->utype.structuredef.name) {
    944         cst->name =
    945             CINT_STRDUP(ast->utype.structuredef.name->utype.identifier.s); 
    946         if (cst->name == NULL) {
    947             cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure");
    948             cint_datatype_clear_structure(cst);
    949             return NULL; 
    950         }
    951     } else {
    952         cint_ast_error(ast, CINT_E_BAD_AST, "structure name not found"); 
    953         cint_datatype_clear_structure(cst);
    954         return NULL; 
    955     }
    956     
    957     m = ast->utype.structuredef.members; 
    958     mcount = cint_ast_count(m); 
    959 
    960     sm_size = sizeof(*p)*(mcount+1);
    961     cst->struct_members = CINT_MALLOC(sm_size);         
    962     if (cst->struct_members == NULL) {
    963         cint_datatype_clear_structure(cst);
    964         cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 
    965         return NULL; 
    966     }
    967     CINT_MEMSET((void *)cst->struct_members, 0, sm_size);     
    968     
    969     p = (cint_parameter_desc_t *) cst->struct_members; 
    970 
    971     p0 = NULL;
    972 
    973     for(; m; m = m->next, p++) {
    974         if (m->ntype != cintAstDeclaration) {
    975             cint_ast_error(ast, CINT_E_BAD_AST,
    976                            "invalid structure definition");
    977             cint_datatype_clear_structure(cst);
    978             return NULL; 
    979         }
    980 
    981         /* point of this exercise is to set p->{basetype,name,pcount}
    982            and to determine member size.
    983         */
    984         p->name =
    985             CINT_STRDUP(m->utype.declaration.identifier->utype.string.s); 
    986 
    987         rv = _cint_eval_ast_declaration_parameter(m,
    988                                                   basetype,
    989                                                   sizeof(basetype),
    990                                                   NULL,
    991                                                   &p->pcount,
    992                                                   &p->num_dimensions,
    993                                                   p->dimensions);
    994 
    995         if (rv != CINT_E_NONE) {
    996             cint_datatype_clear_structure(cst);
    997             return NULL;
    998         }
    999         
   1000         if (CINT_STRLEN(basetype) > 0) {
   1001             /* count and array are already set, so now save the basetype */
   1002             p->basetype = CINT_STRDUP(basetype);
   1003 
   1004             /* Save this structure member in case future structure
   1005                members do not have a base type. Every structure member
   1006                has a right to a base type. If it does not have a base
   1007                type, this function will appoint one.
   1008             */
   1009             p0 = p;
   1010         } else {
   1011             /* This structure member doesn't have a basetype, so use
   1012                the basetype from the most recent structure member that
   1013                *did* have one. At least one structure member needs to
   1014                have a basetype. */
   1015             if (p0 == NULL) {
   1016                 /* It appears that no structure member had a basetype */
   1017                 cint_ast_error(ast, CINT_E_BAD_AST,
   1018                                "no default member type definition found"); 
   1019                 cint_datatype_clear_structure(cst);
   1020                 return NULL; 
   1021             }
   1022             p->basetype = CINT_STRDUP(p0->basetype);
   1023             p->pcount   = p0->pcount;
   1024             p->num_dimensions = p0->num_dimensions;
   1025             for(dim_index = 0;
   1026                 dim_index < p0->num_dimensions; 
   1027                 dim_index++) {
   1028                 p->dimensions[dim_index] = 
   1029                     p0->dimensions[dim_index];
   1030             }
   1031         }
   1032 
   1033         if(cint_datatype_find(p->basetype, &dt) != CINT_E_NONE) {
   1034             cint_ast_error(ast, CINT_E_BAD_AST,
   1035                            "unknown type '%s' in structure definition",
   1036                            p->basetype); 
   1037             cint_datatype_clear_structure(cst);
   1038             return NULL; 
   1039         }
   1040 
   1041         for(dim_index = 0;
   1042             dim_index < p->num_dimensions; 
   1043             dim_index++) {
   1044             dt.desc.dimensions[dim_index + dt.desc.num_dimensions] = 
   1045                 p->dimensions[dim_index];
   1046         }
   1047         dt.desc.num_dimensions += p->num_dimensions;
   1048         dt.desc.pcount += p->pcount; 
   1049 
   1050         ssize += cint_datatype_size(&dt); 
   1051 
   1052         /* All members start on a word aligned address */
   1053         while(ssize % 4) ssize++; 
   1054         
   1055     }    
   1056     
   1057     cst->size = ssize; 
   1058     cst->maddr = cint_maddr_dynamic_struct_t; 
   1059 
   1060     cint_datatype_add_structure(cst); 
   1061 
   1062     return NULL; 
   1063 }
   1064 
   1065 /* function parameter and return types can be a composite type, like
   1066    unsigned int, but only one of those AST nodes that comprise the
   1067    composite is the 'Type' AST node. */
   1068 static cint_ast_t *
   1069 __cint_ast_basetype(cint_ast_t* ast)
   1070 {
   1071     int rc = CINT_E_NONE;
   1072     char basetype[64];
   1073     if(ast) {
   1074         rc = cint_eval_type_list(ast,
   1075                                  basetype, sizeof(basetype),
   1076                                  NULL, 0);
   1077         if (rc != CINT_E_NONE) {
   1078             return NULL;
   1079         }
   1080         if(CINT_AST(ast,Type) && ast->utype.type.s){
   1081             CINT_FREE((char*) ast->utype.type.s);
   1082         }
   1083         ast->ntype = cintAstType;
   1084         ast->utype.type.s = CINT_STRDUP(basetype);
   1085     }
   1086 
   1087     return ast;
   1088 }
   1089 
   1090 static cint_variable_t*
   1091 __cint_eval_ast_FunctionDef(cint_ast_t* ast)
   1092 {
   1093     cint_function_t* f;
   1094 
   1095     cint_ast_t* decl = ast->utype.functiondef.declaration; 
   1096     cint_ast_t* params = ast->utype.functiondef.parameters;
   1097     cint_ast_t* ret;
   1098     cint_ast_t* name;
   1099 
   1100     cint_parameter_desc_t* p; 
   1101     int count; 
   1102     int desc_size;
   1103     cint_datatype_t dt;
   1104 
   1105     if (decl == NULL) {
   1106         cint_ast_error(ast, CINT_E_BAD_AST, "cannot determine declaration"); 
   1107         return NULL; 
   1108     }
   1109     if (decl->ntype == cintAstType
   1110         || decl->ntype == cintAstInteger
   1111 #if CINT_CONFIG_INCLUDE_LONGLONGS == 1
   1112         || decl->ntype == cintAstLongLong
   1113 #endif
   1114 #if CINT_CONFIG_INCLUDE_FLOATS == 1
   1115         || decl->ntype == cintAstFloat
   1116 #endif
   1117         ) {
   1118         /* This is a declaration, not a definition, so there's really
   1119            nothing to do, yet. */
   1120         return NULL;
   1121     } else if (decl->ntype != cintAstDeclaration) {
   1122         cint_internal_error(__FILE__, __LINE__,
   1123                             "Node type %d unexpected", decl->ntype);
   1124         return NULL;
   1125     }
   1126 
   1127     /* Function name */
   1128     name = decl->utype.declaration.identifier;
   1129     if (!CINT_AST(name, Identifier)) {
   1130         cint_internal_error(__FILE__, __LINE__,
   1131                             "Node type %d unexpected", name->ntype);
   1132         return NULL; 
   1133     }
   1134 
   1135     f = CINT_MALLOC(sizeof(*f));
   1136     if (f == NULL) {
   1137         cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 
   1138         return NULL; 
   1139     }
   1140     CINT_MEMSET(f, 0, sizeof(*f)); 
   1141 
   1142     f->name = CINT_STRDUP(name->utype.identifier.s);    
   1143         
   1144     /* Return Type */
   1145     ret = __cint_ast_basetype(decl->utype.declaration.type);
   1146 
   1147     if (ret == NULL) {
   1148         cint_internal_error(__FILE__, __LINE__, "unknown return type");
   1149         cint_datatype_clear_function(f);
   1150         return NULL; 
   1151     }
   1152 
   1153     if (ret->utype.type.s == NULL) {
   1154         cint_internal_error(__FILE__, __LINE__, "unknown return basetype");
   1155         cint_datatype_clear_function(f);
   1156         return NULL; 
   1157     }
   1158     
   1159     /* Number of parameters */
   1160     count = cint_ast_count(params); 
   1161 
   1162     /* Allocate parameter description array to hold parameters and return value */
   1163     desc_size = sizeof(*p)*(count+2);
   1164     p = CINT_MALLOC(desc_size);         
   1165     if (p == NULL) {
   1166         cint_ast_error(ast, CINT_E_MEMORY, "memory allocation failure"); 
   1167         cint_datatype_clear_function(f);
   1168         return NULL; 
   1169     }
   1170     CINT_MEMSET(p, 0, desc_size); 
   1171     f->params = p; 
   1172 
   1173     p->basetype = CINT_STRDUP(ret->utype.type.s);
   1174     p->name = CINT_STRDUP("r"); 
   1175     p->pcount = decl->utype.declaration.pcount; 
   1176     p->num_dimensions = 0;
   1177     
   1178     for(count = 1, params = ast->utype.functiondef.parameters; 
   1179         params; 
   1180         params = params->next, count++) {
   1181         if (CINT_AST(params, Declaration)) {
   1182             cint_ast_t *ty;
   1183             cint_ast_t *ident = params->utype.declaration.identifier;
   1184 
   1185             ty = __cint_ast_basetype(params->utype.declaration.type);
   1186 
   1187             if (ty == NULL) {
   1188                 cint_ast_error(ast, CINT_E_BAD_AST,
   1189                                "param type not found"); 
   1190                 cint_datatype_clear_function(f);
   1191                 return NULL; 
   1192             }
   1193             
   1194             if (ident && !CINT_AST(ident, Identifier)) {
   1195                 cint_ast_error(ast, CINT_E_BAD_AST,
   1196                                "unexpected param ident AST %d", ident->ntype);
   1197                 cint_datatype_clear_function(f);
   1198                 return NULL;
   1199             }
   1200 
   1201             /* A NULL basetype is used as a sentinel for the parameter
   1202                array, so it is not allowed to be NULL here */
   1203             if (ty->utype.type.s == NULL) {
   1204                 cint_ast_error(ast, CINT_E_BAD_AST, "base type not found");
   1205                 cint_datatype_clear_function(f);
   1206                 return NULL;
   1207             }
   1208             
   1209             
   1210 
   1211             p[count].basetype = CINT_STRDUP(ty->utype.type.s);
   1212 
   1213             p[count].name = ident ?
   1214                 CINT_STRDUP(ident->utype.identifier.s) : NULL; 
   1215             p[count].pcount = params->utype.declaration.pcount; 
   1216             p[count].num_dimensions = 0;
   1217             /* for CINT, parameters are either IN or INOUT */
   1218             p[count].flags = CINT_PARAM_IN;
   1219             if (p[count].pcount > 0) {
   1220                 cint_ast_t *modifier = params->utype.declaration.type;
   1221 
   1222                 /* const pointer is in, else in/out */
   1223                 if (!(CINT_AST(modifier, Integer) &&
   1224                       modifier->utype.integer.i == CINT_AST_TYPE_F_CONST)) {
   1225                     p[count].flags |= CINT_PARAM_OUT;
   1226                 }
   1227             }
   1228         } else {
   1229             /* If it is not a declaration, treat it as a dummy parameter.
   1230                There still needs to be a basetype, though. */
   1231             p[count].basetype = CINT_STRDUP("void");
   1232         }
   1233     }
   1234     p[count].basetype = NULL; 
   1235     
   1236     /* Statements */
   1237     f->body.statements = ast->utype.functiondef.statements; 
   1238 
   1239     /* if function is already defined, remove previous definition */
   1240     CINT_MEMSET(&dt, 0, sizeof(dt));
   1241     if(CINT_E_NONE == cint_datatype_find(f->name, &dt)) {
   1242         cint_datatype_delete_function(f->name);
   1243     }
   1244     
   1245     /*
   1246      * Register with interpreter
   1247      */
   1248     cint_interpreter_add_function(f);
   1249     return NULL; 
   1250 }
   1251 
   1252 
   1253 int
   1254 cint_interpreter_callback(cint_function_pointer_t* cb, int nargs, int nreturn, ...)
   1255 {
   1256     int i; 
   1257     cint_datatype_t dt; 
   1258     cint_parameter_desc_t* params; 
   1259     cint_variable_t* v; 
   1260     const char* fname; 
   1261     int returns; 
   1262     int fcount;
   1263     int errno_save;
   1264     va_list args; 
   1265 
   1266     va_start(args,nreturn); 
   1267 
   1268     if(cb == NULL) {
   1269         cint_internal_error(__FILE__, __LINE__, "callback pointer is NULL"); 
   1270         va_end(args); 
   1271         return 0; 
   1272     }
   1273     
   1274     fname = (char*)cb->data; 
   1275 
   1276     if(fname == NULL) {
   1277         cint_internal_error(__FILE__, __LINE__, "callback name is NULL"); 
   1278         va_end(args); 
   1279         return 0; 
   1280     }
   1281 
   1282     CINT_MEMSET(&dt, 0, sizeof(dt));
   1283     if(cint_datatype_find(fname, &dt) != 0) {
   1284         cint_internal_error(__FILE__, __LINE__, "callback type '%s' was not found", fname); 
   1285         va_end(args); 
   1286         return 0; 
   1287     }   
   1288 
   1289     if (CINT_STRLEN(fname) == 0) {
   1290         cint_internal_error(__FILE__, __LINE__, "callback name is NULL String");
   1291         va_end(args); 
   1292         return 0;
   1293     }
   1294 
   1295     /*
   1296      * Call dynamic function. 
   1297      *
   1298      * Sanity check the signature to detect mismatched type errors. 
   1299      * This could be augmented to pass full type information back with the parameters. 
   1300      */    
   1301     returns = !cint_parameter_void(dt.basetype.fp->params); 
   1302     fcount = cint_parameter_count(dt.basetype.fp->params) - 1; 
   1303     if(cint_parameter_void(dt.basetype.fp->params+1)) fcount--; 
   1304 
   1305     if(fcount != nargs) {
   1306         cint_internal_error(__FILE__, __LINE__, "callback type '%s' was not passed the correct number of arguments (expected %d, received %d)", 
   1307                             fname, fcount, nargs); 
   1308         va_end(args); 
   1309         return 0; 
   1310     }
   1311     if((returns) && (nreturn == 0)) {
   1312         cint_internal_error(__FILE__, __LINE__, "callback type '%s' returns a value but calling function did not specify one", fname); 
   1313         va_end(args); 
   1314         return 0; 
   1315     }
   1316     if((returns == 0) && (nreturn)) {
   1317         cint_internal_error(__FILE__, __LINE__, "callback type '%s' does not return a value but calling function expects one", fname); 
   1318         va_end(args); 
   1319         return 0; 
   1320     }   
   1321 
   1322     cint_variable_scope_push(fname); 
   1323     for(i = 0, params = dt.basetype.fp->params+1; params && params->basetype; params++, i++) {
   1324         void* addr;
   1325         if(cint_parameter_void(params)) {
   1326             continue;
   1327         }
   1328         /* Get the address of this variable */
   1329         addr = va_arg(args, void*); 
   1330         
   1331         /* Create a variable of the appropriate type with this address */
   1332         cint_variable_create(&v, 
   1333                              params->name, 
   1334                              params, 
   1335                              CINT_VARIABLE_F_SDATA, 
   1336                              addr); 
   1337     }
   1338     /* Evaluate function body */
   1339     cint_ftrace(dt.basetype.fp->name, 1); 
   1340     __returnable++;
   1341     errno_save = cint_errno;
   1342     v = cint_eval_asts(dt.basetype.fp->body.statements); 
   1343     cint_errno = errno_save;
   1344     __returnable--; 
   1345     cint_ftrace(dt.basetype.fp->name, 0); 
   1346     
   1347     /* Return value? */
   1348     if(v && returns) {
   1349         void* addr = va_arg(args, void*); 
   1350         if(addr) {
   1351             cint_datatype_t rt; 
   1352             CINT_MEMSET(&rt, 0, sizeof(rt));
   1353             if (cint_datatype_find(dt.basetype.fp->params->basetype, &rt) != 0) {
   1354                 cint_internal_error(__FILE__, __LINE__,
   1355                                     "callback return type '%s' was not found",
   1356                                     dt.basetype.fp->params->basetype); 
   1357                 va_end(args); 
   1358                 return 0; 
   1359             }
   1360 
   1361             if (cint_type_check(&rt, &v->dt)) {
   1362                 CINT_MEMCPY(addr, v->data, v->size);
   1363             } else {
   1364                 /* At least clear out the return value to avoid
   1365                    valgrind complaints. */
   1366                 int size;
   1367 
   1368                 size = cint_datatype_size(&rt);
   1369                 if (size > 0) {
   1370                     CINT_MEMSET(addr, 0, size);
   1371                 }
   1372                 cint_ast_error(dt.basetype.fp->body.statements,
   1373                                CINT_E_BAD_AST,
   1374                                "return type mismatch"); 
   1375             }
   1376         }
   1377     }
   1378 
   1379     cint_variable_scope_pop(fname); 
   1380 
   1381     va_end(args); 
   1382 
   1383     return 0; 
   1384 }
   1385 
   1386 
   1387 
   1388 
   1389 
   1390 struct {
   1391     const char* name; 
   1392     cint_variable_t* (*handler)(cint_ast_t* ast); 
   1393 } __ast_handler_table[] = {
   1394 
   1395 #define CINT_AST_LIST_ENTRY(_entry) { #_entry, __cint_eval_ast_##_entry },
   1396 #include "cint_ast_entry.h"
   1397 
   1398     { NULL }
   1399 };
   1400 
   1401 cint_variable_t* 
   1402 cint_eval_ast(cint_ast_t* ast)
   1403 {
   1404     cint_variable_t* rv = NULL; 
   1405     cint_ast_type_t type; 
   1406 
   1407     cint_atrace(ast); 
   1408 
   1409     if(ast == NULL) {
   1410         return NULL; 
   1411     }
   1412 
   1413     type = ast->ntype; 
   1414 
   1415     if(type < 0 || type >= cintAstLast) {
   1416         return NULL; 
   1417     }
   1418     
   1419     CINT_DTRACE(("AST: %s", __ast_handler_table[type].name)); 
   1420     if(ast->noexec) {
   1421         CINT_DTRACE((" marked as noexec\n")); 
   1422     }
   1423     else {
   1424         rv = __ast_handler_table[type].handler(ast); 
   1425     }
   1426     return rv;
   1427 }
   1428     
   1429 cint_variable_t*
   1430 cint_eval_asts(cint_ast_t* ast)
   1431 {
   1432     cint_variable_t* rv = NULL; 
   1433     cint_ast_t* p; 
   1434     
   1435     cint_errno = CINT_E_NONE; 
   1436 
   1437     for(p = ast; p && (cint_errno == CINT_E_NONE); p = p->next) {
   1438         rv = cint_eval_ast(p); 
   1439     }
   1440     cint_variable_auto_save(rv); 
   1441     cint_variable_auto_clear();         
   1442     return rv; 
   1443 }