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