Click here to Skip to main content
15,897,371 members
Articles / Programming Languages / C

Compiler Patterns

Rate me:
Please Sign up or sign in to vote.
4.87/5 (35 votes)
27 Jul 2017CPOL36 min read 64K   905   76  
Traces the evolution of a high-speed EXPRESSION EVALUATOR to demonstrate the various PATTERNS you will need to "roll your own" recursive descent compiler.
/*************************************************************************
*    NAME: debug.h
*  AUTHOR: David Qualls (davidlqualls@yahoo.com)
* PURPOSE: Declare globals variables, macros, and functions needed for
*          debugging and error reporting.
*
*   NOTES:

 -Either NODEBUG, or DEBUG must be #defined.  NODEBUG takes precedence 
  over DEBUG.  Set DEBUG to 0 (zero) for no general-level debugging, to 
  1 (one) for standard debug output to a debugging file, and to 2 for 
  panic debugging (outputting to console and to debugging file).  Can 
  also be set to negative numbers to reduce the immediacy of individual 
  function debugging.
  
 -Individual function debugging is controlled by the DEBUG_funcname macro 
  (with funcname replaced by the actual function name).  For example:
  #define DEBUG_getOffset 2
  will set the debugging level for the function getOffset() to 2.
  The higher the value, the more panicky the messages are; at least, they 
  get printed to more places.  These values can also be set to negative ints 
  to omit debugging output from a function you know to be working, when
  general level debugging is turned on (greater than zero).
  
 -The actual behavior of individual debugging code is controlled by the 
  sum of the global DEBUG value, and the individual function DEBUG_funcname
  value.
  
 -Here is a list of the only debugging code available from this system.
 
 dbgmsg( const char *msg, ... ) //format just like printf
 dbgcode{ //any code you want evaluated ONLY WHEN DEBUGGING 
          //goes between these braces.
 }
 infunc( funcname )  //Makes tracing the execution possible.
 outfunc()           //Must accompany any infunc() call.  Function logic must 
                     //be arranged such that EXACTLY ONE of these is called
                     //during function execution.  In other words, at run-time,
                     //infunc() and outfunc() calls must balance.
                     
 Note that raising exceptions (long jumping out of the normal flow and 
 bypassing normal returns) will wreak havoc with your infunc/outfunc 
 balance... Good luck!! 
 
 -The "infunc( funcname )" macro will produce a compile-time error
  unless the macro DEBUG_funcname (with funcname replaced by the actual
  function name) is defined to a numeric value.  

 -A convenient place to put the DEBUG macros is in the <source_file>_cfg.h file.

*************************************************************************/

#ifndef DEBUG_H
# define DEBUG_H

//#include "debug_cfg.h"

#include <stdio.h>

extern FILE *debug_file_G;

//extern int   ErrorTrap;
// #define your ErrorTrap to be whatever will trip when true!

#ifdef NODEBUG

inline void dbgmsg( const char *msg, ... )
{
  /*this may cause warnings, but hopefully, an optimizer 
    will remove any actual code.
  */
  ;
}
inline void dbgprint( const char *fmt_string, ... )
{
  ;
}
//const int debug_always_zero_G = 0;

//#define dbgcode if(debug_always_zero_G)
#define dbgcode if(0)

#define infunc( a )
#define outfunc( )
#define dbgchkpt 

#else
/* NODEBUG is NOT defined, */

# ifndef DEBUG_main
#  define DEBUG_main 0
# endif

# if  !defined( DEBUG ) || (DEBUG < -3)
#  error "You need to give a valid numeric value to the macro DEBUG, or just define NODEBUG"
# endif

extern int debug_G; /* Global flag indicating to "debug" everything. */
                    /* Initially gets set to value of macro DEBUG.   */

void dbgmsg( const char *msg, ... );
void dbgprint( const char *msg, ... );
int  get_debug_value();
#define dbgcode  if( get_debug_value() > 0 )
#define infunc( name ) infunc_( #name, __LINE__, __FILE__, DEBUG_##name )
#define dbgchkpt dbgmsg( "checkpoint -- file %s, line %d", __FILE__ , __LINE__ );
void outfunc( void );

//void infunc_( const char *fname, int num );
void infunc_( const char *fname, int linenum, const char *file, int num );


#endif
/*closure for #ifdef NODEBUG */

#endif
/* end of #ifndef DEBUG_H */

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer USAF
United States United States
Education:
-BS Mechanical Engineering
-MS Mechanical Engineering
Languages:
-Perl
-SQL
-C and C++
-Fortran
-VB
Past Jobs:
-Jet engines engineer
-Adjunct Engineering Professor
-Structural Tracking System: IT Engineer
-Mathematician/Forecasting Models Architect/Implementer
Current Job:
-Financial manager for a small company, and CTO at another small company.

Comments and Discussions