parser_misc.c File Reference

#include <stdio.h>
#include "db.h"
#include "defines.h"
#include "expr.h"
#include "link.h"
#include "obfuscate.h"
#include "parser_misc.h"
#include "static.h"
#include "util.h"

Functions

void VLerror (char *msg)
void VLwarn (char *msg)
int VLwrap ()
void parser_dealloc_sig_range (sig_range *range, bool rm_ptr)
 Deallocates the curr_sig_width variable if it has been previously set.
sig_rangeparser_copy_curr_range (bool packed)
 Creates a copy of the curr_range variable.
void parser_copy_range_to_curr_range (sig_range *range, bool packed)
 Copies specifies static expressions to the current range.
void parser_explicitly_set_curr_range (static_expr *left, static_expr *right, bool packed)
 Deallocates and sets the curr_range variable from explicitly set values.
void parser_implicitly_set_curr_range (int left_num, int right_num, bool packed)
 Deallocates and sets the curr_range variable from implicitly set values.
bool parser_check_generation (unsigned int gen)
 Checks the specified generation value to see if it holds in the specified module.
void parser_handle_case_statement (exp_op_type case_op, expression *cs_expr, expression *c_expr, statement *cs_stmt, unsigned int line, unsigned int ppline, statement **last_stmt)
 Adds the specified case statement item to the statement tree.
void parser_handle_case_statement_list (exp_op_type case_op, expression *cs_expr, expression *c_expr, statement *cs_stmt, unsigned int line, unsigned int ppline, statement **last_stmt)
 Adds each expression within an expression list as a cast statement item.
void parser_handle_generate_case_statement (expression *cs_expr, expression *c_expr, gen_item *gi, unsigned int line, gen_item **last_gi)
 Addes the given expression as a case statement item.
void parser_handle_generate_case_statement_list (expression *cs_expr, expression *c_expr, gen_item *gi, unsigned int line, gen_item **last_gi)

Variables

char user_msg [USER_MSG_LENGTH]
sig_range curr_prange
sig_range curr_urange
func_unitcurr_funit
str_linkgen_mod_head
unsigned int flag_global_generation
unsigned error_count = 0
static unsigned warn_count = 0

Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
12/19/2001

Function Documentation

bool parser_check_generation ( unsigned int  gen  ) 

Checks the specified generation value to see if it holds in the specified module.

Returns:
Returns TRUE if the given gen value (see Supported Generations for legal values) is less than or equal to the generation value specified for the current functional unit (or globally).
Parameters:
gen Generation value to check

References flag_global_generation, func_unit_s::name, PROFILE, PROFILE_END, str_link_find(), and str_link_s::suppl.

00300   { PROFILE(PARSER_CHECK_GENERATION);
00301 
00302   bool      retval;    /* Return value for this function */
00303   str_link* strl;      /* Pointer to the str_link found to match the given mod_name */
00304 
00305   /* Search the generation module list to see if the specified module name has been set there */
00306   if( (curr_funit != NULL) && ((strl = str_link_find( curr_funit->name, gen_mod_head )) != NULL) ) {
00307 
00308     /* The user has specified a generation value for this module so check it against this */
00309     retval = (gen <= strl->suppl);
00310 
00311   } else {
00312 
00313     retval = (gen <= flag_global_generation);
00314 
00315   }
00316 
00317   PROFILE_END;
00318 
00319   return( retval );
00320 
00321 }

sig_range* parser_copy_curr_range ( bool  packed  ) 

Creates a copy of the curr_range variable.

Parameters:
packed Specifies if curr_prange (TRUE) or curr_urange (FALSE) should be copied.

Creates a copy of the curr_range variable for stored usage.

References sig_range_s::clear, sig_range_s::dim, sig_range_s::dim_num, static_expr_s::exp, sig_range_s::exp_dealloc, FALSE, vector_width_s::implicit, vector_width_s::left, malloc_safe, static_expr_s::num, PROFILE, and vector_width_s::right.

