2000-01-01 22:40 UTC+0800 Ron Pinkas <ron@profit-master.com>

* include/hberrors.h
   * source/compiler/hbgenerr.c
     + Added: "Unterminated inline block in function: \'%s\'" and "Too many inline blocks"

   * include/hbcomp.h
   * source/compiler/harbour.c
     + Added hb_compInlineNew(), hb_compInlineAdd(), and hb_compInlineFind()

   * source/pp/ppcomp.c
   * source/compiler/harbour.slx
   * source/compiler/genc.c
     + Added support for inline C code blocks.

   + tests/inline_c.prg
     + Added new test to demonstrate new inline C support.
This commit is contained in:
Ron Pinkas
2001-01-02 06:53:30 +00:00
parent 471902aaba
commit 8d2b4bd7f0
9 changed files with 279 additions and 12 deletions

View File

@@ -1,3 +1,21 @@
2000-01-01 22:40 UTC+0800 Ron Pinkas <ron@profit-master.com>
* include/hberrors.h
* source/compiler/hbgenerr.c
+ Added: "Unterminated inline block in function: \'%s\'" and "Too many inline blocks"
* include/hbcomp.h
* source/compiler/harbour.c
+ Added hb_compInlineNew(), hb_compInlineAdd(), and hb_compInlineFind()
* source/pp/ppcomp.c
* source/compiler/harbour.slx
* source/compiler/genc.c
+ Added support for inline C code blocks.
+ tests/inline_c.prg
+ Added new test to demonstrate new inline C support.
2001-01-01 22:15 GMT -3 Luiz Rafael Culik <culik@sl.conex.net>
*utils/hbdoc/genpdf.prg
*contrib/pdflib/pdfhbdoc.c

View File

