2000-11-07 22:50 UTC+0800 Ron Pinkas <ron@profit-master.com>

* include/hberrors.h
     + Added: #define HB_COMP_ERR_BLOCK                       47
   * source/compiler/hbgenerr.c
     + Added Error: "Code block contains both macro and declared symbol references"

   * source/compiler/harbour.c
     * Made public: hb_compLocalGetPos() and hb_compStaticGetPos()

   * source/compiler/harbour.slx
     + Added: char * hb_comp_SLX_LastBlock( BOOL bReset )

   * source/compiler/harbour.sly
     + Added logic to support Early Expansions of Macro within CodeBlock unless parenthesized.

   + tests/tstblock.prg
     + New test of Early/Late expansion of Macros within CodeBlocks.
This commit is contained in:
Ron Pinkas
2000-11-08 07:25:07 +00:00
parent 9372a26e6b
commit bcca8b7b78
6 changed files with 175 additions and 47 deletions

View File

@@ -1,10 +1,28 @@
2000-11-07 22:50 UTC+0800 Ron Pinkas <ron@profit-master.com>
* include/hberrors.h
+ Added: #define HB_COMP_ERR_BLOCK 47
* source/compiler/hbgenerr.c
+ Added Error: "Code block contains both macro and declared symbol references"
* source/compiler/harbour.c
* Made public: hb_compLocalGetPos() and hb_compStaticGetPos()
* source/compiler/harbour.slx
+ Added: char * hb_comp_SLX_LastBlock( BOOL bReset )
* source/compiler/harbour.sly
+ Added logic to support Early Expansions of Macro within CodeBlock unless parenthesized.
+ tests/tstblock.prg
+ New test of Early/Late expansion of Macros within CodeBlocks.
2000-11-07 16:25 UTC+0100 Ryszard Glab <rglab@imid.med.pl>
*include/hbexpra.c
*source/compiler/expropta.c
*source/macro/macroa.c
*fixed internal _GET_ optimization for macro variables
*source/rtl/tgetint.prg
*__GET uses macro operator if no initial value is passed and
there is no set/get block

View File