00156   { PROFILE(PARSER_COPY_CURR_RANGE);
00157 
00158   sig_range* crange;  /* Pointer to curr_range variable to copy */
00159   sig_range* range;   /* Copy of the curr_range variable */
00160   int        i;       /* Loop iterator */
00161 
00162   /* Get the correct global range */
00163   crange = packed ? &curr_prange : &curr_urange;
00164 
00165   /* Allocate memory for the new range */
00166   range = (sig_range*)malloc_safe( sizeof( sig_range ) );
00167 
00168   /* Set curr_range */
00169   range->dim_num = crange->dim_num;
00170   if( crange->dim_num > 0 ) {
00171     range->dim = (vector_width*)malloc_safe( sizeof( vector_width ) * crange->dim_num );
00172     for( i=0; i<crange->dim_num; i++ ) {
00173       range->dim[i].left       = (static_expr*)malloc_safe( sizeof( static_expr ) );
00174       range->dim[i].left->num  = crange->dim[i].left->num;
00175       range->dim[i].left->exp  = crange->dim[i].left->exp;
00176       range->dim[i].right      = (static_expr*)malloc_safe( sizeof( static_expr ) );
00177       range->dim[i].right->num = crange->dim[i].right->num;
00178       range->dim[i].right->exp = crange->dim[i].right->exp;
00179       range->dim[i].implicit   = FALSE;
00180     }
00181   }
00182   range->clear       = crange->clear;
00183   range->exp_dealloc = crange->exp_dealloc;
00184 
00185   return( range );
00186 
00187 }

void parser_copy_range_to_curr_range ( sig_range range,
bool  packed 
)

Copies specifies static expressions to the current range.

Parameters:
range Pointer to signal vector range
packed Specifies if curr_prange (TRUE) or curr_urange (FALSE) should be updated.

Copies specifies static expressions to the specified current range. Primarily used for copying typedef'ed ranges to the current range.

References sig_range_s::clear, sig_range_s::dim, sig_range_s::dim_num, static_expr_s::exp, sig_range_s::exp_dealloc, FALSE, vector_width_s::implicit, vector_width_s::left, malloc_safe, static_expr_s::num, parser_dealloc_sig_range(), PROFILE, and vector_width_s::right.

00199   { PROFILE(PARSER_COPY_RANGE_TO_CURR_RANGE);
00200 
00201   sig_range* crange = packed ? &curr_prange : &curr_urange;  /* Pointer to curr_Xrange to use */
00202   int        i;                                              /* Loop iterator */
00203 
00204   /* Deallocate any memory currently associated with the curr_range variable */
00205   parser_dealloc_sig_range( crange, FALSE );
00206 
00207   /* Set curr_range */
00208   crange->dim_num = range->dim_num;
00209   if( range->dim_num > 0 ) {
00210     crange->dim = (vector_width*)malloc_safe( sizeof( vector_width ) * range->dim_num );
00211     for( i=0; i<range->dim_num; i++ ) {
00212       crange->dim[i].left       = (static_expr*)malloc_safe( sizeof( static_expr ) );
00213       crange->dim[i].left->num  = range->dim[i].left->num;
00214       crange->dim[i].left->exp  = range->dim[i].left->exp;
00215       crange->dim[i].right      = (static_expr*)malloc_safe( sizeof( static_expr ) );
00216       crange->dim[i].right->num = range->dim[i].right->num;
00217       crange->dim[i].right->exp = range->dim[i].right->exp;
00218       crange->dim[i].implicit   = FALSE;
00219     }
00220   }
00221   crange->clear       = range->clear;
00222   crange->exp_dealloc = range->exp_dealloc;
00223 
00224 }

void parser_dealloc_sig_range ( sig_range range,
bool  rm_ptr 
)

Deallocates the curr_sig_width variable if it has been previously set.

Deallocates all allocated memory within associated signal range variable, but does not deallocate the pointer itself (unless rm_ptr is set to TRUE).

Parameters:
range Pointer to signal range to deallocate
rm_ptr If TRUE, deallocates the pointer to the given range

References sig_range_s::clear, sig_range_s::dim, sig_range_s::dim_num, sig_range_s::exp_dealloc, FALSE, free_safe, vector_width_s::left, PROFILE, PROFILE_END, vector_width_s::right, static_expr_dealloc(), and TRUE.

Referenced by funit_clean(), parse_design(), parser_copy_range_to_curr_range(), parser_explicitly_set_curr_range(), and parser_implicitly_set_curr_range().

00118   { PROFILE(PARSER_DEALLOC_SIG_RANGE);
00119 
00120   int i;  /* Loop iterator */
00121 
00122   for( i=0; i<range->dim_num; i++ ) {
00123     static_expr_dealloc( range->dim[i].left,  range->exp_dealloc );
00124     static_expr_dealloc( range->dim[i].right, range->exp_dealloc );
00125   }
00126 
00127   if( i > 0 ) {
00128     free_safe( range->dim, (sizeof( vector_width ) * range->dim_num) );
00129     range->dim     = NULL;
00130     range->dim_num = 0;
00131   }
00132 
00133   /* Clear the clear bit */
00134   range->clear       = FALSE;
00135 
00136   /* Set the deallocation bit */
00137   range->exp_dealloc = TRUE;
00138 
00139   /* Deallocate pointer itself, if specified to do so */
00140   if( rm_ptr ) {
00141     free_safe( range, sizeof( sig_range ) );
00142   }
00143 
00144   PROFILE_END;
00145 
00146 }

