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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user