@@ -156,6 +156,15 @@ typedef struct __FUNC
struct __FUNC * pNext; /* pointer to the next defined function */
} _FUNC, * PFUNCTION;
/* structure to hold a Clipper defined function */
typedef struct __INLINE
{
char * szName; /* name of a inline function */
BYTE * pCode; /* pointer to a memory block where pcode is stored */
ULONG lPCodeSize; /* total memory size for pcode */
struct __INLINE * pNext; /* pointer to the next defined inline */
} _INLINE, * PINLINE;
/* structure to control all Clipper defined functions */
typedef struct
{
@@ -164,6 +173,14 @@ typedef struct
int iCount; /* number of defined functions */
} FUNCTIONS;
/* structure to control all Clipper defined functions */
typedef struct
{
PINLINE pFirst; /* pointer to the first defined inline */
PINLINE pLast; /* pointer to the last defined inline */
int iCount; /* number of defined inlines */
} INLINES;
/* compiler symbol support structure */
typedef struct _COMSYMBOL
{
@@ -232,9 +249,11 @@ void hb_compPCodeEval( PFUNCTION, HB_PCODE_FUNC_PTR *, void * );
extern void hb_compFunctionAdd( char * szFunName, HB_SYMBOLSCOPE cScope, int iType ); /* starts a new Clipper language function definition */
extern PFUNCTION hb_compFunctionFind( char * szFunName ); /* locates a previously defined function */
extern PINLINE hb_compInlineFind( char * szFunName );
extern USHORT hb_compFunctionGetPos( char * szSymbolName ); /* returns the index + 1 of a function on the functions defined list */
extern PFUNCTION hb_compFunctionKill( PFUNCTION ); /* releases all memory allocated by function and returns the next one */
extern void hb_compAnnounce( char * );
extern PINLINE hb_compInlineAdd( char * szFunName );
extern PFUNCTION hb_compFunCallAdd( char * szFuntionName );
extern PFUNCTION hb_compFunCallFind( char * szFunName ); /* locates a previously defined called function */
@@ -443,6 +462,9 @@ extern char * hb_comp_szWarnings[];
extern char * hb_pp_STD_CH;
extern BOOL hb_comp_bAutoOpen;
extern BOOL hb_comp_bError;
extern char hb_comp_cInlineID;
extern INLINES hb_comp_inlines;
/* /GC command line setting types */
#define HB_COMPGENC_COMPACT 0

View File

@@ -93,6 +93,8 @@ extern "C" {
#define HB_COMP_ERR_CASE 46
#define HB_COMP_ERR_BLOCK 47
#define HB_COMP_ERR_GET_COMPLEX_MACRO 48
#define HB_COMP_ERR_INVALID_INLINE 49
#define HB_COMP_ERR_TOOMANY_INLINE 50
#define HB_COMP_WARN_AMBIGUOUS_VAR 1
#define HB_COMP_WARN_MEMVAR_ASSUMED 2

View File

@@ -52,6 +52,7 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou
PCOMSYMBOL pSym = hb_comp_symbols.pFirst;
PCOMDECLARED pDeclared;
FILE * yyc; /* file handle for C output */
PINLINE pInline = hb_comp_inlines.pFirst;
if( ! pFileName->szExtension )
pFileName->szExtension = ".c";
@@ -98,13 +99,27 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou
fprintf( yyc, "HB_FUNC( %s );\n", pFunc->szName );
pFunc = pFunc->pNext;
}
/* write functions prototypes for inline blocks */
while( pInline )
{
fprintf( yyc, "static HB_FUNC( %s );\n", pInline->szName );
pInline = pInline->pNext;
}
/* write functions prototypes for called functions outside this PRG */
pFunc = hb_comp_funcalls.pFirst;
while( pFunc )
{
pFTemp = hb_compFunctionFind( pFunc->szName );
if( ! pFTemp || pFTemp == hb_comp_functions.pFirst )
fprintf( yyc, "extern HB_FUNC( %s );\n", pFunc->szName );
{
if( pFTemp == NULL && hb_compInlineFind( pFunc->szName ) == NULL )
{
fprintf( yyc, "extern HB_FUNC( %s );\n", pFunc->szName );
}
}
pFunc = pFunc->pNext;
}
@@ -213,6 +228,20 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou
fprintf( yyc, " hb_vmExecute( pcode, symbols );\n}\n\n" );
pFunc = pFunc->pNext;
}
/* Generate codeblocks data
*/
if( hb_comp_inlines.iCount )
{
fprintf( yyc, "#include \"hbapi.h\"\n" );
pInline = hb_comp_inlines.pFirst;
while( pInline )
{
fprintf( yyc, "static HB_FUNC( %s )\n", pInline->szName );
fprintf( yyc, "%s", pInline->pCode );
pInline = pInline->pNext;
}
}
}
else
fprintf( yyc, "/* Empty source file */\n\n" );
@@ -231,6 +260,14 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou
pFunc = hb_comp_funcalls.pFirst;
}
pInline = hb_comp_inlines.pFirst;
while( pInline )
{
hb_comp_inlines.pFirst = pInline->pNext;
hb_xfree( ( void * ) pInline ); /* NOTE: szName will be released by hb_compSymbolKill() */
pInline = hb_comp_inlines.pFirst;
}
pDeclared = hb_comp_pFirstDeclared;
while( pDeclared )
{

View File

@@ -69,6 +69,7 @@ static void hb_compGenVariablePCode( BYTE , char * ); /* generates the pcode
static void hb_compGenVarPCode( BYTE , char * ); /* generates the pcode for undeclared variable */
static PFUNCTION hb_compFunctionNew( char *, HB_SYMBOLSCOPE ); /* creates and initialises the _FUNC structure */
static PINLINE hb_compInlineNew( char * ); /* creates and initialises the _INLINE structure */
static void hb_compCheckDuplVars( PVAR pVars, char * szVarName ); /*checks for duplicate variables definitions */
/* int hb_compSort_ULONG( ULONG * ulLeft, ULONG * ulRight ); */
@@ -129,6 +130,9 @@ char * hb_comp_szDeclaredFun = NULL;
BOOL hb_comp_bAutoOpen = TRUE;
BOOL hb_comp_bError = FALSE;
char hb_comp_cInlineID = '0';
INLINES hb_comp_inlines;
/* EXTERNAL statement can be placed into any place in a function - this flag is
* used to suppress error report generation
@@ -976,6 +980,20 @@ static PFUNCTION hb_compFunctionNew( char * szName, HB_SYMBOLSCOPE cScope )
return pFunc;
}
static PINLINE hb_compInlineNew( char * szName )
{
PINLINE pInline;
pInline = ( PINLINE ) hb_xgrab( sizeof( _INLINE ) );
pInline->szName = szName;
pInline->pCode = NULL;
pInline->lPCodeSize = 0;
pInline->pNext = NULL;
return pInline;
}
/*
* Stores a Clipper defined function/procedure
* szFunName - name of a function
@@ -1059,6 +1077,28 @@ void hb_compFunctionAdd( char * szFunName, HB_SYMBOLSCOPE cScope, int iType )
hb_comp_bDontGenLineNum = FALSE; /* reset the flag */
}
PINLINE hb_compInlineAdd( char * szFunName )
{
PINLINE pInline;
pInline = hb_compInlineNew( szFunName );
if( hb_comp_inlines.iCount == 0 )
{
hb_comp_inlines.pFirst = pInline;
hb_comp_inlines.pLast = pInline;
}
else
{
hb_comp_inlines.pLast->pNext = pInline;
hb_comp_inlines.pLast = pInline;
}
hb_comp_inlines.iCount++;
return pInline;
}
/* create an ANNOUNCEd procedure
*/
void hb_compAnnounce( char * szFunName )
@@ -1245,6 +1285,25 @@ PFUNCTION hb_compFunctionFind( char * szFunctionName ) /* returns a previously d
return NULL;
}
PINLINE hb_compInlineFind( char * szFunctionName )
{
PINLINE pInline = hb_comp_inlines.pFirst;
while( pInline )
{
if( ! strcmp( pInline->szName, szFunctionName ) )
return pInline;
else
{
if( pInline->pNext )
pInline = pInline->pNext;
else
return NULL;
}
}
return NULL;
}
/* return variable using its order after final fixing */
PVAR hb_compLocalVariableFind( PFUNCTION pFunc, USHORT wVar )
{
@@ -3273,6 +3332,10 @@ static void hb_compInitVars( void )
hb_comp_ulLastLinePos = 0;
hb_comp_iStaticCnt = 0;
hb_comp_iVarScope = VS_LOCAL;
hb_comp_inlines.iCount = 0;
hb_comp_inlines.pFirst = NULL;
hb_comp_inlines.pLast = NULL;
}
static void hb_compGenOutput( int iLanguage )

