ChangeLog 20000103-19:48 GMT+1
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user