2007-05-12 10:45 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/include/hbcomp.h
  * harbour/include/hbexpra.c
  * harbour/include/hbexprb.c
  * harbour/include/hbexprop.h
  * harbour/include/hbpp.h
  * harbour/source/compiler/complex.c
  * harbour/source/compiler/harbour.y
  * harbour/source/compiler/harbour.yyc
  * harbour/source/compiler/harbour.yyh
  * harbour/source/compiler/hbmain.c
  * harbour/source/pp/ppcore.c
    + added support for extended multiline codeblocks:
         { |<params,...>| <EOL>
            <statement1>
            ...
            <statementN>
            return <val>
         }
      Such codeblocks allow nested definitions. They can also have their
      own variable declarations (local, static, field, memvar, parameters,
      private, public) and visibility of declared variables is similar to
      nested function in Pascal but please note that there is one limitation
      which exists also for normal codeblocks (Clipper compatible behavior):
      internal codeblock local parameters and local variables cannot be
      used in nested codeblocks, f.e. such code:
            eval( { |p| eval( {|| qout( p + 1 ) } ) } )
      is illegal in Clipper and Harbour. This limitation also can be
      eliminated but but it will be necessary to make deeper modifications
      in code for local detaching changing the method of generating
      codeblocks local variables in nested blocks so unlike the above
      also some modifications in HVM will be necessary.
      Please test.
This commit is contained in:
Przemyslaw Czerpak
2007-05-12 08:48:12 +00:00
parent 034731b566
commit 2f0189d34f
11 changed files with 3484 additions and 3088 deletions

View File

@@ -8,6 +8,40 @@
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
2007-05-12 10:45 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbcomp.h
* harbour/include/hbexpra.c
* harbour/include/hbexprb.c
* harbour/include/hbexprop.h
* harbour/include/hbpp.h
* harbour/source/compiler/complex.c
* harbour/source/compiler/harbour.y
* harbour/source/compiler/harbour.yyc
* harbour/source/compiler/harbour.yyh
* harbour/source/compiler/hbmain.c
* harbour/source/pp/ppcore.c
+ added support for extended multiline codeblocks:
{ |<params,...>| <EOL>
<statement1>
...
<statementN>
return <val>
}
Such codeblocks allow nested definitions. They can also have their
own variable declarations (local, static, field, memvar, parameters,
private, public) and visibility of declared variables is similar to
nested function in Pascal but please note that there is one limitation
which exists also for normal codeblocks (Clipper compatible behavior):
internal codeblock local parameters and local variables cannot be
used in nested codeblocks, f.e. such code:
eval( { |p| eval( {|| qout( p + 1 ) } ) } )
is illegal in Clipper and Harbour. This limitation also can be
eliminated but but it will be necessary to make deeper modifications
in code for local detaching changing the method of generating
codeblocks local variables in nested blocks so unlike the above
also some modifications in HVM will be necessary.
Please test.
2007-05-11 22:50 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbcomp.h
* harbour/include/hbcompdf.h

View File

@@ -133,6 +133,7 @@ extern int hb_compVariableScope( HB_COMP_DECL, char * );
#define FUN_BREAK_CODE 0x08 /* last statement breaks execution flow */
#define FUN_USES_LOCAL_PARAMS 0x10 /* parameters are declared using () */
#define FUN_WITH_RETURN 0x20 /* there was RETURN statement in previous line */
#define FUN_EXTBLOCK 0x40 /* it's extended codeblock */
extern void hb_compFunctionAdd( HB_COMP_DECL, char * szFunName, HB_SYMBOLSCOPE cScope, int iType ); /* starts a new Clipper language function definition */
extern PFUNCTION hb_compFunctionFind( HB_COMP_DECL, char * szFunName ); /* locates a previously defined function */

View File