View File

@@ -172,6 +172,8 @@ SELF_CONTAINED_WORDS_ARE {
/* When reservered words are used as Identifier. */
#define HB_IDENTIFIER LEX_CUSTOM_ACTION - 24
#define HB_INLINE LEX_CUSTOM_ACTION - 25
#define USE_KEYWORDS
/* Key Words. */
@@ -257,6 +259,7 @@ LANGUAGE_WORDS_ARE {
LEX_WORD( "AS{WS}USUAL" ) AS_TOKEN( AS_CHARACTER + DONT_REDUCE ),
LEX_WORD( "FIELD" ) AS_TOKEN( FIELD ),
LEX_WORD( "HB_INLINE" ) AS_TOKEN( HB_INLINE ),
LEX_WORD( "IF" ) AS_TOKEN( IIF ),
LEX_WORD( "IIF" ) AS_TOKEN( IIF ),
LEX_WORD( "IN" ) AS_TOKEN( HB_IN ),
@@ -762,9 +765,9 @@ int hb_comp_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, BOOL *ptr_bIg
if( x < HB_WANTS_EXP )
{
*ptr_bIgnoreWords = FALSE;
*ptr_bIgnoreWords = FALSE;
iWantsEXP = (-x) + (HB_WANTS_EXP) ;
return REJECT_OP;
return REJECT_OP;
}
else if( x < HB_WANTS_EOL )
{
@@ -942,14 +945,14 @@ int hb_comp_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, BOOL *ptr_bIg
return IDENTIFIER + DONT_REDUCE;
case HB_NESTED_LIT :
{
int iPairLen = strlen( sPair );
{
int iPairLen = strlen( sPair );
sPair[ iPairLen ] = sTerm[0];
sPair[ iPairLen + 1 ] = '\0';
yylval.string = hb_compIdentifierNew( sPair, TRUE );
return LITERAL + DONT_REDUCE ;
}
sPair[ iPairLen ] = sTerm[0];
sPair[ iPairLen + 1 ] = '\0';
yylval.string = hb_compIdentifierNew( sPair, TRUE );
return LITERAL + DONT_REDUCE ;
}
case HB_QOUT_ACT :
iIdentifier++;
@@ -997,6 +1000,96 @@ int hb_comp_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, BOOL *ptr_bIg
DEBUG_INFO( printf( "RELEASED ID_ON_HOLD: %s - Increased to: %i\n", sIdOnHold, iIdentifier ) );
return IDENTIFIER;
case HB_INLINE :
{
char sBuffer[ YY_BUF_SIZE ], *pBuffer, sInlineSym[] = "HB_INLINE_0";
int iSize, iBraces = 0;
extern BOOL hb_pp_bInline;
PINLINE pInline;
hb_pp_bInline = TRUE;
sInlineSym[10] = hb_comp_cInlineID++;
switch( sInlineSym[10] )
{
case '9' + 1 :
sInlineSym[10] = 'A';
break;
case 'Z' + 1 :
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_TOOMANY_INLINE, NULL, NULL );
break;
}
pInline = hb_compInlineAdd( hb_compIdentifierNew( sInlineSym, TRUE ) );
DigestInline :
YY_INPUT( (char*) sBuffer, iSize, YY_BUF_SIZE );
if( iSize == 0 )
{
hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_INVALID_INLINE, hb_comp_functions.pLast->szName, NULL );
hb_pp_bInline = FALSE;
return '\n' + DONT_REDUCE;
}
pBuffer = (char*) sBuffer;
while( *pBuffer && ( *pBuffer == ' ' || *pBuffer == '\t' ) )
{
pBuffer++;
}
if( *pBuffer == '\0' )
{
goto DigestInline;
}
else if( *pBuffer == '{' )
{
iBraces++;
}
else if( *pBuffer == '}' && iBraces > 1 )
{
iBraces--;
}
else if( *pBuffer == '}' )
{
if( pInline->pCode == NULL )
{
pInline->pCode = hb_xgrab( ( iSize = strlen( (char*) sBuffer ) ) + 1 );
strcpy( pInline->pCode, (char*) sBuffer );
}
else
{
pInline->pCode = hb_xrealloc( pInline->pCode, pInline->lPCodeSize + ( iSize = strlen( (char*) sBuffer ) ) + 1 );
strcpy( pInline->pCode + pInline->lPCodeSize, (char*) sBuffer );
}
pInline->lPCodeSize += iSize;
hb_pp_bInline = FALSE;
yylval.string = hb_compIdentifierNew( sInlineSym, TRUE );
iIdentifier++;
DEBUG_INFO( printf( "INLINE, Primary Identifier %s Increased to: %i\n", "INLINE", iIdentifier ) );
return IDENTIFIER + DONT_REDUCE;
}
if( pInline->pCode == NULL )
{
pInline->pCode = hb_xgrab( ( iSize = strlen( (char*) sBuffer ) ) + 1 );
strcpy( pInline->pCode, (char*) sBuffer );
}
else
{
pInline->pCode = hb_xrealloc( pInline->pCode, pInline->lPCodeSize + ( iSize = strlen( (char*) sBuffer ) ) + 1 );
strcpy( pInline->pCode + pInline->lPCodeSize, (char*) sBuffer );
}
pInline->lPCodeSize += iSize;
goto DigestInline;
}
default:
printf( "WARNING! No Handler for Custom Action %i\n", x );
}