void parser_explicitly_set_curr_range ( static_expr left,
static_expr right,
bool  packed 
)

Deallocates and sets the curr_range variable from explicitly set values.

Parameters:
left Pointer to static expression of expression/value on the left side of the colon.
right Pointer to static expression of expression/value on the right side of the colon.
packed If TRUE, adds a packed dimension; otherwise, adds an unpacked dimension.

Deallocates and sets the curr_range variable from static expressions

References sig_range_s::clear, sig_range_s::dim, sig_range_s::dim_num, FALSE, vector_width_s::implicit, vector_width_s::left, parser_dealloc_sig_range(), PROFILE, realloc_safe, and vector_width_s::right.

00237   { PROFILE(PARSER_EXPLICITLY_SET_CURR_RANGE);
00238 
00239   sig_range* crange;  /* Pointer to curr_Xrange to change */
00240 
00241   /* Get a pointer to the correct signal range to use */
00242   crange = packed ? &curr_prange : &curr_urange;
00243 
00244   /* Clear current range, if specified */
00245   if( crange->clear ) {
00246     parser_dealloc_sig_range( crange, FALSE );
00247   }
00248 
00249   /* Now rebuild current range, adding in the new range */
00250   crange->dim_num++;
00251   crange->dim = (vector_width*)realloc_safe( crange->dim, (sizeof( vector_width ) * (crange->dim_num - 1)), (sizeof( vector_width ) * crange->dim_num) );
00252   crange->dim[crange->dim_num - 1].left     = left;
00253   crange->dim[crange->dim_num - 1].right    = right;
00254   crange->dim[crange->dim_num - 1].implicit = FALSE;
00255 
00256 }

void parser_handle_case_statement ( exp_op_type  case_op,
expression cs_expr,
expression c_expr,
statement cs_stmt,
unsigned int  line,
unsigned int  ppline,
statement **  last_stmt 
)

Adds the specified case statement item to the statement tree.

Adds the given case statement expression for individual expressions (if it is a list) and adds these expressions as case item statements.

Parameters:
case_op Case statement operation
cs_expr Pointer to case_statement expression
c_expr Pointer to case expression
cs_stmt Pointer to case_statement statement
line Line number of default statement
ppline Preprocessor line of expression
last_stmt Pointer to last statement traversed

References db_connect_statement_false(), db_connect_statement_true(), db_create_expression(), db_create_statement(), EXP_OP_DEFAULT, expr_stmt_u::expr, FALSE, expression_s::line, expression_s::parent, PROFILE, and PROFILE_END.

Referenced by parser_handle_case_statement_list().

00335   { PROFILE(PARSER_HANDLE_CASE_STATEMENT);
00336 
00337   expression* expr;
00338   statement*  stmt;
00339 
00340   if( cs_expr != NULL ) {
00341     cs_expr->parent->expr = NULL;
00342     expr    = db_create_expression( cs_expr, c_expr, case_op, FALSE, cs_expr->line, 0, 0, NULL );
00343     ppline += (cs_expr->line - line);
00344   } else {
00345     expr = db_create_expression( NULL, NULL, EXP_OP_DEFAULT, FALSE, line, 0, 0, NULL );
00346   }
00347 
00348   stmt = db_create_statement( expr, ppline );
00349   db_connect_statement_true( stmt, cs_stmt );
00350   db_connect_statement_false( stmt, *last_stmt );
00351 
00352   if( stmt != NULL ) {
00353     *last_stmt = stmt;
00354   }
00355 
00356   PROFILE_END;
00357 
00358 }

void parser_handle_case_statement_list ( exp_op_type  case_op,
expression cs_expr,
expression c_expr,
statement cs_stmt,
unsigned int  line,
unsigned int  ppline,
statement **  last_stmt 
)

Adds each expression within an expression list as a cast statement item.

Parses an expression tree list structure, adding each expression within the list as an individual case expression.

Parameters:
case_op Case statement operation
cs_expr Pointer to case_statement expression
c_expr Pointer to case expression
cs_stmt Pointer to case_statement statement
line Default statement line
ppline Preprocessor line of expression
last_stmt Pointer to last statement traversed

References EXP_OP_LIST, expression_dealloc(), expression_s::left, expression_s::op, parser_handle_case_statement(), PROFILE, PROFILE_END, expression_s::right, and TRUE.

