ChangeLog 20000103-19:48 GMT+1

This commit is contained in:
Ryszard Glab
2000-01-03 18:36:59 +00:00
parent 1ecd9bcc55
commit a3792dc1c1
10 changed files with 368 additions and 126 deletions

View File

@@ -1,3 +1,41 @@
20000103-19:48 GMT+1 Ryszard Glab <rglab@imid.med.pl>
*include/expropt.h
*include/hbexpr.c
* renamed: hb_compExprNewSymbol() -> hb_compExprNewFunName()
* added new expression type: HB_ET_RTVAR and hb_compExprNewRTVar()
for PUBLIC and PRIVATE variable declarations
*source/compiler/expropt.c
*source/compiler/harbour.c
*source/compiler/harbour.y
*source/compiler/harbour.l
* added support for macro variables in PUBLIC and PRIVATE declarations
PRIVATE &var, &var.end
* optimization of PUBLIC/PRIVATE variables creation (there was a
single call __MVPUBLIC/__MVPRIVATE function for every variable,
there is a single call for a single statement now), for example:
PRIVATE var1, var2, var3
// 3 calls previously - only one call now
*source/macro/macro.y
* renamed: hb_compExprNewSymbol() -> hb_compExprNewFunName()
* fixed handling of &var.text syntax
*source/macro/macro.c
* fixed handling of &var.text syntax
* handling of text substitution is now Clipper compatible -
previously only substituted value was scanned for nested macro
operator - the whole text is rescanned now, for example:
PRIVATE a:='&', b:='b'
? &a.b
will print a value of variable 'b' now instead of a generation
of a syntax error.
*include/extend.h
* added declaration for hb_macroTextSubst()
* added declaration for hb_macroIsIdent()
20000102-14:27 EST Paul Tucker <ptucker@sympatico.ca>
* source/rtl/environ.c
* remove Borland check on define of VER_PLATFORM_WIN32_CE

View File

