ChangeLog 19991209-17:10
This commit is contained in:
@@ -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 ¯o"
|
||||
- function calls: ¯o()
|
||||
- aliased macro variables: ¯o->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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
|
||||
@@ -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
218
harbour/include/expropt.h
Normal 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_ */
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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
105
harbour/include/macro.h
Normal 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
|
||||
@@ -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 */
|
||||
|
||||
@@ -60,5 +60,7 @@ LIBS=\
|
||||
rdd \
|
||||
rtl \
|
||||
pp \
|
||||
common \
|
||||
macro \
|
||||
|
||||
include $(TOP)$(ROOT)config/bin.cf
|
||||
|
||||
@@ -20,5 +20,7 @@ LIBS=\
|
||||
rdd \
|
||||
rtl \
|
||||
pp \
|
||||
common \
|
||||
macro \
|
||||
|
||||
include $(TOP)$(ROOT)config/bin.cf
|
||||
|
||||
@@ -18,5 +18,7 @@ LIBS=\
|
||||
rdd \
|
||||
rtl \
|
||||
pp \
|
||||
common \
|
||||
macro \
|
||||
|
||||
include $(TOP)$(ROOT)config/bin.cf
|
||||
|
||||
@@ -14,6 +14,8 @@ LIBS=\
|
||||
rtl \
|
||||
pp \
|
||||
runner \
|
||||
common \
|
||||
macro \
|
||||
|
||||
ifeq ($(PM),)
|
||||
PM := $(pm)
|
||||
|
||||
@@ -21,5 +21,7 @@ LIBS=\
|
||||
rdd \
|
||||
rtl \
|
||||
pp \
|
||||
common \
|
||||
macro \
|
||||
|
||||
include $(TOP)$(ROOT)config/bin.cf
|
||||
|
||||
@@ -11,6 +11,7 @@ DIRS=\
|
||||
rtl \
|
||||
vm \
|
||||
rdd \
|
||||
macro \
|
||||
debug \
|
||||
tools \
|
||||
runner \
|
||||
|
||||
@@ -8,6 +8,7 @@ C_SOURCES=\
|
||||
hbfsapi.c \
|
||||
hbstr.c \
|
||||
hbtrace.c \
|
||||
reserved.c \
|
||||
|
||||
PRG_SOURCES=\
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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() ); }
|
||||
|
||||
@@ -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 */
|
||||
|
||||
40
harbour/source/macro/Makefile
Normal file
40
harbour/source/macro/Makefile
Normal 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
|
||||
669
harbour/source/macro/macro.c
Normal file
669
harbour/source/macro/macro.c
Normal 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"
|
||||
|
||||
496
harbour/source/macro/macro.l
Normal file
496
harbour/source/macro/macro.l
Normal 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;
|
||||
}
|
||||
*/
|
||||
|
||||
721
harbour/source/macro/macro.y
Normal file
721
harbour/source/macro/macro.y
Normal 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 );
|
||||
}
|
||||
|
||||
@@ -24,5 +24,6 @@ LIBS=\
|
||||
rtl \
|
||||
pp \
|
||||
common \
|
||||
macro \
|
||||
|
||||
include $(TOP)$(ROOT)config/bin.cf
|
||||
|
||||
@@ -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()"));
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -25,6 +25,7 @@ LIBS=\
|
||||
vm \
|
||||
rdd \
|
||||
rtl \
|
||||
macro \
|
||||
pp \
|
||||
runner \
|
||||
common \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#INCLUDE "HBCLASS.CH"
|
||||
#include "hbclass.ch"
|
||||
|
||||
Function Main( )
|
||||
|
||||
|
||||
Reference in New Issue
Block a user