00372   { PROFILE(PARSER_HANDLE_CASE_STATEMENT_LIST);
00373 
00374   while( cs_expr->left->op == EXP_OP_LIST ) {
00375     expression* tmpexp = cs_expr;
00376     parser_handle_case_statement( case_op, cs_expr->right, c_expr, cs_stmt, line, ppline, last_stmt );
00377     cs_expr = cs_expr->left;
00378     expression_dealloc( tmpexp, TRUE );
00379   }
00380 
00381   parser_handle_case_statement( case_op, cs_expr->right, c_expr, cs_stmt, line, ppline, last_stmt );
00382   parser_handle_case_statement( case_op, cs_expr->left,  c_expr, cs_stmt, line, ppline, last_stmt ); 
00383 
00384   expression_dealloc( cs_expr, TRUE );
00385 
00386   PROFILE_END;
00387 
00388 }

void parser_handle_generate_case_statement ( expression cs_expr,
expression c_expr,
gen_item gi,
unsigned int  line,
gen_item **  last_gi 
)

Addes the given expression as a case statement item.

Adds the given case statement expression for individual expressions (if it is a list) and adds these expressions as case item statements.

Parameters:
cs_expr Pointer to case_statement expression
c_expr Pointer to case expression
gi Pointer to case_statement gen_item
line Line number of default statement
last_gi Pointer to last gen_item traversed

References db_add_expression(), db_create_expression(), db_gen_item_connect_false(), db_gen_item_connect_true(), db_get_curr_gen_block(), EXP_OP_CASE, EXP_OP_DEFAULT, expr_stmt_u::expr, FALSE, expression_s::line, expression_s::parent, PROFILE, and PROFILE_END.

Referenced by parser_handle_generate_case_statement_list().

00400   { PROFILE(PARSER_HANDLE_GENERATE_CASE_STATEMENT);
00401 
00402   expression* expr;
00403   gen_item*   stmt;
00404 
00405   if( cs_expr != NULL ) {
00406     cs_expr->parent->expr = NULL;
00407     expr = db_create_expression( cs_expr, c_expr, EXP_OP_CASE, FALSE, cs_expr->line, 0, 0, NULL );
00408   } else {
00409     expr = db_create_expression( NULL, NULL, EXP_OP_DEFAULT, FALSE, line, 0, 0, NULL );
00410   }
00411 
00412   db_add_expression( expr );
00413   stmt = db_get_curr_gen_block();
00414   db_gen_item_connect_true( stmt, gi );
00415   db_gen_item_connect_false( stmt, *last_gi );
00416 
00417   if( stmt != NULL ) {
00418     *last_gi = stmt;
00419   }
00420 
00421   PROFILE_END;
00422 
00423 }

void parser_handle_generate_case_statement_list ( expression cs_expr,
expression c_expr,
gen_item gi,
unsigned int  line,
gen_item **  last_gi 
)

Parses an expression tree list structure, adding each expression within the list as an individual case expression.

Parameters:
cs_expr Pointer to case_statement expression
c_expr Pointer to case expression
gi Pointer to case_statement gen_item
line Line number of default statement
last_gi Pointer to last gen_item traversed

References EXP_OP_LIST, expression_dealloc(), expression_s::left, expression_s::op, parser_handle_generate_case_statement(), PROFILE, PROFILE_END, expression_s::right, and TRUE.

00435   { PROFILE(PARSER_HANDLE_GENERATE_CASE_STATEMENT_LIST);
00436 
00437   while( cs_expr->left->op == EXP_OP_LIST ) {
00438     expression* tmpexp = cs_expr;
00439     parser_handle_generate_case_statement( cs_expr->right, c_expr, gi, line, last_gi );
00440     cs_expr = cs_expr->left;
00441     expression_dealloc( tmpexp, TRUE );
00442   }
00443 
00444   parser_handle_generate_case_statement( cs_expr->right, c_expr, gi, line, last_gi );
00445   parser_handle_generate_case_statement( cs_expr->left,  c_expr, gi, line, last_gi ); 
00446 
00447   expression_dealloc( cs_expr, TRUE );
00448 
00449   PROFILE_END;
00450 
00451 }

void parser_implicitly_set_curr_range ( int  left_num,
int  right_num,
bool  packed 
)

Deallocates and sets the curr_range variable from implicitly set values.

Parameters:
left_num Integer value of left expression
right_num Integer value of right expression
packed If TRUE, adds a packed dimension; otherwise, adds an unpacked dimension.

Deallocates and sets the curr_range variable from known integer values.

References sig_range_s::clear, sig_range_s::dim, sig_range_s::dim_num, static_expr_s::exp, FALSE, vector_width_s::implicit, vector_width_s::left, malloc_safe, static_expr_s::num, parser_dealloc_sig_range(), PROFILE, realloc_safe, vector_width_s::right, and TRUE.

