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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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--;
|
||||
|
||||
28
harbour/tests/inline_c.prg
Normal file
28
harbour/tests/inline_c.prg
Normal 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
|
||||
Reference in New Issue
Block a user