@@ -566,6 +566,18 @@ HB_EXPR_PTR hb_compExprAssignStatic( HB_EXPR_PTR pLeftExpr, HB_EXPR_PTR pRightEx
return pExpr;
}
HB_EXPR_PTR hb_compExprSetCodeblockBody( HB_EXPR_PTR pExpr, BYTE * pCode, ULONG ulLen )
{
HB_TRACE(HB_TR_DEBUG, ("hb_compExprSetCodeblockBody(%p,%p,%lu)", pExpr, pCode, ulLen));
pExpr->value.asCodeblock.string = ( char * ) hb_xgrab( ulLen + 1 );
memcpy( pExpr->value.asCodeblock.string, pCode, ulLen );
pExpr->value.asCodeblock.string[ ulLen ] = '\0';
pExpr->ulLength = ulLen;
return pExpr;
}
#endif
/* ************************************************************************* */

View File

@@ -133,6 +133,7 @@ static HB_EXPR_FUNC( hb_compExprUseNegate );
#else
static void hb_compExprCodeblockPush( HB_EXPR_PTR, BOOL, HB_COMP_DECL );
static void hb_compExprCodeblockEarly( HB_EXPR_PTR, HB_COMP_DECL );
static void hb_compExprCodeblockExtPush( HB_EXPR_PTR pSelf, HB_COMP_DECL );
#endif
static void hb_compExprPushSendPop( HB_EXPR_PTR pSelf, HB_COMP_DECL );
@@ -409,9 +410,11 @@ static HB_EXPR_FUNC( hb_compExprUseCodeblock )
#if defined(HB_MACRO_SUPPORT)
HB_EXPR_PCODE1( hb_compExprCodeblockPush, pSelf );
#else
if( ( pSelf->value.asCodeblock.flags & HB_BLOCK_MACRO ) &&
!( pSelf->value.asCodeblock.flags &
( HB_BLOCK_LATEEVAL | HB_BLOCK_VPARAMS ) ) )
if( pSelf->value.asCodeblock.flags & HB_BLOCK_EXT )
hb_compExprCodeblockExtPush( pSelf, HB_COMP_PARAM );
else if( ( pSelf->value.asCodeblock.flags & HB_BLOCK_MACRO ) &&
!( pSelf->value.asCodeblock.flags &
( HB_BLOCK_LATEEVAL | HB_BLOCK_VPARAMS ) ) )
/* early evaluation of a macro */
hb_compExprCodeblockEarly( pSelf, HB_COMP_PARAM );
else
@@ -3874,6 +3877,12 @@ static void hb_compExprCodeblockPush( HB_EXPR_PTR pSelf, BOOL bLateEval, HB_COMP
/* This generates a push pcode for early evaluation of a macro
*/
#if !defined(HB_MACRO_SUPPORT)
static void hb_compExprCodeblockExtPush( HB_EXPR_PTR pSelf, HB_COMP_DECL )
{
hb_compGenPCodeN( ( BYTE * ) pSelf->value.asCodeblock.string,
pSelf->ulLength, HB_COMP_PARAM );
}
static void hb_compExprCodeblockEarly( HB_EXPR_PTR pSelf, HB_COMP_DECL )
{
HB_EXPR_PTR pExpr;

View File

@@ -143,6 +143,7 @@ extern HB_EXPR_PTR hb_compExprAddListExpr( HB_EXPR_PTR, HB_EXPR_PTR );
extern HB_EXPR_PTR hb_compExprCBVarAdd( HB_EXPR_PTR, char *, BYTE, HB_COMP_DECL );
extern void hb_compExprCBVarDel( HB_CBVAR_PTR );
extern HB_EXPR_PTR hb_compExprAddCodeblockExpr( HB_EXPR_PTR, HB_EXPR_PTR );
extern HB_EXPR_PTR hb_compExprSetCodeblockBody( HB_EXPR_PTR pExpr, BYTE * pCode, ULONG ulLen );
extern HB_EXPR_PTR hb_compExprNewIIF( HB_EXPR_PTR );
extern HB_EXPR_PTR hb_compExprMacroAsAlias( HB_EXPR_PTR );
extern HB_EXPR_PTR hb_compExprAssign( HB_EXPR_PTR, HB_EXPR_PTR, HB_COMP_DECL );

View File

@@ -62,6 +62,7 @@ HB_EXTERN_BEGIN
#define HB_BLOCK_MACRO 1
#define HB_BLOCK_LATEEVAL 2
#define HB_BLOCK_VPARAMS 4
#define HB_BLOCK_EXT 8
/* #pragma {__text,__stream,__cstream}|functionOut|functionEnd|functionStart */
#define HB_PP_STREAM_OFF 0 /* standard preprocessing */
@@ -599,6 +600,8 @@ typedef struct
int iInLineCount; /* number of hb_inLine() functions */
int iInLineState; /* hb_inLine() state */
int iInLineBraces; /* braces counter for hb_inLine() */
int iNestedBlock; /* nested extended block counter */
int iBlockState; /* state of extended block declaration */
PHB_PP_FILE pFile; /* currently preprocessed file structure */
int iFiles; /* number of open files */

View File

@@ -164,7 +164,7 @@ extern void yyerror( HB_COMP_DECL, char * ); /* parsing error management fun
%token AS_ARRAY AS_BLOCK AS_CHARACTER AS_CLASS AS_DATE AS_LOGICAL AS_NUMERIC AS_OBJECT AS_VARIANT DECLARE OPTIONAL DECLARE_CLASS DECLARE_MEMBER
%token AS_ARRAY_ARRAY AS_BLOCK_ARRAY AS_CHARACTER_ARRAY AS_CLASS_ARRAY AS_DATE_ARRAY AS_LOGICAL_ARRAY AS_NUMERIC_ARRAY AS_OBJECT_ARRAY
%token PROCREQ
%token CBSTART BEGINCODE DOIDENT
%token CBSTART DOIDENT
%token FOREACH DESCEND
%token DOSWITCH WITHOBJECT
%token NUM_DATE
@@ -211,7 +211,7 @@ extern void yyerror( HB_COMP_DECL, char * ); /* parsing error management fun
%type <lNumber> WhileBegin
%type <pVoid> IfElseIf Cases
%type <asExpr> Argument ExtArgument RefArgument ArgList ElemList
%type <asExpr> BlockExpList BlockVars BlockVarList
%type <asExpr> BlockHead BlockExpList BlockVars BlockVarList
%type <asExpr> DoName DoProc DoArgs DoArgument DoArgList
%type <asExpr> NumValue NumAlias
%type <asExpr> NilValue NilAlias
@@ -408,7 +408,11 @@ Statement : ExecFlow CrlfStmnt
}
/* TODO: check if return value agree with declared value */
HB_COMP_EXPR_DELETE( hb_compExprGenPush( $3, HB_COMP_PARAM ) );
hb_compGenPCode2( HB_P_RETVALUE, HB_P_ENDPROC, HB_COMP_PARAM );
if( HB_COMP_PARAM->functions.pLast->bFlags & FUN_EXTBLOCK )
/* extended clodeblock, use HB_P_ENDBLOCK to return value and stop execution */
hb_compGenPCode1( HB_P_ENDBLOCK, HB_COMP_PARAM );
else
hb_compGenPCode2( HB_P_RETVALUE, HB_P_ENDPROC, HB_COMP_PARAM );
if( HB_COMP_PARAM->functions.pLast->bFlags & FUN_PROCEDURE )
{ /* procedure returns a value */
hb_compGenWarning( HB_COMP_PARAM, hb_comp_szWarnings, 'W', HB_COMP_WARN_PROC_RETURN_VALUE, NULL, NULL );
@@ -1010,17 +1014,11 @@ ElemList : ExtArgument { $$ = hb_compExprNewList( $1, HB_COMP_PA
| ElemList ',' ExtArgument { $$ = hb_compExprAddListExpr( $1, $3 ); }
;
CodeBlock : CBSTART { $<asExpr>$ = hb_compExprNewCodeBlock( $1.string, $1.length, $1.flags, HB_COMP_PARAM ); $1.string = NULL; }
BlockVars '|' BlockExpList '}' { $$ = $<asExpr>2; }
;
BlockHead : CBSTART { $$ = hb_compExprNewCodeBlock( $1.string, $1.length, $1.flags, HB_COMP_PARAM ); $1.string = NULL; }
BlockVars '|' { $$ = $<asExpr>2; }
;
/* NOTE: This uses $-2 then don't use BlockExpList in other context
*/
BlockExpList : Expression { $$ = hb_compExprAddCodeblockExpr( $<asExpr>-2, $1 ); }
| BlockExpList ',' Expression { $$ = hb_compExprAddCodeblockExpr( $<asExpr>-2, $3 ); }
;
/* NOTE: This uses $0 then don't use BlockVars and BlockVarList in other context
/* NOTE: This uses $0 then don't use BlockVars, BlockVarList and BlockExpList in other context
*/
BlockVars : /* empty list */ { $$ = NULL; }
| EPSILON { $$ = NULL; $<asExpr>0->value.asCodeblock.flags |= HB_BLOCK_VPARAMS; }
@@ -1032,6 +1030,47 @@ BlockVarList : IdentName AsType { HB_COMP_PARAM->iVarScope =
| BlockVarList ',' IdentName AsType { HB_COMP_PARAM->iVarScope = VS_LOCAL; $$ = hb_compExprCBVarAdd( $<asExpr>0, $3, HB_COMP_PARAM->cVarType, HB_COMP_PARAM ); HB_COMP_PARAM->cVarType = ' '; }
;
BlockExpList : Expression { $$ = hb_compExprAddCodeblockExpr( $<asExpr>0, $1 ); }
| BlockExpList ',' Expression { $$ = hb_compExprAddCodeblockExpr( $<asExpr>0, $3 ); }
;
CodeBlock : BlockHead BlockExpList '}'
| BlockHead Crlf
{ /* 3 */
HB_CBVAR_PTR pVar;
$<lNumber>$ = HB_COMP_PARAM->functions.pLast->lPCodePos;
hb_compCodeBlockStart( HB_COMP_PARAM, TRUE );
HB_COMP_PARAM->functions.pLast->bFlags |= FUN_EXTBLOCK;
HB_COMP_PARAM->functions.pLast->fVParams =
( $1->value.asCodeblock.flags & HB_BLOCK_VPARAMS ) != 0;
$1->value.asCodeblock.flags |= HB_BLOCK_EXT;
if( $1->value.asCodeblock.string )
{
hb_xfree( $1->value.asCodeblock.string );
$1->value.asCodeblock.string = NULL;
$1->ulLength = 0;
}
HB_COMP_PARAM->iVarScope = VS_PARAMETER;
pVar = $1->value.asCodeblock.pLocals;
while( pVar )
{
hb_compVariableAdd( HB_COMP_PARAM, pVar->szName, pVar->bType );
pVar =pVar->pNext;
}
}
EmptyStats '}'
{ /* 6 */
hb_compCodeBlockEnd( HB_COMP_PARAM );
$$ = hb_compExprSetCodeblockBody( $1,
HB_COMP_PARAM->functions.pLast->pCode + ( ULONG ) $<lNumber>3,
HB_COMP_PARAM->functions.pLast->lPCodePos - $<lNumber>3 );
HB_COMP_PARAM->functions.pLast->lPCodePos = $<lNumber>3;
HB_COMP_PARAM->lastLinePos = 0;
}
;
ExpList : Expression { $$ = hb_compExprNewList( $1, HB_COMP_PARAM ); }
| ExpList ',' Expression { $$ = hb_compExprAddListExpr( $1, $3 ); }
@@ -1108,6 +1147,11 @@ VarDef : IdentName AsType { hb_compVariableAdd( HB_COMP_PARAM, $1, HB_COMP_P
{
hb_compRTVariableAdd( HB_COMP_PARAM, hb_compExprNewRTVar( $1, NULL, HB_COMP_PARAM ), FALSE );
}
else if( HB_COMP_PARAM->iVarScope == VS_LOCAL &&
( HB_COMP_PARAM->functions.pLast->bFlags & FUN_EXTBLOCK ) )
{
HB_COMP_EXPR_DELETE( hb_compExprGenPush( hb_compExprNewNil( HB_COMP_PARAM ), HB_COMP_PARAM ) );
}
}
| IdentName AsType { $<iNumber>$ = HB_COMP_PARAM->iVarScope;
hb_compVariableAdd( HB_COMP_PARAM, $1, HB_COMP_PARAM->cVarType );
@@ -1129,6 +1173,11 @@ VarDef : IdentName AsType { hb_compVariableAdd( HB_COMP_PARAM, $1, HB_COMP_P
HB_COMP_EXPR_DELETE( hb_compExprGenPush( $6, HB_COMP_PARAM ) );
hb_compRTVariableAdd( HB_COMP_PARAM, hb_compExprNewRTVar( $1, NULL, HB_COMP_PARAM ), TRUE );
}
else if( HB_COMP_PARAM->iVarScope == VS_LOCAL &&
( HB_COMP_PARAM->functions.pLast->bFlags & FUN_EXTBLOCK ) )
{
HB_COMP_EXPR_DELETE( hb_compExprGenPush( $6, HB_COMP_PARAM ) );
}
else
{
HB_COMP_EXPR_DELETE( hb_compExprGenStatement( hb_compExprAssign( hb_compExprNewVar( $1, HB_COMP_PARAM ), $6, HB_COMP_PARAM ), HB_COMP_PARAM ) );
@@ -2212,7 +2261,12 @@ static void hb_compVariableDim( char * szName, HB_EXPR_PTR pInitValue, HB_COMP_D
hb_compVariableAdd( HB_COMP_PARAM, szName, 'A' );
HB_COMP_EXPR_DELETE( hb_compExprGenPush( pInitValue, HB_COMP_PARAM ) );
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ), HB_COMP_PARAM );
HB_COMP_EXPR_DELETE( hb_compExprGenPop( hb_compExprNewVar( szName, HB_COMP_PARAM ), HB_COMP_PARAM ) );
if( HB_COMP_PARAM->iVarScope != VS_LOCAL ||
!( HB_COMP_PARAM->functions.pLast->bFlags & FUN_EXTBLOCK ) )
{
HB_COMP_EXPR_DELETE( hb_compExprGenPop( hb_compExprNewVar( szName, HB_COMP_PARAM ), HB_COMP_PARAM ) );
}
}
}
@@ -2596,6 +2650,11 @@ BOOL hb_compCheckUnclosedStru( HB_COMP_DECL )
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_UNCLOSED_STRU, "BEGIN SEQUENCE", NULL );
HB_COMP_PARAM->wSeqCounter = 0;
}
else if( HB_COMP_PARAM->functions.pLast &&
( HB_COMP_PARAM->functions.pLast->bFlags & FUN_EXTBLOCK ) )
{
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_UNCLOSED_STRU, "<||...>", NULL );
}
else
fUnclosed = FALSE;

File diff suppressed because it is too large Load Diff

View File

@@ -132,18 +132,17 @@
AS_OBJECT_ARRAY = 348,
PROCREQ = 349,
CBSTART = 350,
BEGINCODE = 351,
DOIDENT = 352,
FOREACH = 353,
DESCEND = 354,
DOSWITCH = 355,
WITHOBJECT = 356,
NUM_DATE = 357,
EPSILON = 358,
HASHOP = 359,
POST = 360,
UNARY = 361,
PRE = 362
DOIDENT = 351,
FOREACH = 352,
DESCEND = 353,
DOSWITCH = 354,
WITHOBJECT = 355,
NUM_DATE = 356,
EPSILON = 357,
HASHOP = 358,
POST = 359,
UNARY = 360,
PRE = 361
};
#endif
/* Tokens. */
@@ -240,18 +239,17 @@
#define AS_OBJECT_ARRAY 348
#define PROCREQ 349
#define CBSTART 350
#define BEGINCODE 351
#define DOIDENT 352
#define FOREACH 353
#define DESCEND 354
#define DOSWITCH 355
#define WITHOBJECT 356
#define NUM_DATE 357
#define EPSILON 358
#define HASHOP 359
#define POST 360
#define UNARY 361
#define PRE 362
#define DOIDENT 351
#define FOREACH 352
#define DESCEND 353
#define DOSWITCH 354
#define WITHOBJECT 355
#define NUM_DATE 356
#define EPSILON 357
#define HASHOP 358
#define POST 359
#define UNARY 360
#define PRE 361
@@ -301,7 +299,7 @@ typedef union YYSTYPE
} asMessage;
}
/* Line 1533 of yacc.c. */
#line 305 "harboury.h"
#line 303 "harboury.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1

View File

@@ -485,6 +485,12 @@ void hb_compVariableAdd( HB_COMP_DECL, char * szVarName, BYTE cValueType )
HB_COMP_PARAM->iVarScope == VS_PUBLIC ) )
hb_compCheckDuplVars( HB_COMP_PARAM, pFunc->pMemvars, szVarName );
}
else if( pFunc->bFlags & FUN_EXTBLOCK )
{
/* variable defined in an extended codeblock */
hb_compCheckDuplVars( HB_COMP_PARAM, pFunc->pFields, szVarName );
hb_compCheckDuplVars( HB_COMP_PARAM, pFunc->pStatics, szVarName );
}
else if( HB_COMP_PARAM->iVarScope != VS_PARAMETER )
{
fprintf( hb_comp_errFile, "Wrong type of codeblock parameter, is: %d, should be: %d\r\n", HB_COMP_PARAM->iVarScope, VS_PARAMETER );
@@ -845,6 +851,30 @@ PVAR hb_compVariableFind( HB_COMP_DECL, char * szVarName, int * piPos, int * piS
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_OUTER_VAR, szVarName, NULL );
}
}
else if( pFunc->bFlags & FUN_EXTBLOCK )
{ /* extended codeblock */
/* check static variables */
pVar = hb_compVariableGet( pFunc->pStatics, szVarName, piPos );
if( pVar )
{
*piScope = HB_VS_STATIC_VAR;
*piPos += pFunc->iStaticsBase;
}
else
{
/* check FIELDs */
pVar = hb_compVariableGet( pFunc->pFields, szVarName, piPos );
if( pVar )
*piScope = HB_VS_LOCAL_FIELD;
else
{
/* check MEMVARs */
pVar = hb_compVariableGet( pFunc->pMemvars, szVarName, piPos );
if( pVar )
*piScope = HB_VS_LOCAL_MEMVAR;
}
}
}
}
if( pVar )
@@ -3007,7 +3037,8 @@ void hb_compGenPopVar( char * szVarName, HB_COMP_DECL ) /* generates the pcode t
* if PARAMETERS statement will be used then it is safe to
* use 2 bytes for LOCALNEAR
*/
if( HB_LIM_INT8( iVar ) && !HB_COMP_PARAM->functions.pLast->szName )
if( HB_LIM_INT8( iVar ) && !HB_COMP_PARAM->functions.pLast->szName &&
!( HB_COMP_PARAM->functions.pLast->bFlags & FUN_EXTBLOCK ) )
hb_compGenPCode2( HB_P_POPLOCALNEAR, ( BYTE ) iVar, HB_COMP_PARAM );
else
hb_compGenPCode3( HB_P_POPLOCAL, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ), HB_COMP_PARAM );
@@ -3082,7 +3113,8 @@ void hb_compGenPushVar( char * szVarName, BOOL bMacroVar, HB_COMP_DECL )
* if PARAMETERS statement will be used then it is safe to
* use 2 bytes for LOCALNEAR
*/
if( HB_LIM_INT8( iVar ) && !HB_COMP_PARAM->functions.pLast->szName )
if( HB_LIM_INT8( iVar ) && !HB_COMP_PARAM->functions.pLast->szName &&
!( HB_COMP_PARAM->functions.pLast->bFlags & FUN_EXTBLOCK ) )
hb_compGenPCode2( HB_P_PUSHLOCALNEAR, ( BYTE ) iVar, HB_COMP_PARAM );
else
hb_compGenPCode3( HB_P_PUSHLOCAL, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ), HB_COMP_PARAM );
@@ -3791,6 +3823,17 @@ void hb_compCodeBlockEnd( HB_COMP_DECL )
pCodeblock = HB_COMP_PARAM->functions.pLast;
/* Check if the extended codeblock has return statement */
if( ( pCodeblock->bFlags & FUN_EXTBLOCK ) &&
!( pCodeblock->bFlags & FUN_WITH_RETURN ) )
{
if( HB_COMP_PARAM->iWarnings >= 1 )
hb_compGenWarning( HB_COMP_PARAM, hb_comp_szWarnings, 'W', HB_COMP_WARN_FUN_WITH_NO_RETURN,
"<||...>", NULL );
/* finish the codeblock without popping the return value from HVM stack */
hb_compGenPCode1( HB_P_ENDPROC, HB_COMP_PARAM );
}
hb_compGenPCode1( HB_P_ENDBLOCK, HB_COMP_PARAM ); /* finish the codeblock */
if( !pCodeblock->bError )