@@ -91,6 +91,7 @@ extern "C" {
#define HB_COMP_ERR_FUNC_ANNOUNCE 44
#define HB_COMP_ERR_JUMP_NOT_FOUND 45
#define HB_COMP_ERR_CASE 46
#define HB_COMP_ERR_BLOCK 47
#define HB_COMP_WARN_AMBIGUOUS_VAR 1
#define HB_COMP_WARN_MEMVAR_ASSUMED 2

View File

@@ -53,10 +53,10 @@ static void hb_compInitVars( void );
static void hb_compGenOutput( int );
static void hb_compOutputFile( void );
int hb_compLocalGetPos( char * szVarName ); /* returns the order + 1 of a local variable */
int hb_compStaticGetPos( char *, PFUNCTION ); /* return if passed name is a static variable */
static int hb_compFieldGetPos( char *, PFUNCTION ); /* return if passed name is a field variable */
static int hb_compLocalGetPos( char * szVarName ); /* returns the order + 1 of a local variable */
static int hb_compMemvarGetPos( char *, PFUNCTION ); /* return if passed name is a memvar variable */
static int hb_compStaticGetPos( char *, PFUNCTION ); /* return if passed name is a static variable */
static void hb_compGenFieldPCode( BYTE , int, char *, PFUNCTION ); /* generates the pcode for database field */
static void hb_compGenVariablePCode( BYTE , char * ); /* generates the pcode for undeclared variable */
@@ -1288,7 +1288,7 @@ USHORT hb_compVariableGetPos( PVAR pVars, char * szVarName ) /* returns the orde
return 0;
}
static int hb_compLocalGetPos( char * szVarName ) /* returns the order + 1 of a variable if defined or zero */
int hb_compLocalGetPos( char * szVarName ) /* returns the order + 1 of a variable if defined or zero */
{
int iVar;
PFUNCTION pFunc = hb_comp_functions.pLast;
@@ -1423,7 +1423,7 @@ static int hb_compLocalGetPos( char * szVarName ) /* returns the order + 1 of a
* All static variables are hold in a single array at runtime then positions
* are numbered for whole PRG module.
*/
static int hb_compStaticGetPos( char * szVarName, PFUNCTION pFunc )
int hb_compStaticGetPos( char * szVarName, PFUNCTION pFunc )
{
int iVar;

View File

@@ -42,20 +42,23 @@
#define YY_BUF_SIZE HB_PP_STR_SIZE
static int iTexts = 0, iCloseSquare = 0, iWantsEOL, iWantsEXP, iWantsID, iWantsVAR;
static char * aTexts[ NUMERALS_PER_LINE ];
static char *aTexts[ NUMERALS_PER_LINE ];
static unsigned char iIdentifier = 0;
static char* sIdOnHold;
static char *sIdOnHold, *s_sLastBlock = NULL;
char * hb_comp_SLX_LastBlock( BOOL bReset );
long hb_comp_SLX_Hex2L( char* sHex );
static int hb_comp_SLX_ElementToken( char* szToken, unsigned int iTokenLen );
static int hb_comp_SLX_InterceptAction( int iRet, char *sToken );
static int hb_comp_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, BOOL *ptr_bIgnoreWords, int iLastToken, char *sToken );
static int hb_comp_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, BOOL *ptr_bIgnoreWords, int iLastToken, char *sToken, char *s_szBuffer );
/* ----------------------------------------------------- Language Definitions. ---------------------------------------------------- */
/* Delimiters. */
ACCEPT_TOKEN_AND_DROP_DELIMITER_IF_ONE_OF_THESE( " \t" );
#define HB_CHK_BLOCK LEX_CUSTOM_ACTION - 1
ACCEPT_TOKEN_AND_RETURN_DELIMITERS {
LEX_DELIMITER( ',' ) AS_TOKEN( ',' ),
LEX_DELIMITER( '(' ) AS_TOKEN( '(' ),
@@ -70,7 +73,7 @@ ACCEPT_TOKEN_AND_RETURN_DELIMITERS {
LEX_DELIMITER( '<' ) AS_TOKEN( '<' + DONT_REDUCE ),
LEX_DELIMITER( '>' ) AS_TOKEN( '>' + DONT_REDUCE ),
LEX_DELIMITER( '!' ) AS_TOKEN( NOT + DONT_REDUCE ),
LEX_DELIMITER( '{' ) AS_TOKEN( '{' + DONT_REDUCE ),
LEX_DELIMITER( '{' ) AS_TOKEN( HB_CHK_BLOCK ),
LEX_DELIMITER( '|' ) AS_TOKEN( '|' + DONT_REDUCE ),
LEX_DELIMITER( '^' ) AS_TOKEN( POWER + DONT_REDUCE ),
LEX_DELIMITER( '%' ) AS_TOKEN( '%' + DONT_REDUCE ),
@@ -82,10 +85,10 @@ ACCEPT_TOKEN_AND_RETURN_DELIMITERS {
};
/* Custom Intermediate Token needed to be expanded. */
#define HB_LIT_ACT LEX_CUSTOM_ACTION - 1
#define HB_NESTED_LIT LEX_CUSTOM_ACTION - 2
#define HB_QOUT_ACT LEX_CUSTOM_ACTION - 3
#define HB_RET_QOUT_LIT LEX_CUSTOM_ACTION - 4
#define HB_LIT_ACT LEX_CUSTOM_ACTION - 2
#define HB_NESTED_LIT LEX_CUSTOM_ACTION - 3
#define HB_QOUT_ACT LEX_CUSTOM_ACTION - 4
#define HB_RET_QOUT_LIT LEX_CUSTOM_ACTION - 5
/* Stream Pairs. */
DEFINE_STREAM_AS_ONE_OF_THESE {
@@ -100,7 +103,7 @@ DEFINE_STREAM_AS_ONE_OF_THESE {
START_NEW_LINE_IF_ONE_OF_THESE( "\n;" );
#define HB_SELF LEX_CUSTOM_ACTION - 5
#define HB_SELF LEX_CUSTOM_ACTION - 6
SELF_CONTAINED_WORDS_ARE {
LEX_WORD( ".AND." ) AS_TOKEN( AND + DONT_REDUCE ),
@@ -142,32 +145,32 @@ SELF_CONTAINED_WORDS_ARE {
#define HB_WANTS_EXP LEX_CUSTOM_ACTION - 2048
/* When 2 identifiers are correct syntax like in class declaration, we have to temporarily store the 2nd identifier. */
#define HB_ID_ON_HOLD LEX_CUSTOM_ACTION - 6
#define HB_ID_ON_HOLD LEX_CUSTOM_ACTION - 7
#define HB_MACRO_ERR LEX_CUSTOM_ACTION - 7
#define HB_MACRO_ERR LEX_CUSTOM_ACTION - 8
#define HB_INIT_PROC LEX_CUSTOM_ACTION - 8
#define HB_INIT_FUNC LEX_CUSTOM_ACTION - 9
#define HB_EXIT_PROC LEX_CUSTOM_ACTION - 10
#define HB_EXIT_FUNC LEX_CUSTOM_ACTION - 11
#define HB_STATIC_PROC LEX_CUSTOM_ACTION - 12
#define HB_STATIC_FUNC LEX_CUSTOM_ACTION - 13
#define HB_INIT_PROC LEX_CUSTOM_ACTION - 9
#define HB_INIT_FUNC LEX_CUSTOM_ACTION - 10
#define HB_EXIT_PROC LEX_CUSTOM_ACTION - 11
#define HB_EXIT_FUNC LEX_CUSTOM_ACTION - 12
#define HB_STATIC_PROC LEX_CUSTOM_ACTION - 13
#define HB_STATIC_FUNC LEX_CUSTOM_ACTION - 14
#define HB_DO_CASE_ID LEX_CUSTOM_ACTION - 14
#define HB_DO_CASE_ID LEX_CUSTOM_ACTION - 15
#define HB_DO_WHILE_ID LEX_CUSTOM_ACTION - 15
#define HB_DO_WHILE_WITH LEX_CUSTOM_ACTION - 16
#define HB_DO_WHILE_ID LEX_CUSTOM_ACTION - 16
#define HB_DO_WHILE_WITH LEX_CUSTOM_ACTION - 17
#define _WITH_ID_CR LEX_CUSTOM_ACTION - 17
#define _WITH_ID_SEMI LEX_CUSTOM_ACTION - 18
#define _WITH_ID_CR LEX_CUSTOM_ACTION - 18
#define _WITH_ID_SEMI LEX_CUSTOM_ACTION - 19
#define HB_IN LEX_CUSTOM_ACTION - 19
#define HB_STEP LEX_CUSTOM_ACTION - 20
#define HB_TO LEX_CUSTOM_ACTION - 21
#define HB_WITH LEX_CUSTOM_ACTION - 22
#define HB_IN LEX_CUSTOM_ACTION - 20
#define HB_STEP LEX_CUSTOM_ACTION - 21
#define HB_TO LEX_CUSTOM_ACTION - 22
#define HB_WITH LEX_CUSTOM_ACTION - 23
/* When reservered words are used as Identifier. */
#define HB_IDENTIFIER LEX_CUSTOM_ACTION - 23
#define HB_IDENTIFIER LEX_CUSTOM_ACTION - 24
#define USE_KEYWORDS
@@ -431,7 +434,7 @@ LANGUAGE_RULES_ARE {
#define YY_INPUT( buf, result, max_size ) result = yy_lex_input( buf, max_size );
#undef CUSTOM_ACTION
#define CUSTOM_ACTION(x) x = hb_comp_SLX_CustomAction( x, aiHold, &iHold, &bIgnoreWords, iLastToken, (char*) sToken )
#define CUSTOM_ACTION(x) x = hb_comp_SLX_CustomAction( x, aiHold, &iHold, &bIgnoreWords, iLastToken, (char*) sToken, s_szBuffer )
#undef STREAM_EXCEPTION
#define STREAM_EXCEPTION( sPair, cChar ) \
@@ -743,7 +746,7 @@ long hb_comp_SLX_Hex2L( char* sHex )
return lSum;
}
int hb_comp_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, BOOL *ptr_bIgnoreWords, int iLastToken, char *sToken )
int hb_comp_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, BOOL *ptr_bIgnoreWords, int iLastToken, char *sToken, char *s_szBuffer )
{
DEBUG_INFO( printf( "Custom Action for %i\n", x ) );
@@ -784,6 +787,51 @@ int hb_comp_SLX_CustomAction( int x, int aiHold[], int *ptr_iHold, BOOL *ptr_bIg
DEBUG_INFO( printf( "HB_SELF, Primary Identifier %s Increased to: %i\n", "SELF", iIdentifier ) );
return IDENTIFIER;
case HB_CHK_BLOCK :
if( s_sLastBlock == NULL )
{
char *pTmp = (char *) s_szBuffer;
/* Skip White Space. */
while( *pTmp && ( *pTmp == ' ' || *pTmp == '\t' ) )
{
pTmp++;
}
if( *pTmp == '|' )
{
unsigned int iBrackets = 1;
char cTmp;
pTmp++;
while( *pTmp )
{
if( *pTmp == '}' )
{
iBrackets--;
if( iBrackets == 0 )
{
break;
}
}
else if( *pTmp == '{' )
{
iBrackets++;
}
pTmp++;
}
pTmp++;
cTmp = *pTmp;
*pTmp = '\0';
s_sLastBlock = hb_compIdentifierNew( s_szBuffer - 1, TRUE );
*pTmp = cTmp;
}
}
return '{' + DONT_REDUCE;
case HB_LIT_ACT :
yylval.string = hb_compIdentifierNew( sPair, TRUE );
return LITERAL + DONT_REDUCE ;
@@ -944,3 +992,14 @@ int yy_lex_input( char *buffer, int iBufferSize )
return hb_pp_Internal( hb_comp_bPPO ? hb_comp_yyppo : NULL, buffer );
}
char * hb_comp_SLX_LastBlock( BOOL bReset )
{
if( bReset && s_sLastBlock )
{
//hb_xfree( s_sLastBlock );
s_sLastBlock = NULL;
}
return s_sLastBlock;
}

View File

@@ -118,7 +118,11 @@ static PTR_LOOPEXIT hb_comp_pLoops = NULL;
static HB_RTVAR_PTR hb_comp_rtvars = NULL;
static HB_EXPR_PTR pArrayIndexAsList = NULL, pGetArgList = NULL, pBaseArrayName = NULL;
static BOOL bTrancuateBaseArray = FALSE;
static BOOL bTrancuateBaseArray = FALSE, bBlock = FALSE, bBlockMacro = FALSE, bBlockDeclared = FALSE;
extern int hb_compLocalGetPos( char * szVarName ); /* returns the order + 1 of a local variable */
extern int hb_compStaticGetPos( char *, PFUNCTION ); /* return if passed name is a static variable */
extern char * hb_comp_SLX_LastBlock( BOOL bReset );
char * hb_comp_szAnnounce = NULL; /* ANNOUNCEd procedure */
@@ -497,7 +501,13 @@ ArrayAtAlias : ArrayAt ALIASOP { $$ = $1; }
/* Variables
*/
Variable : IdentName { $$ = hb_compExprNewVar( $1 ); }
Variable : IdentName {
$$ = hb_compExprNewVar( $1 );
if( bBlock && ( hb_compLocalGetPos( $1 ) || hb_compStaticGetPos( $1, hb_comp_functions.pLast ) ) )
{
bBlockDeclared = TRUE;
}
}
;
VarAlias : IdentName ALIASOP { $$ = hb_compExprNewAlias( $1 ); }
@@ -505,8 +515,8 @@ VarAlias : IdentName ALIASOP { $$ = hb_compExprNewAlias( $1 ); }
/* Macro variables
*/
MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 ); }
| MACROTEXT { $$ = hb_compExprNewMacro( NULL, 0, $1 ); }
MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 ); if( bBlock ) bBlockMacro = TRUE }
| MACROTEXT { $$ = hb_compExprNewMacro( NULL, 0, $1 ); if( bBlock ) bBlockMacro = TRUE; }
;
MacroVarAlias : MacroVar ALIASOP { $$ = $1; }
@@ -980,12 +990,6 @@ ElemList : Argument { $$ = hb_compExprNewList( $1 ); }
| ElemList ',' Argument { $$ = hb_compExprAddListExpr( $1, $3 ); }
;
CodeBlock : '{' '|' { $<asExpr>$ = hb_compExprNewCodeBlock(); } BlockNoVar
'|' BlockExpList '}' { $$ = $<asExpr>3; }
| '{' '|' { $<asExpr>$ = hb_compExprNewCodeBlock(); } BlockVarList
'|' BlockExpList '}' { $$ = $<asExpr>3; }
;
Get : GET Variable { pGetArgList = hb_compExprNewArgList( $2 ); } ',' GetArgList ')'
{ $$ = hb_compExprNewFunCall( hb_compExprNewFunName( "__GET"), pGetArgList ); pGetArgList = NULL; }
| GET AliasVar { pGetArgList = hb_compExprNewArgList( $2 ); } ',' GetArgList ')'
@@ -1038,11 +1042,56 @@ GetAExt : { /* Nothing*/ }
| ',' GetArgList
;
CodeBlock : '{' '|' { bBlock = TRUE; $<asExpr>$ = hb_compExprNewCodeBlock() } BlockNoVar '|' BlockExpList '}'
{
if( bBlockMacro )
{
if( bBlockDeclared )
{
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_BLOCK, NULL, NULL );
$$ = $<asExpr>3;
}
else
{
$<asExpr>$ = hb_compExprNewMacro( hb_compExprNewString( hb_comp_SLX_LastBlock( FALSE ) ), 0, NULL );
}
}
else
{
$$ = $<asExpr>3;
}
hb_comp_SLX_LastBlock( TRUE );
bBlock = FALSE; bBlockMacro = FALSE; bBlockDeclared = FALSE;
}
| '{' '|' { bBlock = TRUE; $<asExpr>$ = hb_compExprNewCodeBlock(); } BlockVarList '|' BlockExpList '}'
{
if( bBlockMacro )
{
if( bBlockDeclared )
{
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_BLOCK, NULL, NULL );
$$ = $<asExpr>3;
}
else
{
$<asExpr>$ = hb_compExprNewMacro( hb_compExprNewString( hb_comp_SLX_LastBlock( FALSE ) ), 0, NULL );
}
}
else
{
$$ = $<asExpr>3;
}
hb_comp_SLX_LastBlock( TRUE );
bBlock = FALSE; bBlockMacro = FALSE; bBlockDeclared = FALSE;
}
;
/* NOTE: This uses $-2 then don't use BlockExpList in other context
*/
BlockExpList : Expression { $$ = hb_compExprAddListExpr( $<asExpr>-2, $1 ); }
| BlockExpList ',' Expression { $$ = hb_compExprAddListExpr( $<asExpr>-2, $3 ); }
;
BlockExpList : Expression { $$ = hb_compExprAddListExpr( $<asExpr>-2, $1 ); }
| BlockExpList ',' Expression { $$ = hb_compExprAddListExpr( $<asExpr>-2, $3 ); }
;
/* NOTE: This is really not needed however it allows the use of $-2 item
* in BlockExpList to refer the same rule defined in Codeblock

View File

@@ -86,6 +86,7 @@ char * hb_comp_szErrors[] =
"ANNOUNCEd procedure \'%s\' must be a public symbol",
"Jump PCode not found",
"CASE or OTHERWISE does not match DO CASE",
"Code block contains both macro and declared symbol references"
};
/* Table with parse warnings */