ChangeLog 19991209-17:10

This commit is contained in:
Ryszard Glab
1999-12-09 16:15:00 +00:00
parent 9b4e3b94f8
commit 7a9444924f
34 changed files with 3721 additions and 659 deletions

View File

@@ -1,3 +1,101 @@
19991209-17:10 GMT+1 Ryszard Glab <rglab@imid.med.pl>
*config/rules.cf
* YACC_FLAGS and LEX_FLAGS can be set in local Makefile - this
local settings will be added to the global ones
* include/compiler.h
* include/expropt.h
* moved declarations related to expression optimizer into expropt.h
which is used also at runtime library
* added support for macro generation
*source/compiler/harbour.c
* removed some functions that were no longer used
* fixed recognition of static and memvar variables for which
function-wide declaration owerwrites file-wide declaration
e.g.
STATIC myvar
FUNCTION MyTest()
MEMVAR myvar
*source/compiler/genc.c
*source/compiler/genhrb.c
*source/compiler/genjava.c
* updated to support new macro related opcodes
* include/hberrors.h
* source/compiler/hbgenerr.c
* added new errors
ERR_BAD_MACRO (declared variable in macro)
ERR_INVALID_SEND (macro operator with send operator)
*source/compiler/harbour.l
* '.' character is correctly passed to grammar analyzer
* moved here all rules for a macro variable use recognition
*source/common/Makefile
*source/common/reserved.c
* file with function and date used to check for reserved
functions name
NOTE: All non GNU-Make scripts should be updated!
* include/ctoharb.h
* added declaration of hb_stackPop() function
*source/vm/hvm.c
* changed visibility of hb_stackPop() function (static -> global)
* added code related to macro generation and evaluation
*source/macro/
*source/macro/macro.c
*source/macro/macro.l
*source/macro/macro.y
*source/macro/Makefile
*include/macro.h
* new files used for macro generation and evaluation
* macro compiler supports now:
+ macro variables: &var1 := &var2
* not supported yet (there is a proper pcode generated only -
there are no actions in the virtual machine)
- text substitution: "text &macro"
- function calls: &macro()
- aliased macro variables: &macro->var and alias->&var
- macro-compiled codeblocks
NOTE: All non GNU-Make scripts should be updated!
NOTE: source/macro/macro.c file includes source/compiler/expropt.c
I didn't found other method of reusing the expropt.c. Unfortunately
the code in expropt.c differs a little if used from macro compiler
(it uses a local variable that holds the compilation state instead
of global variables)
*source/compiler/expropt.c
* added support for macro pcode generation and macro compilation
NOTE: this file is included by macro.c
*include/pcode.h
* added pcodes used in macro generation and macro evaluation
*source/runner/stdalone/Makefile
*tests/Makefile
*tests/regress/Makefile
*samples/cccppc/Makefile
*samples/guestbk/Makefile
*samples/hscript/Makefile
*samples/misc/Makefile
*samples/pe/Makefile
* 'macro' library added
*source/compiler/cmdcheck.c
* replaced strupr with hb_strupr
NOTE: All PRG sources HAVE TO be recompiled!!!
NOTE: Add macro.lib to all non-GNU make scripts or batch files.
19991209-01:05 GMT+1 Victor Szel <info@szelvesz.hu>
* source/compiler/*
include/compiler.h

View File

@@ -4,11 +4,11 @@
# How to run yacc.
YACC = bison
YACC_FLAGS = -d
YACC_FLAGS := -d $(YACC_FLAGS)
# How to run lex.
LEX = flex
LEX_FLAGS = -i -8
LEX_FLAGS := -i -8 $(LEX_FLAGS)
#
# How to run Harbour.

View File

@@ -48,6 +48,7 @@
#include "hberrors.h"
#include "hbpp.h"
#include "hbver.h"
#include "expropt.h"
/* compiler related declarations */
@@ -138,60 +139,6 @@ typedef struct
int iCount; /* number of defined symbols */
} SYMBOLS;
typedef struct HB_EXPR_
{
union
{
char *asString; /* literal strings */
char *asSymbol; /* variable name */
BOOL asLogical; /* logical value */
struct
{
long lVal; /* long value */
double dVal; /* double value */
unsigned char bDec; /* unsigned char used intentionally */
unsigned char NumType; /* used to distinguish LONG and DOUBLE */
} asNum;
struct
{
struct HB_EXPR_ *pVar; /* macro variable */
char * szNameExt; /* text after the macro terminator */
} asMacro;
struct
{
struct HB_EXPR_ *pExprList; /* list elements */
struct HB_EXPR_ *pIndex; /* array index, others */
} asList;
struct
{
struct HB_EXPR_ *pAlias; /* alias expression */
char * szVarName; /* aliased variable */
struct HB_EXPR_ *pExpList; /* aliased expression list */
} asAlias;
struct
{
char * szFunName; /* function name */
struct HB_EXPR_ *pParms; /* function call parameters */
} asFunCall;
struct
{
struct HB_EXPR_ *pObject; /* object */
char * szMessage; /* message */
struct HB_EXPR_ *pParms; /* method parameters */
} asMessage;
struct
{
struct HB_EXPR_ *pLeft; /* object */
struct HB_EXPR_ *pRight; /* object */
} asOperator;
} value;
ULONG ulLength;
unsigned char ExprType; /* internal expression type */
USHORT ValType; /* language level value type */
struct HB_EXPR_ *pNext; /* next expression in the list of expressions */
} HB_EXPR, *HB_EXPR_PTR;
#define VS_LOCAL 1
#define VS_STATIC 2
#define VS_FIELD 4
@@ -210,7 +157,6 @@ typedef struct HB_EXPR_
#define FUN_USES_LOCAL_PARAMS 16 /* parameters are declared using () */
#define FUN_WITH_RETURN 32 /* there was RETURN statement in previous line */
extern void hb_compFunctionAdd( char * szFunName, HB_SYMBOLSCOPE cScope, int iType ); /* starts a new Clipper language function definition */
extern PFUNCTION hb_compFunctionFind( char * szFunName ); /* locates a previously defined function */
extern USHORT hb_compFunctionGetPos( char * szSymbolName ); /* returns the index + 1 of a function on the functions defined list */
@@ -234,11 +180,57 @@ extern void hb_compGenBreak( void ); /* generate code for BREAK statement */
extern void hb_compExternGen( void ); /* generates the symbols for the EXTERN names */
extern void hb_compExternAdd( char * szExternName ); /* defines a new extern name */
extern ULONG hb_compGenJump( LONG lOffset ); /* generates the pcode to jump to a specific offset */
extern ULONG hb_compGenJumpFalse( LONG lOffset ); /* generates the pcode to jump if false */
extern ULONG hb_compGenJumpTrue( LONG lOffset ); /* generates the pcode to jump if true */
extern void hb_compGenJumpHere( ULONG ulOffset ); /* returns the pcode pos where to set a jump offset */
extern void hb_compGenJumpThere( ULONG ulFrom, ULONG ulTo ); /* sets a jump offset */
#ifdef HB_MACRO_SUPPORT
extern BOOL hb_compVariableMacroCheck( char *, HB_MACRO_DECL ); /* checks if passed variable can be used in macro */
extern ULONG hb_compGenJump( LONG, HB_MACRO_DECL ); /* generates the pcode to jump to a specific offset */
extern ULONG hb_compGenJumpFalse( LONG, HB_MACRO_DECL ); /* generates the pcode to jump if false */
extern ULONG hb_compGenJumpTrue( LONG, HB_MACRO_DECL ); /* generates the pcode to jump if true */
extern void hb_compGenJumpHere( ULONG, HB_MACRO_DECL ); /* returns the pcode pos where to set a jump offset */
extern void hb_compGenJumpThere( ULONG, ULONG, HB_MACRO_DECL ); /* sets a jump offset */
extern void hb_compGenMessage( char *, HB_MACRO_DECL ); /* sends a message to an object */
extern void hb_compGenMessageData( char *, HB_MACRO_DECL ); /* generates an underscore-symbol name for a data assignment */
extern void hb_compGenPopVar( char *, HB_MACRO_DECL ); /* generates the pcode to pop a value from the virtual machine stack onto a variable */
extern void hb_compGenPushDouble( double , BYTE, HB_MACRO_DECL ); /* Pushes a number on the virtual machine stack */
extern void hb_compGenPushFunCall( char *, HB_MACRO_DECL ); /* generates the pcode to push function's call */
extern void hb_compGenPushVar( char *, HB_MACRO_DECL ); /* generates the pcode to push a variable value to the virtual machine stack */
extern void hb_compGenPushVarRef( char *, HB_MACRO_DECL ); /* generates the pcode to push a variable by reference to the virtual machine stack */
extern void hb_compGenPushLogical( int, HB_MACRO_DECL ); /* pushes a logical value on the virtual machine stack */
extern void hb_compGenPushLong( long, HB_MACRO_DECL ); /* Pushes a long number on the virtual machine stack */
extern void hb_compGenPushNil( HB_MACRO_DECL ); /* Pushes nil on the virtual machine stack */
extern void hb_compGenPushString( char *, ULONG, HB_MACRO_DECL ); /* Pushes a string on the virtual machine stack */
extern void hb_compGenPushSymbol( char *, int, HB_MACRO_DECL ); /* Pushes a symbol on to the Virtual machine stack */
extern void hb_compGenPushAliasedVar( char *, BOOL, char *, long, HB_MACRO_DECL );
extern void hb_compGenPopAliasedVar( char *, BOOL, char *, long, HB_MACRO_DECL );
extern void hb_compGenPushFunRef( char *, HB_MACRO_DECL );
extern void hb_compGenPCode1( BYTE, HB_MACRO_DECL ); /* generates 1 byte of pcode */
extern void hb_compGenPCode3( BYTE, BYTE, BYTE, HB_MACRO_DECL ); /* generates 3 bytes of pcode */
extern void hb_compGenPCodeN( BYTE * pBuffer, ULONG ulSize, HB_MACRO_DECL ); /* copy bytes to a pcode buffer */
/* Codeblocks */
void hb_compCodeBlockStart( HB_MACRO_DECL ); /* starts a codeblock creation */
void hb_compCodeBlockEnd( HB_MACRO_DECL ); /* end of codeblock creation */
#define hb_compErrorType( p ) hb_macroError( EG_ARG, HB_MACRO_PARAM )
#define hb_compErrorIndex( p ) hb_macroError( EG_BOUND, HB_MACRO_PARAM )
#define hb_compErrorSyntax( p ) hb_macroError( EG_SYNTAX, HB_MACRO_PARAM )
#define hb_compErrorLValue( p ) hb_macroError( EG_SYNTAX, HB_MACRO_PARAM )
#define hb_compErrorBound( p ) hb_macroError( EG_BOUND, HB_MACRO_PARAM )
#define hb_compErrorAlias( p ) hb_macroError( EG_NOALIAS, HB_MACRO_PARAM )
#define hb_compErrorDuplVar( c ) hb_macroError( EG_SYNTAX, HB_MACRO_PARAM )
#define hb_compWarnMeaningless( p )
#else /* HB_MACRO_SUPPORT */
extern BOOL hb_compVariableMacroCheck( char * ); /* checks if passed variable can be used in macro */
extern ULONG hb_compGenJump( LONG ); /* generates the pcode to jump to a specific offset */
extern ULONG hb_compGenJumpFalse( LONG ); /* generates the pcode to jump if false */
extern ULONG hb_compGenJumpTrue( LONG ); /* generates the pcode to jump if true */
extern void hb_compGenJumpHere( ULONG ); /* returns the pcode pos where to set a jump offset */
extern void hb_compGenJumpThere( ULONG, ULONG ); /* sets a jump offset */
extern void hb_compLinePush( void ); /* generates the pcode with the currently compiled source code line */
@@ -265,14 +257,14 @@ extern void hb_compGenPCode1( BYTE ); /* generates 1 byte of pcode *
extern void hb_compGenPCode3( BYTE, BYTE, BYTE ); /* generates 3 bytes of pcode */
extern void hb_compGenPCodeN( BYTE * pBuffer, ULONG ulSize ); /* copy bytes to a pcode buffer */
/* Codeblocks */
extern void hb_compCodeBlockStart( void ); /* starts a codeblock creation */
extern void hb_compCodeBlockEnd( void ); /* end of codeblock creation */
extern ULONG hb_compSequenceBegin( void );
extern ULONG hb_compSequenceEnd( void );
extern void hb_compSequenceFinish( ULONG, int );
/* Codeblocks */
void hb_compCodeBlockStart( void ); /* starts a codeblock creation */
void hb_compCodeBlockEnd( void ); /* end of codeblock creation */
/* support for FIELD declaration */
extern void hb_compFieldSetAlias( char *, int );
extern int hb_compFieldsCount( void );
@@ -291,9 +283,6 @@ HB_EXPR_PTR hb_compErrorAlias( HB_EXPR_PTR );
extern void hb_compErrorDuplVar( char * );
HB_EXPR_PTR hb_compWarnMeaningless( HB_EXPR_PTR );
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);
extern void hb_compChkCompilerSwitch( int, char * Args[] );
extern void hb_compChkEnvironVar( char * );
extern void hb_compChkCompileFileName( int, char * Args[] );
@@ -303,6 +292,11 @@ extern void hb_compPrintUsage( char * );
extern void hb_compPrintCredits( void );
extern void hb_compPrintLogo( void );
#endif /* HB_MACRO_SUPPORT */
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);
/* variable used by compiler
*/
extern int hb_comp_iLine;
@@ -355,75 +349,5 @@ extern char * hb_comp_szWarnings[];
#define HB_EXITLEVEL_SETEXIT 1
#define HB_EXITLEVEL_DELTARGET 2
HB_EXPR_PTR hb_compExprNewEmpty( void );
HB_EXPR_PTR hb_compExprNewNil( void );
HB_EXPR_PTR hb_compExprNewDouble( double, BYTE );
HB_EXPR_PTR hb_compExprNewLong( LONG );
HB_EXPR_PTR hb_compExprNewString( char * );
HB_EXPR_PTR hb_compExprNewLogical( int );
HB_EXPR_PTR hb_compExprNewSelf( void );
HB_EXPR_PTR hb_compExprNewCodeBlock( void );
HB_EXPR_PTR hb_compExprNewArray( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewArrayAt( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewVar( char * );
HB_EXPR_PTR hb_compExprNewAliasVar( HB_EXPR_PTR, char * );
HB_EXPR_PTR hb_compExprNewAliasExpr( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewSymbol( char * );
HB_EXPR_PTR hb_compExprNewEQ( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewNE( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewLT( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewLE( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewGT( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewGE( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewIN( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPlus( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMinus( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMult( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewDiv( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMod( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPower( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewAssign( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewEqual( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPlusEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMinusEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMultEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewDivEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewModEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewExpEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPostInc( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPostDec( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPreInc( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPreDec( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewAnd( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewOr( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewNot( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewNegate( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMacro( HB_EXPR_PTR, char * );
HB_EXPR_PTR hb_compExprNewVarRef( char * );
HB_EXPR_PTR hb_compExprNewFunRef( char * );
HB_EXPR_PTR hb_compExprNewCodeblockExpr( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewFunCall( char *, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewFunCallArg( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewSend( HB_EXPR_PTR, char * );
HB_EXPR_PTR hb_compExprNewMethodCall( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprSetOperand( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewList( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewArgList( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprAddListExpr( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewIIF( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprReduce( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprAssign( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprEqual( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprAssignStatic( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprGenPop( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprGenPush( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprGenStatement( HB_EXPR_PTR );
extern ULONG hb_compExprListLen( HB_EXPR_PTR );
extern void hb_compExprDelete( HB_EXPR_PTR );
extern void hb_compExprClear( HB_EXPR_PTR );
extern char * hb_compExprDescription( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprCBVarAdd( HB_EXPR_PTR, char *, BYTE );
#endif /* HB_COMPILER_H_ */

View File

@@ -81,5 +81,6 @@ extern void hb_vmPushSymbol( PHB_SYMB pSym ); /* pushes a function pointer on
/* stack management functions */
extern void hb_stackDispCall( void );
extern void hb_stackPop( void ); /* pops an item from the stack */
#endif /* HB_CTOHARB_H_ */

218
harbour/include/expropt.h Normal file
View File

@@ -0,0 +1,218 @@
/*
* $Id$
*/
/*
* Harbour Project source code:
* Header file for the Harbour Compiler
*
* Copyright 1999 Ryszard Glab
* www - http://www.harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version, with one exception:
*
* The exception is that if you link the Harbour Runtime Library (HRL)
* and/or the Harbour Virtual Machine (HVM) with other files to produce
* an executable, this does not by itself cause the resulting executable
* to be covered by the GNU General Public License. Your use of that
* executable is in no way restricted on account of linking the HRL
* and/or HVM code into it.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
* their web site at http://www.gnu.org/).
*
*/
#ifndef HB_EXPROPT_H_
#define HB_EXPROPT_H_
/* This structure holds local variables declared in a codeblock
*/
typedef struct HB_CBVAR_
{
char * szName;
BYTE bType;
struct HB_CBVAR_ * pNext;
} HB_CBVAR, *HB_CBVAR_PTR;
typedef struct HB_EXPR_
{
union
{
char *asString; /* literal strings */
char *asSymbol; /* variable name */
BOOL asLogical; /* logical value */
struct
{
long lVal; /* long value */
double dVal; /* double value */
unsigned char bDec; /* unsigned char used intentionally */
unsigned char NumType; /* used to distinguish LONG and DOUBLE */
} asNum;
struct
{
unsigned char cMacroOp; /* macro operator */
unsigned char SubType; /* context in which macro is used */
char * szMacro; /* identifier after the macro operator */
struct HB_EXPR_ *pExprList; /* list elements if &(...) was used */
} asMacro;
struct
{
struct HB_EXPR_ *pExprList; /* list elements */
struct HB_EXPR_ *pIndex; /* array index, others */
} asList;
struct
{
struct HB_EXPR_ *pAlias; /* alias expression */
struct HB_EXPR_ *pVar; /* aliased variable or macro */
struct HB_EXPR_ *pExpList; /* aliased expression list */
} asAlias;
struct
{
struct HB_EXPR_ *pFunName; /* function name */
struct HB_EXPR_ *pParms; /* function call parameters */
} asFunCall;
struct
{
struct HB_EXPR_ *pObject; /* object */
char * szMessage; /* message */
struct HB_EXPR_ *pParms; /* method parameters */
} asMessage;
struct
{
struct HB_EXPR_ *pLeft; /* object */
struct HB_EXPR_ *pRight; /* object */
} asOperator;
} value;
ULONG ulLength;
unsigned char ExprType; /* internal expression type */
USHORT ValType; /* language level value type */
struct HB_EXPR_ *pNext; /* next expression in the list of expressions */
} HB_EXPR, *HB_EXPR_PTR;
/* Definitions of function templates used in expression's message
* handling
*/
#ifdef HB_MACRO_SUPPORT
/* Compilation for macro compiler
*/
#define HB_EXPR_FUNC( proc ) HB_EXPR_PTR proc( HB_EXPR_PTR pSelf, int iMessage, void * pMacro )
typedef HB_EXPR_FUNC( HB_EXPR_FUNC_ );
typedef HB_EXPR_FUNC_ *HB_EXPR_FUNC_PTR;
#define HB_EXPR_USE( pSelf, iMessage ) \
s_ExprTable[ (pSelf)->ExprType ]( (pSelf), (iMessage), pMacro )
typedef HB_EXPR_PTR HB_EXPR_ACTION( HB_EXPR_PTR pSelf, int iMessage, void * pMacro );
#else
#define HB_EXPR_FUNC( proc ) HB_EXPR_PTR proc( HB_EXPR_PTR pSelf, int iMessage )
typedef HB_EXPR_FUNC( HB_EXPR_FUNC_ );
typedef HB_EXPR_FUNC_ *HB_EXPR_FUNC_PTR;
#define HB_EXPR_USE( pSelf, iMessage ) \
s_ExprTable[ (pSelf)->ExprType ]( (pSelf), (iMessage) )
typedef HB_EXPR_PTR HB_EXPR_ACTION( HB_EXPR_PTR pSelf, int iMessage );
#endif
HB_EXPR_PTR hb_compExprNewEmpty( void );
HB_EXPR_PTR hb_compExprNewNil( void );
HB_EXPR_PTR hb_compExprNewDouble( double, BYTE );
HB_EXPR_PTR hb_compExprNewLong( LONG );
HB_EXPR_PTR hb_compExprNewString( char * );
HB_EXPR_PTR hb_compExprNewLogical( int );
HB_EXPR_PTR hb_compExprNewSelf( void );
HB_EXPR_PTR hb_compExprNewCodeBlock( void );
HB_EXPR_PTR hb_compExprNewArray( HB_EXPR_PTR );
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_compExprNewAlias( char * );
HB_EXPR_PTR hb_compExprNewEQ( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewNE( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewLT( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewLE( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewGT( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewGE( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewIN( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPlus( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMinus( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMult( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewDiv( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMod( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPower( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewAssign( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewEqual( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPlusEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMinusEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewMultEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewDivEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewModEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewExpEq( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPostInc( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPostDec( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPreInc( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewPreDec( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewAnd( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewOr( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewNot( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewNegate( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewVarRef( char * );
HB_EXPR_PTR hb_compExprNewFunRef( char * );
HB_EXPR_PTR hb_compExprNewCodeblockExpr( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewFunCallArg( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewSend( HB_EXPR_PTR, char * );
HB_EXPR_PTR hb_compExprNewMethodCall( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewList( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewArgList( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprAddListExpr( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewIIF( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprReduce( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprAssign( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprEqual( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprAssignStatic( HB_EXPR_PTR, HB_EXPR_PTR );
ULONG hb_compExprListLen( HB_EXPR_PTR );
void hb_compExprClear( HB_EXPR_PTR );
char * hb_compExprDescription( HB_EXPR_PTR );
#ifdef HB_MACRO_SUPPORT
HB_EXPR_PTR hb_compExprNewArrayAt( HB_EXPR_PTR, HB_EXPR_PTR, HB_MACRO_DECL );
HB_EXPR_PTR hb_compExprSetOperand( HB_EXPR_PTR, HB_EXPR_PTR, HB_MACRO_DECL );
HB_EXPR_PTR hb_compExprGenPop( HB_EXPR_PTR, HB_MACRO_DECL );
HB_EXPR_PTR hb_compExprGenPush( HB_EXPR_PTR, HB_MACRO_DECL );
HB_EXPR_PTR hb_compExprGenStatement( HB_EXPR_PTR, HB_MACRO_DECL );
HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR, HB_EXPR_PTR, HB_MACRO_DECL );
void hb_compExprDelete( HB_EXPR_PTR, HB_MACRO_DECL );
HB_EXPR_PTR hb_compExprCBVarAdd( HB_EXPR_PTR, char *, HB_MACRO_DECL );
#else
HB_EXPR_PTR hb_compExprNewArrayAt( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprSetOperand( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprGenPop( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprGenPush( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprGenStatement( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR, HB_EXPR_PTR );
void hb_compExprDelete( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprCBVarAdd( HB_EXPR_PTR, char *, BYTE );
#endif
#endif /* HB_EXPROPT_H_ */

View File

@@ -412,6 +412,13 @@ extern USHORT hb_setCursor( BOOL bSetCursor, USHORT usNewCursor );
extern void hb_tone( double dFrequency, double dDuration );
extern char * hb_setColor( char * );
/* compiler and macro compiler */
extern char * hb_compReservedName( char * );
/* macro compiler */
extern void hb_macroGetValue( HB_ITEM_PTR, PHB_SYMB );
extern void hb_macroSetValue( HB_ITEM_PTR, PHB_SYMB );
/* misc */
extern char * hb_version( USHORT uiMode );

View File

@@ -80,6 +80,8 @@
#define ERR_INVALID_ALIAS 39
#define ERR_INVALID_INDEX 40
#define ERR_INVALID_BOUND 41
#define ERR_BAD_MACRO 42
#define ERR_INVALID_SEND 43
#define WARN_AMBIGUOUS_VAR 1
#define WARN_MEMVAR_ASSUMED 2

105
harbour/include/macro.h Normal file
View File

@@ -0,0 +1,105 @@
/*
* $Id$
*/
/*
* Harbour Project source code:
* Header file for the Macro compiler
*
* Copyright 1999 Ryszard Glab
* www - http://www.harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version, with one exception:
*
* The exception is that if you link the Harbour Runtime Library (HRL)
* and/or the Harbour Virtual Machine (HVM) with other files to produce
* an executable, this does not by itself cause the resulting executable
* to be covered by the GNU General Public License. Your use of that
* executable is in no way restricted on account of linking the HRL
* and/or HVM code into it.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
* their web site at http://www.gnu.org/).
*
*/
#ifndef HB_MACRO_H_
#define HB_MACRO_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <time.h>
/* Standard parameters passed to macro aware functions
*/
#define HB_MACRO_DECL void * pMacro
#define HB_MACRO_PARAM pMacro
#include "hbsetup.h"
#include "extend.h"
#include "ctoharb.h"
#include "pcode.h" /* pcode values */
#include "itemapi.h"
#include "errorapi.h"
#include "expropt.h"
typedef struct HB_PCODE_INFO_
{
BYTE * pCode; /* pointer to a memory block where pcode is stored */
ULONG lPCodeSize; /* total memory size for pcode */
ULONG lPCodePos; /* actual pcode offset */
struct HB_PCODE_INFO_ *pPrev;
HB_CBVAR_PTR pLocals;
} HB_PCODE_INFO, * HB_PCODE_INFO_PTR;
typedef struct HB_MACRO_
{
char * string; /* compiled string */
ULONG length; /* length of the string */
ULONG pos; /* current position inside of compiled string */
int Flags; /* some flags we may need */
int status; /* status of compilation */
HB_PCODE_INFO_PTR pCodeInfo; /* pointer to pcode buffer and info */
void * pParseInfo; /* data needed by the parser - it should be 'void *' to allow different implementation of macr compiler */
BOOL bName10; /* are we limiting identifier names to 10 chars ? */
BOOL bShortCuts; /* are we using logical shorcuts (in OR/AND) */
PHB_SYMB pSymbols; /* local symbol table */
} HB_MACRO, * HB_MACRO_PTR;
#define HB_MACRO_OK 0 /* macro compiled successfully */
#define HB_MACRO_FAILURE 1 /* syntax error */
#define HB_MACRO_TOO_COMPLEX 2 /* compiled expression is too complex */
/* Global functions
*/
void hb_macroError( int, HB_MACRO_DECL );
int hb_compParse( HB_MACRO_PTR );
void hb_compGenPCode1( BYTE, HB_MACRO_DECL );
void hb_compGenPCode3( BYTE, BYTE, BYTE, HB_MACRO_DECL );
void hb_compGenPCodeN( BYTE * pBuffer, ULONG ulSize, HB_MACRO_DECL );
/* Size of pcode buffer incrementation
*/
#define HB_PCODE_SIZE 512
/* Bison requires (void *) pointer - some code needs HB_MACRO_PTR pointer
*/
#define HB_MACRO_DATA ( (HB_MACRO_PTR) HB_MACRO_PARAM )
#define HB_PCODE_DATA ( HB_MACRO_DATA->pCodeInfo )
#endif

View File

@@ -68,10 +68,29 @@ typedef enum
HB_P_LESS, /* checks if the second latest value on the stack is less that the lastest one */
HB_P_LINE, /* currently compiled source code line number */
HB_P_LOCALNAME, /* sets the name of local variable */
HB_P_MACROPOP, /* compile and run - pop a value from the stack */
HB_P_MACROPOPALIASED, /* compile and run - pop a field value from the stack */
HB_P_MACROPUSH, /* compile and run - leave the result on the stack */
HB_P_MACROPUSHALIASED, /* compile and run - leave the field value on the stack */
HB_P_MACROSYMBOL, /* compile into a symbol name (used in function calls) */
HB_P_MACROTEXT, /* macro text substitution */
HB_P_MESSAGE, /* sends a message to an object */
HB_P_MINUS, /* subs the latest two values on the stack, removing them and leaving there the result */
HB_P_MODULUS, /* calculates the modulus of the two values on the stack, removing them and leaving there the result */
HB_P_MODULENAME, /* sets the name of debugged module */
/* start: pcodes generated by the macro compiler - the symbol address is used */
HB_P_MMESSAGE,
HB_P_MPOPALIASEDFIELD,
HB_P_MPOPFIELD,
HB_P_MPOPMEMVAR,
HB_P_MPUSHALIASEDFIELD,
HB_P_MPUSHBLOCK,
HB_P_MPUSHFIELD,
HB_P_MPUSHMEMVAR,
HB_P_MPUSHMEMVARREF,
HB_P_MPUSHSYM,
HB_P_MPUSHVARIABLE,
/* end: */
HB_P_MULT, /* multiplies the latest two values on the stack, removing them and leaving there the result */
HB_P_NEGATE, /* numerically negates the latest value on the stack */
HB_P_NOOP, /* no operation */

View File

@@ -60,5 +60,7 @@ LIBS=\
rdd \
rtl \
pp \
common \
macro \
include $(TOP)$(ROOT)config/bin.cf

View File

@@ -20,5 +20,7 @@ LIBS=\
rdd \
rtl \
pp \
common \
macro \
include $(TOP)$(ROOT)config/bin.cf

View File

@@ -18,5 +18,7 @@ LIBS=\
rdd \
rtl \
pp \
common \
macro \
include $(TOP)$(ROOT)config/bin.cf

View File

@@ -14,6 +14,8 @@ LIBS=\
rtl \
pp \
runner \
common \
macro \
ifeq ($(PM),)
PM := $(pm)

View File

@@ -21,5 +21,7 @@ LIBS=\
rdd \
rtl \
pp \
common \
macro \
include $(TOP)$(ROOT)config/bin.cf

View File

@@ -11,6 +11,7 @@ DIRS=\
rtl \
vm \
rdd \
macro \
debug \
tools \
runner \

View File

@@ -8,6 +8,7 @@ C_SOURCES=\
hbfsapi.c \
hbstr.c \
hbtrace.c \
reserved.c \
PRG_SOURCES=\

View File

@@ -479,7 +479,7 @@ void hb_compChkCompileFileName( int iArg, char * Args[] )
*/
if( n > 1 )
/* GenWarning() */
printf( "Warning: File %s will be ignored\n", strupr( Args[ i ] ) );
printf( "Warning: File %s will be ignored\n", hb_strupr( Args[ i ] ) );
else
{
hb_comp_pFileName = hb_fsFNameSplit( Args[ i ] );

File diff suppressed because it is too large Load Diff

View File

@@ -411,6 +411,36 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou
lPCodePos++;
break;
case HB_P_MACROPOP:
fprintf( yyc, "\tHB_P_MACROPOP,\n" );
lPCodePos++;
break;
case HB_P_MACROPOPALIASED:
fprintf( yyc, "\tHB_P_MACROPOPALIASED,\n" );
lPCodePos++;
break;
case HB_P_MACROPUSH:
fprintf( yyc, "\tHB_P_MACROPUSH,\n" );
lPCodePos++;
break;
case HB_P_MACROPUSHALIASED:
fprintf( yyc, "\tHB_P_MACROPUSHALIASED,\n" );
lPCodePos++;
break;
case HB_P_MACROSYMBOL:
fprintf( yyc, "\tHB_P_MACROSYMBOL,\n" );
lPCodePos++;
break;
case HB_P_MACROTEXT:
fprintf( yyc, "\tHB_P_MACROTEXT,\n" );
lPCodePos++;
break;
case HB_P_MESSAGE:
{
USHORT wFixPos;

View File

@@ -181,6 +181,12 @@ void hb_compGenPortObj( PHB_FNAME pFileName )
case HB_P_INSTRING:
case HB_P_LESS:
case HB_P_LESSEQUAL:
case HB_P_MACROPOP:
case HB_P_MACROPOPALIASED:
case HB_P_MACROPUSH:
case HB_P_MACROPUSHALIASED:
case HB_P_MACROSYMBOL:
case HB_P_MACROTEXT:
case HB_P_MINUS:
case HB_P_MODULUS:
case HB_P_MULT:

View File

@@ -203,6 +203,12 @@ void hb_compGenJava( PHB_FNAME pFileName )
case HB_P_INSTRING:
case HB_P_LESS:
case HB_P_LESSEQUAL:
case HB_P_MACROPOP:
case HB_P_MACROPOPALIASED:
case HB_P_MACROPUSH:
case HB_P_MACROPUSHALIASED:
case HB_P_MACROSYMBOL:
case HB_P_MACROTEXT:
case HB_P_MINUS:
case HB_P_MODULUS:
case HB_P_MULT:

View File

@@ -59,17 +59,20 @@ static void hb_compInitVars( void );
static void hb_compGenOutput( int );
static void hb_compOutputFile( void );
static char * RESERVED_FUNC( char * );
static void hb_compCheckDuplVars( PVAR pVars, char * szVarName, int iVarScope ); /*checks for duplicate variables definitions */
static void hb_compFieldGenPCode( BYTE , char * ); /* generates the pcode for database field */
static int hb_compFieldGetVarPos( char *, PFUNCTION ); /* return if passed name is a field variable */
static int hb_compFieldGetPos( char *, PFUNCTION ); /* return if passed name is a field variable */
static int hb_compLocalGetPos( char * szVarName ); /* returns the order + 1 of a local variable */
static int hb_compMemvarGetPos( char *, PFUNCTION ); /* return if passed name is a memvar variable */
static int hb_compStaticGetPos( char *, PFUNCTION ); /* return if passed name is a static variable */
static USHORT hb_compVariableGetPos( PVAR pVars, char * szVarName ); /* returns the order + 1 of a variable if defined or zero */
static void hb_compGenFieldPCode( BYTE , int, char *, PFUNCTION ); /* generates the pcode for database field */
static void hb_compGenVariablePCode( BYTE , char * ); /* generates the pcode for undeclared variable */
static void hb_compGenVarPCode( BYTE , char * ); /* generates the pcode for undeclared variable */
static void hb_compFixReturns( void ); /* fixes all last defined function returns jumps offsets */
static PFUNCTION hb_compFunctionNew( char *, char ); /* creates and initialises the _FUNC structure */
static int hb_compLocalVarGetPos( char * szVarName ); /* returns the order + 1 of a local variable */
static int hb_compMemvarGetPos( char *, PFUNCTION ); /* return if passed name is a memvar variable */
static void hb_compMemvarGenPCode( BYTE , char * ); /* generates the pcode for memvar variable */
static USHORT hb_compVariableGetPos( PVAR pVars, char * szVarName ); /* returns the order + 1 of a variable if defined or zero */
static void hb_compVariableGenPCode( BYTE , char * ); /* generates the pcode for undeclared variable */
static void hb_compCheckDuplVars( PVAR pVars, char * szVarName, int iVarScope ); /*checks for duplicate variables definitions */
void EXTERNAL_LINKAGE close_on_exit( void );
@@ -127,77 +130,7 @@ static BOOL hb_comp_bExternal = FALSE;
*/
static PEXTERN hb_comp_pExterns = NULL;
/* Table with parse warnings */
/* Table with reserved functions names
* NOTE: THIS TABLE MUST BE SORTED ALPHABETICALLY
*/
static const char * s_szReservedFun[] = {
"AADD" ,
"ABS" ,
"ASC" ,
"AT" ,
"BOF" ,
"BREAK" ,
"CDOW" ,
"CHR" ,
"CMONTH" ,
"COL" ,
"CTOD" ,
"DATE" ,
"DAY" ,
"DELETED" ,
"DEVPOS" ,
"DOW" ,
"DTOC" ,
"DTOS" ,
"EMPTY" ,
"EOF" ,
"EXP" ,
"FCOUNT" ,
"FIELDNAME" ,
"FLOCK" ,
"FOUND" ,
"INKEY" ,
"INT" ,
"LASTREC" ,
"LEFT" ,
"LEN" ,
"LOCK" ,
"LOG" ,
"LOWER" ,
"LTRIM" ,
"MAX" ,
"MIN" ,
"MONTH" ,
"PCOL" ,
"PCOUNT" ,
"PROW" ,
"QSELF" ,
"RECCOUNT" ,
"RECNO" ,
"REPLICATE" ,
"RLOCK" ,
"ROUND" ,
"ROW" ,
"RTRIM" ,
"SECONDS" ,
"SELECT" ,
"SETPOS" ,
"SETPOSBS" ,
"SPACE" ,
"SQRT" ,
"STR" ,
"SUBSTR" ,
"TIME" ,
"TRANSFORM" ,
"TRIM" ,
"TYPE" ,
"UPPER" ,
"VAL" ,
"WORD" ,
"YEAR"
};
/* ************************************************************************* */
int main( int argc, char * argv[] )
{
@@ -370,32 +303,6 @@ void hb_xfree( void * pMem ) /* frees fixed memory */
hb_compGenError( hb_comp_szErrors, 'F', ERR_MEMFREE, NULL, NULL );
}
/* ------------------------------------------------------------------------- */
/* checks if passed string is a reserved function name
*/
static char * RESERVED_FUNC( char * szName )
{
USHORT uiNum = 0;
int iFound = 1;
while( uiNum < ( ( sizeof( s_szReservedFun ) / sizeof( char * ) ) ) && iFound != 0 )
{
/* Compare first 4 characters
* If they are the same then compare the whole name
* SECO() is not allowed because of Clipper function SECONDS()
* however SECO32() is a valid name.
*/
iFound = strncmp( szName, s_szReservedFun[ uiNum ], 4 );
if( iFound == 0 )
iFound = strncmp( szName, s_szReservedFun[ uiNum ], strlen( szName ) );
++uiNum;
}
return iFound == 0 ? ( char * ) s_szReservedFun[ uiNum - 1 ] : NULL;
}
/* ------------------------------------------------------------------------- */
/** ACTIONS **/
/* ------------------------------------------------------------------------- */
@@ -655,6 +562,42 @@ void hb_compVariableAdd( char * szVarName, char cValueType )
}
}
/* Generate an error if passed variable name cannot be used in macro
* expression.
* Only MEMVAR or undeclared (memvar will be assumed) variables can be used.
*/
BOOL hb_compVariableMacroCheck( char * szVarName )
{
BOOL bValid = FALSE;
if( hb_compLocalGetPos( szVarName ) > 0 )
hb_compGenError( hb_comp_szErrors, 'E', ERR_BAD_MACRO, szVarName, NULL );
else if( hb_compStaticGetPos( szVarName, hb_comp_functions.pLast ) > 0 )
hb_compGenError( hb_comp_szErrors, 'E', ERR_BAD_MACRO, szVarName, NULL );
else if( hb_compFieldGetPos( szVarName, hb_comp_functions.pLast ) > 0 )
hb_compGenError( hb_comp_szErrors, 'E', ERR_BAD_MACRO, szVarName, NULL );
else if( ! hb_comp_bStartProc )
{
if( hb_compMemvarGetPos( szVarName, hb_comp_functions.pLast ) == 0 )
{
/* This is not a local MEMVAR
*/
if( hb_compFieldGetPos( szVarName, hb_comp_functions.pFirst ) > 0 )
hb_compGenError( hb_comp_szErrors, 'E', ERR_BAD_MACRO, szVarName, NULL );
else if( hb_compStaticGetPos( szVarName, hb_comp_functions.pFirst ) > 0 )
hb_compGenError( hb_comp_szErrors, 'E', ERR_BAD_MACRO, szVarName, NULL );
else
bValid = TRUE; /* undeclared variable */
}
else
bValid = TRUE;
}
else
bValid = TRUE; /* undeclared variable */
return bValid;
}
PCOMSYMBOL hb_compSymbolAdd( char * szSymbolName, USHORT * pwPos )
{
PCOMSYMBOL pSym = ( PCOMSYMBOL ) hb_xgrab( sizeof( COMSYMBOL ) );
@@ -683,21 +626,6 @@ PCOMSYMBOL hb_compSymbolAdd( char * szSymbolName, USHORT * pwPos )
return pSym;
}
/*
* Function generates passed pcode for passed database field
*/
void hb_compFieldGenPCode( BYTE bPCode, char * szVarName )
{
USHORT wVar;
PCOMSYMBOL pVar;
pVar = hb_compSymbolFind( szVarName, &wVar );
if( ! pVar )
pVar = hb_compSymbolAdd( szVarName, &wVar );
pVar->cScope |= VS_MEMVAR;
hb_compGenPCode3( bPCode, HB_LOBYTE( wVar ), HB_HIBYTE( wVar ) );
}
/*
* This function creates and initialises the _FUNC structure
*/
@@ -748,7 +676,7 @@ void hb_compFunctionAdd( char * szFunName, HB_SYMBOLSCOPE cScope, int iType )
hb_compGenError( hb_comp_szErrors, 'F', ERR_FUNC_DUPL, szFunName, NULL );
}
szFunction = RESERVED_FUNC( szFunName );
szFunction = hb_compReservedName( szFunName );
if( szFunction && !( hb_comp_functions.iCount==0 && !hb_comp_bStartProc ) )
{
/* We are ignoring it when it is the name of PRG file and we are
@@ -799,11 +727,6 @@ void hb_compFunctionAdd( char * szFunName, HB_SYMBOLSCOPE cScope, int iType )
}
}
void hb_compGenPushFunRef( char * szName )
{
HB_SYMBOL_UNUSED( szName ); /* TODO: */
}
PFUNCTION hb_compFunctionKill( PFUNCTION pFunc )
{
@@ -979,7 +902,7 @@ USHORT hb_compVariableGetPos( PVAR pVars, char * szVarName ) /* returns the orde
return 0;
}
static int hb_compLocalVarGetPos( char * szVarName ) /* returns the order + 1 of a variable if defined or zero */
static int hb_compLocalGetPos( char * szVarName ) /* returns the order + 1 of a variable if defined or zero */
{
int iVar = 0;
PFUNCTION pFunc = hb_comp_functions.pLast;
@@ -1073,42 +996,41 @@ static int hb_compLocalVarGetPos( char * szVarName ) /* returns the order + 1 of
return iVar;
}
/*
* Gets position of passed static variables.
/* Checks if passed variable name is declared as STATIC
* Returns 0 if not found in STATIC list or its position in this list if found
*
* All static variables are hold in a single array at runtime then positions
* are numbered for whole PRG module.
*/
int GetStaticVarPos( char * szVarName )
static int hb_compStaticGetPos( char * szVarName, PFUNCTION pFunc )
{
int iPos;
PFUNCTION pFunc = hb_comp_functions.pLast;
int iVar;
/* First we have to check if this name belongs to a static variable
* defined in current function
*/
if( pFunc->pOwner )
pFunc = pFunc->pOwner; /* we are in the static variable definition state */
iPos = hb_compVariableGetPos( pFunc->pStatics, szVarName );
if( iPos )
return iPos + pFunc->iStaticsBase;
while( pFunc->pOwner ) /* pOwner is not NULL if STATIC var := value is used */
pFunc = pFunc->pOwner;
/* Next we have to check the list of global static variables
* Note: It is not possible to have global static variables when
* implicit starting procedure is defined
*/
if( !hb_comp_bStartProc )
if( pFunc->szName )
/* we are in a function/procedure -we don't need any tricks */
iVar = hb_compVariableGetPos( pFunc->pStatics, szVarName );
else
{
iPos = hb_compVariableGetPos( hb_comp_functions.pFirst->pStatics, szVarName );
if( iPos )
return iPos;
/* we have to check the list of nested codeblock up to a function
* where the codeblock is defined
*/
while( pFunc->pOwner )
pFunc = pFunc->pOwner;
iVar = hb_compVariableGetPos( pFunc->pStatics, szVarName );
}
return 0;
if( iVar )
iVar += pFunc->iStaticsBase;
return iVar;
}
/* Checks if passed variable name is declared as FIELD
* Returns 0 if not found in FIELD list or its position in this list if found
*/
static int hb_compFieldGetVarPos( char * szVarName, PFUNCTION pFunc )
static int hb_compFieldGetPos( char * szVarName, PFUNCTION pFunc )
{
int iVar;
@@ -1339,126 +1261,63 @@ void hb_compLinePushIfInside( void ) /* generates the pcode with the currently c
}
/*
* Function generates passed pcode for passed variable name
* Function generates pcode for undeclared variable
*/
static void hb_compVariableGenPCode( BYTE bPCode, char * szVarName )
static void hb_compGenVariablePCode( BYTE bPCode, char * szVarName )
{
USHORT wVar;
PCOMSYMBOL pSym;
PFUNCTION pOwnerFunc = NULL;
int iType = VS_LOCAL; /* not really */
/* Check if it is a FIELD declared in current function
*/
wVar = hb_compFieldGetVarPos( szVarName, hb_comp_functions.pLast );
if( wVar == 0 )
{
/* Check if it is a MEMVAR declared in current function
*/
wVar = hb_compMemvarGetPos( szVarName, hb_comp_functions.pLast );
if( wVar )
iType = VS_MEMVAR;
}
else
{
iType = VS_FIELD;
pOwnerFunc = hb_comp_functions.pLast;
}
/* if it is not declared in current function then check if it is
* a symbol with file wide scope
*/
if( wVar == 0 && ! hb_comp_bStartProc )
{
wVar = hb_compFieldGetVarPos( szVarName, hb_comp_functions.pFirst );
if( wVar == 0 )
{
wVar = hb_compMemvarGetPos( szVarName, hb_comp_functions.pFirst );
if( wVar )
iType = VS_MEMVAR;
}
else
{
iType = VS_FIELD;
pOwnerFunc = hb_comp_functions.pFirst;
}
}
if( wVar == 0 )
{
/* This is undeclared variable */
/*
* NOTE:
* Clipper always assumes a memvar variable if undeclared variable
* is popped (a value is asssigned to a variable).
*
*/
/*
* NOTE:
* Clipper always assumes a memvar variable if undeclared variable
* is popped (a value is asssigned to a variable).
*/
#if defined( HARBOUR_STRICT_CLIPPER_COMPATIBILITY )
if( hb_comp_bForceMemvars || bPCode == HB_P_POPVARIABLE )
if( hb_comp_bForceMemvars || bPCode == HB_P_POPVARIABLE )
#else
if( hb_comp_bForceMemvars )
if( hb_comp_bForceMemvars )
#endif
{
/* -v switch was used -> assume it is a memvar variable
*/
iType = VS_MEMVAR;
hb_compGenWarning( hb_comp_szWarnings, 'W', WARN_MEMVAR_ASSUMED, szVarName, NULL );
}
else
hb_compGenWarning( hb_comp_szWarnings, 'W', WARN_AMBIGUOUS_VAR, szVarName, NULL );
}
if( iType == VS_FIELD )
{ /* variable is declared using FIELD statement */
PVAR pField = hb_compVariableFind( pOwnerFunc->pFields, wVar );
if( pField->szAlias )
{ /* the alias was specified in FIELD declaration */
if( bPCode == HB_P_POPVARIABLE )
bPCode = HB_P_POPALIASEDFIELD;
else if( bPCode == HB_P_PUSHVARIABLE )
bPCode = HB_P_PUSHALIASEDFIELD;
else
/* pushing fields by reference is not allowed */
hb_compGenError( hb_comp_szErrors, 'E', ERR_INVALID_REFER, szVarName, NULL );
/*
* Push alias symbol before the field symbol
*/
hb_compGenPushSymbol( hb_strdup( pField->szAlias ), 0 );
}
else
{ /* this is unaliased field */
if( bPCode == HB_P_POPVARIABLE )
bPCode = HB_P_POPFIELD;
else if( bPCode == HB_P_PUSHVARIABLE )
bPCode = HB_P_PUSHFIELD;
else if( bPCode == HB_P_PUSHMEMVARREF )
/* pushing fields by reference is not allowed */
hb_compGenError( hb_comp_szErrors, 'E', ERR_INVALID_REFER, szVarName, NULL );
}
}
else if( iType == VS_MEMVAR )
{
/* variable is declared or assumed MEMVAR */
/* -v switch was used -> assume it is a memvar variable
*/
hb_compGenWarning( hb_comp_szWarnings, 'W', WARN_MEMVAR_ASSUMED, szVarName, NULL );
if( bPCode == HB_P_POPVARIABLE )
bPCode = HB_P_POPMEMVAR;
else if( bPCode == HB_P_PUSHVARIABLE )
bPCode = HB_P_PUSHMEMVAR;
else
bPCode = HB_P_PUSHMEMVARREF;
}
else
hb_compGenWarning( hb_comp_szWarnings, 'W', WARN_AMBIGUOUS_VAR, szVarName, NULL );
/* Check if this variable name is placed into the symbol table
*/
pSym = hb_compSymbolFind( szVarName, &wVar );
if( ! pSym )
pSym = hb_compSymbolAdd( szVarName, &wVar );
pSym->cScope |= VS_MEMVAR;
hb_compGenPCode3( bPCode, HB_LOBYTE( wVar ), HB_HIBYTE( wVar ) );
hb_compGenVarPCode( bPCode, szVarName );
}
/* Generate a pcode for a field variable
*/
void hb_compGenFieldPCode( BYTE bPCode, int wVar, char * szVarName, PFUNCTION pFunc )
{
PVAR pField = hb_compVariableFind( pFunc->pFields, wVar );
if( pField->szAlias )
{ /* the alias was specified in FIELD declaration
* Push alias symbol before the field symbol
*/
if( bPCode == HB_P_POPFIELD )
bPCode = HB_P_POPALIASEDFIELD;
else if( bPCode == HB_P_PUSHFIELD )
bPCode = HB_P_PUSHALIASEDFIELD;
hb_compGenPushSymbol( hb_strdup( pField->szAlias ), 0 );
}
hb_compGenVarPCode( bPCode, szVarName );
}
/*
* Function generates passed pcode for passed memvar name
* Function generates passed pcode for passed runtime variable
* (field or memvar)
*/
void hb_compMemvarGenPCode( BYTE bPCode, char * szVarName )
void hb_compGenVarPCode( BYTE bPCode, char * szVarName )
{
USHORT wVar;
PCOMSYMBOL pSym;
@@ -1493,24 +1352,96 @@ void hb_compGenMessageData( char * szMsg ) /* generates an underscore-symbol nam
hb_compGenMessage( szResult );
}
/* Check variable in the following order:
* LOCAL variable
* local STATIC variable
* local FIELD variable
* local MEMVAR variable
* global STATIC variable
* global FIELD variable
* global MEMVAR variable
* (if not found - it is an undeclared variable)
*/
void hb_compGenPopVar( char * szVarName ) /* generates the pcode to pop a value from the virtual machine stack onto a variable */
{
int iVar;
iVar = hb_compLocalVarGetPos( szVarName );
iVar = hb_compLocalGetPos( szVarName );
if( iVar )
{
/* local variable
*/
hb_compGenPCode3( HB_P_POPLOCAL, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
}
else
{
iVar = GetStaticVarPos( szVarName );
iVar = hb_compStaticGetPos( szVarName, hb_comp_functions.pLast );
if( iVar )
{
/* Static variable declared in current function
*/
hb_compGenPCode3( HB_P_POPSTATIC, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
hb_comp_functions.pLast->bFlags |= FUN_USES_STATICS;
}
else
{
hb_compVariableGenPCode( HB_P_POPVARIABLE, szVarName );
iVar = hb_compFieldGetPos( szVarName, hb_comp_functions.pLast );
if( iVar )
{
/* field declared in current function
*/
hb_compGenFieldPCode( HB_P_POPFIELD, iVar, szVarName, hb_comp_functions.pLast );
}
else
{
iVar = hb_compMemvarGetPos( szVarName, hb_comp_functions.pLast );
if( iVar )
{
/* Memvar variable declared in current functions
*/
hb_compGenVarPCode( HB_P_POPMEMVAR, szVarName );
}
else
{
if( ! hb_comp_bStartProc )
iVar = hb_compStaticGetPos( szVarName, hb_comp_functions.pFirst );
if( iVar )
{
/* Global static variable
*/
hb_compGenPCode3( HB_P_POPSTATIC, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
hb_comp_functions.pLast->bFlags |= FUN_USES_STATICS;
}
else
{
if( ! hb_comp_bStartProc )
iVar = hb_compFieldGetPos( szVarName, hb_comp_functions.pFirst );
if( iVar )
{
/* Global field declaration
*/
hb_compGenFieldPCode( HB_P_POPFIELD, iVar, szVarName, hb_comp_functions.pFirst );
}
else
{
if( ! hb_comp_bStartProc )
iVar = hb_compMemvarGetPos( szVarName, hb_comp_functions.pFirst );
if( iVar )
{
/* Global Memvar variable declaration
*/
hb_compGenVarPCode( HB_P_POPMEMVAR, szVarName );
}
else
{
/* undeclared variable
*/
hb_compGenVariablePCode( HB_P_POPVARIABLE, szVarName );
}
}
}
}
}
}
}
}
@@ -1529,7 +1460,7 @@ void hb_compGenPopAliasedVar( char * szVarName,
{
if( szAlias[ 0 ] == 'M' && szAlias[ 1 ] == '\0' )
{ /* M->variable */
hb_compMemvarGenPCode( HB_P_POPMEMVAR, szVarName );
hb_compGenVarPCode( HB_P_POPMEMVAR, szVarName );
}
else
{
@@ -1538,7 +1469,7 @@ void hb_compGenPopAliasedVar( char * szVarName,
iCmp = strncmp( szAlias, "MEMVAR", strlen( szAlias ) );
if( iCmp == 0 )
{ /* MEMVAR-> or MEMVA-> or MEMV-> */
hb_compMemvarGenPCode( HB_P_POPMEMVAR, szVarName );
hb_compGenVarPCode( HB_P_POPMEMVAR, szVarName );
}
else
{ /* field variable */
@@ -1547,12 +1478,12 @@ void hb_compGenPopAliasedVar( char * szVarName,
iCmp = strncmp( szAlias, "FIELD", strlen( szAlias ) );
if( iCmp == 0 )
{ /* FIELD-> */
hb_compFieldGenPCode( HB_P_POPFIELD, szVarName );
hb_compGenVarPCode( HB_P_POPFIELD, szVarName );
}
else
{ /* database alias */
hb_compGenPushSymbol( hb_strdup( szAlias ), 0 );
hb_compFieldGenPCode( HB_P_POPALIASEDFIELD, szVarName );
hb_compGenVarPCode( HB_P_POPALIASEDFIELD, szVarName );
}
}
}
@@ -1560,12 +1491,12 @@ void hb_compGenPopAliasedVar( char * szVarName,
else
{
hb_compGenPushLong( lWorkarea );
hb_compFieldGenPCode( HB_P_POPALIASEDFIELD, szVarName );
hb_compGenVarPCode( HB_P_POPALIASEDFIELD, szVarName );
}
}
else
/* Alias is already placed on stack */
hb_compFieldGenPCode( HB_P_POPALIASEDFIELD, szVarName );
hb_compGenVarPCode( HB_P_POPALIASEDFIELD, szVarName );
}
/* generates the pcode to push a nonaliased variable value to the virtual
@@ -1575,46 +1506,165 @@ void hb_compGenPushVar( char * szVarName )
{
int iVar;
iVar = hb_compLocalVarGetPos( szVarName );
iVar = hb_compLocalGetPos( szVarName );
if( iVar )
{
/* local variable
*/
hb_compGenPCode3( HB_P_PUSHLOCAL, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
}
else
{
iVar = GetStaticVarPos( szVarName );
iVar = hb_compStaticGetPos( szVarName, hb_comp_functions.pLast );
if( iVar )
{
/* Static variable declared in current function
*/
hb_compGenPCode3( HB_P_PUSHSTATIC, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
hb_comp_functions.pLast->bFlags |= FUN_USES_STATICS;
}
else
{
hb_compVariableGenPCode( HB_P_PUSHVARIABLE, szVarName );
iVar = hb_compFieldGetPos( szVarName, hb_comp_functions.pLast );
if( iVar )
{
/* field declared in current function
*/
hb_compGenFieldPCode( HB_P_PUSHFIELD, iVar, szVarName, hb_comp_functions.pLast );
}
else
{
iVar = hb_compMemvarGetPos( szVarName, hb_comp_functions.pLast );
if( iVar )
{
/* Memvar variable declared in current functions
*/
hb_compGenVarPCode( HB_P_PUSHMEMVAR, szVarName );
}
else
{
if( ! hb_comp_bStartProc )
iVar = hb_compStaticGetPos( szVarName, hb_comp_functions.pFirst );
if( iVar )
{
/* Global static variable
*/
hb_compGenPCode3( HB_P_PUSHSTATIC, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
hb_comp_functions.pLast->bFlags |= FUN_USES_STATICS;
}
else
{
if( ! hb_comp_bStartProc )
iVar = hb_compFieldGetPos( szVarName, hb_comp_functions.pFirst );
if( iVar )
{
/* Global field declaration
*/
hb_compGenFieldPCode( HB_P_PUSHFIELD, iVar, szVarName, hb_comp_functions.pFirst );
}
else
{
if( ! hb_comp_bStartProc )
iVar = hb_compMemvarGetPos( szVarName, hb_comp_functions.pFirst );
if( iVar )
{
/* Global Memvar variable declaration
*/
hb_compGenVarPCode( HB_P_PUSHMEMVAR, szVarName );
}
else
{
/* undeclared variable
*/
hb_compGenVariablePCode( HB_P_PUSHVARIABLE, szVarName );
}
}
}
}
}
}
}
}
void hb_compGenPushVarRef( char * szVarName ) /* generates the pcode to push a variable by reference to the virtual machine stack */
{
USHORT iVar;
int iVar;
iVar = hb_compLocalVarGetPos( szVarName );
iVar = hb_compLocalGetPos( szVarName );
if( iVar )
{
/* local variable
*/
hb_compGenPCode3( HB_P_PUSHLOCALREF, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
}
else
{
iVar = GetStaticVarPos( szVarName );
iVar = hb_compStaticGetPos( szVarName, hb_comp_functions.pLast );
if( iVar )
{
/* Static variable declared in current function
*/
hb_compGenPCode3( HB_P_PUSHSTATICREF, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
hb_comp_functions.pLast->bFlags |= FUN_USES_STATICS;
}
else
{
/* if undeclared variable is passed by reference then a memvar
* variable is assumed because fields cannot be passed by
* a reference
*/
hb_compVariableGenPCode( HB_P_PUSHMEMVARREF, szVarName );
iVar = hb_compFieldGetPos( szVarName, hb_comp_functions.pLast );
if( iVar )
{
/* pushing fields by reference is not allowed */
hb_compGenError( hb_comp_szErrors, 'E', ERR_INVALID_REFER, szVarName, NULL );
}
else
{
iVar = hb_compMemvarGetPos( szVarName, hb_comp_functions.pLast );
if( iVar )
{
/* Memvar variable declared in current functions
*/
hb_compGenVarPCode( HB_P_PUSHMEMVARREF, szVarName );
}
else
{
if( ! hb_comp_bStartProc )
iVar = hb_compStaticGetPos( szVarName, hb_comp_functions.pFirst );
if( iVar )
{
/* Global static variable
*/
hb_compGenPCode3( HB_P_PUSHSTATICREF, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ) );
hb_comp_functions.pLast->bFlags |= FUN_USES_STATICS;
}
else
{
if( ! hb_comp_bStartProc )
iVar = hb_compFieldGetPos( szVarName, hb_comp_functions.pFirst );
if( iVar )
{
/* pushing fields by reference is not allowed */
hb_compGenError( hb_comp_szErrors, 'E', ERR_INVALID_REFER, szVarName, NULL );
}
else
{
if( ! hb_comp_bStartProc )
iVar = hb_compMemvarGetPos( szVarName, hb_comp_functions.pFirst );
if( iVar )
{
/* Global Memvar variable declaration
*/
hb_compGenVarPCode( HB_P_PUSHMEMVARREF, szVarName );
}
else
{
/* undeclared variable - field cannot be passed by the
* reference - assume the memvar
*/
hb_compGenVariablePCode( HB_P_PUSHMEMVARREF, szVarName );
}
}
}
}
}
}
}
}
@@ -1637,7 +1687,7 @@ void hb_compGenPushAliasedVar( char * szVarName,
*/
if( szAlias[ 0 ] == 'M' && szAlias[ 1 ] == '\0' )
{ /* M->variable */
hb_compMemvarGenPCode( HB_P_PUSHMEMVAR, szVarName );
hb_compGenVarPCode( HB_P_PUSHMEMVAR, szVarName );
}
else
{
@@ -1646,7 +1696,7 @@ void hb_compGenPushAliasedVar( char * szVarName,
iCmp = strncmp( szAlias, "MEMVAR", strlen( szAlias ) );
if( iCmp == 0 )
{ /* MEMVAR-> or MEMVA-> or MEMV-> */
hb_compMemvarGenPCode( HB_P_PUSHMEMVAR, szVarName );
hb_compGenVarPCode( HB_P_PUSHMEMVAR, szVarName );
}
else
{ /* field variable */
@@ -1655,12 +1705,12 @@ void hb_compGenPushAliasedVar( char * szVarName,
iCmp = strncmp( szAlias, "FIELD", strlen( szAlias ) );
if( iCmp == 0 )
{ /* FIELD-> */
hb_compFieldGenPCode( HB_P_PUSHFIELD, szVarName );
hb_compGenVarPCode( HB_P_PUSHFIELD, szVarName );
}
else
{ /* database alias */
hb_compGenPushSymbol( hb_strdup( szAlias ), 0 );
hb_compFieldGenPCode( HB_P_PUSHALIASEDFIELD, szVarName );
hb_compGenVarPCode( HB_P_PUSHALIASEDFIELD, szVarName );
}
}
}
@@ -1668,12 +1718,12 @@ void hb_compGenPushAliasedVar( char * szVarName,
else
{
hb_compGenPushLong( lWorkarea );
hb_compFieldGenPCode( HB_P_PUSHALIASEDFIELD, szVarName );
hb_compGenVarPCode( HB_P_PUSHALIASEDFIELD, szVarName );
}
}
else
/* Alias is already placed on stack */
hb_compFieldGenPCode( HB_P_PUSHALIASEDFIELD, szVarName );
hb_compGenVarPCode( HB_P_PUSHALIASEDFIELD, szVarName );
}
void hb_compGenPushLogical( int iTrueFalse ) /* pushes a logical value on the virtual machine stack */
@@ -1696,10 +1746,17 @@ void hb_compGenPushDouble( double dNumber, BYTE bDec )
void hb_compGenPushFunCall( char * szFunName )
{
char * szFunction = RESERVED_FUNC( szFunName );
char * szFunction;
/* If an abbreviated function name was used - change it for whole name */
hb_compGenPushSymbol( ( szFunction ? hb_strdup( szFunction ) : szFunName ), 1 );
szFunction = hb_compReservedName( szFunName );
if( szFunction )
{
/* Abbreviated function name was used - change it for whole name
*/
hb_compGenPushSymbol( hb_strdup( szFunction ), 1 );
}
else
hb_compGenPushSymbol( szFunName, 1 );
}
/* generates the pcode to push a integer number on the virtual machine stack */
@@ -1741,7 +1798,7 @@ void hb_compGenPushSymbol( char * szSymbolName, int iIsFunction )
if( iIsFunction )
{
char * pName = RESERVED_FUNC( szSymbolName );
char * pName = hb_compReservedName( szSymbolName );
/* If it is reserved function name then we should truncate
* the requested name.
* We have to use passed szSymbolName so we can latter deallocate it

View File

@@ -91,11 +91,14 @@ InvalidNumber [0-9]+\.
HexNumber 0x[0-9A-F]+
Identifier (([a-zA-Z])|([_a-zA-Z][_a-zA-Z0-9]+))
MacroVar \&{Identifier}[\.]?
MacroEnd \&{Identifier}\.({Identifier})|([0-9]+)
MacroId ({Identifier}\&(({Identifier}[\.]?)|({Identifier}\.({Identifier})|([0-9]+))))
MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+
TrueValue "."[t|y]"."
FalseValue "."[f|n]"."
PseudoFunc {Identifier}"("+.*")"+
Array {Identifier}[ \t]*"["
AtArray "}"[ \t]*"["
ExpArray ")"[ \t]*"["
@@ -361,7 +364,7 @@ Separator {SpaceTab}
hb_comp_iState =DO;
yyless( yyleng-5 );
}
<DO_>{Separator}+[_a-zA-Z] { /* an identifier DO id WITH */
<DO_>{Separator}+[_a-zA-Z\&] { /* an identifier 'DO id WITH' or 'DO &id WITH' */
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
unput( yytext[ yyleng-1 ] );
if( hb_comp_iState == LOOKUP )
@@ -756,8 +759,9 @@ Separator {SpaceTab}
/* ************************************************************************ */
%}
"#"{Separator}*"line" return LINE;
"loca"|"local" { BEGIN LOCAL_;
"loca"|"local" {
yylval.string = hb_strupr( hb_strdup( yytext ) );
BEGIN LOCAL_;
}
<LOCAL_>{Separator}+[_a-zA-Z] { /* an identifier after LOCAL */
unput( yytext[ yyleng-1 ] );
@@ -1143,7 +1147,7 @@ Separator {SpaceTab}
".or." hb_comp_iState =OPERATOR; return OR;
"!"|".not." hb_comp_iState =OPERATOR; return NOT;
"::" unput( ':' ); unput( 'f' ); unput( 'l' ); unput( 'e' ); unput( 'S' );
[,\{\}\|\#\&\:\<\>\[\]\@] hb_comp_iState =OPERATOR; return yytext[ 0 ];
[,\{\}\|\#\&\.\:\<\>\[\]\@] hb_comp_iState =OPERATOR; return yytext[ 0 ];
[\(] ++_iOpenBracket; hb_comp_iState =SEPARATOR; return yytext[ 0 ];
[\)] --_iOpenBracket; hb_comp_iState =SEPARATOR; return yytext[ 0 ];
@@ -1265,16 +1269,43 @@ Separator {SpaceTab}
return '}';
}
{Identifier} {
if( hb_comp_bRestrictSymbolLength && strlen( yytext ) > 10 )
{
yytext[ 10 ] = 0;
yyleng = 10;
}
yylval.string = hb_strupr( hb_strdup( yytext ) );
hb_comp_iState =IDENTIFIER;
return IDENTIFIER;
}
{MacroVar} {
if( yytext[ yyleng-1 ] == '.' )
yytext[ yyleng-1 ] = '\0';
yylval.string = hb_strupr( hb_strdup( yytext+1 ) );
hb_comp_iState = MACROVAR;
return MACROVAR;
}
{MacroEnd} {
yylval.string = hb_strupr( hb_strdup( yytext ) );
hb_comp_iState = MACROTEXT;
return MACROTEXT;
}
{MacroId} {
yylval.string = hb_strupr( hb_strdup( yytext ) );
hb_comp_iState = MACROTEXT;
return MACROTEXT;
}
{MacroTxt} {
yylval.string = hb_strupr( hb_strdup( yytext ) );
hb_comp_iState = MACROTEXT;
return MACROTEXT;
}
{Identifier} {
if( hb_comp_bRestrictSymbolLength && strlen( yytext ) > 10 )
{
yytext[ 10 ] = 0;
yyleng = 10;
}
yylval.string = hb_strupr( hb_strdup( yytext ) );
hb_comp_iState = IDENTIFIER;
return IDENTIFIER;
}
%{
#ifdef __WATCOMC__

View File

@@ -146,7 +146,7 @@ PTR_LOOPEXIT hb_comp_pLoops = NULL;
%token INC DEC ALIASOP DOCASE CASE OTHERWISE ENDCASE ENDDO MEMVAR
%token WHILE EXIT LOOP END FOR NEXT TO STEP LE GE FIELD IN PARAMETERS
%token PLUSEQ MINUSEQ MULTEQ DIVEQ POWER EXPEQ MODEQ EXITLOOP
%token PRIVATE BEGINSEQ BREAK RECOVER USING DO WITH SELF LINE
%token PRIVATE BEGINSEQ BREAK RECOVER USING DO WITH SELF LINE MACROVAR MACROTEXT
%token AS_NUMERIC AS_CHARACTER AS_LOGICAL AS_DATE AS_ARRAY AS_BLOCK AS_OBJECT DECLARE_FUN
/*the lowest precedence*/
@@ -175,7 +175,7 @@ PTR_LOOPEXIT hb_comp_pLoops = NULL;
%right '\n' ';' ','
/*the highest precedence*/
%type <string> IDENTIFIER LITERAL
%type <string> IDENTIFIER LITERAL SendId MACROVAR MACROTEXT
%type <valDouble> NUM_DOUBLE
%type <valInteger> NUM_INTEGER
%type <valLong> NUM_LONG
@@ -186,7 +186,7 @@ PTR_LOOPEXIT hb_comp_pLoops = NULL;
%type <lNumber> WhileBegin
%type <pVoid> IfElseIf Cases
%type <asExpr> Argument ArgList ElemList BlockExpList BlockVarList BlockNoVar
%type <asExpr> DoProc DoArgument DoArgList
%type <asExpr> DoName DoProc DoArgument DoArgList
%type <asExpr> PareExpList1 PareExpList2 PareExpList3 PareExpListN
%type <asExpr> ExpList ExpList1 ExpList2 ExpList3
%type <asExpr> NumValue NumAlias
@@ -200,7 +200,7 @@ PTR_LOOPEXIT hb_comp_pLoops = NULL;
%type <asExpr> Variable VarAlias
%type <asExpr> MacroVar MacroVarAlias
%type <asExpr> MacroExpr MacroExprAlias
%type <asExpr> AliasVar AliasExpr
%type <asExpr> AliasId AliasVar AliasExpr
%type <asExpr> VariableAt VariableAtAlias
%type <asExpr> FunCall FunCallAlias
%type <asExpr> ObjectData ObjectDataAlias
@@ -284,7 +284,7 @@ Statement : ExecFlow CrlfStmnt { }
| PareExpList CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
| ExprPreOp CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
| ExprPostOp CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
| ExprOperEq CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
| ExprOperEq CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
| ExprEqual CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
| ExprAssign CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
| DoProc CrlfStmnt { hb_compExprDelete( hb_compExprGenStatement( $1 ) ); }
@@ -340,7 +340,7 @@ LineStat : Crlf { $<lNumber>$ = 0; hb_comp_bDontGenLineNum = TRUE; }
;
Statements : LineStat { $<lNumber>$ = $<lNumber>1; }
| Statements LineStat { $<lNumber>$ += $<lNumber>1; }
| Statements LineStat { $<lNumber>$ += $<lNumber>2; }
;
ExtList : IDENTIFIER { hb_compExternAdd( $1 ); }
@@ -418,24 +418,21 @@ ArrayAtAlias : ArrayAt ALIASOP { $$ = $1; }
Variable : IDENTIFIER { $$ = hb_compExprNewVar( $1 ); }
;
VarAlias : IDENTIFIER ALIASOP { $$ = hb_compExprNewSymbol( $1 ); }
VarAlias : IDENTIFIER ALIASOP { $$ = hb_compExprNewAlias( $1 ); }
;
/* Macro variables
*/
MacroVar : '&' IDENTIFIER { hb_compExprNewMacro( hb_compExprNewVar( $2 ), NULL ); }
| '&' IDENTIFIER '.' { hb_compExprNewMacro( hb_compExprNewVar( $2 ), NULL ); }
| '&' IDENTIFIER '.' IDENTIFIER { hb_compExprNewMacro( hb_compExprNewVar( $2 ), $4 ); }
| '&' IDENTIFIER '.' NUM_INTEGER { hb_compExprNewMacro( hb_compExprNewVar( $2 ), $4.szValue ); }
| '&' IDENTIFIER '.' NUM_LONG { hb_compExprNewMacro( hb_compExprNewVar( $2 ), $4.szValue ); }
;
MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 ); }
| MACROTEXT { $$ = hb_compExprNewMacro( NULL, 0, $1 ); }
;
MacroVarAlias : MacroVar ALIASOP { $$ = $1; }
;
/* Macro expressions
*/
MacroExpr : '&' PareExpList { $$ = hb_compExprNewMacro( $2, NULL ); }
MacroExpr : '&' PareExpList { $$ = hb_compExprNewMacro( $2, 0, NULL ); }
;
MacroExprAlias : MacroExpr ALIASOP { $$ = $1; }
@@ -445,7 +442,7 @@ MacroExprAlias : MacroExpr ALIASOP { $$ = $1; }
*/
/* special case: _FIELD-> and FIELD-> can be nested
*/
FieldAlias : FIELD ALIASOP { $$ = hb_compExprNewSymbol( "FIELD" ); }
FieldAlias : FIELD ALIASOP { $$ = hb_compExprNewAlias( "FIELD" ); }
| FIELD ALIASOP FieldAlias { $$ = $3; }
;
@@ -466,25 +463,29 @@ FieldVarAlias : FieldAlias VarAlias { hb_compExprDelete( $1 ); $$ =
| FieldAlias IfInlineAlias { hb_compExprDelete( $1 ); $$ = hb_compErrorAlias( $2 ); }
;
AliasVar : NumAlias IDENTIFIER { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| MacroVarAlias IDENTIFIER { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| MacroExprAlias IDENTIFIER { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| PareExpListAlias IDENTIFIER { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| NilAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); }
| LiteralAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); }
| LogicalAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); }
| CodeBlockAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); }
| SelfAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); }
| ArrayAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); }
| ArrayAtAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| VariableAtAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| IfInlineAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| FunCallAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| ObjectDataAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| ObjectMethodAlias IDENTIFIER { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| VarAlias IDENTIFIER { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| FieldAlias IDENTIFIER { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| FieldVarAlias IDENTIFIER { $$ = hb_compExprNewAliasVar( $1, $2 ); }
AliasId : IDENTIFIER { $$ = hb_compExprNewVar( $1 ); }
| MacroVar { $$ = $1; }
;
AliasVar : NumAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| MacroVarAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| MacroExprAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| PareExpListAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| NilAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
| LiteralAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
| LogicalAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
| CodeBlockAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
| SelfAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
| ArrayAlias AliasId { $$ = hb_compErrorAlias( $1 ); }
| ArrayAtAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| VariableAtAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| IfInlineAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| FunCallAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| ObjectDataAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| ObjectMethodAlias AliasId { $$ = hb_compErrorAlias( $1 ); } /* QUESTION: Clipper reports error here - we can handle this */
| VarAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| FieldAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| FieldVarAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
;
/* Aliased expressions
@@ -493,11 +494,11 @@ AliasVar : NumAlias IDENTIFIER { $$ = hb_compExprNewAliasVar( $1, $2
* alias->( Expression )
* alias always selects a workarea at runtime
*/
AliasExpr : NumAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, hb_compExprReduce( $2 ) ); }
| VarAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, hb_compExprReduce( $2 ) ); }
| MacroVarAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, hb_compExprReduce( $2 ) ); }
| MacroExprAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, hb_compExprReduce( $2 ) ); }
| PareExpListAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, hb_compExprReduce( $2 ) ); }
AliasExpr : NumAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
| VarAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
| MacroVarAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
| MacroExprAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
| PareExpListAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
| FieldAlias PareExpList { $$ = hb_compErrorAlias( $2 ); } /* QUESTION: Clipper reports error here - we can handle it */
;
@@ -525,7 +526,8 @@ VariableAtAlias : VariableAt ALIASOP { $$ = $1; }
/* Function call
*/
FunCall : IDENTIFIER '(' ArgList ')' { $$ = hb_compExprNewFunCall( $1, $3 ); }
FunCall : IDENTIFIER '(' ArgList ')' { $$ = hb_compExprNewFunCall( hb_compExprNewSymbol( $1 ), $3 ); }
| MacroVar '(' ArgList ')' { $$ = hb_compExprNewFunCall( $1, $3 ); }
;
ArgList : Argument { $$ = hb_compExprNewArgList( $1 ); }
@@ -542,25 +544,29 @@ FunCallAlias : FunCall ALIASOP { $$ = $1; }
/* Object's instance variable
*/
ObjectData : NumValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| NilValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| LiteralValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| CodeBlock ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| Logical ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| SelfValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| Array ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| ArrayAt ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| Variable ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| AliasVar ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| AliasExpr ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| MacroVar ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| MacroExpr ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| FunCall ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| IfInline ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| PareExpList ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| VariableAt ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| ObjectMethod ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| ObjectData ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
SendId : IDENTIFIER { $$ = $1; }
| MacroVar { $$ = "&"; hb_compGenError( hb_comp_szErrors, 'E', ERR_INVALID_SEND, "&", NULL); }
;
ObjectData : NumValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| NilValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| LiteralValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| CodeBlock ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| Logical ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| SelfValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| Array ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| ArrayAt ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| Variable ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| AliasVar ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| AliasExpr ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| MacroVar ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| MacroExpr ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| FunCall ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| IfInline ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| PareExpList ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| VariableAt ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| ObjectMethod ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
| ObjectData ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
;
ObjectDataAlias : ObjectData ALIASOP { $$ = $1; }
@@ -929,7 +935,7 @@ PareExpList : PareExpList1 { $$ = $1; }
| PareExpListN { $$ = $1; }
;
PareExpListAlias : PareExpList ALIASOP { $$ = hb_compExprReduce( $1 ); }
PareExpListAlias : PareExpList ALIASOP { $$ = $1; }
;
ExpList1 : '(' EmptyExpression { $$ = hb_compExprNewList( $2 ); }
@@ -1312,12 +1318,16 @@ RecoverUsing : RECOVER USING IDENTIFIER
* DO .. WITH ++variable
* will pass the value of variable not a reference
*/
DoProc : DO IDENTIFIER
DoName : IDENTIFIER { $$ = hb_compExprNewSymbol( $1 ); }
| MacroVar { $$ = $1; }
;
DoProc : DO DoName
{ $$ = hb_compExprNewFunCall( $2, NULL ); }
| DO IDENTIFIER WITH DoArgList
| DO DoName WITH DoArgList
{ $$ = hb_compExprNewFunCall( $2, $4 ); }
| WHILE WITH DoArgList
{ $$ = hb_compExprNewFunCall( hb_strdup("WHILE"), $3 ); }
{ $$ = hb_compExprNewFunCall( hb_compExprNewSymbol( hb_strdup("WHILE") ), $3 ); }
;
DoArgList : ',' { $$ = hb_compExprAddListExpr( hb_compExprNewArgList( hb_compExprNewNil() ), hb_compExprNewNil() ); }

View File

@@ -79,6 +79,8 @@ char * hb_comp_szErrors[] =
"Invalid alias expression: \'%s\'",
"Invalid array index expression: \'%s\'",
"Bound error: \'%s\'"
"Macro of declared symbol: \'%s\'",
"Invalid selector in send: \'%s\'"
};
/* Table with parse warnings */

View File

@@ -0,0 +1,40 @@
#
# $Id$
#
ROOT = ../../
YACC_FLAGS = -p hb_comp
YACC_SOURCE=macro.y
YACC_HEADERS=\
macro.h \
hbsetup.h \
pcode.h \
hbdefs.h \
#NOTE: You can pass additional parameters that control the speed/size
# ratio of generated flex scanner. These parameters are:
# -Cf - fastest/biggest
# -CF
# -C - in between
# -Cm
# -Ce
# -Cem - slowest/smallest
# see Flex documentation for full set of switches
LEX_FLAGS = -Phb_comp -C
LEX_SOURCE=macro.l
LEX_HEADERS=\
hbsetup.h \
hberrors.h \
hbdefs.h \
macro.h \
C_SOURCES=macro.c \
LIBNAME=macro
include $(TOP)$(ROOT)config/lib.cf

View File

@@ -0,0 +1,669 @@
/*
* $Id$
*/
/*
* Harbour Project source code:
* Compiler main file
*
* Copyright 1999 Ryszard Glab <rglab@imid.med.pl>
* www - http://www.harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version, with one exception:
*
* The exception is that if you link the Harbour Runtime Library (HRL)
* and/or the Harbour Virtual Machine (HVM) with other files to produce
* an executable, this does not by itself cause the resulting executable
* to be covered by the GNU General Public License. Your use of that
* executable is in no way restricted on account of linking the HRL
* and/or HVM code into it.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
* their web site at http://www.gnu.org/).
*
*/
/* this #define HAVE TO be placed before all #include directives
*/
#define HB_MACRO_SUPPORT
#include "macro.h"
/* TODO:
* include these variables in SET subsystem ?
*/
static BOOL hb_comp_bShortCuts = TRUE; /* .and. & .or. expressions shortcuts */
static BOOL hb_comp_bUseName10 = FALSE; /* names limited to 10 characters */
/* ************************************************************************* */
/* Compile passes string into a pcode buffer
*/
static int hb_macroCompile( HB_MACRO_PTR pMacro, char * szString, int iFlag )
{
/* initialize the input buffer - it will be scanned by lex */
pMacro->string = szString;
pMacro->length = strlen( szString );
pMacro->pos = 0;
/* initialize the output (pcode) buffer - it will be filled by yacc */
pMacro->pCodeInfo = (HB_PCODE_INFO_PTR ) hb_xgrab( sizeof( HB_PCODE_INFO ) );
pMacro->pCodeInfo->lPCodeSize = HB_PCODE_SIZE;
pMacro->pCodeInfo->lPCodePos = 0;
pMacro->pCodeInfo->pLocals = NULL;
pMacro->pCodeInfo->pPrev = NULL;
pMacro->pCodeInfo->pCode = ( BYTE * ) hb_xgrab( HB_PCODE_SIZE );
/* We have to specify if we want a push or pop operation because
* we are using different pcodes for these operations
*/
pMacro->Flags = iFlag;
return hb_compParse( pMacro );
}
static void hb_macroDelete( HB_MACRO_PTR pMacro )
{
hb_xfree( (void *) pMacro->pCodeInfo->pCode );
hb_xfree( (void *) pMacro->pCodeInfo );
}
static BOOL hb_macroCheckParam( HB_ITEM_PTR pItem )
{
BOOL bValid = TRUE;
if( ! IS_STRING(pItem) )
{
HB_ITEM_PTR pResult = hb_errRT_BASE_Subst( EG_ARG, 1080, NULL, "&" );
bValid = FALSE;
if( pResult )
{
hb_stackPop();
hb_vmPush( pResult );
hb_itemRelease( pResult );
bValid = TRUE;
}
}
return bValid;
}
static void hb_macroRun( HB_MACRO_PTR pMacro )
{
hb_vmExecute( pMacro->pCodeInfo->pCode, pMacro->pSymbols );
}
static void hb_macroSyntaxError( HB_MACRO_PTR pMacro )
{
HB_ITEM_PTR pResult = hb_errRT_BASE_Subst( EG_SYNTAX, 1449, NULL, "&" );
if( pResult )
{
hb_vmPush( pResult );
hb_itemRelease( pResult );
}
HB_SYMBOL_UNUSED( pMacro ); /* TODO: better error messagess */
}
/* NOTE:
* This will be called when macro variable or macro expression is
* placed on the right side of the assignment or when it is used as
* a parameter.
*/
void hb_macroGetValue( HB_ITEM_PTR pItem, PHB_SYMB pTable )
{
if( hb_macroCheckParam( pItem ) )
{
HB_MACRO struMacro;
int iStatus;
char * szString = pItem->item.asString.value;
struMacro.bShortCuts = hb_comp_bShortCuts;
struMacro.bName10 = hb_comp_bUseName10;
struMacro.pSymbols = pTable;
iStatus = hb_macroCompile( &struMacro, szString, HB_P_MACROPUSH );
hb_stackPop(); /* remove compiled string */
if( iStatus == HB_MACRO_OK && struMacro.status == HB_MACRO_OK )
hb_macroRun( &struMacro );
else
hb_macroSyntaxError( &struMacro );
hb_macroDelete( &struMacro );
}
}
/* NOTE:
* This will be called when macro variable or macro expression is
* placed on the left side of the assignment
*/
void hb_macroSetValue( HB_ITEM_PTR pItem, PHB_SYMB pTable )
{
if( hb_macroCheckParam( pItem ) )
{
HB_MACRO struMacro;
int iStatus;
char * szString = pItem->item.asString.value;
struMacro.bShortCuts = hb_comp_bShortCuts;
struMacro.bName10 = hb_comp_bUseName10;
struMacro.pSymbols = pTable;
iStatus = hb_macroCompile( &struMacro, szString, HB_P_MACROPOP );
hb_stackPop(); /* remove compiled string */
if( iStatus == HB_MACRO_OK && struMacro.status == HB_MACRO_OK )
hb_macroRun( &struMacro );
else
hb_macroSyntaxError( &struMacro );
hb_macroDelete( &struMacro );
}
}
/* ************************************************************************* */
/* returns the order + 1 of a variable if defined or zero */
int hb_compLocalVarGetPos( char * szVarName, HB_MACRO_DECL )
{
int iVar = 1;
HB_CBVAR_PTR pVars = HB_PCODE_DATA->pLocals;
while( pVars )
{
if( pVars->szName && ! strcmp( pVars->szName, szVarName ) )
return iVar;
else
{
if( pVars->pNext )
{
pVars = pVars->pNext;
iVar++;
}
else
return 0;
}
}
return 0;
}
ULONG hb_compGenJump( LONG lOffset, HB_MACRO_DECL )
{
/* TODO: We need a longer offset (longer then two bytes)
*/
if( lOffset < ( LONG ) SHRT_MIN || lOffset > ( LONG ) SHRT_MAX )
hb_macroError( HB_MACRO_TOO_COMPLEX, HB_MACRO_PARAM );
hb_compGenPCode3( HB_P_JUMP, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_MACRO_PARAM );
return HB_PCODE_DATA->lPCodePos - 2;
}
ULONG hb_compGenJumpFalse( LONG lOffset, HB_MACRO_DECL )
{
/* TODO: We need a longer offset (longer then two bytes)
*/
if( lOffset < ( LONG ) SHRT_MIN || lOffset > ( LONG ) SHRT_MAX )
hb_macroError( HB_MACRO_TOO_COMPLEX, HB_MACRO_PARAM );
hb_compGenPCode3( HB_P_JUMPFALSE, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_MACRO_PARAM );
return HB_PCODE_DATA->lPCodePos - 2;
}
void hb_compGenJumpThere( ULONG ulFrom, ULONG ulTo, HB_MACRO_DECL )
{
BYTE * pCode = HB_PCODE_DATA->pCode;
LONG lOffset = ulTo - ulFrom + 1;
/* TODO: We need a longer offset (longer then two bytes)
*/
if( lOffset < ( LONG ) SHRT_MIN || lOffset > ( LONG ) SHRT_MAX )
hb_macroError( HB_MACRO_TOO_COMPLEX, HB_MACRO_PARAM );
pCode[ ( ULONG ) ulFrom ] = HB_LOBYTE( lOffset );
pCode[ ( ULONG ) ulFrom + 1 ] = HB_HIBYTE( lOffset );
}
void hb_compGenJumpHere( ULONG ulOffset, HB_MACRO_DECL )
{
hb_compGenJumpThere( ulOffset, HB_PCODE_DATA->lPCodePos, HB_MACRO_PARAM );
}
ULONG hb_compGenJumpTrue( LONG lOffset, HB_MACRO_DECL )
{
/* TODO: We need a longer offset (longer then two bytes)
*/
if( lOffset < ( LONG ) SHRT_MIN || lOffset > ( LONG ) SHRT_MAX )
hb_macroError( HB_MACRO_TOO_COMPLEX, HB_MACRO_PARAM );
hb_compGenPCode3( HB_P_JUMPTRUE, HB_LOBYTE( lOffset ), HB_HIBYTE( lOffset ), HB_MACRO_PARAM );
return HB_PCODE_DATA->lPCodePos - 2;
}
/*
* Function generates pcode for passed memvar name
*/
void hb_compMemvarGenPCode( BYTE bPCode, char * szVarName, HB_MACRO_DECL )
{
HB_DYNS_PTR pSym;
/* Find the address of passed symbol - create the symbol if doesn't exist
*/
pSym = hb_dynsymGet( szVarName );
hb_compGenPCode1( bPCode, HB_MACRO_PARAM );
hb_compGenPCodeN( ( BYTE * )( &pSym ), sizeof( pSym ), HB_MACRO_PARAM );
}
/* generates the pcode to push a symbol on the virtual machine stack */
void hb_compGenPushSymbol( char * szSymbolName, int iIsFunction, HB_MACRO_DECL )
{
HB_DYNS_PTR pSym;
if( iIsFunction )
{
char * pName = hb_compReservedName( szSymbolName );
/* If it is reserved function name then we should truncate
* the requested name.
* We have to use passed szSymbolName so we can latter deallocate it
* (pName points to static data)
*/
if( pName )
szSymbolName[ strlen( pName ) ] ='\0';
}
pSym = hb_dynsymGet( szSymbolName );
hb_compGenPCode1( HB_P_MPUSHSYM, HB_MACRO_PARAM );
hb_compGenPCodeN( ( BYTE * ) &pSym, sizeof( pSym ), HB_MACRO_PARAM );
}
/* generates the pcode to push a long number on the virtual machine stack */
void hb_compGenPushLong( long lNumber, HB_MACRO_DECL )
{
if( lNumber )
{
hb_compGenPCode1( HB_P_PUSHLONG, HB_MACRO_PARAM );
hb_compGenPCode1( ( ( char * ) &lNumber )[ 0 ], HB_MACRO_PARAM );
hb_compGenPCode1( ( ( char * ) &lNumber )[ 1 ], HB_MACRO_PARAM );
hb_compGenPCode1( ( ( char * ) &lNumber )[ 2 ], HB_MACRO_PARAM );
hb_compGenPCode1( ( ( char * ) &lNumber )[ 3 ], HB_MACRO_PARAM );
}
else
hb_compGenPCode1( HB_P_ZERO, HB_MACRO_PARAM );
}
/* sends a message to an object */
void hb_compGenMessage( char * szMsgName, HB_MACRO_DECL )
{
/* Find the address of passed symbol - create the symbol if doesn't exist
*/
HB_DYNS_PTR pSym = hb_dynsymGet( szMsgName );
hb_compGenPCode1( HB_P_MMESSAGE, HB_MACRO_PARAM );
hb_compGenPCodeN( ( BYTE * ) &pSym, sizeof( pSym ), HB_MACRO_PARAM );
}
/* generates an underscore-symbol name for a data assignment */
void hb_compGenMessageData( char * szMsg, HB_MACRO_DECL )
{
char * szResult = ( char * ) hb_xgrab( strlen( szMsg ) + 2 );
strcpy( szResult, "_" );
strcat( szResult, szMsg );
hb_compGenMessage( szResult, HB_MACRO_PARAM );
}
/* generates the pcode to pop a value from the virtual machine stack onto a variable */
void hb_compGenPopVar( char * szVarName, HB_MACRO_DECL )
{
int iVar;
iVar = hb_compLocalVarGetPos( szVarName, HB_MACRO_PARAM );
if( iVar )
{
/* this is a codeblock parameter */
hb_compGenPCode3( HB_P_POPLOCAL, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ), HB_MACRO_PARAM );
}
else
{
/* NOTE: In clipper all undeclared variables are assumed MEMVAR if
* they are popped however there is nno such assumption if avariable
* is pushed on the eval stack
*/
hb_compMemvarGenPCode( HB_P_MPOPMEMVAR, szVarName, HB_MACRO_PARAM );
}
}
/* generates the pcode to pop a value from the virtual machine stack onto
* an aliased variable
*/
void hb_compGenPopAliasedVar( char * szVarName,
BOOL bPushAliasValue,
char * szAlias,
long lWorkarea, HB_MACRO_DECL )
{
if( bPushAliasValue )
{
if( szAlias )
{
if( szAlias[ 0 ] == 'M' && szAlias[ 1 ] == '\0' )
{ /* M->variable */
hb_compMemvarGenPCode( HB_P_MPOPMEMVAR, szVarName, HB_MACRO_PARAM );
}
else
{
int iCmp = strncmp( szAlias, "MEMVAR", 4 );
if( iCmp == 0 )
iCmp = strncmp( szAlias, "MEMVAR", strlen( szAlias ) );
if( iCmp == 0 )
{ /* MEMVAR-> or MEMVA-> or MEMV-> */
hb_compMemvarGenPCode( HB_P_MPOPMEMVAR, szVarName, HB_MACRO_PARAM );
}
else
{ /* field variable */
iCmp = strncmp( szAlias, "FIELD", 4 );
if( iCmp == 0 )
iCmp = strncmp( szAlias, "FIELD", strlen( szAlias ) );
if( iCmp == 0 )
{ /* FIELD-> */
hb_compMemvarGenPCode( HB_P_MPOPFIELD, szVarName, HB_MACRO_PARAM );
}
else
{ /* database alias */
hb_compGenPushSymbol( hb_strdup( szAlias ), 0, HB_MACRO_PARAM );
hb_compMemvarGenPCode( HB_P_MPOPALIASEDFIELD, szVarName, HB_MACRO_PARAM );
}
}
}
}
else
{
hb_compGenPushLong( lWorkarea, HB_MACRO_PARAM );
hb_compMemvarGenPCode( HB_P_MPOPALIASEDFIELD, szVarName, HB_MACRO_PARAM );
}
}
else
/* Alias is already placed on stack */
hb_compMemvarGenPCode( HB_P_MPOPALIASEDFIELD, szVarName, HB_MACRO_PARAM );
}
/* generates the pcode to push a nonaliased variable value to the virtual
* machine stack
*/
void hb_compGenPushVar( char * szVarName, HB_MACRO_DECL )
{
int iVar;
iVar = hb_compLocalVarGetPos( szVarName, HB_MACRO_PARAM );
if( iVar )
{
/* this is a codeblock parameter */
hb_compGenPCode3( HB_P_PUSHLOCAL, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ), HB_MACRO_PARAM );
}
else
{
/* NOTE: In clipper all undeclared variables are assumed MEMVAR if
* they are popped however there is nno such assumption if avariable
* is pushed on the eval stack
*/
hb_compMemvarGenPCode( HB_P_MPUSHVARIABLE, szVarName, HB_MACRO_PARAM );
}
}
/* generates the pcode to push a variable by reference to the virtual machine stack */
void hb_compGenPushVarRef( char * szVarName, HB_MACRO_DECL )
{
USHORT iVar;
iVar = hb_compLocalVarGetPos( szVarName, HB_MACRO_PARAM );
if( iVar )
hb_compGenPCode3( HB_P_PUSHLOCALREF, HB_LOBYTE( iVar ), HB_HIBYTE( iVar ), HB_MACRO_PARAM );
else
{
hb_compMemvarGenPCode( HB_P_MPUSHMEMVARREF, szVarName, HB_MACRO_PARAM );
}
}
/* generates the pcode to push an aliased variable value to the virtual
* machine stack
*/
void hb_compGenPushAliasedVar( char * szVarName,
BOOL bPushAliasValue,
char * szAlias,
long lWorkarea, HB_MACRO_DECL )
{
if( bPushAliasValue )
{
if( szAlias )
{
/* myalias->var
* FIELD->var
* MEMVAR->var
*/
if( szAlias[ 0 ] == 'M' && szAlias[ 1 ] == '\0' )
{ /* M->variable */
hb_compMemvarGenPCode( HB_P_MPUSHMEMVAR, szVarName, HB_MACRO_PARAM );
}
else
{
int iCmp = strncmp( szAlias, "MEMVAR", 4 );
if( iCmp == 0 )
iCmp = strncmp( szAlias, "MEMVAR", strlen( szAlias ) );
if( iCmp == 0 )
{ /* MEMVAR-> or MEMVA-> or MEMV-> */
hb_compMemvarGenPCode( HB_P_MPUSHMEMVAR, szVarName, HB_MACRO_PARAM );
}
else
{ /* field variable */
iCmp = strncmp( szAlias, "FIELD", 4 );
if( iCmp == 0 )
iCmp = strncmp( szAlias, "FIELD", strlen( szAlias ) );
if( iCmp == 0 )
{ /* FIELD-> */
hb_compMemvarGenPCode( HB_P_MPUSHFIELD, szVarName, HB_MACRO_PARAM );
}
else
{ /* database alias */
hb_compGenPushSymbol( hb_strdup( szAlias ), 0, HB_MACRO_PARAM );
hb_compMemvarGenPCode( HB_P_MPUSHALIASEDFIELD, szVarName, HB_MACRO_PARAM );
}
}
}
}
else
{
hb_compGenPushLong( lWorkarea, HB_MACRO_PARAM );
hb_compMemvarGenPCode( HB_P_MPUSHALIASEDFIELD, szVarName, HB_MACRO_PARAM );
}
}
else
/* Alias is already placed on stack */
hb_compMemvarGenPCode( HB_P_MPUSHALIASEDFIELD, szVarName, HB_MACRO_PARAM );
}
/* pushes a logical value on the virtual machine stack , */
void hb_compGenPushLogical( int iTrueFalse, HB_MACRO_DECL )
{
if( iTrueFalse )
hb_compGenPCode1( HB_P_TRUE, HB_MACRO_PARAM );
else
hb_compGenPCode1( HB_P_FALSE, HB_MACRO_PARAM );
}
/* generates the pcode to push a double number on the virtual machine stack */
void hb_compGenPushDouble( double dNumber, BYTE bDec, HB_MACRO_DECL )
{
hb_compGenPCode1( HB_P_PUSHDOUBLE, HB_MACRO_PARAM );
hb_compGenPCodeN( ( BYTE * ) &dNumber, sizeof( double ), HB_MACRO_PARAM );
hb_compGenPCode1( bDec, HB_MACRO_PARAM );
}
void hb_compGenPushFunCall( char * szFunName, HB_MACRO_DECL )
{
char * szFunction;
szFunction = hb_compReservedName( szFunName );
if( szFunction )
{
/* Abbreviated function name was used - change it for whole name
*/
hb_compGenPushSymbol( szFunction, 1, HB_MACRO_PARAM );
}
else
hb_compGenPushSymbol( szFunName, 1, HB_MACRO_PARAM );
}
/* generates the pcode to push a string on the virtual machine stack */
void hb_compGenPushString( char * szText, ULONG ulStrLen, HB_MACRO_DECL )
{
hb_compGenPCode3( HB_P_PUSHSTR, HB_LOBYTE( ulStrLen ), HB_HIBYTE( ulStrLen ), HB_MACRO_PARAM );
hb_compGenPCodeN( ( BYTE * ) szText, ulStrLen, HB_MACRO_PARAM );
}
void hb_compGenPCode1( BYTE byte, HB_MACRO_DECL )
{
HB_PCODE_INFO_PTR pFunc = HB_PCODE_DATA;
if( ( pFunc->lPCodeSize - pFunc->lPCodePos ) < 1 )
pFunc->pCode = ( BYTE * ) hb_xrealloc( pFunc->pCode, pFunc->lPCodeSize += HB_PCODE_SIZE );
pFunc->pCode[ pFunc->lPCodePos++ ] = byte;
}
void hb_compGenPCode3( BYTE byte1, BYTE byte2, BYTE byte3, HB_MACRO_DECL )
{
HB_PCODE_INFO_PTR pFunc = HB_PCODE_DATA;
if( ( pFunc->lPCodeSize - pFunc->lPCodePos ) < 3 )
pFunc->pCode = ( BYTE * ) hb_xrealloc( pFunc->pCode, pFunc->lPCodeSize += HB_PCODE_SIZE );
pFunc->pCode[ pFunc->lPCodePos++ ] = byte1;
pFunc->pCode[ pFunc->lPCodePos++ ] = byte2;
pFunc->pCode[ pFunc->lPCodePos++ ] = byte3;
}
void hb_compGenPCodeN( BYTE * pBuffer, ULONG ulSize, HB_MACRO_DECL )
{
HB_PCODE_INFO_PTR pFunc = HB_PCODE_DATA;
if( pFunc->lPCodePos + ulSize > pFunc->lPCodeSize )
{
/* not enough free space in pcode buffer - increase it */
pFunc->lPCodeSize += ( ( ( ulSize / HB_PCODE_SIZE ) + 1 ) * HB_PCODE_SIZE );
pFunc->pCode = ( BYTE * ) hb_xrealloc( pFunc->pCode, pFunc->lPCodeSize );
}
memcpy( pFunc->pCode + pFunc->lPCodePos, pBuffer, ulSize );
pFunc->lPCodePos += ulSize;
}
/* ************************************************************************* */
void hb_macroError( int iError, HB_MACRO_DECL )
{
HB_MACRO_DATA->status = iError;
}
/*
* Start a new pcode buffer for a codeblock
*/
void hb_compCodeBlockStart( HB_MACRO_DECL )
{
HB_PCODE_INFO_PTR pCB = ( HB_PCODE_INFO_PTR ) hb_xgrab( sizeof( HB_PCODE_INFO ) );
/* replace current pcode buffer with the new one
*/
pCB->pPrev = HB_PCODE_DATA;
HB_PCODE_DATA = pCB;
pCB->pCode = ( BYTE * ) hb_xgrab( HB_PCODE_SIZE );
pCB->lPCodeSize = HB_PCODE_SIZE;
pCB->lPCodePos = 0;
pCB->pLocals = NULL;
}
void hb_compCodeBlockEnd( HB_MACRO_DECL )
{
HB_PCODE_INFO_PTR pCodeblock; /* pointer to the current codeblock */
USHORT wSize;
USHORT wParms = 0; /* number of codeblock parameters */
HB_CBVAR_PTR pVar, pFree;
/* a currently processed codeblock */
pCodeblock = HB_PCODE_DATA;
/* return to pcode buffer of a codeblock in which the current
* codeblock was defined
*/
HB_PCODE_DATA = pCodeblock->pPrev;
/* generate a proper codeblock frame with a codeblock size and with
* a number of expected parameters
*/
/*QUESTION: would be 64kB enough for a codeblock size?
* we are assuming now a USHORT for a size of codeblock
*/
/* Count the number of codeblock parameters */
pVar = pCodeblock->pLocals;
while( pVar )
{
pVar = pVar->pNext;
++wParms;
}
/*NOTE: 8 = HB_P_MPUSHBLOCK + USHORT( size ) + USHORT( wParams ) + USHORT( 0 ) + _ENDBLOCK
* runtime compiled codeblock cannot reference local variables defined in a
* function
*/
wSize = ( USHORT ) pCodeblock->lPCodePos + 8;
/*NOTE: HB_P_MPUSHBLOCK differs from HB_P_PUSHBLOCK - the pcode
* is stored in dynamic memory pool instead of static memory
*/
hb_compGenPCode3( HB_P_MPUSHBLOCK, HB_LOBYTE( wSize ), HB_HIBYTE( wSize ), HB_MACRO_PARAM );
hb_compGenPCode1( HB_LOBYTE( wParms ), HB_MACRO_PARAM );
hb_compGenPCode1( HB_HIBYTE( wParms ), HB_MACRO_PARAM );
hb_compGenPCode1( 0, HB_MACRO_PARAM );
hb_compGenPCode1( 0, HB_MACRO_PARAM );
/* copy a codeblock pcode buffer */
hb_compGenPCodeN( pCodeblock->pCode, pCodeblock->lPCodePos, HB_MACRO_PARAM );
hb_compGenPCode1( HB_P_ENDBLOCK, HB_MACRO_PARAM ); /* finish the codeblock */
/* free memory allocated for a codeblock */
hb_xfree( ( void * ) pCodeblock->pCode );
pVar = pCodeblock->pLocals;
while( pVar )
{
/* free used variables */
pFree = pVar;
hb_xfree( ( void * ) pFree->szName );
pVar = pVar->pNext;
hb_xfree( ( void * ) pFree );
}
hb_xfree( ( void * ) pCodeblock );
}
/* ************************************************************************ */
/* Include the common part of expression optimalizer
* NOTE: It cannot be compiled into a single library because the code
* required for macro compiler differs a little - we are passing additional
* parameter that holds macro compiler internal data
*/
#include "../compiler/expropt.c"

View File

@@ -0,0 +1,496 @@
%option noyywrap
%option never-interactive
%{
/*
* $Id$
*/
/*
* Harbour Project source code:
* Macro Compiler LEX rules
*
* Copyright 1999 Antonio Linares <alinares@fivetech.com>
* www - http://www.harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version, with one exception:
*
* The exception is that if you link the Harbour Runtime Library (HRL)
* and/or the Harbour Virtual Machine (HVM) with other files to produce
* an executable, this does not by itself cause the resulting executable
* to be covered by the GNU General Public License. Your use of that
* executable is in no way restricted on account of linking the HRL
* and/or HVM code into it.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
* their web site at http://www.gnu.org/).
*
*/
/* Compile using: flex -i -8 -omacrol.c -Phb_comp -C macro.l
NOTE: -C controls the speed/size ratio of generated scanner
-Cf = fastest/biggest
-CF
-C = in between
-Cm
-Ce
-Cem = slowest/smallest
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "macro.h"
#include "macroy.h"
#include "hbsetup.h" /* main configuration file */
#include "hberrors.h"
#include "hbdefs.h"
/* NOTE: these symbols are used internally in bison.simple
*/
#undef alloca
#define alloca hb_xgrab
#undef malloc
#define malloc hb_xgrab
/* declaration of yylex function
* NOTE: yylval is paassed automaticaly by bison if %pure_parser is used
*/
#undef YY_DECL
#define YY_DECL int yylex( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro )
#define YYLEX_PARAM pMacro
/* code that fills input buffer
*/
#define YY_INPUT( buf, result, max_size ) result = 0;
#define LOOKUP 0 /* scan from the begining of line */
#define OPERATOR -1
#define SEPARATOR -2
static int hb_comp_iState = LOOKUP;
static int _iOpenBracket = 0;
/* Support for Array Index */
static int iIndexSets = 0;
static int i_INDEX_STATE = 0;
%}
%{
#ifdef __WATCOMC__
/* disable warnings for unreachable code */
#pragma warning 13 9
#endif
%}
SpaceTab [ \t]+
Number ([0-9]+)|([0-9]*\.[0-9]+)
InvalidNumber [0-9]+\.
HexNumber 0x[0-9A-F]+
Identifier (([a-zA-Z])|([_a-zA-Z][_a-zA-Z0-9]+))
MacroVar \&{Identifier}[\.]?
MacroEnd \&{Identifier}\.({Identifier})|([0-9]+)
MacroId {Identifier}({MacroVar}|{MacroEnd})
MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+
Array {Identifier}[ \t]*"["
AtArray "}"[ \t]*"["
ExpArray ")"[ \t]*"["
SubArray "]"[ \t]*"["
Separator {SpaceTab}
%x STRING1 STRING2 STRING3
%x FIELD_ IIF_ IF_
%s INDEX
%%
"&"("'"|\"|\[) { hb_macroError( EG_SYNTAX, YYLEX_PARAM ); }
' BEGIN STRING1;
\" BEGIN STRING2;
"="[ \t]*"[" { BEGIN STRING3; return '='; }
"+"[ \t]*"[" { BEGIN STRING3; return '+'; }
"-"[ \t]*"[" { BEGIN STRING3; return '-'; }
"*"[ \t]*"[" { BEGIN STRING3; return '*'; }
"/"[ \t]*"[" { BEGIN STRING3; return '/'; }
"%"[ \t]*"[" { BEGIN STRING3; return '%'; }
"$"[ \t]*"[" { BEGIN STRING3; return '$'; }
("<>"|"!=")[ \t]*"[" { BEGIN STRING3; return NE2; }
":="[ \t]*"[" { BEGIN STRING3; return INASSIGN; }
"=="[ \t]*"[" { BEGIN STRING3; return EQ; }
"<="[ \t]*"[" { BEGIN STRING3; return LE; }
">="[ \t]*"[" { BEGIN STRING3; return GE; }
"+="[ \t]*"[" { BEGIN STRING3; return PLUSEQ; }
"-="[ \t]*"[" { BEGIN STRING3; return MINUSEQ; }
"*="[ \t]*"[" { BEGIN STRING3; return MULTEQ; }
"/="[ \t]*"[" { BEGIN STRING3; return DIVEQ; }
"^="[ \t]*"[" { BEGIN STRING3; return EXPEQ; }
"%="[ \t]*"[" { BEGIN STRING3; return MODEQ; }
("**"|"^")[ \t]*"[" { BEGIN STRING3; return POWER; }
".and."[ \t]*"[" { BEGIN STRING3; return AND; }
".or."[ \t]*"[" { BEGIN STRING3; return OR; }
("!"|".not.")[ \t]*"[" { BEGIN STRING3; return NOT; }
(","|"{"|"<"|">"|"(")[ \t]*"[" { BEGIN STRING3; yyleng = 1; yytext[1] = 0; return yytext[ 0 ]; }
<INITIAL>\[ BEGIN STRING3;
<STRING1>[^'^\n]* { hb_macroError( EG_SYNTAX, YYLEX_PARAM ); BEGIN 0; }
<STRING2>[^\"^\n]* { hb_macroError( EG_SYNTAX, YYLEX_PARAM ); BEGIN 0; }
<STRING3>[^\]]*\n { hb_macroError( EG_SYNTAX, YYLEX_PARAM ); BEGIN 0; }
<STRING1>[^']*' { if( i_INDEX_STATE )
BEGIN INDEX;
else
BEGIN 0;
yyleng--;
yytext[yyleng] = 0;
yylval_ptr->string = hb_strdup( yytext );
return LITERAL;
}
<STRING2>[^\"]*\" { if( i_INDEX_STATE )
BEGIN INDEX;
else
BEGIN 0;
yyleng--;
yytext[yyleng] = 0;
yylval_ptr->string = hb_strdup( yytext );
return LITERAL;
}
<STRING3>[^\]]*\] { if( i_INDEX_STATE )
BEGIN INDEX;
else
BEGIN 0;
yyleng--;
yytext[yyleng] = 0;
yylval_ptr->string = hb_strdup( yytext );
return LITERAL;
}
<INDEX>\n { hb_macroError( EG_SYNTAX, YYLEX_PARAM ); }
<INDEX>\[ { iIndexSets++; return yytext[ 0 ]; }
<INDEX>\] {
iIndexSets-- ;
if( iIndexSets == 0 )
{
/*printf( "\nIndex End\n" );*/
/* No longer in this state. */
i_INDEX_STATE = 0;
BEGIN 0;
}
return yytext[ 0 ];
}
{SpaceTab} ;
\n.* {
yyless( 1 );
return '\n';
}
%{
/* ************************************************************************ */
%}
"_fie"|"_fiel"|"_field" {
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
return FIELD;
}
"fiel"|"field" {
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
hb_comp_iState =FIELD;
}
"iif" {
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
return IIF;
}
"if" {
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
return IF;
}
"nil" return NIL;
"qself"{SpaceTab}*\({SpaceTab}*\) return SELF;
%{
/* ************************************************************************ */
%}
"#" return NE1;
"=" return yytext[ 0 ];
"+" return yytext[ 0 ];
"-" return yytext[ 0 ];
"*" return yytext[ 0 ];
[\/] return yytext[ 0 ];
"%" return yytext[ 0 ];
"$" return yytext[ 0 ];
"<>"|"!=" return NE2;
":=" return INASSIGN;
"==" return EQ;
"++" return INC;
"--" return DEC;
"->" return ALIASOP;
"<=" return LE;
">=" return GE;
"+=" return PLUSEQ;
"-=" return MINUSEQ;
"*=" return MULTEQ;
"/=" return DIVEQ;
"^=" return EXPEQ;
"%=" return MODEQ;
"**"|"^" return POWER;
".and." return AND;
".or." return OR;
"."[t|y]"." return TRUEVALUE;
"."[f|n]"." return FALSEVALUE;
"!"|".not." return NOT;
"::" unput( ':' ); unput( 'f' ); unput( 'l' ); unput( 'e' ); unput( 'S' );
[,\{\}\|\#\&\.\:\<\>\[\]\@] return yytext[ 0 ];
[\(] ++_iOpenBracket; return yytext[ 0 ];
[\)] --_iOpenBracket; return yytext[ 0 ];
{Number} {
char * ptr;
yylval_ptr->valDouble.dNumber = atof( yytext );
ptr = strchr( yytext, '.' );
if( ptr )
{
yylval_ptr->valDouble.bDec = strlen( ptr + 1 );
yylval_ptr->valDouble.szValue = yytext ;
return NUM_DOUBLE;
}
else
{
if( ( double )LONG_MIN <= yylval_ptr->valDouble.dNumber &&
yylval_ptr->valDouble.dNumber <= ( double )LONG_MAX )
{
yylval_ptr->valLong.lNumber = ( long ) yylval_ptr->valDouble.dNumber;
yylval_ptr->valLong.szValue = yytext;
return NUM_LONG;
}
else
{
yylval_ptr->valDouble.bDec = 0;
yylval_ptr->valDouble.szValue = yytext;
return NUM_DOUBLE;
}
}
}
{HexNumber} {
long lNumber = 0;
sscanf( yytext, "%lxI", &lNumber );
if( ( double )LONG_MIN <= lNumber &&
lNumber <= ( double )LONG_MAX )
{
yylval_ptr->valLong.lNumber = lNumber;
yylval_ptr->valLong.szValue = yytext;
return NUM_LONG;
}
else
{
yylval_ptr->valDouble.dNumber = lNumber;
yylval_ptr->valDouble.bDec = 0;
yylval_ptr->valDouble.szValue = yytext;
return NUM_DOUBLE;
}
}
{Array} {
if( ! i_INDEX_STATE )
{
BEGIN INDEX;
i_INDEX_STATE = 1;
}
unput( '[' );
yyleng--;
/* Remove optional white space between Identifier and Index */
while( yytext[ yyleng - 1 ] < 48 )
yyleng--;
yytext[yyleng] = 0;
{
if( YYLEX_PARAM->bName10 && strlen( yytext ) > 10 )
{
yytext[ 10 ] = 0;
yyleng = 10;
}
yylval_ptr->string = hb_strupr( hb_strdup( yytext ) );
return IDENTIFIER;
}
}
{ExpArray} {
/* Must be recursive */
if( ! i_INDEX_STATE )
{
BEGIN INDEX;
i_INDEX_STATE = 1;
}
unput( '[' );
--_iOpenBracket;
return ')';
}
{SubArray} {
/* Must be recursive */
if( i_INDEX_STATE )
{
BEGIN INDEX;
i_INDEX_STATE = 1;
}
iIndexSets--;
unput( '[' );
return ']';
}
{AtArray} {
/* Must be recursive */
if( ! i_INDEX_STATE )
{
BEGIN INDEX;
i_INDEX_STATE = 1;
}
unput( '[' );
--_iOpenBracket;
return '}';
}
{MacroVar} {
if( yytext[ yyleng-1 ] == '.' )
yytext[ yyleng-1 ] = '\0';
yylval_ptr->string = hb_strupr( hb_strdup( yytext+1 ) );
hb_comp_iState = MACROVAR;
return MACROVAR;
}
{MacroEnd} {
yylval_ptr->string = hb_strupr( hb_strdup( yytext ) );
hb_comp_iState = MACROTEXT;
return MACROTEXT;
}
{MacroId} {
yylval_ptr->string = hb_strupr( hb_strdup( yytext ) );
hb_comp_iState = MACROTEXT;
return MACROTEXT;
}
{MacroTxt} {
yylval_ptr->string = hb_strupr( hb_strdup( yytext ) );
hb_comp_iState = MACROTEXT;
return MACROTEXT;
}
{Identifier} {
if( YYLEX_PARAM->bName10 && strlen( yytext ) > 10 )
{
yytext[ 10 ] = 0;
yyleng = 10;
}
yylval_ptr->string = hb_strupr( hb_strdup( yytext ) );
return IDENTIFIER;
}
%%
#ifdef __WATCOMC__
/* enable warnings for unreachable code */
#pragma warning 13 1
#endif
void * hb_compFlexNew( HB_MACRO_PTR pMacro )
{
/* This creates the scanner buffer based on passed string.
* Unfortunately it creates a copy of this string - the string can be
* modified during scanning and the string have to end with TWO zero bytes
* NOTE: It must be used in macro.l because yy_scan_bytes is not
* visible in macro.y
*/
return (void *) yy_scan_bytes( pMacro->string, pMacro->length );
}
void hb_compFlexDelete( void * pBuffer )
{
yy_delete_buffer( ( YY_BUFFER_STATE ) pBuffer );
}
/*
static int hb_compInput( char * buf, int max_size, HB_MACRO_PTR pMacro )
{
int iRead;
if( pMacro->length < max_size )
{
memcpy( buf, pMacro->string, pMacro->length );
buf[ pMacro->length++ ] = '\n';
buf[ pMacro->length ] = 0;
iRead = pMacro->length;
}
else
{
int iLen = pMacro->length - pMacro->pos;
if( iLen <= 0 )
{
iRead = 0;
}
else if( iLen >= max_size )
{
iRead = max_size;
memcpy( buf, pMacro->string + pMacro->pos, iRead );
pMacro->pos += iRead;
}
else
{
memcpy( buf, pMacro->string + pMacro->pos, iLen );
buf[ iLen++ ] = '\n';
buf[ iLen ] = 0;
iRead = iLen;
pMacro->pos += iRead;
}
}
return iRead;
}
*/

View File

@@ -0,0 +1,721 @@
%pure_parser
%{
/*
* $Id$
*/
/*
* Harbour Project source code:
* Macro compiler YACC rules and actions
*
* Copyright 1999 Antonio Linares <alinares@fivetech.com>
* www - http://www.harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version, with one exception:
*
* The exception is that if you link the Harbour Runtime Library (HRL)
* and/or the Harbour Virtual Machine (HVM) with other files to produce
* an executable, this does not by itself cause the resulting executable
* to be covered by the GNU General Public License. Your use of that
* executable is in no way restricted on account of linking the HRL
* and/or HVM code into it.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
* their web site at http://www.gnu.org/).
*
*/
/* TODO list
* 1) jumps longer then 2^15 bytes
* 2) Change the pcode generated by ::cVar from Self:cVar to QSELF():cVar
* 3) Support this syntax: nPtr := @Hello()
*/
/* this #define HAVE TO be placed before all #include directives
*/
#define HB_MACRO_SUPPORT
#include "macro.h"
/* Compile using: bison -d -p hb_comp macro.y */
/* NOTE: these symbols are used internally in bison.simple
*/
#undef alloca
#define alloca hb_xgrab
#undef malloc
#define malloc hb_xgrab
/* yacc/lex related definitions
*/
#undef YYPARSE_PARAM
#define YYPARSE_PARAM HB_MACRO_PARAM /* parameter passed to yyparse function - it have to be of 'void *' type */
#undef YYLEX_PARAM
#define YYLEX_PARAM ( (HB_MACRO_PTR)YYPARSE_PARAM ) /* additional parameter passed to yylex */
extern void * hb_compFlexNew( HB_MACRO_PTR );
extern void hb_compFlexDelete( void * );
extern void yyerror( char * ); /* parsing error management function */
/* Standard checking for valid expression creation
*/
#define HB_MACRO_CHECK( pExpr ) \
if( HB_MACRO_DATA->status != HB_MACRO_OK ) \
{ \
hb_compExprDelete( pExpr, HB_MACRO_PARAM ); \
YYABORT; \
}
%}
%union /* special structure used by lex and yacc to share info */
{
char * string; /* to hold a string returned by lex */
int iNumber; /* to hold a temporary integer number */
long lNumber; /* to hold a temporary long number */
struct
{
int iNumber; /* to hold a number returned by lex */
char * szValue;
} valInteger;
struct
{
long lNumber; /* to hold a long number returned by lex */
char * szValue;
} valLong;
struct
{
double dNumber; /* to hold a double number returned by lex */
/* NOTE: Intentionally using "unsigned char" instead of "BYTE" */
unsigned char bDec; /* to hold the number of decimal points in the value */
char * szValue;
} valDouble;
HB_EXPR_PTR asExpr;
void * pVoid; /* to hold any memory structure we may need */
};
%{
/* This must be placed after the above union - the union is
* typedef-ined to YYSTYPE
*/
int yylex( YYSTYPE *, HB_MACRO_PTR );
%}
%token IDENTIFIER NIL NUM_DOUBLE INASSIGN NUM_LONG
%token IIF IF LITERAL TRUEVALUE FALSEVALUE
%token AND OR NOT EQ NE1 NE2 INC DEC ALIASOP SELF
%token LE GE FIELD MACROVAR MACROTEXT
%token PLUSEQ MINUSEQ MULTEQ DIVEQ POWER EXPEQ MODEQ
/*the lowest precedence*/
/*postincrement and postdecrement*/
%left POST
/*assigment - from right to left*/
%right INASSIGN
%right PLUSEQ MINUSEQ
%right MULTEQ DIVEQ MODEQ
%right EXPEQ
/*logical operators*/
%right OR
%right AND
%right NOT
/*relational operators*/
%right '=' '<' '>' EQ NE1 NE2 LE GE '$'
/*mathematical operators*/
%right '+' '-'
%right '*' '/' '%'
%right POWER
%right UNARY
/*preincrement and predecrement*/
%right PRE
/*special operators*/
%right ALIASOP '&' '@'
%right ','
/*the highest precedence*/
%type <string> IDENTIFIER LITERAL MACROVAR MACROTEXT
%type <valDouble> NUM_DOUBLE
%type <valLong> NUM_LONG
%type <asExpr> Argument ArgList ElemList BlockExpList BlockVarList BlockNoVar
%type <asExpr> NumValue NumAlias
%type <asExpr> NilValue
%type <asExpr> LiteralValue
%type <asExpr> CodeBlock
%type <asExpr> Logical
%type <asExpr> SelfValue
%type <asExpr> Array
%type <asExpr> ArrayAt
%type <asExpr> Variable VarAlias
%type <asExpr> MacroVar MacroVarAlias
%type <asExpr> MacroExpr MacroExprAlias
%type <asExpr> AliasId AliasVar AliasExpr
%type <asExpr> VariableAt
%type <asExpr> FunCall
%type <asExpr> ObjectData
%type <asExpr> ObjectMethod
%type <asExpr> IfInline
%type <asExpr> ExpList PareExpList PareExpListAlias
%type <asExpr> Expression SimpleExpression
%type <asExpr> EmptyExpression
%type <asExpr> ExprAssign ExprOperEq ExprPreOp ExprPostOp
%type <asExpr> ExprMath ExprBool ExprRelation ExprUnary
%type <asExpr> ExprPlusEq ExprMinusEq ExprMultEq ExprDivEq ExprModEq ExprExpEq
%type <asExpr> ArrayIndex IndexList
%type <asExpr> FieldAlias FieldVarAlias
%type <asExpr> PostOp
%%
Main : Expression '\n' { if( HB_MACRO_DATA->Flags & HB_P_MACROPUSH )
hb_compExprDelete( hb_compExprGenPush( $1, HB_MACRO_PARAM ), HB_MACRO_PARAM );
else
hb_compExprDelete( hb_compExprGenPop( $1, HB_MACRO_PARAM ), HB_MACRO_PARAM );
hb_compGenPCode1( HB_P_ENDPROC, HB_MACRO_PARAM );
}
| Expression { if( HB_MACRO_DATA->Flags & HB_P_MACROPUSH )
hb_compExprDelete( hb_compExprGenPush( $1, HB_MACRO_PARAM ), HB_MACRO_PARAM );
else
hb_compExprDelete( hb_compExprGenPop( $1, HB_MACRO_PARAM ), HB_MACRO_PARAM );
hb_compGenPCode1( HB_P_ENDPROC, HB_MACRO_PARAM );
}
| error { hb_macroError( EG_SYNTAX, HB_MACRO_PARAM ); }
;
/* Numeric values
*/
NumValue : NUM_DOUBLE { $$ = hb_compExprNewDouble( $1.dNumber, $1.bDec ); }
| NUM_LONG { $$ = hb_compExprNewLong( $1.lNumber ); }
;
NumAlias : NUM_LONG ALIASOP { $$ = hb_compExprNewLong( $1.lNumber ); }
;
/* NIL value
*/
NilValue : NIL { $$ = hb_compExprNewNil(); }
;
/* Literal string value
*/
LiteralValue : LITERAL { $$ = hb_compExprNewString( $1 ); }
;
/* Logical value
*/
Logical : TRUEVALUE { $$ = hb_compExprNewLogical( TRUE ); }
| FALSEVALUE { $$ = hb_compExprNewLogical( FALSE ); }
;
/* SELF value and expressions
*/
SelfValue : SELF { $$ = hb_compExprNewSelf(); }
;
/* Literal array
*/
Array : '{' ElemList '}' { $$ = hb_compExprNewArray( $2 ); }
;
/* Literal array access
*/
ArrayAt : Array ArrayIndex { $$ = $2; }
;
/* Variables
*/
Variable : IDENTIFIER { $$ = hb_compExprNewVar( $1 ); }
;
VarAlias : IDENTIFIER ALIASOP { $$ = hb_compExprNewAlias( $1 ); }
;
/* Macro variables - this can signal compilation errors
*/
MacroVar : MACROVAR { $$ = hb_compExprNewMacro( NULL, '&', $1 );
HB_MACRO_CHECK( $$ );
}
| MACROTEXT { $$ = hb_compExprNewMacro( NULL, 0, $1 );
HB_MACRO_CHECK( $$ );
}
;
MacroVarAlias : MacroVar ALIASOP { $$ = $1; }
;
/* Macro expressions
*/
MacroExpr : '&' PareExpList { $$ = hb_compExprNewMacro( $2, 0, NULL ); }
;
MacroExprAlias : MacroExpr ALIASOP { $$ = $1; }
;
/* Aliased variables
*/
/* special case: _FIELD-> and FIELD-> can be nested
*/
FieldAlias : FIELD ALIASOP { $$ = hb_compExprNewAlias( "FIELD" ); }
| FIELD ALIASOP FieldAlias { $$ = $3; }
;
/* ignore _FIELD-> or FIELD-> if a real alias is specified
*/
FieldVarAlias : FieldAlias VarAlias { hb_compExprDelete( $1, HB_MACRO_PARAM ); $$ = $2; }
| FieldAlias NumAlias { hb_compExprDelete( $1, HB_MACRO_PARAM ); $$ = $2; }
| FieldAlias PareExpListAlias { hb_compExprDelete( $1, HB_MACRO_PARAM ); $$ = $2; }
| FieldAlias MacroVarAlias { hb_compExprDelete( $1, HB_MACRO_PARAM ); $$ = $2; }
| FieldAlias MacroExprAlias { hb_compExprDelete( $1, HB_MACRO_PARAM ); $$ = $2; }
;
AliasId : IDENTIFIER { $$ = hb_compExprNewVar( $1 ); }
| MacroVar { $$ = $1; }
;
AliasVar : NumAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| MacroVarAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| MacroExprAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| PareExpListAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| VarAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| FieldAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
| FieldVarAlias AliasId { $$ = hb_compExprNewAliasVar( $1, $2 ); }
;
/* Aliased expressions
*/
/* NOTE: In the case:
* alias->( Expression )
* alias always selects a workarea at runtime
*/
AliasExpr : NumAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
| VarAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
| MacroVarAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
| MacroExprAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
| PareExpListAlias PareExpList { $$ = hb_compExprNewAliasExpr( $1, $2 ); }
;
/* Array expressions access
*/
VariableAt : NilValue ArrayIndex { $$ = $2; }
| LiteralValue ArrayIndex { $$ = $2; }
| CodeBlock ArrayIndex { $$ = $2; }
| Logical ArrayIndex { $$ = $2; }
| SelfValue ArrayIndex { $$ = $2; }
| Variable ArrayIndex { $$ = $2; }
| AliasVar ArrayIndex { $$ = $2; }
| AliasExpr ArrayIndex { $$ = $2; }
| MacroVar ArrayIndex { $$ = $2; }
| MacroExpr ArrayIndex { $$ = $2; }
| ObjectData ArrayIndex { $$ = $2; }
| ObjectMethod ArrayIndex { $$ = $2; }
| FunCall ArrayIndex { $$ = $2; }
| IfInline ArrayIndex { $$ = $2; }
| PareExpList ArrayIndex { $$ = $2; }
;
/* Function call
*/
FunCall : IDENTIFIER '(' ArgList ')' { $$ = hb_compExprNewFunCall( hb_compExprNewSymbol( $1 ), $3, HB_MACRO_PARAM );
HB_MACRO_CHECK( $$ );
}
| MacroVar '(' ArgList ')' { $$ = hb_compExprNewFunCall( $1, $3, HB_MACRO_PARAM );
HB_MACRO_CHECK( $$ );
}
;
ArgList : Argument { $$ = hb_compExprNewArgList( $1 ); }
| ArgList ',' Argument { $$ = hb_compExprAddListExpr( $1, $3 ); }
;
Argument : EmptyExpression { $$ = $1; }
| '@' IDENTIFIER { $$ = hb_compExprNewVarRef( $2 ); }
| '@' IDENTIFIER '(' ')' { $$ = hb_compExprNewFunRef( $2 ); }
;
/* Object's instance variable
*/
ObjectData : NumValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| NilValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| LiteralValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| CodeBlock ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| Logical ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| SelfValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| Array ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| ArrayAt ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| Variable ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| AliasVar ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| AliasExpr ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| MacroVar ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| MacroExpr ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| FunCall ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| IfInline ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| PareExpList ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| VariableAt ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| ObjectMethod ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
| ObjectData ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
;
/* Object's method
*/
ObjectMethod : ObjectData '(' ArgList ')' { $$ = hb_compExprNewMethodCall( $1, $3 ); }
;
SimpleExpression :
NumValue
| NilValue { $$ = $1; }
| LiteralValue { $$ = $1; }
| CodeBlock { $$ = $1; }
| Logical { $$ = $1; }
| SelfValue { $$ = $1; }
| Array { $$ = $1; }
| ArrayAt { $$ = $1; }
| AliasVar { $$ = $1; }
| MacroVar { $$ = $1; }
| MacroExpr { $$ = $1; }
| Variable { $$ = $1; }
| VariableAt { $$ = $1; }
| FunCall { $$ = $1; }
| IfInline { $$ = $1; }
| ObjectData { $$ = $1; }
| ObjectMethod { $$ = $1; }
| AliasExpr { $$ = $1; }
| ExprAssign { $$ = $1; }
| ExprOperEq { $$ = $1; }
| ExprPostOp { $$ = $1; }
| ExprPreOp { $$ = $1; }
| ExprUnary { $$ = $1; }
| ExprMath { $$ = $1; }
| ExprBool { $$ = $1; }
| ExprRelation { $$ = $1; }
;
Expression : SimpleExpression { $$ = $1; HB_MACRO_CHECK( $$ ); }
| PareExpList { $$ = $1; HB_MACRO_CHECK( $$ ); }
;
EmptyExpression: /* nothing => nil */ { $$ = hb_compExprNewEmpty(); }
| Expression
;
/* NOTE: PostOp can be used in one context only - it uses $0 rule
* (the rule that stands before PostOp)
*/
PostOp : INC { $$ = hb_compExprNewPostInc( $<asExpr>0 ); }
| DEC { $$ = hb_compExprNewPostDec( $<asExpr>0 ); }
;
/* NOTE: We cannot use 'Expression PostOp' because it caused
* shift/reduce conflicts
*/
ExprPostOp : NumValue PostOp %prec POST { $$ = $2; }
| NilValue PostOp %prec POST { $$ = $2; }
| LiteralValue PostOp %prec POST { $$ = $2; }
| CodeBlock PostOp %prec POST { $$ = $2; }
| Logical PostOp %prec POST { $$ = $2; }
| SelfValue PostOp %prec POST { $$ = $2; }
| Array PostOp %prec POST { $$ = $2; }
| ArrayAt PostOp %prec POST { $$ = $2; }
| Variable PostOp %prec POST { $$ = $2; }
| MacroVar PostOp %prec POST { $$ = $2; }
| MacroExpr PostOp %prec POST { $$ = $2; }
| AliasVar PostOp %prec POST { $$ = $2; }
| AliasExpr PostOp %prec POST { $$ = $2; }
| VariableAt PostOp %prec POST { $$ = $2; }
| PareExpList PostOp %prec POST { $$ = $2; }
| IfInline PostOp %prec POST { $$ = $2; }
| FunCall PostOp %prec POST { $$ = $2; }
| ObjectData PostOp %prec POST { $$ = $2; }
| ObjectMethod PostOp %prec POST { $$ = $2; }
;
ExprPreOp : INC Expression %prec PRE { $$ = hb_compExprNewPreInc( $2 ); }
| DEC Expression %prec PRE { $$ = hb_compExprNewPreDec( $2 ); }
;
ExprUnary : NOT Expression { $$ = hb_compExprNewNot( $2 ); }
| '-' Expression %prec UNARY { $$ = hb_compExprNewNegate( $2 ); }
| '+' Expression %prec UNARY { $$ = $2; }
;
ExprAssign : NumValue INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| NilValue INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| LiteralValue INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| CodeBlock INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| Logical INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| SelfValue INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| Array INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| ArrayAt INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| Variable INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| MacroVar INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| MacroExpr INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| AliasVar INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| AliasExpr INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| VariableAt INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| PareExpList INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| IfInline INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| FunCall INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| ObjectData INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
| ObjectMethod INASSIGN Expression { $$ = hb_compExprAssign( $1, $3 ); }
;
ExprPlusEq : NumValue PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| NilValue PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| LiteralValue PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| CodeBlock PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| Logical PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| SelfValue PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| Array PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| ArrayAt PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| Variable PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroVar PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroExpr PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasVar PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasExpr PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| VariableAt PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| PareExpList PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| IfInline PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| FunCall PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectData PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectMethod PLUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlusEq( $1 ), $3, HB_MACRO_PARAM ); }
;
ExprMinusEq : NumValue MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| NilValue MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| LiteralValue MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| CodeBlock MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| Logical MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| SelfValue MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| Array MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| ArrayAt MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| Variable MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroVar MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroExpr MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasVar MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasExpr MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| VariableAt MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| PareExpList MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| IfInline MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| FunCall MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectData MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectMethod MINUSEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinusEq( $1 ), $3, HB_MACRO_PARAM ); }
;
ExprMultEq : NumValue MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| NilValue MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| LiteralValue MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| CodeBlock MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| Logical MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| SelfValue MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| Array MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| ArrayAt MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| Variable MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroVar MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroExpr MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasVar MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasExpr MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| VariableAt MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| PareExpList MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| IfInline MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| FunCall MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectData MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectMethod MULTEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewMultEq( $1 ), $3, HB_MACRO_PARAM ); }
;
ExprDivEq : NumValue DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| NilValue DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| LiteralValue DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| CodeBlock DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| Logical DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| SelfValue DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| Array DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| ArrayAt DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| Variable DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroVar DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroExpr DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasVar DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasExpr DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| VariableAt DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| PareExpList DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| IfInline DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| FunCall DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectData DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectMethod DIVEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewDivEq( $1 ), $3, HB_MACRO_PARAM ); }
;
ExprModEq : NumValue MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| NilValue MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| LiteralValue MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| CodeBlock MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| Logical MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| SelfValue MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| Array MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| ArrayAt MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| Variable MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroVar MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroExpr MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasVar MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasExpr MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| VariableAt MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| PareExpList MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| IfInline MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| FunCall MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectData MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectMethod MODEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewModEq( $1 ), $3, HB_MACRO_PARAM ); }
;
ExprExpEq : NumValue EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| NilValue EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| LiteralValue EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| CodeBlock EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| Logical EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| SelfValue EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| Array EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| ArrayAt EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| Variable EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroVar EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| MacroExpr EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasVar EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| AliasExpr EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| VariableAt EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| PareExpList EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| IfInline EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| FunCall EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectData EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
| ObjectMethod EXPEQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewExpEq( $1 ), $3, HB_MACRO_PARAM ); }
;
ExprOperEq : ExprPlusEq { $$ = $1; }
| ExprMinusEq { $$ = $1; }
| ExprMultEq { $$ = $1; }
| ExprDivEq { $$ = $1; }
| ExprModEq { $$ = $1; }
| ExprExpEq { $$ = $1; }
;
ExprMath : Expression '+' Expression { $$ = hb_compExprSetOperand( hb_compExprNewPlus( $1 ), $3, HB_MACRO_PARAM ); }
| Expression '-' Expression { $$ = hb_compExprSetOperand( hb_compExprNewMinus( $1 ), $3, HB_MACRO_PARAM ); }
| Expression '*' Expression { $$ = hb_compExprSetOperand( hb_compExprNewMult( $1 ), $3, HB_MACRO_PARAM ); }
| Expression '/' Expression { $$ = hb_compExprSetOperand( hb_compExprNewDiv( $1 ), $3, HB_MACRO_PARAM ); }
| Expression '%' Expression { $$ = hb_compExprSetOperand( hb_compExprNewMod( $1 ), $3, HB_MACRO_PARAM ); }
| Expression POWER Expression { $$ = hb_compExprSetOperand( hb_compExprNewPower( $1 ), $3, HB_MACRO_PARAM ); }
;
ExprBool : Expression AND Expression { $$ = hb_compExprSetOperand( hb_compExprNewAnd( $1 ), $3, HB_MACRO_PARAM ); }
| Expression OR Expression { $$ = hb_compExprSetOperand( hb_compExprNewOr( $1 ), $3, HB_MACRO_PARAM ); }
;
ExprRelation: Expression EQ Expression { $$ = hb_compExprSetOperand( hb_compExprNewEQ( $1 ), $3, HB_MACRO_PARAM ); }
| Expression '<' Expression { $$ = hb_compExprSetOperand( hb_compExprNewLT( $1 ), $3, HB_MACRO_PARAM ); }
| Expression '>' Expression { $$ = hb_compExprSetOperand( hb_compExprNewGT( $1 ), $3, HB_MACRO_PARAM ); }
| Expression LE Expression { $$ = hb_compExprSetOperand( hb_compExprNewLE( $1 ), $3, HB_MACRO_PARAM ); }
| Expression GE Expression { $$ = hb_compExprSetOperand( hb_compExprNewGE( $1 ), $3, HB_MACRO_PARAM ); }
| Expression NE1 Expression { $$ = hb_compExprSetOperand( hb_compExprNewNE( $1 ), $3, HB_MACRO_PARAM ); }
| Expression NE2 Expression { $$ = hb_compExprSetOperand( hb_compExprNewNE( $1 ), $3, HB_MACRO_PARAM ); }
| Expression '$' Expression { $$ = hb_compExprSetOperand( hb_compExprNewIN( $1 ), $3, HB_MACRO_PARAM ); }
| Expression '=' Expression { $$ = hb_compExprSetOperand( hb_compExprNewEqual( $1 ), $3, HB_MACRO_PARAM ); }
;
ArrayIndex : IndexList ']' { $$ = $1; }
;
/* NOTE: $0 represents the expression before ArrayIndex
* Don't use ArrayIndex in other context than as an array index!
*/
IndexList : '[' Expression { $$ = hb_compExprNewArrayAt( $<asExpr>0, $2, HB_MACRO_PARAM ); }
| IndexList ',' Expression { $$ = hb_compExprNewArrayAt( $1, $3, HB_MACRO_PARAM ); }
| IndexList ']' '[' Expression { $$ = hb_compExprNewArrayAt( $1, $4, HB_MACRO_PARAM ); }
;
ElemList : EmptyExpression { $$ = hb_compExprNewList( $1 ); }
| ElemList ',' EmptyExpression { $$ = hb_compExprAddListExpr( $1, $3 ); }
;
CodeBlock : '{' '|'
{ $<asExpr>$ = hb_compExprNewCodeBlock(); } BlockNoVar
'|' BlockExpList '}'
{ $$ = $<asExpr>3; }
| '{' '|'
{ $<asExpr>$ = hb_compExprNewCodeBlock(); }
BlockVarList
'|' BlockExpList '}'
{ $$ = $<asExpr>3; }
;
/* NOTE: This uses $-2 then don't use BlockExpList in other context
*/
BlockExpList : Expression { $$ = hb_compExprAddListExpr( $<asExpr>-2, $1 ); }
| BlockExpList ',' Expression { $$ = hb_compExprAddListExpr( $<asExpr>-2, $3 ); }
;
/* NOTE: This is really not needed however it allows the use of $-2 item
* in BlockExpList to refer the same rule defined in Codeblock
*/
BlockNoVar : /* empty list */ { $$ = NULL; }
;
BlockVarList : IDENTIFIER { $$ = hb_compExprCBVarAdd( $<asExpr>0, $1, HB_MACRO_PARAM ); }
| BlockVarList ',' IDENTIFIER { $$ = hb_compExprCBVarAdd( $<asExpr>0, $3, HB_MACRO_PARAM ); HB_MACRO_CHECK( $$ ); }
;
ExpList : '(' EmptyExpression { $$ = hb_compExprNewList( $2 ); }
| ExpList ',' EmptyExpression { $$ = hb_compExprAddListExpr( $1, $3 ); }
;
PareExpList : ExpList ')' { $$ = $1; }
;
PareExpListAlias : PareExpList ALIASOP { $$ = $1; }
;
IfInline : IIF '(' Expression ',' EmptyExpression ','
{ $<asExpr>$ = hb_compExprAddListExpr( $3, $5 ); }
EmptyExpression ')'
{ $$ = hb_compExprNewIIF( hb_compExprAddListExpr( $<asExpr>7, $8 ) ); }
| IF '(' Expression ',' EmptyExpression ','
{ $<asExpr>$ = hb_compExprAddListExpr( $3, $5 ); }
EmptyExpression ')'
{ $$ = hb_compExprNewIIF( hb_compExprAddListExpr( $<asExpr>7, $8 ) ); }
;
%%
/*
** ------------------------------------------------------------------------ **
*/
int hb_compParse( HB_MACRO_PTR pMacro )
{
int iResult;
void * lexBuffer;
lexBuffer = hb_compFlexNew( pMacro );
pMacro->status = HB_MACRO_OK;
/* NOTE: bison requires (void *) pointer
*/
iResult = yyparse( ( void * ) pMacro );
hb_compFlexDelete( lexBuffer );
return iResult;
}
/* ************************************************************************* */
void yyerror( char * s )
{
HB_SYMBOL_UNUSED( s );
}

View File

@@ -24,5 +24,6 @@ LIBS=\
rtl \
pp \
common \
macro \
include $(TOP)$(ROOT)config/bin.cf

View File

@@ -135,6 +135,7 @@ static void hb_vmPushLocal( SHORT iLocal ); /* pushes the containts of a l
static void hb_vmPushLocalByRef( SHORT iLocal ); /* pushes a local by refrence onto the stack */
static void hb_vmPushStatic( USHORT uiStatic ); /* pushes the containts of a static onto the stack */
static void hb_vmPushStaticByRef( USHORT uiStatic ); /* pushes a static by refrence onto the stack */
static void hb_vmPushVariable( PHB_SYMB pVarSymb ); /* pushes undeclared variable */
static void hb_vmDuplicate( void ); /* duplicates the latest value on the stack */
static void hb_vmDuplTwo( void ); /* duplicates the latest two value on the stack */
@@ -149,8 +150,8 @@ static void hb_vmPopLocal( SHORT iLocal ); /* pops the stack latest value
static void hb_vmPopStatic( USHORT uiStatic ); /* pops the stack latest value onto a static */
/* stack management functions */
void hb_stackPop( void ); /* pops an item from the stack */
static void hb_stackDec( void ); /* pops an item from the stack without clearing it's contents */
static void hb_stackPop( void ); /* pops an item from the stack */
static void hb_stackFree( void ); /* releases all memory used by the stack */
static void hb_stackPush( void ); /* pushes an item on to the stack */
static void hb_stackInit( void ); /* initializes the stack */
@@ -838,39 +839,8 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
case HB_P_PUSHVARIABLE:
/* Push a value of variable of unknown type onto the eval stack
*/
{
USHORT uiAction = E_DEFAULT;
PHB_SYMB pVarSymb = pSymbols + pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 );
do
{
/* First try if passed symbol is a name of field
* in a current workarea - if it is not a field (FAILURE)
* then try the memvar variable
*/
if( hb_rddFieldGet( hb_stack.pPos, pVarSymb ) == SUCCESS )
hb_stackPush();
else
{
if( hb_memvarGet( hb_stack.pPos, pVarSymb ) == SUCCESS )
hb_stackPush();
else
{
HB_ITEM_PTR pError;
pError = hb_errRT_New( ES_ERROR, NULL, EG_NOVAR, 1003,
NULL, pVarSymb->szName,
0, EF_CANRETRY );
uiAction = hb_errLaunch( pError );
hb_errRelease( pError );
}
}
}
while( uiAction == E_RETRY );
HB_TRACE(HB_TR_INFO, ("(hb_vmPushVariable)"));
w += 3;
}
hb_vmPushVariable( pSymbols + pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) );
w += 3;
break;
case HB_P_DUPLICATE:
@@ -950,6 +920,151 @@ void hb_vmExecute( BYTE * pCode, PHB_SYMB pSymbols )
w += 3;
break;
/* macro creation */
case HB_P_MACROPOP:
/* compile and run - pop a value from the stack */
hb_macroSetValue( hb_stack.pPos - 1, pSymbols );
w++;
break;
case HB_P_MACROPOPALIASED:
/* compile and run - pop a field value from the stack */
w++;
break;
case HB_P_MACROPUSH:
/* compile and run - leave the result on the stack */
/* the topmost element on the stack contains a macro
* string for compilation
*/
hb_macroGetValue( hb_stack.pPos - 1, pSymbols );
w++;
break;
case HB_P_MACROPUSHALIASED:
/* compile and run - leave the field value on the stack */
w++;
break;
case HB_P_MACROSYMBOL:
/* compile into a symbol name (used in function calls) */
w++;
break;
case HB_P_MACROTEXT:
/* macro text substitution */
w++;
break;
/* macro compiled opcodes - we are using symbol address here */
case HB_P_MMESSAGE:
{
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
hb_vmMessage( ( *pDynSym )->pSymbol );
w += sizeof( HB_DYNS_PTR ) + 1;
}
break;
case HB_P_MPOPALIASEDFIELD:
{
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
hb_vmPopAliasedField( ( *pDynSym )->pSymbol );
w += sizeof( HB_DYNS_PTR ) + 1;
}
break;
case HB_P_MPOPFIELD:
{
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
/* Pops a value from the eval stack and uses it to set
* a new value of the given field
*/
hb_stackDec();
hb_rddPutFieldValue( hb_stack.pPos, ( *pDynSym )->pSymbol );
hb_itemClear( hb_stack.pPos );
HB_TRACE(HB_TR_INFO, ("(hb_vmMPopField)"));
w += sizeof( HB_DYNS_PTR ) + 1;
}
break;
case HB_P_MPOPMEMVAR:
{
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
hb_stackDec();
hb_memvarSetValue( ( *pDynSym )->pSymbol, hb_stack.pPos );
hb_itemClear( hb_stack.pPos );
HB_TRACE(HB_TR_INFO, ("(hb_vmMPopMemvar)"));
w += sizeof( HB_DYNS_PTR ) + 1;
}
break;
case HB_P_MPUSHALIASEDFIELD:
{
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
hb_vmPushAliasedField( ( *pDynSym )->pSymbol );
w += sizeof( HB_DYNS_PTR ) + 1;
}
break;
case HB_P_MPUSHBLOCK:
{
/*NOTE: the pcode is stored in damically allocated memory
* We need to handle it with more care than compile-time
* codeblocks
*/
w += ( pCode[ w + 1 ] + ( pCode[ w + 2 ] * 256 ) );
}
break;
case HB_P_MPUSHFIELD:
{
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
/* It pushes the current value of the given field onto the eval stack
*/
hb_rddGetFieldValue( hb_stack.pPos, ( *pDynSym )->pSymbol );
hb_stackPush();
HB_TRACE(HB_TR_INFO, ("(hb_vmMPushField)"));
w += sizeof( HB_DYNS_PTR ) + 1;
}
break;
case HB_P_MPUSHMEMVAR:
{
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
hb_memvarGetValue( hb_stack.pPos, ( *pDynSym )->pSymbol );
hb_stackPush();
HB_TRACE(HB_TR_INFO, ("(hb_vmMPushMemvar)"));
w += sizeof( HB_DYNS_PTR ) + 1;
}
break;
case HB_P_MPUSHMEMVARREF:
{
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
hb_memvarGetRefer( hb_stack.pPos, ( *pDynSym )->pSymbol );
hb_stackPush();
HB_TRACE(HB_TR_INFO, ("(hb_vmMPushMemvarRef)"));
w += sizeof( HB_DYNS_PTR ) + 1;
}
break;
case HB_P_MPUSHSYM:
{
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
hb_vmPushSymbol( ( *pDynSym )->pSymbol );
}
w += sizeof( HB_DYNS_PTR ) + 1;
break;
case HB_P_MPUSHVARIABLE:
{
HB_DYNS_PTR *pDynSym = ( HB_DYNS_PTR *) ( pCode + w + 1 );
hb_vmPushVariable( ( *pDynSym )->pSymbol );
}
w += sizeof( HB_DYNS_PTR ) + 1;
break;
/* misc */
case HB_P_NOOP:
@@ -2817,6 +2932,40 @@ static void hb_vmPushStaticByRef( USHORT uiStatic )
hb_stackPush();
}
static void hb_vmPushVariable( PHB_SYMB pVarSymb )
{
USHORT uiAction = E_DEFAULT;
do
{
/* First try if passed symbol is a name of field
* in a current workarea - if it is not a field (FAILURE)
* then try the memvar variable
*/
if( hb_rddFieldGet( hb_stack.pPos, pVarSymb ) == SUCCESS )
hb_stackPush();
else
{
if( hb_memvarGet( hb_stack.pPos, pVarSymb ) == SUCCESS )
hb_stackPush();
else
{
HB_ITEM_PTR pError;
pError = hb_errRT_New( ES_ERROR, NULL, EG_NOVAR, 1003,
NULL, pVarSymb->szName,
0, EF_CANRETRY );
uiAction = hb_errLaunch( pError );
hb_errRelease( pError );
}
}
}
while( uiAction == E_RETRY );
HB_TRACE(HB_TR_INFO, ("(hb_vmPushVariable)"));
}
static void hb_vmDuplicate( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_vmDuplicate()"));
@@ -3017,7 +3166,7 @@ static void hb_vmPopStatic( USHORT uiStatic )
/* stack management functions */
/* ------------------------------- */
static void hb_stackPop( void )
void hb_stackPop( void )
{
HB_TRACE(HB_TR_DEBUG, ("hb_stackPop()"));

View File

@@ -16,6 +16,7 @@ LIBS=\
vm \
rdd \
rtl \
macro \
pp \
runner \
common \
@@ -180,6 +181,11 @@ BAD_C_SOURCES=\
include $(TOP)$(ROOT)config/test.cf
DIRS=\
regress \
include $(TOP)$(ROOT)config/dir.cf
else #PM defined = build specified file
ifneq ($(findstring .prg,$(PM)),)
@@ -195,8 +201,3 @@ include $(TOP)$(ROOT)config/bin.cf
endif
DIRS=\
regress \
include $(TOP)$(ROOT)config/dir.cf

View File

@@ -25,6 +25,7 @@ LIBS=\
vm \
rdd \
rtl \
macro \
pp \
runner \
common \

View File

@@ -1,4 +1,4 @@
#INCLUDE "HBCLASS.CH"
#include "hbclass.ch"
Function Main( )