View File

@@ -529,6 +529,12 @@ static void hb_pp_tokenAddCmdSep( PHB_PP_STATE pState )
pState->pFile->iTokens++;
pState->fNewStatement = TRUE;
pState->fCanNextLine = FALSE;
if( pState->iBlockState )
{
if( pState->iBlockState == 5 )
pState->iNestedBlock++;
pState->iBlockState = 0;
}
}
static void hb_pp_tokenAddNext( PHB_PP_STATE pState, const char * value, ULONG ulLen,
@@ -537,12 +543,44 @@ static void hb_pp_tokenAddNext( PHB_PP_STATE pState, const char * value, ULONG u
if( pState->fCanNextLine )
hb_pp_tokenAddCmdSep( pState );
if( !pState->fDirective && pState->fNewStatement &&
ulLen == 1 && * value == '#' )
if( !pState->fDirective )
{
pState->fDirective = TRUE;
value = "#";
type = HB_PP_TOKEN_DIRECTIVE | HB_PP_TOKEN_STATIC;
if( pState->iNestedBlock && pState->fNewStatement &&
HB_PP_TOKEN_TYPE( type ) == HB_PP_TOKEN_RIGHT_CB )
{
pState->iBlockState = 0;
pState->iNestedBlock--;
}
else if( pState->iLastType == HB_PP_TOKEN_LEFT_CB &&
HB_PP_TOKEN_TYPE( type ) == HB_PP_TOKEN_PIPE )
{
pState->iBlockState = 1;
}
else if( pState->iBlockState )
{
if( ( pState->iBlockState == 1 || pState->iBlockState == 2 ||
pState->iBlockState == 4 ) &&
HB_PP_TOKEN_TYPE( type ) == HB_PP_TOKEN_PIPE )
pState->iBlockState = 5;
else if( pState->iBlockState == 1 &&
HB_PP_TOKEN_TYPE( type ) == HB_PP_TOKEN_KEYWORD )
pState->iBlockState = 2;
else if( pState->iBlockState == 1 &&
HB_PP_TOKEN_TYPE( type ) == HB_PP_TOKEN_EPSILON )
pState->iBlockState = 4;
else if( pState->iBlockState == 2 &&
HB_PP_TOKEN_TYPE( type ) == HB_PP_TOKEN_COMMA )
pState->iBlockState = 1;
else
pState->iBlockState = 0;
}
if( pState->fNewStatement && ulLen == 1 && * value == '#' )
{
pState->fDirective = TRUE;
value = "#";
type = HB_PP_TOKEN_DIRECTIVE | HB_PP_TOKEN_STATIC;
}
}
#ifndef HB_C52_STRICT
@@ -788,6 +826,7 @@ static void hb_pp_getLine( PHB_PP_STATE pState )
pState->iLastType = HB_PP_TOKEN_NUL;
pState->iInLineState = HB_PP_INLINE_OFF;
pState->iInLineBraces = 0;
pState->iBlockState = pState->iNestedBlock = 0;
do
{
@@ -1286,10 +1325,25 @@ static void hb_pp_getLine( PHB_PP_STATE pState )
ulLen -= ul;
ul = 0;
}
if( !pState->fCanNextLine &&
( pState->iNestedBlock || pState->iBlockState == 5 ) )
{
pState->pFile->iCurrentLine--;
hb_pp_tokenAdd( &pState->pNextTokenPtr, "\n", 1, 0, HB_PP_TOKEN_EOL | HB_PP_TOKEN_STATIC );
pState->pFile->iTokens++;
pState->fNewStatement = TRUE;
if( pState->iBlockState )
{
if( pState->iBlockState == 5 )
pState->iNestedBlock++;
pState->iBlockState = 0;
}
}
}
while( ( pState->pFile->pLineBuf ? pState->pFile->ulLineBufLen != 0 :
!pState->pFile->fEof ) &&
( pState->fCanNextLine ||
( pState->fCanNextLine || pState->iNestedBlock ||
( pState->iStreamDump && pState->iStreamDump != HB_PP_STREAM_CLIPPER ) ) );
if( pState->iStreamDump )
@@ -3074,11 +3128,56 @@ static void hb_pp_directiveNew( PHB_PP_STATE pState, PHB_PP_TOKEN pToken,
hb_pp_tokenListFree( &pResult );
}
static BOOL hb_pp_tokenStartExtBlock( PHB_PP_TOKEN * pTokenPtr )
{
PHB_PP_TOKEN pToken = * pTokenPtr;
if( pToken && HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_LEFT_CB &&
pToken->pNext && HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_PIPE )
{
USHORT prevtype = HB_PP_TOKEN_COMMA;
pToken = pToken->pNext->pNext;
while( pToken )
{
USHORT type = HB_PP_TOKEN_TYPE( pToken->type );
if( ( ( type == HB_PP_TOKEN_KEYWORD || type == HB_PP_TOKEN_EPSILON ) &&
prevtype == HB_PP_TOKEN_COMMA ) ||
( type == HB_PP_TOKEN_COMMA && prevtype == HB_PP_TOKEN_KEYWORD ) )
{
prevtype = type;
pToken = pToken->pNext;
}
else
break;
}
if( pToken && pToken->pNext && HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_PIPE &&
HB_PP_TOKEN_ISEOC( pToken->pNext ) )
{
*pTokenPtr = pToken->pNext;
return TRUE;
}
}
return FALSE;
}
static BOOL hb_pp_tokenStopExtBlock( PHB_PP_TOKEN * pTokenPtr )
{
PHB_PP_TOKEN pToken = * pTokenPtr;
if( HB_PP_TOKEN_ISEOC( pToken ) && pToken->pNext &&
HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_RIGHT_CB )
{
*pTokenPtr = pToken->pNext->pNext;
return TRUE;
}
return FALSE;
}
static BOOL hb_pp_tokenSkipExp( PHB_PP_TOKEN * pTokenPtr, PHB_PP_TOKEN pStop,
USHORT mode, BOOL * pfStop )
{
USHORT curtype, prevtype = 0, lbrtype = 0, rbrtype = 0;
PHB_PP_TOKEN pToken = * pTokenPtr;
PHB_PP_TOKEN pToken = * pTokenPtr, pPrev;
int iBraces = 0;
BOOL fMatch;
@@ -3087,7 +3186,27 @@ static BOOL hb_pp_tokenSkipExp( PHB_PP_TOKEN * pTokenPtr, PHB_PP_TOKEN pStop,
while( TRUE )
{
if( HB_PP_TOKEN_ISEOC( pToken ) )
pPrev = pToken;
if( hb_pp_tokenStartExtBlock( &pToken ) )
{
int iExtBlock = 1;
while( pToken )
{
if( hb_pp_tokenStartExtBlock( &pToken ) )
iExtBlock++;
else if( hb_pp_tokenStopExtBlock( &pToken ) )
{
if( --iExtBlock == 0 )
break;
}
else
pToken = pToken->pNext;
}
if( iExtBlock )
pToken = pPrev;
}
if( HB_PP_TOKEN_ISEOC( pToken ) && mode != HB_PP_CMP_ADDR )
{
if( pfStop )
* pfStop = TRUE;
@@ -4357,7 +4476,7 @@ static void hb_pp_genLineTokens( PHB_PP_STATE pState )
#endif
}
static void hb_pp_preprocesToken( PHB_PP_STATE pState )
static void hb_pp_preprocessToken( PHB_PP_STATE pState )
{
while( !pState->pTokenOut && pState->pFile )
{
@@ -4678,7 +4797,7 @@ PHB_PP_TOKEN hb_pp_tokenGet( PHB_PP_STATE pState )
}
if( !pState->pTokenOut )
hb_pp_preprocesToken( pState );
hb_pp_preprocessToken( pState );
if( pState->fWritePreprocesed && pState->pTokenOut )
{