@@ -46,6 +46,11 @@ typedef struct HB_EXPR_
char *asSymbol; /* variable name */
BOOL asLogical; /* logical value */
struct
{
struct HB_EXPR_ *pMacro; /* macro variable */
char *szName; /* variable name */
} asRTVar; /* PUBLIC or PRIVATE variable declaration */
struct
{
long lVal; /* long value */
double dVal; /* double value */
@@ -134,7 +139,8 @@ HB_EXPR_PTR hb_compExprNewVar( char * );
HB_EXPR_PTR hb_compExprNewAliasVar( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewAliasExpr( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMacro( HB_EXPR_PTR, unsigned char, char * );
HB_EXPR_PTR hb_compExprNewSymbol( char * );
HB_EXPR_PTR hb_compExprNewFunName( char * );
HB_EXPR_PTR hb_compExprNewRTVar( char *, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewAlias( char * );
HB_EXPR_PTR hb_compExprNewEQ( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewNE( HB_EXPR_PTR );

View File

@@ -461,6 +461,8 @@ extern void hb_macroPushSymbol( HB_ITEM_PTR );
extern void hb_macroRun( HB_MACRO_PTR );
extern HB_MACRO_PTR hb_macroCompile( char * );
extern void hb_macroDelete( HB_MACRO_PTR );
extern char * hb_macroTextSubst( char *, ULONG * );
extern BOOL hb_macroIsIdent( char * );
/* misc */
extern char * hb_version( USHORT uiMode );

View File

@@ -123,7 +123,7 @@ typedef enum
/* additional definitions used to distinguish macro expressions
*/
#define HB_ET_MACRO_VAR 0 /* &variable */
#define HB_ET_MACRO_FUNCALL 1 /* &fimcall() */
#define HB_ET_MACRO_SYMBOL 1 /* &fimcall() */
#define HB_ET_MACRO_ALIASED 2 /* &alias->&variable */
/* types of expressions
@@ -153,8 +153,9 @@ typedef enum
HB_ET_ALIASVAR,
HB_ET_ALIASEXPR,
HB_ET_SEND,
HB_ET_SYMBOL,
HB_ET_FUNNAME,
HB_ET_ALIAS,
HB_ET_RTVAR, /* PRIVATE or PUBLIC declaration of variable */
HB_ET_VARIABLE,
HB_EO_POSTINC, /* post-operators -> lowest precedence */
HB_EO_POSTDEC,
@@ -208,8 +209,9 @@ static HB_EXPR_FUNC( hb_compExprUseFunCall );
static HB_EXPR_FUNC( hb_compExprUseAliasVar );
static HB_EXPR_FUNC( hb_compExprUseAliasExpr );
static HB_EXPR_FUNC( hb_compExprUseSend );
static HB_EXPR_FUNC( hb_compExprUseSymbol );
static HB_EXPR_FUNC( hb_compExprUseFunName );
static HB_EXPR_FUNC( hb_compExprUseAlias );
static HB_EXPR_FUNC( hb_compExprUseRTVariable );
static HB_EXPR_FUNC( hb_compExprUseVariable );
static HB_EXPR_FUNC( hb_compExprUseAssign );
static HB_EXPR_FUNC( hb_compExprUseEqual );
@@ -261,8 +263,9 @@ static HB_EXPR_FUNC_PTR s_ExprTable[] = {
hb_compExprUseAliasVar,
hb_compExprUseAliasExpr,
hb_compExprUseSend,
hb_compExprUseSymbol,
hb_compExprUseFunName,
hb_compExprUseAlias,
hb_compExprUseRTVariable,
hb_compExprUseVariable,
hb_compExprUsePostInc, /* post-operators -> lowest precedence */
hb_compExprUsePostDec,
@@ -320,8 +323,9 @@ static BYTE s_PrecedTable[] = {
HB_ET_NIL, /* HB_ET_ALIASVAR, */
HB_ET_NIL, /* HB_ET_ALIASEXPR, */
HB_ET_NIL, /* HB_ET_SEND, */
HB_ET_NIL, /* HB_ET_SYMBOL, */
HB_ET_NIL, /* HB_ET_ALIAS, */
HB_ET_NIL, /* HB_ET_FUNNAME, */
HB_ET_NIL, /* HB_ET_ALIAS, */
HB_ET_NIL, /* HB_ET_RTVARIABLE, */
HB_ET_NIL, /* HB_ET_VARIABLE, */
HB_ET_NIL, /* HB_EO_POSTINC, post-operators */
HB_ET_NIL, /* HB_EO_POSTDEC, */
@@ -376,6 +380,7 @@ static char * s_OperTable[] = {
":",
"", /* symbol */
"", /* alias */
"", /* RunTime variable */
"", /* variable */
"++", /* post-operators -> lowest precedence */
"--",
@@ -718,7 +723,7 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms )
{
HB_EXPR_PTR pExpr = NULL;
if( pName->ExprType == HB_ET_SYMBOL )
if( pName->ExprType == HB_ET_FUNNAME )
{
/* The name of a function is specified at compile time
* e.g. MyFunc()
@@ -800,7 +805,7 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms )
/* Signal that macro compiler have to generate a pcode that will
* return function name as symbol instead of usual value
*/
pName->value.asMacro.SubType = HB_ET_MACRO_FUNCALL;
pName->value.asMacro.SubType = HB_ET_MACRO_SYMBOL;
HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewFunCall(&)"));
}
@@ -1044,11 +1049,27 @@ HB_EXPR_PTR hb_compExprNewVar( char * szName )
return pExpr;
}
/* Create a new declaration of PUBLIC or PRIVATE variable.
*
* szName is a string with variable name if 'PUBLIC varname' context
* pMacroVar is a macro expression if 'PUBLIC &varname' context
*/
HB_EXPR_PTR hb_compExprNewRTVar( char * szName, HB_EXPR_PTR pMacroVar )
{
HB_EXPR_PTR pExpr = hb_compExprNew( HB_ET_RTVAR );
pExpr->value.asRTVar.szName = szName;
pExpr->value.asRTVar.pMacro = pMacroVar;
if( pMacroVar )
pMacroVar->value.asMacro.SubType = HB_ET_MACRO_SYMBOL;
return pExpr;
}
/* Create a new symbol used in function calls
*/
HB_EXPR_PTR hb_compExprNewSymbol( char * szName )
HB_EXPR_PTR hb_compExprNewFunName( char * szName )
{
HB_EXPR_PTR pExpr = hb_compExprNew( HB_ET_SYMBOL );
HB_EXPR_PTR pExpr = hb_compExprNew( HB_ET_FUNNAME );
pExpr->value.asSymbol = szName;
return pExpr;
}
@@ -1331,7 +1352,7 @@ HB_EXPR_PTR hb_compExprAssign( HB_EXPR_PTR pLeftExpr, HB_EXPR_PTR pRightExpr )
/* It initializes static variable.
* It is called in the following context:
* STATIC sVar := expression
*
*
* pLeftExpr - is a variable name
* pRightExpr - can be an expression of any type
*/
@@ -2346,7 +2367,7 @@ static HB_EXPR_FUNC( hb_compExprUseMacro )
}
/* compile & run - leave a result on the eval stack
*/
if( pSelf->value.asMacro.SubType == HB_ET_MACRO_FUNCALL )
if( pSelf->value.asMacro.SubType == HB_ET_MACRO_SYMBOL )
hb_compGenPCode1( HB_P_MACROSYMBOL );
else if( pSelf->value.asMacro.SubType != HB_ET_MACRO_ALIASED )
hb_compGenPCode1( HB_P_MACROPUSH );
@@ -2723,7 +2744,7 @@ static HB_EXPR_FUNC( hb_compExprUseAlias )
return pSelf;
}
static HB_EXPR_FUNC( hb_compExprUseSymbol )
static HB_EXPR_FUNC( hb_compExprUseFunName )
{
switch( iMessage )
{
@@ -2747,6 +2768,41 @@ static HB_EXPR_FUNC( hb_compExprUseSymbol )
return pSelf;
}
static HB_EXPR_FUNC( hb_compExprUseRTVariable )
{
switch( iMessage )
{
case HB_EA_REDUCE:
case HB_EA_ARRAY_AT:
case HB_EA_ARRAY_INDEX:
case HB_EA_LVALUE:
break;
case HB_EA_PUSH_PCODE:
if( pSelf->value.asRTVar.szName )
#ifndef HB_MACRO_SUPPORT
hb_compGenPushSymbol( pSelf->value.asRTVar.szName, 0 ); /* this is not a function name */
#else
hb_compGenPushSymbol( pSelf->value.asRTVar.szName );
#endif
else
HB_EXPR_USE( pSelf->value.asRTVar.pMacro, HB_EA_PUSH_PCODE );
break;
case HB_EA_POP_PCODE:
if( pSelf->value.asRTVar.szName )
hb_compGenPopVar( pSelf->value.asRTVar.szName );
else
HB_EXPR_USE( pSelf->value.asRTVar.pMacro, HB_EA_POP_PCODE );
break;
case HB_EA_PUSH_POP:
case HB_EA_STATEMENT:
case HB_EA_DELETE:
break;
}
return pSelf;
}
static HB_EXPR_FUNC( hb_compExprUseVariable )
{
switch( iMessage )

View File

@@ -3,7 +3,7 @@
*/
/* hbexpr.c is also included from ../macro/macro.c
* However it produces a slighty different code if used in macro
* compiler
* However it produces a slighty different code if used in
* macro compiler
*/
#include "hbexpr.c"

View File

@@ -479,21 +479,17 @@ void hb_compVariableAdd( char * szVarName, char cValueType )
break;
case VS_PRIVATE:
{
hb_compGenPushSymbol( hb_strdup( "__MVPRIVATE" ), 1);
hb_compGenPushNil();
hb_compGenPushSymbol( hb_strdup( szVarName ), 0 );
hb_compGenPCode3( HB_P_DO, 1, 0 );
pSym = hb_compSymbolFind( szVarName, NULL );
pSym = hb_compSymbolFind( szVarName, &wPos ); /* check if symbol exists already */
if( ! pSym )
pSym = hb_compSymbolAdd( hb_strdup( szVarName ), &wPos );
pSym->cScope |= VS_MEMVAR;
}
break;
case VS_PUBLIC:
{
hb_compGenPushSymbol( hb_strdup( "__MVPUBLIC" ), 1);
hb_compGenPushNil();
hb_compGenPushSymbol( hb_strdup( szVarName ), 0 );
hb_compGenPCode3( HB_P_DO, 1, 0 );
pSym = hb_compSymbolFind( szVarName, NULL );
pSym = hb_compSymbolFind( szVarName, &wPos ); /* check if symbol exists already */
if( ! pSym )
pSym = hb_compSymbolAdd( hb_strdup( szVarName ), &wPos );
pSym->cScope |= VS_MEMVAR;
}
break;

View File

@@ -947,7 +947,7 @@ Separator {SpaceTab}
"priv"("ate"|"at"|"a")? { BEGIN PRIVATE_;
yylval.string = hb_strupr( hb_strdup( yytext ) );
}
<PRIVATE_>{Separator}+[_a-zA-Z] { /* an Identifier after PRIVATE */
<PRIVATE_>{Separator}+[_a-zA-Z\&] { /* an Identifier after PRIVATE */
unput( yytext[ yyleng-1 ] );
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
if( hb_comp_iState == LOOKUP )
@@ -963,7 +963,6 @@ Separator {SpaceTab}
}
}
<PRIVATE_>{Separator}*[^a-zA-Z] { /* any character (not identifier) after PRIVATE */
/* TODO: add support for macro operator */
unput( yytext[ yyleng-1 ] );
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
hb_comp_iState =IDENTIFIER;
@@ -979,7 +978,7 @@ Separator {SpaceTab}
"publ"("ic"|"i")? { BEGIN PUBLIC_;
yylval.string = hb_strupr( hb_strdup( yytext ) );
}
<PUBLIC_>{Separator}+[_a-zA-Z] { /* an identifier after PUBLIC */
<PUBLIC_>{Separator}+[_a-zA-Z\&] { /* an identifier after PUBLIC */
unput( yytext[ yyleng-1 ] );
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
if( hb_comp_iState == LOOKUP )
@@ -995,7 +994,6 @@ Separator {SpaceTab}
}
}
<PUBLIC_>{Separator}*[^a-zA-Z] { /* any character (not identifier) after PUBLIC */
/* TODO: add support for macro operator */
unput( yytext[ yyleng-1 ] );
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
hb_comp_iState =IDENTIFIER;
@@ -1097,10 +1095,10 @@ Separator {SpaceTab}
<WITH_>{Separator}*. {
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
unput( yytext[ yyleng-1 ] );
if( hb_comp_iState == WHILE ||
hb_comp_iState == DO ||
hb_comp_iState == MACROVAR ||
hb_comp_iState == MACROTEXT ||
if( hb_comp_iState == WHILE ||
hb_comp_iState == DO ||
hb_comp_iState == MACROVAR ||
hb_comp_iState == MACROTEXT ||
hb_comp_iState == IDENTIFIER )
{ /* DO <ident> WITH <arg> */
hb_comp_iState =WITH;

View File

@@ -81,6 +81,9 @@ static void hb_compLoopHere( void );
static void * hb_compElseIfGen( void * pFirstElseIf, ULONG ulOffset ); /* generates a support structure for elseifs pcode fixups */
static void hb_compElseIfFix( void * pIfElseIfs ); /* implements the ElseIfs pcode fixups */
static void hb_compRTVariableAdd( HB_EXPR_PTR, BOOL );
static void hb_compRTVariableGen( char * );
/* Misc functions defined in harbour.c */
extern void hb_compGenError( char* _szErrors[], char cPrefix, int iError, char * szError1, char * szError2 );
extern void hb_compGenWarning( char* _szWarnings[], char cPrefix, int iWarning, char * szWarning1, char * szWarning2);
@@ -106,13 +109,22 @@ typedef struct _LOOPEXIT
struct _LOOPEXIT * pNext;
} LOOPEXIT, * PTR_LOOPEXIT; /* support structure for EXIT and LOOP statements */
typedef struct HB_RTVAR_
{
HB_EXPR_PTR pVar;
BOOL bPopValue;
struct HB_RTVAR_ *pNext;
struct HB_RTVAR_ *pPrev;
} HB_RTVAR, *HB_RTVAR_PTR; /* support structure for PUBLIC and PRIVATE statements */
USHORT hb_comp_wSeqCounter = 0;
USHORT hb_comp_wForCounter = 0;
USHORT hb_comp_wIfCounter = 0;
USHORT hb_comp_wWhileCounter = 0;
USHORT hb_comp_wCaseCounter = 0;
PTR_LOOPEXIT hb_comp_pLoops = NULL;
static PTR_LOOPEXIT hb_comp_pLoops = NULL;
static HB_RTVAR_PTR hb_comp_rtvars = NULL;
%}
@@ -183,7 +195,7 @@ PTR_LOOPEXIT hb_comp_pLoops = NULL;
%type <valLong> NUM_LONG
%type <iNumber> FunScope AsType
%type <iNumber> Params ParamList
%type <iNumber> IfBegin VarList
%type <iNumber> IfBegin VarList ExtVarList
%type <iNumber> FieldList
%type <lNumber> WhileBegin
%type <pVoid> IfElseIf Cases
@@ -326,8 +338,10 @@ Statement : ExecFlow CrlfStmnt { }
hb_comp_bDontGenLineNum = TRUE;
hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE;
}
| PUBLIC { hb_comp_iVarScope = VS_PUBLIC; } VarList CrlfStmnt
| PRIVATE { hb_comp_iVarScope = VS_PRIVATE; } VarList CrlfStmnt
| PUBLIC { hb_comp_iVarScope = VS_PUBLIC; } ExtVarList
{ hb_compRTVariableGen( "__MVPUBLIC" ); } CrlfStmnt
| PRIVATE { hb_comp_iVarScope = VS_PRIVATE; } ExtVarList
{ hb_compRTVariableGen( "__MVPRIVATE" ); } CrlfStmnt
| EXITLOOP CrlfStmnt { hb_compLoopExit(); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; }
| LOOP CrlfStmnt { hb_compLoopLoop(); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; }
@@ -529,7 +543,7 @@ VariableAtAlias : VariableAt ALIASOP { $$ = $1; }
/* Function call
*/
FunCall : IDENTIFIER '(' ArgList ')' { $$ = hb_compExprNewFunCall( hb_compExprNewSymbol( $1 ), $3 ); }
FunCall : IDENTIFIER '(' ArgList ')' { $$ = hb_compExprNewFunCall( hb_compExprNewFunName( $1 ), $3 ); }
| MacroVar '(' ArgList ')' { $$ = hb_compExprNewFunCall( $1, $3 ); }
;
@@ -977,6 +991,38 @@ VarList : VarDef { $$ = 1; }
| VarList ',' VarDef { $$++; }
;
ExtVarList : ExtVarDef { $$ = 1; }
| ExtVarList ',' ExtVarDef { $$++; }
;
/* NOTE: if STATIC or LOCAL variables are declared and initialized then we can
* assign a value immediately - however for PRIVATE and PUBLIC variables
* initialization have to be delayed because we have to create these variables
* first.
*/
ExtVarDef : VarDef
| MacroVar AsType
{ hb_compRTVariableAdd( hb_compExprNewRTVar( NULL, $1 ), FALSE ); }
| MacroVar AsType INASSIGN Expression
{ hb_compExprDelete( hb_compExprGenPush( $4 ) );
hb_compRTVariableAdd( hb_compExprNewRTVar( NULL, $1 ), TRUE );
}
| MacroVar DimList
{
USHORT uCount = hb_compExprListLen( $2 );
hb_compExprDelete( hb_compExprGenPush( $2 ) );
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
hb_compRTVariableAdd( hb_compExprNewRTVar( NULL, $1 ), TRUE );
}
| MacroVar DimList AS_ARRAY
{
USHORT uCount = hb_compExprListLen( $2 );
hb_compExprDelete( hb_compExprGenPush( $2 ) );
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
hb_compRTVariableAdd( hb_compExprNewRTVar( NULL, $1 ), TRUE );
}
;
VarDef : IDENTIFIER AsType
{
if( hb_comp_iVarScope == VS_STATIC )
@@ -985,6 +1031,11 @@ VarDef : IDENTIFIER AsType
hb_compVariableAdd( $1, $2 );
hb_compStaticDefEnd();
}
else if( hb_comp_iVarScope == VS_PUBLIC || hb_comp_iVarScope == VS_PRIVATE )
{
hb_compVariableAdd( $1, $2 );
hb_compRTVariableAdd( hb_compExprNewRTVar( $1, NULL ), FALSE );
}
else
hb_compVariableAdd( $1, $2 );
}
@@ -998,6 +1049,12 @@ VarDef : IDENTIFIER AsType
hb_compExprDelete( hb_compExprGenStatement( hb_compExprAssignStatic( hb_compExprNewVar( $1 ), $4 ) ) );
hb_compStaticDefEnd();
}
else if( hb_comp_iVarScope == VS_PUBLIC || hb_comp_iVarScope == VS_PRIVATE )
{
hb_compExprDelete( hb_compExprGenPush( $4 ) );
hb_compVariableAdd( $1, $2 );
hb_compRTVariableAdd( hb_compExprNewRTVar( $1, NULL ), TRUE );
}
else
{
hb_compVariableAdd( $1, $2 );
@@ -1007,19 +1064,41 @@ VarDef : IDENTIFIER AsType
| IDENTIFIER DimList
{
USHORT uCount = hb_compExprListLen( $2 );
hb_compVariableAdd( $1, 'A' );
hb_compExprDelete( hb_compExprGenPush( $2 ) );
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
hb_compExprDelete( hb_compExprGenPop( hb_compExprNewVar( $1 ) ) );
if( hb_comp_iVarScope == VS_PUBLIC || hb_comp_iVarScope == VS_PRIVATE )
{
USHORT uCount = hb_compExprListLen( $2 );
hb_compVariableAdd( $1, 'A' );
hb_compExprDelete( hb_compExprGenPush( $2 ) );
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
hb_compRTVariableAdd( hb_compExprNewRTVar( $1, NULL ), TRUE );
}
else
{
USHORT uCount = hb_compExprListLen( $2 );
hb_compVariableAdd( $1, 'A' );
hb_compExprDelete( hb_compExprGenPush( $2 ) );
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
hb_compExprDelete( hb_compExprGenPop( hb_compExprNewVar( $1 ) ) );
}
}
| IDENTIFIER DimList AS_ARRAY
{
USHORT uCount = hb_compExprListLen( $2 );
hb_compVariableAdd( $1, 'A' );
hb_compExprDelete( hb_compExprGenPush( $2 ) );
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
hb_compExprDelete( hb_compExprGenPop( hb_compExprNewVar( $1 ) ) );
if( hb_comp_iVarScope == VS_PUBLIC || hb_comp_iVarScope == VS_PRIVATE )
{
USHORT uCount = hb_compExprListLen( $2 );
hb_compVariableAdd( $1, 'A' );
hb_compExprDelete( hb_compExprGenPush( $2 ) );
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
hb_compRTVariableAdd( hb_compExprNewRTVar( $1, NULL ), TRUE );
}
else
{
USHORT uCount = hb_compExprListLen( $2 );
hb_compVariableAdd( $1, 'A' );
hb_compExprDelete( hb_compExprGenPush( $2 ) );
hb_compGenPCode3( HB_P_ARRAYDIM, HB_LOBYTE( uCount ), HB_HIBYTE( uCount ) );
hb_compExprDelete( hb_compExprGenPop( hb_compExprNewVar( $1 ) ) );
}
}
;
@@ -1321,7 +1400,7 @@ RecoverUsing : RECOVER USING IDENTIFIER
* DO .. WITH ++variable
* will pass the value of variable not a reference
*/
DoName : IDENTIFIER { $$ = hb_compExprNewSymbol( $1 ); }
DoName : IDENTIFIER { $$ = hb_compExprNewFunName( $1 ); }
| MacroVar { $$ = $1; }
;
@@ -1330,7 +1409,7 @@ DoProc : DO DoName
| DO DoName WITH DoArgList
{ $$ = hb_compExprNewFunCall( $2, $4 ); }
| WHILE WITH DoArgList
{ $$ = hb_compExprNewFunCall( hb_compExprNewSymbol( hb_strdup("WHILE") ), $3 ); }
{ $$ = hb_compExprNewFunCall( hb_compExprNewFunName( hb_strdup("WHILE") ), $3 ); }
;
DoArgList : ',' { $$ = hb_compExprAddListExpr( hb_compExprNewArgList( hb_compExprNewNil() ), hb_compExprNewNil() ); }
@@ -1692,3 +1771,60 @@ static void hb_compElseIfFix( void * pFixElseIfs )
}
}
static void hb_compRTVariableAdd( HB_EXPR_PTR pVar, BOOL bPopInitValue )
{
HB_RTVAR_PTR pRTvar = ( HB_RTVAR_PTR ) hb_xgrab( sizeof( HB_RTVAR ) );
pRTvar->pVar = pVar;
pRTvar->bPopValue = bPopInitValue;
pRTvar->pNext = NULL;
pRTvar->pPrev = NULL;
if( hb_comp_rtvars )
{
HB_RTVAR_PTR pLast = hb_comp_rtvars;
while( pLast->pNext )
pLast = pLast->pNext;
pLast->pNext = pRTvar;
pRTvar->pPrev = pLast;
}
else
hb_comp_rtvars = pRTvar;
}
static void hb_compRTVariableGen( char * szCreateFun )
{
USHORT usCount = 0;
HB_RTVAR_PTR pVar = hb_comp_rtvars;
HB_RTVAR_PTR pDel;
/* generate the function call frame */
hb_compGenPushSymbol( hb_strdup( szCreateFun ), 1);
hb_compGenPushNil();
/* push variable names to create */
while( pVar->pNext )
{
hb_compExprGenPush( pVar->pVar );
pVar = pVar->pNext;
++usCount;
}
hb_compExprGenPush( pVar->pVar );
++usCount;
/* call function that will create either PUBLIC or PRIVATE variables */
hb_compGenPCode3( HB_P_DO, HB_LOBYTE( usCount ), HB_HIBYTE( usCount ) );
/* pop initial values */
while( pVar )
{
if( pVar->bPopValue )
hb_compExprDelete( hb_compExprGenPop( pVar->pVar ) );
else
hb_compExprDelete( pVar->pVar );
pDel = pVar;
pVar = pVar->pPrev;
hb_xfree( pDel );
}
hb_comp_rtvars = NULL;
}

View File

@@ -137,7 +137,8 @@ static void hb_macroSyntaxError( HB_MACRO_PTR pMacro )
HB_TRACE(HB_TR_DEBUG, ("hb_macroSyntaxError(%p)", pMacro));
hb_macroDelete( pMacro ); /* TODO: use pMacro->status for more detailed error messagess */
if( pMacro )
hb_macroDelete( pMacro ); /* TODO: use pMacro->status for more detailed error messagess */
pResult = hb_errRT_BASE_Subst( EG_SYNTAX, 1449, NULL, "&" );
@@ -148,9 +149,9 @@ static void hb_macroSyntaxError( HB_MACRO_PTR pMacro )
}
}
/* Check if passed string is a valid function name
/* Check if passed string is a valid function or variable name
*/
static BOOL hb_macroIsIdent( char * szString )
BOOL hb_macroIsIdent( char * szString )
{
char * pTmp = szString;
BOOL bIsIdent = FALSE;
@@ -191,13 +192,21 @@ static BOOL hb_macroIsIdent( char * szString )
* string if there was no macro operator in it or a pointer to a new
* allocated memory with expanded string if there was a macro operator
* in passed string.
* NOTE:
* Clipper restarts scanning of the text from the beginning of
* inserted text after macro expansion, for example:
* PRIVATE a:='&', b:='c'
* PRIVATE &a.b // this will create 'c' variable
*
* PRIVATE a:=0, b:='b', ab:='c'
* PRIVATE &a&b //this will cause syntax error '&'
*
*/
static char * hb_macroTextSubst( char * szString, ULONG *pulStringLen )
char * hb_macroTextSubst( char * szString, ULONG *pulStringLen )
{
char * szResult;
ULONG ulCopy;
ULONG ulResLen;
ULONG ulResPos;
ULONG ulResStrLen;
ULONG ulResBufLen;
ULONG ulCharsLeft;
char * pHead;
char * pTail;
@@ -208,29 +217,28 @@ static char * hb_macroTextSubst( char * szString, ULONG *pulStringLen )
if( pHead == NULL )
return szString; /* no more processing is required */
/* initial length of the string and the result buffer (it can contain null bytes) */
ulResBufLen = ulResStrLen = *pulStringLen;
/* initial buffer for return value */
szResult = (char *) hb_xgrab( *pulStringLen + 1 );
/* copy initial length of the string (it can contain null bytes) */
ulResLen = ulCharsLeft = *pulStringLen;
/* current position within the buffer where byte will be copied */
ulResPos = 0;
szResult = (char *) hb_xgrab( ulResBufLen + 1 );
/* copy the input string with trailing zero byte
*/
memcpy( szResult, szString, ulResStrLen + 1 );
/* switch the pointer so it will point into the result buffer
*/
pHead = szResult + ( pHead - szString );
pTail = szString;
do
{
ulCopy = pHead - pTail;
if( ulCopy )
{
/* copy bytes located before '&' character */
memcpy( szResult + ulResPos, pTail, ulCopy );
ulResPos += ulCopy;
pTail = pHead;
}
/* store the position where '&' was found so we can restart scanning
* from this point after macro expansion
*/
pTail = pHead;
/* check if the next character can start a valid identifier
* (only _a-zA-Z are allowed)
*/
++pHead;
++pHead; /* skip '&' character */
if( *pHead == '_' || (*pHead >= 'A' && *pHead <= 'Z') || (*pHead >= 'a' && *pHead <= 'z') )
{
/* extract a variable name */
@@ -266,74 +274,64 @@ static char * hb_macroTextSubst( char * szString, ULONG *pulStringLen )
szValPtr = hb_memvarGetStrValuePtr( pName, &ulValLen );
if( szValPtr )
{
char * szValSubst;
if( *pHead == '.' )
{
/* we have stopped at the macro terminator '.' - skip it */
++pHead;
++ulNameLen;
}
++ulNameLen; /* count also the '&' character */
/* Check if returned string contains nested macro operators
* and expand them if they exist
*/
szValSubst = hb_macroTextSubst( szValPtr, &ulValLen );
/* number of characters left on the right side of a variable name */
ulCharsLeft = ulResStrLen - ( pHead - szResult );
/* expand the result buffer if the substituted value is too
* long to be stored in the current buffer
/* NOTE:
* if a replacement string is shorter then the variable
* name then we don't have to reallocate the result buffer:
* 'ulResStrLen' stores the current length of a string in the buffer
* 'ulResBufLen' stores the length of the buffer
*/
if( (ulResPos + ulValLen) >= ulResLen )
if( ulValLen > ulNameLen )
{
ulResLen = ulResPos + ulValLen;
szResult = ( char * ) hb_xrealloc( szResult, ulResLen + 1 );
ulResStrLen += ( ulValLen - ulNameLen );
if( ulResStrLen > ulResBufLen )
{
ulResBufLen = ulResStrLen;
szResult = ( char * ) hb_xrealloc( szResult, ulResBufLen + 1 );
}
}
memcpy( szResult + ulResPos, szValSubst, ulValLen );
ulResPos += ulValLen;
if( szValSubst != szValPtr )
{
/* a new pointer was created in hb_macroTextSubst
* (if a macro operator was expanded) - we should release it
*/
hb_xfree( szValSubst );
}
/* move a pointer to the characters processed so far -
* replaced characters shouldn't be copied
else
ulResStrLen -= ( ulNameLen - ulValLen );
/* move bytes located on the right side of a variable name */
memmove( pTail + ulValLen, pHead, ulCharsLeft + 1 );
/* copy substituted value */
memcpy( pTail, szValPtr, ulValLen );
/* restart scanning from the beginning of replaced string */
/* NOTE: This causes that the following code:
* a := '&a'
* var := '&a.b'
* is the same as:
* var := '&ab'
*/
pTail = pHead;
pHead = pTail;
}
}
}
/* copy characters that were not a valid identifier */
ulCopy = pHead - pTail;
if( ulCopy )
{
memcpy( szResult + ulResPos, pTail, ulCopy );
ulResPos += ulCopy;
pTail = pHead;
}
ulCharsLeft = *pulStringLen - ( pTail - szString );
ulCharsLeft = ulResStrLen - ( pHead - szResult );
}
while( ulCharsLeft && ( pHead = (char *) memchr( (void *)pTail, '&', ulCharsLeft ) ) );
while( ulCharsLeft && ( pHead = (char *) memchr( (void *)pHead, '&', ulCharsLeft ) ) );
if( ulCharsLeft )
{
/* copy trailing characters */
memcpy( szResult + ulResPos, pTail, ulCharsLeft );
ulResPos += ulCharsLeft;
}
if( ulResPos < ulResLen )
if( ulResStrLen < ulResBufLen )
{
/* result string is shorter then allocated buffer -
* cut it to a required length
*/
szResult = ( char * ) hb_xrealloc( szResult, ulResPos + 1 );
szResult = ( char * ) hb_xrealloc( szResult, ulResStrLen + 1 );
}
szResult[ ulResPos ] = 0; /* place terminating null character */
szResult[ ulResStrLen ] = 0; /* place terminating null character */
/* return a length of result string */
*pulStringLen = ulResPos;
*pulStringLen = ulResStrLen;
return szResult; /* a new memory buffer was allocated */
}
@@ -379,9 +377,9 @@ void hb_macroSetValue( HB_ITEM_PTR pItem )
if( hb_macroCheckParam( pItem ) )
{
char * szString = pItem->item.asString.value;
HB_MACRO struMacro;
int iStatus;
char * szString = pItem->item.asString.value;
struMacro.bShortCuts = hb_comp_bShortCuts;
struMacro.bName10 = hb_comp_bUseName10;
@@ -434,7 +432,6 @@ void hb_macroPushSymbol( HB_ITEM_PTR pItem )
if( hb_macroCheckParam( pItem ) )
{
HB_MACRO struMacro;
char * szString;
BOOL bNewBuffer;
ULONG ulLength = pItem->item.asString.length;
@@ -460,7 +457,7 @@ void hb_macroPushSymbol( HB_ITEM_PTR pItem )
{
if( bNewBuffer )
hb_xfree( szString ); /* free space allocated in hb_macroTextSubst */
hb_macroSyntaxError( &struMacro );
hb_macroSyntaxError( NULL );
}
}
}

View File

@@ -57,7 +57,7 @@
#define malloc hb_xgrab
#undef free
#define free hb_xfree
/* This is workaround of yyparse() declaration bug in bison.simple
/* This is workaround of yyparse() declaration bug in bison.simple
*/
#ifdef __GNUC__
#undef __GNUC__
@@ -253,8 +253,21 @@ VarAlias : IDENTIFIER ALIASOP { $$ = hb_compExprNewAlias( $1 ); }
MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 );
HB_MACRO_CHECK( $$ );
}
| MACROTEXT { $$ = hb_compExprNewMacro( NULL, 0, $1 );
HB_MACRO_CHECK( $$ );
| MACROTEXT { ULONG ulLen = strlen( $1 );
char * szVarName = hb_macroTextSubst( $1, &ulLen );
if( hb_macroIsIdent( szVarName ) )
{
$$ = hb_compExprNewVar( szVarName );
hb_xfree( $1 );
HB_MACRO_CHECK( $$ );
}
else
{
/* invalid variable name
*/
hb_xfree( $1 );
YYABORT;
}
}
;
@@ -333,7 +346,7 @@ VariableAt : NilValue ArrayIndex { $$ = $2; }
/* Function call
*/
FunCall : IDENTIFIER '(' ArgList ')' { $$ = hb_compExprNewFunCall( hb_compExprNewSymbol( $1 ), $3, HB_MACRO_PARAM );
FunCall : IDENTIFIER '(' ArgList ')' { $$ = hb_compExprNewFunCall( hb_compExprNewFunName( $1 ), $3, HB_MACRO_PARAM );
HB_MACRO_CHECK( $$ );
}
| MacroVar '(' ArgList ')' { $$ = hb_compExprNewFunCall( $1, $3, HB_MACRO_PARAM );