00269   { PROFILE(PARSER_IMPLICITLY_SET_CURR_RANGE);
00270 
00271   sig_range* crange;  /* Pointer to curr_Xrange to modify */
00272 
00273   /* Get a pointer to the curr_Xrange to modify */
00274   crange = packed ? &curr_prange : &curr_urange;
00275 
00276   /* Clear current range, if specified */
00277   if( crange->clear ) {
00278     parser_dealloc_sig_range( crange, FALSE );
00279   }
00280 
00281   /* Now rebuild current range, adding in the new range */
00282   crange->dim_num++;
00283   crange->dim = (vector_width*)realloc_safe( crange->dim, (sizeof( vector_width ) * (crange->dim_num - 1)), (sizeof( vector_width ) * crange->dim_num) );
00284   crange->dim[crange->dim_num - 1].left       = (static_expr*)malloc_safe( sizeof( static_expr ) );
00285   crange->dim[crange->dim_num - 1].left->num  = left_num;
00286   crange->dim[crange->dim_num - 1].left->exp  = NULL;
00287   crange->dim[crange->dim_num - 1].right      = (static_expr*)malloc_safe( sizeof( static_expr ) );
00288   crange->dim[crange->dim_num - 1].right->num = right_num;
00289   crange->dim[crange->dim_num - 1].right->exp = NULL;
00290   crange->dim[crange->dim_num - 1].implicit   = TRUE;
00291 
00292 }

void VLerror ( char *  msg  ) 

Outputs specified error message string to standard output and increments error count.

Parameters:
msg String containing error message to display to user

References error_count, FATAL, FATAL_WRAP, obf_file, print_output(), PROFILE, PROFILE_END, user_msg, USER_MSG_LENGTH, and yylloc.

00059   { PROFILE(VLERROR);
00060 
00061   unsigned int rv;
00062 
00063   error_count++;
00064   
00065   rv = snprintf( user_msg, USER_MSG_LENGTH, "%s,", msg );
00066   assert( rv < USER_MSG_LENGTH );
00067   print_output( user_msg, FATAL, __FILE__, __LINE__ );
00068   rv = snprintf( user_msg, USER_MSG_LENGTH, "File: %s, Line: %u, Column: %u",
00069                  obf_file( yylloc.text ), yylloc.first_line, yylloc.first_column );
00070   assert( rv < USER_MSG_LENGTH );
00071   print_output( user_msg, FATAL_WRAP, __FILE__, __LINE__ );
00072 
00073   PROFILE_END;
00074 
00075 }

void VLwarn ( char *  msg  ) 

Outputs specified warning message string to standard output and increments warning count.

Parameters:
msg String containing warning message to display to user

References obf_file, print_output(), PROFILE, PROFILE_END, user_msg, USER_MSG_LENGTH, warn_count, WARNING, WARNING_WRAP, and yylloc.

00083   { PROFILE(VLWARN);
00084 
00085   unsigned int rv;
00086 
00087   warn_count++;
00088   
00089   rv = snprintf( user_msg, USER_MSG_LENGTH, "%s,", msg );
00090   assert( rv < USER_MSG_LENGTH );
00091   print_output( user_msg, WARNING, __FILE__, __LINE__ );
00092   rv = snprintf( user_msg, USER_MSG_LENGTH, "File: %s, Line: %u, Column: %u",
00093                  obf_file( yylloc.text ), yylloc.first_line, yylloc.first_column );
00094   assert( rv < USER_MSG_LENGTH );
00095   print_output( user_msg, WARNING_WRAP, __FILE__, __LINE__ );
00096 
00097   PROFILE_END;
00098 
00099 }

int VLwrap (  ) 

Called by parser when file wrapping is required.

00104              {
00105 
00106   return -1;
00107 
00108 }


Variable Documentation

Pointer to the functional unit structure for the functional unit that is currently being parsed.

unsigned error_count = 0

Counts the number of errors found during the parsing process.

Referenced by parse_design(), and VLerror().

unsigned int flag_global_generation

Specifies the supported global generation value

Referenced by parser_check_generation(), score_parse_args(), and search_init().

Pointer to the head of the generation module list

char user_msg[USER_MSG_LENGTH]

Holds some output that will be displayed via the print_output command. This is created globally so that memory does not need to be reallocated for each function that wishes to use it.

unsigned warn_count = 0 [static]

Counts the number of warnings found during the parsing process.

Referenced by VLwarn().

Generated on Sun Nov 21 00:55:40 2010 for Covered by  doxygen 1.6.3