View File

@@ -87,7 +87,9 @@ char * hb_comp_szErrors[] =
"Jump PCode not found",
"CASE or OTHERWISE does not match DO CASE",
"Code block contains both macro and declared symbol references",
"GET contains complex macro"
"GET contains complex macro",
"Unterminated inline block in function: \'%s\'",
"Too many inline blocks"
};
/* Table with parse warnings */

View File

@@ -49,6 +49,8 @@
#include "hbpp.h"
#include "hbcomp.h"
BOOL hb_pp_bInline = FALSE;
static char s_szLine[ HB_PP_STR_SIZE ];
static char s_szOutLine[ HB_PP_STR_SIZE ];
static int hb_pp_LastOutLine = 1;
@@ -86,7 +88,7 @@ int hb_pp_Internal( FILE * handl_o, char * sOut )
hb_compGenError( hb_pp_szErrors, 'F', HB_PP_ERR_BUFFER_OVERFLOW, NULL, NULL );
}
if( s_szLine[ lens - 1 ] == ';' )
if( s_szLine[ lens - 1 ] == ';' && ! hb_pp_bInline )
{
lContinue = 1;
lens--;

View File

@@ -0,0 +1,28 @@
Function Main()
LOCAL cVar := "Hello"
cVar := HB_INLINE( cVar )
{
if( ISCHAR(1) )
{
char *szPar1 = hb_parc(1);
if( strcmp( szPar1, "Hello") == 0 )
{
hb_retc( "It was Hello" );
}
else
{
hb_retc( "No, it was not Hello" );
}
}
else
{
hb_retc( "No Param passed" );
}
}
? cVar
RETURN NIL