diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 61fde02fd5..08b90a1cf2 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,103 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ + +2006-11-21 05:05 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/source/compiler/complex.c + + harbour/source/compiler/hbcomp.c + * added missing header and file in my previous commit + +2006-11-21 03:30 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/common.mak + * harbour/source/compiler/Makefile + * harbour/include/hbcomp.h + * harbour/include/hbexprb.c + * harbour/include/hbexprc.c + * harbour/source/compiler/cmdcheck.c + * harbour/source/compiler/genc.c + * harbour/source/compiler/harbour.c + * harbour/source/compiler/harbour.l + * harbour/source/compiler/harbour.slx + * harbour/source/compiler/harbour.y + * harbour/source/compiler/hbgenerr.c + * harbour/source/compiler/hbident.c + * harbour/source/compiler/ppcomp.c + + harbour/source/compiler/complex.c + + added new PP based compiler lexer - it's smaller, MT safe and a + little bit faster then then the FLEX version. + + added HB_COMP structure to hold compiler data in future MT version + + added global variable HB_COMP_PTR hb_comp_data to make conversion + to MT easier - now it holds only PP and lexer data. + * update PP related code in compiler to be MT safe + + added %pure-parser, %parse-param and %lex-param for bison to generate + MT safe grammar parser. + * updated FLEX to work with recent compiler modifications and pure-parser + bison API + + * harbour/makefile.bc + * harbour/makefile.vc + * harbour/source/macro/Makefile + * harbour/source/macro/macro.l + * harbour/source/macro/macro.y + * harbour/source/macro/macrolex.c + * use hb_macro prefix instead of hb_comp in bison/flex parser/lexer + used in macro compiler to avoid possible conflicts in the future + * separated lexer data + + * harbour/include/hbapi.h + * harbour/include/hbpp.h + * harbour/source/pp/ppcore.c + * harbour/source/pp/ppgen.c + * harbour/source/pp/pplib.c + * harbour/source/vm/macro.c + * removed not used members from HB_MACRO structure to make it + cleaner before creating common to compiler and macro compiler + structure + + added new token HB_PP_TOKEN_EPSILON + + added void * cargo parameters passed to executed user functions + + hb_pp_tokenGet(), hb_pp_tokenToString(), hb_pp_tokenBlockString() + functions for new PP based compiler lexer + + * harbour/utils/hbpp/hbpp.c + * harbour/utils/hbpp/hbpp.h + * harbour/utils/hbpp/hbppcomp.c + * harbour/utils/hbpp/hbppcore.c + * harbour/utils/hbpp/hbpplib.c + * harbour/utils/hbpp/pragma.c + * updated to compile with recent compiler header file modifications + + + PP, new lexer and most of grammar parser should be MT safe. Now we should + update all compiler functions to pass pointer to HB_COMP data structure + where we should all current global variables. This structure as first + member should have HB_CMPCOMMON structure which will hold common to + compiler and macro compiler data. Ryszard I think you are the best person + to define this structure. + + We have new lexer which is MT safe but please note that it has to be + extensively tested so I would like to ask everybody to compile as much + as possible different code and check if the final programs work as + expected. Working on new code I removed some limitations existing in + FLEX though not all. At the beginning I tried to replicate the exact + FLEX behavior but I've found that in few places it does not work as + it should so I begin to encode rules in a way which remove some + limitations. In fact now it's much easier to control some things. + I kept the FLEX code working and made all necessary modifications + so it still can be used but keeping FLEX working cost us IMHO too + much. It's not possible to introduce some improvements to grammar + parser. All identifiers, keyword and macros returned by new lexer + are converted to upper letters, do not have to be freed by hb_xfree() + and is guarantied that will be always accessible. So from grammar file + we can remove all hb_compIdentifierNew( hb_strupr($1), TRUE ) what + should give noticeable speed improvement but will break the FLEX code. + Ryszard and other you will have to decide if we will support FLEX in + the future. We can also clean the code and remove most of other + redundant hb_strupr() and hb_strdup() used in many places. BTW only + one terminal symbol can be returned with lower letters: DOIDENT + and I make it intentionally so it's possible to use: + DO prog1 WITH "sth" + on case sensitive file systems so this symbol should be cloned in + upper cases as function symbol but used without modification as file name. It's current behavior but I'm not sure you will want to keep it. Maybe compiler switch to always convert file names created from diff --git a/harbour/common.mak b/harbour/common.mak index 938900760d..2890f711c9 100644 --- a/harbour/common.mak +++ b/harbour/common.mak @@ -734,7 +734,7 @@ GTGUI_DLL_OBJS = $(GTGUI_LIB_COMMON_OBJS) $(GTGUI_LIB_SHARED_OBJS) HARBOUR_EXE_OBJS = \ $(OBJ_DIR)\harbour.obj \ $(OBJ_DIR)\harboury.obj \ - $(OBJ_DIR)\harbourl.obj \ + $(OBJ_DIR)\complex.obj \ $(OBJ_DIR)\cmdcheck.obj \ $(OBJ_DIR)\hbdead.obj \ $(OBJ_DIR)\hbstripl.obj \ diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index e6df4ef82d..ea1f3cd8ee 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -798,19 +798,15 @@ typedef struct HB_MACRO_ /* a macro compiled pcode container */ { 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_ITEM_PTR pError; /* error object returned from the parser */ ULONG supported; /* various flags for supported capabilities */ - int FlexState; /* internal flex state during parsing */ - void * pLex; /* lexer buffer pointer */ + HB_ITEM_PTR pError; /* error object returned from the parser */ 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 */ - USHORT uiNameLen; /* the maximum symbol name length */ - BOOL bShortCuts; /* are we using logical shorcuts (in OR/AND) */ + void * pLex; /* lexer buffer pointer */ int exprType; /* type of successfully compiled expression */ - int iListElements; + USHORT uiListElements; /* number of elements in macro list expression */ + USHORT uiNameLen; /* the maximum symbol name length */ } HB_MACRO, * HB_MACRO_PTR; extern void hb_macroGetValue( HB_ITEM_PTR pItem, BYTE iContext, BYTE flags ); /* retrieve results of a macro expansion */ diff --git a/harbour/include/hbcomp.h b/harbour/include/hbcomp.h index 7a75e81990..6d96fee1b8 100644 --- a/harbour/include/hbcomp.h +++ b/harbour/include/hbcomp.h @@ -85,27 +85,6 @@ typedef enum LANG_OBJ_MODULE /* Platform dependant object module */ } LANGUAGES; /* supported Harbour output languages */ -/* #include support */ -typedef struct -{ - FILE * handle; /* handle of the opened file */ - void * pBuffer; /* file buffer */ - char * yyBuffer; /* buffer used by yyac */ - int iBuffer; /* current position in file buffer */ - int lenBuffer; /* current length of data in file buffer */ - char * szFileName; /* name of the file */ - void * pPrev; /* pointer to the previous opened file */ - void * pNext; /* pointer to the next opened file */ - int iLine; /* currently processed line number */ -} _FILE, * PFILE; /* structure to hold an opened PRG or CH */ - -/* structure to control several opened PRGs and CHs */ -typedef struct -{ - PFILE pLast; /* pointer to the last opened file */ - int iFiles; /* number of files currently opened */ -} FILES; - struct _COMCLASS; /* forward declaration */ /* Declared Function/Method support structure */ @@ -274,6 +253,34 @@ extern void hb_compPCodeTrace( PFUNCTION, HB_PCODE_FUNC_PTR *, void * ); extern void hb_compGenLabelTable( PFUNCTION pFunc, PHB_LABEL_INFO label_info ); + +typedef struct _HB_COMP_LEX +{ + PHB_PP_STATE pPP; + int iState; + char * lasttok; +} +HB_COMP_LEX, * PHB_COMP_LEX; + +typedef struct _HB_COMP +{ + PHB_COMP_LEX pLex; +} +HB_COMP, * HB_COMP_PTR; + +extern HB_COMP_PTR hb_comp_new( void ); +extern void hb_comp_free( HB_COMP_PTR ); + + +/* compiler PP functions and variables */ +#define HB_PP_STR_SIZE 12288 +#define HB_PP_BUFF_SIZE 4096 +extern void hb_pp_SetRules( BOOL fQuiet, int argc, char * argv[] ); +extern int hb_pp_Internal( char * ); +extern void hb_compParserStop( HB_COMP_PTR pComp ); + + + #define VS_NONE 0 #define VS_LOCAL 1 #define VS_STATIC 2 @@ -323,7 +330,7 @@ extern PINLINE hb_compInlineFind( char * szFunName ); extern USHORT hb_compFunctionGetPos( char * szSymbolName ); /* returns the index + 1 of a function on the functions defined list */ extern PFUNCTION hb_compFunctionKill( PFUNCTION ); /* releases all memory allocated by function and returns the next one */ extern void hb_compAnnounce( char * ); -extern PINLINE hb_compInlineAdd( char * szFunName ); +extern PINLINE hb_compInlineAdd( HB_COMP_PTR pComp, char * szFunName, int iLine ); extern PFUNCTION hb_compFunCallAdd( char * szFuntionName ); extern PFUNCTION hb_compFunCallFind( char * szFunName ); /* locates a previously defined called function */ @@ -484,15 +491,6 @@ extern void hb_compStripFuncLines( PFUNCTION pFunc ); /* Misc functions defined in hbdead.c */ extern void hb_compCodeTraceMarkDead( PFUNCTION pFunc ); -/* Misc functions defined in harbour.y */ -#if 0 -extern int hb_compYACCMain( char * szName ); -#endif -extern BOOL hb_compInclude( char * szFileName, HB_PATHNAMES * pSearchPath ); /* end #include support */ -extern void hb_compParserStop( void ); /* cleanup the bison parser */ - -extern char * hb_comp_buffer; /* yacc input buffer */ - /* output related functions defined in gen*.c */ extern void hb_compGenCCode( PHB_FNAME ); /* generates the C language output */ extern void hb_compGenILCode( PHB_FNAME ); /* generates the .NET IL language output */ @@ -508,6 +506,8 @@ extern void hb_compIdentifierClose( void ); /* release the table of identifiers /* variable used by compiler */ +extern HB_COMP_PTR hb_comp_data; + extern int hb_comp_iLine; extern FUNCTIONS hb_comp_functions; extern FUNCTIONS hb_comp_funcalls; @@ -520,12 +520,10 @@ extern PCOMCLASS hb_comp_pLastClass; extern PCOMCLASS hb_comp_pReleaseClass; extern char * hb_comp_szFromClass; extern PCOMDECLARED hb_comp_pLastMethod; -extern HB_PATHNAMES * hb_comp_pIncludePath; extern PFUNCTION hb_comp_pInitFunc; extern PHB_FNAME hb_comp_pFileName; extern PHB_FNAME hb_comp_pFilePpo; extern BOOL hb_comp_bPPO; -extern FILE * hb_comp_yyppo; extern BOOL hb_comp_bStartProc; extern BOOL hb_comp_bLineNumbers; extern BOOL hb_comp_bQuiet; @@ -545,7 +543,6 @@ extern char hb_comp_cDataListType; extern char hb_comp_cCastType; extern int hb_comp_iVarScope; extern BOOL hb_comp_bDontGenLineNum; -extern FILES hb_comp_files; extern int hb_comp_iStaticCnt; extern int hb_comp_iErrorCount; @@ -598,15 +595,6 @@ extern FILE *hb_comp_errFile; /* Hide Strings */ extern int hb_comp_iHidden; -/* compiler PP functions and variables */ -#define HB_PP_STR_SIZE 12288 -#define HB_PP_BUFF_SIZE 4096 -extern void hb_pp_SetRules( BOOL hb_comp_bQuiet, int argc, char * argv[] ); -extern void hb_pp_Init( void ); -extern void hb_pp_Free( void ); -extern void hb_pp_AddDefine( char *defname, char *value ); -extern void hb_pp_ParseDirective( char * ); -extern int hb_pp_Internal( FILE *, char * ); extern BOOL hb_pp_LiteralEscSeq; extern BOOL hb_pp_NestedLiteralString; diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 49f2d60fef..4aa080f68b 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -1529,13 +1529,13 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) { /* Always add add byte to pcode indicating requested macro compiler flag. */ #if defined( HB_MACRO_SUPPORT ) - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_COMPFLAG_RT_MACRO ); + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_COMPFLAG_RT_MACRO ); #else - HB_EXPR_GENPCODE1( hb_compGenPData1, - ( hb_comp_Supported & HB_COMPFLAG_HARBOUR ? HB_SM_HARBOUR : 0 ) | - ( hb_comp_Supported & HB_COMPFLAG_XBASE ? HB_SM_XBASE : 0 ) | - ( hb_comp_bShortCuts ? HB_SM_SHORTCUTS : 0 ) | - ( hb_comp_Supported & HB_COMPFLAG_RT_MACRO ? HB_SM_RT_MACRO : 0 ) ); + HB_EXPR_GENPCODE1( hb_compGenPData1, + ( hb_comp_Supported & HB_COMPFLAG_HARBOUR ? HB_SM_HARBOUR : 0 ) | + ( hb_comp_Supported & HB_COMPFLAG_XBASE ? HB_SM_XBASE : 0 ) | + ( hb_comp_bShortCuts ? HB_SM_SHORTCUTS : 0 ) | + ( hb_comp_Supported & HB_COMPFLAG_RT_MACRO ? HB_SM_RT_MACRO : 0 ) ); #endif } @@ -1596,10 +1596,10 @@ static HB_EXPR_FUNC( hb_compExprUseMacro ) HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_COMPFLAG_RT_MACRO ); #else HB_EXPR_GENPCODE1( hb_compGenPData1, - ( hb_comp_Supported & HB_COMPFLAG_HARBOUR ? HB_SM_HARBOUR : 0 ) | - ( hb_comp_Supported & HB_COMPFLAG_XBASE ? HB_SM_XBASE : 0 ) | - ( hb_comp_bShortCuts ? HB_SM_SHORTCUTS : 0 ) | - ( hb_comp_Supported & HB_COMPFLAG_RT_MACRO ? HB_SM_RT_MACRO : 0 ) ); + ( hb_comp_Supported & HB_COMPFLAG_HARBOUR ? HB_SM_HARBOUR : 0 ) | + ( hb_comp_Supported & HB_COMPFLAG_XBASE ? HB_SM_XBASE : 0 ) | + ( hb_comp_bShortCuts ? HB_SM_SHORTCUTS : 0 ) | + ( hb_comp_Supported & HB_COMPFLAG_RT_MACRO ? HB_SM_RT_MACRO : 0 ) ); #endif } } @@ -2760,7 +2760,6 @@ static HB_EXPR_FUNC( hb_compExprUseOr ) } break; - case HB_EA_POP_PCODE: break; diff --git a/harbour/include/hbexprc.c b/harbour/include/hbexprc.c index 44a2ee99fc..1564260142 100644 --- a/harbour/include/hbexprc.c +++ b/harbour/include/hbexprc.c @@ -672,18 +672,15 @@ void hb_compExprUseAliasMacro( HB_EXPR_PTR pAliasedVar, BYTE bAction ) } /* Always add add byte to pcode indicating requested macro compiler flag. */ - #if defined( HB_MACRO_SUPPORT ) - HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_COMPFLAG_RT_MACRO ); - #else - HB_EXPR_GENPCODE1( hb_compGenPData1, - ( - ( hb_comp_Supported & HB_COMPFLAG_HARBOUR ? HB_SM_HARBOUR : 0 ) | - ( hb_comp_Supported & HB_COMPFLAG_XBASE ? HB_SM_XBASE : 0 ) | - ( hb_comp_bShortCuts ? HB_SM_SHORTCUTS : 0 ) | - ( hb_comp_Supported & HB_COMPFLAG_RT_MACRO ? HB_SM_RT_MACRO : 0 ) - ) - ); - #endif +#if defined( HB_MACRO_SUPPORT ) + HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_COMPFLAG_RT_MACRO ); +#else + HB_EXPR_GENPCODE1( hb_compGenPData1, + ( hb_comp_Supported & HB_COMPFLAG_HARBOUR ? HB_SM_HARBOUR : 0 ) | + ( hb_comp_Supported & HB_COMPFLAG_XBASE ? HB_SM_XBASE : 0 ) | + ( hb_comp_bShortCuts ? HB_SM_SHORTCUTS : 0 ) | + ( hb_comp_Supported & HB_COMPFLAG_RT_MACRO ? HB_SM_RT_MACRO : 0 ) ); +#endif } diff --git a/harbour/include/hbpp.h b/harbour/include/hbpp.h index 6d6a3501b1..4abca76229 100644 --- a/harbour/include/hbpp.h +++ b/harbour/include/hbpp.h @@ -78,37 +78,37 @@ HB_EXTERN_BEGIN #define HB_PP_INLINE_QUOTE2 6 /* function to open included files */ -#define HB_PP_OPEN_FUNC_( func ) FILE * func( char *, BOOL, char * ) +#define HB_PP_OPEN_FUNC_( func ) FILE * func( void *, char *, BOOL, char * ) typedef HB_PP_OPEN_FUNC_( HB_PP_OPEN_FUNC ); typedef HB_PP_OPEN_FUNC * PHB_PP_OPEN_FUNC; /* function to close included files */ -#define HB_PP_CLOSE_FUNC_( func ) void func( FILE * ) +#define HB_PP_CLOSE_FUNC_( func ) void func( void *, FILE * ) typedef HB_PP_CLOSE_FUNC_( HB_PP_CLOSE_FUNC ); typedef HB_PP_CLOSE_FUNC * PHB_PP_CLOSE_FUNC; /* function to generate errors */ -#define HB_PP_ERROR_FUNC_( func ) void func( char **, char, int, const char *, const char * ) +#define HB_PP_ERROR_FUNC_( func ) void func( void *, char **, char, int, const char *, const char * ) typedef HB_PP_ERROR_FUNC_( HB_PP_ERROR_FUNC ); typedef HB_PP_ERROR_FUNC * PHB_PP_ERROR_FUNC; /* function to redirect stdout messages */ -#define HB_PP_DISP_FUNC_( func ) void func( const char * ) +#define HB_PP_DISP_FUNC_( func ) void func( void *, const char * ) typedef HB_PP_DISP_FUNC_( HB_PP_DISP_FUNC ); typedef HB_PP_DISP_FUNC * PHB_PP_DISP_FUNC; /* function for catching #pragma dump data */ -#define HB_PP_DUMP_FUNC_( func ) void func( char *, ULONG, int ) +#define HB_PP_DUMP_FUNC_( func ) void func( void *, char *, ULONG, int ) typedef HB_PP_DUMP_FUNC_( HB_PP_DUMP_FUNC ); typedef HB_PP_DUMP_FUNC * PHB_PP_DUMP_FUNC; /* function for catching #pragma dump data */ -#define HB_PP_INLINE_FUNC_( func ) void func( char *, char *, ULONG, int ) +#define HB_PP_INLINE_FUNC_( func ) void func( void *, char *, char *, ULONG, int ) typedef HB_PP_INLINE_FUNC_( HB_PP_INLINE_FUNC ); typedef HB_PP_INLINE_FUNC * PHB_PP_INLINE_FUNC; /* function for catching #pragma dump data */ -#define HB_PP_SWITCH_FUNC_( func ) BOOL func( const char *, int ) +#define HB_PP_SWITCH_FUNC_( func ) BOOL func( void *, const char *, int ) typedef HB_PP_SWITCH_FUNC_( HB_PP_SWITCH_FUNC ); typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC; @@ -193,60 +193,9 @@ typedef HB_PP_SWITCH_FUNC * PHB_PP_SWITCH_FUNC; #define HB_PP_TOKEN_DIV 83 #define HB_PP_TOKEN_MOD 84 #define HB_PP_TOKEN_POWER 85 +#define HB_PP_TOKEN_EPSILON 86 #define HB_PP_TOKEN_TYPE(t) ( (t) & 0xff ) - -typedef struct _HB_PP_TOKEN -{ - struct _HB_PP_TOKEN * pNext; /* next token pointer */ - struct _HB_PP_TOKEN * pMTokens; /* restrict or optional marker token(s) */ - - char * value; /* token value */ - USHORT len; /* token value length */ - USHORT spaces; /* leading spaces for stringify */ - USHORT type; /* token type, see HB_PP_TOKEN_* */ - USHORT index; /* index to match marker or 0 */ -} -HB_PP_TOKEN, * PHB_PP_TOKEN; - - -#ifdef _HB_PP_INTERNAL - -/* default maximum number of translations */ -#define HB_PP_MAX_CYCLES 4096 -/* maximum number of single token translations, in Clipper it's 18 + number - of used rules, we will use also constant but increased by total number - of rules of given type: define, [x]translate, [x]command */ -#define HB_PP_MAX_REPATS 128 - -/* Clipper allows only 16 nested includes */ -#define HB_PP_MAX_INCLUDED_FILES 64 - - -/* comparision modes */ -#define HB_PP_CMP_ADDR 0 /* compare token addresses */ -#define HB_PP_CMP_STD 1 /* standard comparison, ignore the case of the characters */ -#define HB_PP_CMP_DBASE 2 /* dbase keyword comparison (accepts at least four character shortcuts) ignore the case of the characters */ -#define HB_PP_CMP_CASE 3 /* case sensitive comparison */ - -#define HB_PP_CMP_MODE(t) ( (t) & 0xff ) -#define HB_PP_STD_RULE 0x8000 - - -/* conditional compilation */ -#define HB_PP_COND_ELSE 1 /* preprocessing and output stopped until corresponding #else */ -#define HB_PP_COND_DISABLE 2 /* preprocessing and output stopped until corresponding #endif(s) */ - -/* operation precedence for #if calculation */ -#define HB_PP_PREC_NUL 0 -#define HB_PP_PREC_NOT 1 -#define HB_PP_PREC_LOG 2 -#define HB_PP_PREC_REL 3 -#define HB_PP_PREC_BIT 4 -#define HB_PP_PREC_PLUS 5 -#define HB_PP_PREC_MULT 6 -#define HB_PP_PREC_NEG 7 - /* bitfields */ /* #define HB_PP_TOKEN_UNARY 0x0100 */ /* #define HB_PP_TOKEN_BINARY 0x0200 */ @@ -413,6 +362,58 @@ HB_PP_TOKEN, * PHB_PP_TOKEN; HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_DATE && \ HB_PP_TOKEN_TYPE(t) != HB_PP_TOKEN_LOGICAL ) #endif + +typedef struct _HB_PP_TOKEN +{ + struct _HB_PP_TOKEN * pNext; /* next token pointer */ + struct _HB_PP_TOKEN * pMTokens; /* restrict or optional marker token(s) */ + + char * value; /* token value */ + USHORT len; /* token value length */ + USHORT spaces; /* leading spaces for stringify */ + USHORT type; /* token type, see HB_PP_TOKEN_* */ + USHORT index; /* index to match marker or 0 */ +} +HB_PP_TOKEN, * PHB_PP_TOKEN; + + +#ifdef _HB_PP_INTERNAL + +/* default maximum number of translations */ +#define HB_PP_MAX_CYCLES 4096 +/* maximum number of single token translations, in Clipper it's 18 + number + of used rules, we will use also constant but increased by total number + of rules of given type: define, [x]translate, [x]command */ +#define HB_PP_MAX_REPATS 128 + +/* Clipper allows only 16 nested includes */ +#define HB_PP_MAX_INCLUDED_FILES 64 + + +/* comparision modes */ +#define HB_PP_CMP_ADDR 0 /* compare token addresses */ +#define HB_PP_CMP_STD 1 /* standard comparison, ignore the case of the characters */ +#define HB_PP_CMP_DBASE 2 /* dbase keyword comparison (accepts at least four character shortcuts) ignore the case of the characters */ +#define HB_PP_CMP_CASE 3 /* case sensitive comparison */ + +#define HB_PP_CMP_MODE(t) ( (t) & 0xff ) +#define HB_PP_STD_RULE 0x8000 + + +/* conditional compilation */ +#define HB_PP_COND_ELSE 1 /* preprocessing and output stopped until corresponding #else */ +#define HB_PP_COND_DISABLE 2 /* preprocessing and output stopped until corresponding #endif(s) */ + +/* operation precedence for #if calculation */ +#define HB_PP_PREC_NUL 0 +#define HB_PP_PREC_NOT 1 +#define HB_PP_PREC_LOG 2 +#define HB_PP_PREC_REL 3 +#define HB_PP_PREC_BIT 4 +#define HB_PP_PREC_PLUS 5 +#define HB_PP_PREC_MULT 6 +#define HB_PP_PREC_NEG 7 + /* For platforms which does not use ASCII based character tables this macros have to be changed to use valid C functions, f.e.: isalpha(), isdigit(), ... */ @@ -586,6 +587,7 @@ typedef struct PHB_PP_FILE pFile; /* currently preprocessed file structure */ int iFiles; /* number of open files */ + void * cargo; /* parameter passed to user functions */ PHB_PP_OPEN_FUNC pOpenFunc; /* function to open files */ PHB_PP_CLOSE_FUNC pCloseFunc; /* function to close files */ PHB_PP_ERROR_FUNC pErrorFunc; /* function to generate errors */ @@ -610,7 +612,7 @@ typedef void * PHB_PP_STATE; extern PHB_PP_STATE hb_pp_new( void ); extern void hb_pp_free( PHB_PP_STATE pState ); extern void hb_pp_reset( PHB_PP_STATE pState ); -extern void hb_pp_init( PHB_PP_STATE pState, BOOL fQuiet, +extern void hb_pp_init( PHB_PP_STATE pState, BOOL fQuiet, void * cargo, PHB_PP_OPEN_FUNC pOpenFunc, PHB_PP_CLOSE_FUNC pCloseFunc, PHB_PP_ERROR_FUNC pErrorFunc, PHB_PP_DISP_FUNC pDispFunc, PHB_PP_DUMP_FUNC pDumpFunc, PHB_PP_INLINE_FUNC pInLineFunc, @@ -621,8 +623,8 @@ extern void hb_pp_setStdRules( PHB_PP_STATE pState ); extern void hb_pp_setStdBase( PHB_PP_STATE pState ); extern void hb_pp_setStream( PHB_PP_STATE pState, int iMode ); extern void hb_pp_addSearchPath( PHB_PP_STATE pState, const char * szPath, BOOL fReplace ); -extern void hb_pp_inFile( PHB_PP_STATE pState, char * szFileName, FILE * file_in ); -extern void hb_pp_outFile( PHB_PP_STATE pState, char * szOutFileName, FILE * file_out ); +extern BOOL hb_pp_inFile( PHB_PP_STATE pState, char * szFileName, BOOL fSearchPath, FILE * file_in, BOOL fError ); +extern BOOL hb_pp_outFile( PHB_PP_STATE pState, char * szOutFileName, FILE * file_out ); extern char * hb_pp_fileName( PHB_PP_STATE pState ); extern int hb_pp_line( PHB_PP_STATE pState ); extern char * hb_pp_outFileName( PHB_PP_STATE pState ); @@ -630,10 +632,15 @@ extern char * hb_pp_nextLine( PHB_PP_STATE pState, ULONG * pulLen ); extern char * hb_pp_parseLine( PHB_PP_STATE pState, char * pLine, ULONG * pulLen ); extern void hb_pp_addDefine( PHB_PP_STATE pState, char * szDefName, char * szDefValue ); extern void hb_pp_delDefine( PHB_PP_STATE pState, char * szDefName ); +extern BOOL hb_pp_lasterror( PHB_PP_STATE pState ); +extern BOOL hb_pp_eof( PHB_PP_STATE pState ); extern void hb_pp_tokenUpper( PHB_PP_TOKEN pToken ); +extern void hb_pp_tokenToString( PHB_PP_STATE pState, PHB_PP_TOKEN pToken ); +extern char * hb_pp_tokenBlockString( PHB_PP_STATE pState, PHB_PP_TOKEN pToken, int *piType ); extern PHB_PP_STATE hb_pp_lexNew( char * pString, ULONG ulLen ); -extern PHB_PP_TOKEN hb_pp_lex( PHB_PP_STATE pState ); +extern PHB_PP_TOKEN hb_pp_lexGet( PHB_PP_STATE pState ); +extern PHB_PP_TOKEN hb_pp_tokenGet( PHB_PP_STATE pState ); HB_EXTERN_END diff --git a/harbour/makefile.bc b/harbour/makefile.bc index 131147161c..2cfcc1b2a2 100644 --- a/harbour/makefile.bc +++ b/harbour/makefile.bc @@ -629,10 +629,10 @@ $(PP_DIR)\pptable.c : $(BIN_DIR)\ppgen.exe include\hbstdgen.ch #********************************************************** $(OBJ_DIR)\macroy.c : $(MACRO_DIR)\macro.y - bison --no-line -p hb_comp -d $** -o$@ + bison --no-line -p hb_macro -d $** -o$@ $(OBJ_DIR)\macrol.c : $(MACRO_DIR)\macro.l - flex -Phb_comp -i -8 -o$@ $** + flex -Phb_macro -i -8 -o$@ $** $(OBJ_DIR)\macroy.obj : $(OBJ_DIR)\macroy.c $(OBJ_DIR)\macrol.obj : $(OBJ_DIR)\macrol.c @@ -657,10 +657,10 @@ $(OBJ_DIR)\harbourl.obj : $(OBJ_DIR)\harbourl.c #********************************************************** $(DLL_OBJ_DIR)\macroy.c : $(MACRO_DIR)\macro.y - bison --no-line -p hb_comp -d $** -o$@ + bison --no-line -p hb_macro -d $** -o$@ $(DLL_OBJ_DIR)\macrol.c : $(MACRO_DIR)\macro.l - flex -Phb_comp -i -8 -o$@ $** + flex -Phb_macro -i -8 -o$@ $** $(DLL_OBJ_DIR)\macroy.obj : $(DLL_OBJ_DIR)\macroy.c $(DLL_OBJ_DIR)\macrol.obj : $(DLL_OBJ_DIR)\macrol.c diff --git a/harbour/makefile.vc b/harbour/makefile.vc index 146cd26dd4..0e15cae27e 100644 --- a/harbour/makefile.vc +++ b/harbour/makefile.vc @@ -964,10 +964,10 @@ $(PP_DIR)\pptable.c : $(BIN_DIR)\ppgen.exe include\hbstdgen.ch #********************************************************** $(OBJ_DIR)\macroy.c : $(MACRO_DIR)\macro.y - bison --no-line -p hb_comp -d $** -o$@ + bison --no-line -p hb_macro -d $** -o$@ $(OBJ_DIR)\macrol.c : $(MACRO_DIR)\macro.l - flex -Phb_comp -i -8 -o$@ $** + flex -Phb_macro -i -8 -o$@ $** $(OBJ_DIR)\macroy.obj : $(OBJ_DIR)\macroy.c $(OBJ_DIR)\macrol.obj : $(OBJ_DIR)\macrol.c @@ -992,10 +992,10 @@ $(OBJ_DIR)\harbourl.obj : $(OBJ_DIR)\harbourl.c #********************************************************** $(DLL_OBJ_DIR)\macroy.c : $(MACRO_DIR)\macro.y - bison --no-line -p hb_comp -d $** -o$@ + bison --no-line -p hb_macro -d $** -o$@ $(DLL_OBJ_DIR)\macrol.c : $(MACRO_DIR)\macro.l - flex -Phb_comp -i -8 -o$@ $** + flex -Phb_macro -i -8 -o$@ $** $(DLL_OBJ_DIR)\macroy.obj : $(DLL_OBJ_DIR)\macroy.c $(DLL_OBJ_DIR)\macrol.obj : $(DLL_OBJ_DIR)\macrol.c diff --git a/harbour/source/compiler/Makefile b/harbour/source/compiler/Makefile index 5a2df74905..fc4c8c72b6 100644 --- a/harbour/source/compiler/Makefile +++ b/harbour/source/compiler/Makefile @@ -28,7 +28,8 @@ C_EXTRA=hbslex.c else -LEX_SOURCE=harbour.l +#LEX_SOURCE=harbour.l +C_EXTRA=complex.c LEX_HEADERS=\ hbsetup.h \ @@ -38,29 +39,31 @@ endif C_SOURCES=\ cmdcheck.c \ - genc.c \ - gencc.c \ - gencobj.c \ - genhrb.c \ - genjava.c \ + genc.c \ + gencc.c \ + gencobj.c \ + genhrb.c \ + genjava.c \ genobj32.c \ gencli.c \ + hbcomp.c \ hbfunchk.c \ hbgenerr.c \ - hbpcode.c \ - hbfix.c \ - hbdead.c \ - hblbl.c \ + hbpcode.c \ + hbfix.c \ + hbdead.c \ + hblbl.c \ hbstripl.c \ hbstrong.c \ - hbusage.c \ - hbident.c \ - ppcomp.c \ + hbusage.c \ + hbident.c \ + ppcomp.c \ expropta.c \ exproptb.c \ exproptc.c \ $(C_EXTRA) + C_MAIN=harbour.c LIBS=\ diff --git a/harbour/source/compiler/cmdcheck.c b/harbour/source/compiler/cmdcheck.c index e02030fef2..baee064de0 100644 --- a/harbour/source/compiler/cmdcheck.c +++ b/harbour/source/compiler/cmdcheck.c @@ -648,7 +648,7 @@ void hb_compChkEnvironVar( char *szSwitch ) */ case 'i': case 'I': - hb_fsAddSearchPath( s + 1, &hb_comp_pIncludePath ); + hb_pp_addSearchPath( hb_comp_data->pLex->pPP, s + 1, FALSE ); break; case 'k': @@ -899,7 +899,7 @@ void hb_compChkPaths( void ) if( szInclude ) { if( szInclude[0] != '\0' ) - hb_fsAddSearchPath( szInclude, &hb_comp_pIncludePath ); + hb_pp_addSearchPath( hb_comp_data->pLex->pPP, szInclude, FALSE ); hb_xfree( ( void * ) szInclude ); } } @@ -910,7 +910,7 @@ static void hb_compChkDefineSwitch( char *pszSwitch ) { if( pszSwitch[1] == 'd' || pszSwitch[1] == 'D' ) { - char *szDefText = hb_strdup( pszSwitch + 2 ), *pAssign, *szDefLine; + char *szDefText = hb_strdup( pszSwitch + 2 ), *pAssign; unsigned int i = 0; while( i < strlen( szDefText ) && !HB_ISOPTSEP( szDefText[i] ) ) @@ -919,22 +919,11 @@ static void hb_compChkDefineSwitch( char *pszSwitch ) szDefText[i] = '\0'; if( szDefText ) { - if( ( pAssign = strchr( szDefText, '=' ) ) == NULL ) - { - hb_pp_AddDefine( szDefText, 0 ); - } - else - { - szDefText[pAssign - szDefText] = '\0'; - - /* hb_pp_AddDefine( szDefText, pAssign + 1 ); */ - szDefLine = ( char * ) hb_xgrab( strlen( szDefText ) + strlen( pAssign + 1 ) + 10 ); - sprintf( szDefLine, "#define %s %s", szDefText, pAssign + 1 ); - hb_pp_ParseDirective( szDefLine ); - hb_xfree( szDefLine ); - } + pAssign = strchr( szDefText, '=' ); + if( pAssign ) + *pAssign++ = '\0'; + hb_pp_addDefine( hb_comp_data->pLex->pPP, szDefText, pAssign ); } - hb_xfree( szDefText ); } else if( pszSwitch[1] && toupper( pszSwitch[1] ) == 'U' && @@ -945,23 +934,16 @@ static void hb_compChkDefineSwitch( char *pszSwitch ) pszSwitch[6] == ':' ) { char *szDefText = hb_strdup( pszSwitch + 7 ); - char *szDefLine; unsigned int i = 0; while( szDefText[i] && !HB_ISOPTSEP( szDefText[i] ) ) { i++; } - szDefText[i] = '\0'; if( szDefText[0] ) - { - szDefLine = ( char * ) hb_xgrab( 7 + strlen( szDefText ) + 1 ); - sprintf( szDefLine, "#undef %s", szDefText ); - hb_pp_ParseDirective( szDefLine ); - hb_xfree( szDefLine ); - } + hb_pp_delDefine( hb_comp_data->pLex->pPP, szDefText ); hb_xfree( szDefText ); } } diff --git a/harbour/source/compiler/complex.c b/harbour/source/compiler/complex.c new file mode 100644 index 0000000000..9d395c3528 --- /dev/null +++ b/harbour/source/compiler/complex.c @@ -0,0 +1,1020 @@ +#include "hbpp.h" +#include "hbcomp.h" +#include "hbdate.h" +#include "harboury.h" + +/* + keywords: + ANNO[UNCE] -> ANNOUNCE + BEGI[N] SEQU[ENCE]-> BEGINSEQ + BREA[K] -> BREAK + CASE -> CASE + _PROCREQ_( -> PROCREQ + DECL[ARE] -> DECLARE, PRIVATE, IDENTIFIER + OPTI[ONAL] -> OPTIONAL + DO -> DO + DO CASE -> DOCASE + DO WHILE -> WHILE + DESCEND -> DESCEND + ELSE -> ELSE + ELSEI[F] -> ELSEIF + END SEQU[ENCE] -> END + ENDI[F] -> ENDIF + ENDC[ASE] -> ENDCASE + ENDD[O] -> ENDDO + END -> END + EXIT -> EXIT + EXTE[RNAL] -> EXTERN + _FIE[LD] -> FIELD + FIEL[D] -> FIELD + FOR -> FOR + FOR EACH -> FOREACH + FUNC[TION] -> FUNCTION + HB_INLINE -> ??? + IIF -> IIF + IF -> IF, IIF + IN -> IN + INIT -> INIT + LOOP -> LOOP + MEMV[AR] -> MEMVAR + NEXT -> NEXT + NIL -> NIL + OTHE[RWISE] -> OTHERWISE + PARA[METERS] -> PARAMETERS + PRIV[ATE] -> PRIVATE + PROC[EDURE] -> PROCEDURE + PUBL[IC] -> PUBLIC + QSELF() -> SELF + RECO[VER] -> RECOVER + RECO[VER] USIN[G] -> RECOVERUSING + RETU[RN] -> RETURN + STAT[IC] -> STATIC + STEP -> STEP + SWITCH -> DOSWITCH + TO -> TO + WHILE -> WHILE + WITH -> WITH + WITH OBJECT -> WITHOBJECT + AS ARRA[Y] -> AS_ARRAY + AS CODE[BLOCK] -> AS_BLOCK + AS STRI[NG] -> AS_CHARACTER + AS CHAR[ACTER] -> AS_CHARACTER + AS CLAS[S] -> AS_CLASS + AS DATE -> AS_DATE + AS LOGI[CAL] -> AS_LOGICAL + AS NUME[RIC] -> AS_NUMERIC + AS OBJE[CT] -> AS_OBJECT + AS USUA[L] -> AS_VARIANT + AS ANYT[YPE] -> AS_VARIANT + AS ARRA[Y] OF USUA[L] -> AS_ARRAY + AS ARRA[Y] OF ANYT[YPE] -> AS_ARRAY + AS ARRA[Y] OF ARRA[Y] -> AS_ARRAY_ARRAY + AS ARRA[Y] OF CODE[BLOCK] -> AS_BLOCK_ARRAY + AS ARRA[Y] OF STRI[NG] -> AS_CHARACTER_ARRAY + AS ARRA[Y] OF CHAR[ACTER] -> AS_CHARACTER_ARRAY + AS ARRA[Y] OF CLAS[S] -> AS_CLASS_ARRAY + AS ARRA[Y] OF DATE -> AS_DATE_ARRAY + AS ARRA[Y] OF LOGI[CAL] -> AS_LOGICAL_ARRAY + AS ARRA[Y] OF NUME[RIC] -> AS_NUMERIC_ARRAY + AS ARRA[Y] OF OBJE[CT] -> AS_OBJECT_ARRAY + _HB_CLASS -> DECLARE_CLASS + _HB_MEMBER -> DECLARE_MEMBER + + + iState usage: + '[': OPERATOR, LSEPARATOR, LARRAY, IF, ELSEIF, CASE, BREAK, + RETURN, WITH, WHILE + break: LOOKUP + case: LOOKUP + declare: DO + do: LOOKUP + end: LOOKUP + field: LOOKUP + for: LOOKUP + iif: FUNCTION, PROCEDURE + if: FUNCTION, PROCEDURE, LOOKUP + init: LOOKUP + next: LOOKUP + otherwise: LOOKUP + recover: LOOKUP + return: LOOKUP + switch: LOOKUP + while: DO, LOOKUP + whith: LOOKUP, DO, WHILE, MACROVAR, MACROTEXT, IDENTIFIER, + RSEPARATOR + +*/ + +#define HB_PP_LEX_SELF(t) ( HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_SEND && \ + (t)->pNext && t->pNext->spaces == 0 && \ + HB_PP_TOKEN_TYPE((t)->pNext->type) == HB_PP_TOKEN_SEND ) + +#define HB_PP_LEX_NEEDLEFT(t) ( HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_ASSIGN || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_PLUSEQ || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MINUSEQ || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MULTEQ || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_DIVEQ || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MODEQ || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EXPEQ || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EQUAL || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_EQ || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_ALIAS || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MULT || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_DIV || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_MOD || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_POWER || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_IN || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_AND || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_OR || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_PIPE || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_RIGHT_PB || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_RIGHT_SB || \ + HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_RIGHT_CB || \ + ( HB_PP_TOKEN_TYPE((t)->type) == HB_PP_TOKEN_SEND && \ + !HB_PP_LEX_SELF(t) ) ) + +#define LOOKUP 0 +#define OPERATOR -2 +#define LSEPARATOR -3 +#define RSEPARATOR -4 +#define LINDEX -5 +#define RINDEX -6 +#define LARRAY -7 +#define RARRAY -8 +#define AS_TYPE -9 + + +typedef struct +{ + char * value; /* keyword name */ + int minlen; /* minimal length */ + int maxlen; /* maximal length */ + int type; /* terminal symbol code */ +} +HB_LEX_KEY, * PHB_LEX_KEY; + +static const HB_LEX_KEY s_keytable[] = +{ + { "ANNOUNCE", 4, 8, ANNOUNCE }, + { "BEGIN", 4, 5, BEGINSEQ }, + { "BREAK", 4, 5, BREAK }, + { "CASE", 4, 4, CASE }, + { "DECLARE", 4, 7, DECLARE }, + { "OPTIONAL", 4, 8, OPTIONAL }, + { "DO", 2, 2, DO }, + { "DESCEND", 7, 7, DESCEND }, + { "ELSE", 4, 4, ELSE }, + { "ELSEIF", 5, 6, ELSEIF }, + { "END", 3, 3, END }, + { "ENDIF", 4, 5, ENDIF }, + { "ENDCASE", 4, 7, ENDCASE }, + { "ENDDO", 4, 5, ENDDO }, + { "EXIT", 4, 4, EXIT }, + { "EXTERNAL", 4, 8, EXTERN }, + { "_FIELD", 4, 6, FIELD }, + { "FIELD", 4, 5, FIELD }, + { "FOR", 3, 3, FOR }, + { "FUNCTION", 4, 8, FUNCTION }, + { "IIF", 3, 3, IIF }, + { "IF", 2, 2, IF }, + { "IN", 2, 2, IN }, + { "INIT", 4, 4, INIT }, + { "LOCAL", 4, 5, LOCAL }, + { "LOOP", 4, 4, LOOP }, + { "MEMVAR", 4, 6, MEMVAR }, + { "NEXT", 4, 4, NEXT }, + { "NIL", 3, 3, NIL }, + { "OTHERWISE", 4, 9, OTHERWISE }, + { "PARAMETERS", 4, 10, PARAMETERS }, + { "PRIVATE", 4, 7, PRIVATE }, + { "PROCEDURE", 4, 9, PROCEDURE }, + { "PUBLIC", 4, 6, PUBLIC }, + { "QSELF", 4, 5, SELF }, + { "_PROCREQ_", 4, 9, PROCREQ }, + { "RECOVER", 4, 7, RECOVER }, + { "RETURN", 4, 6, RETURN }, + { "STATIC", 4, 6, STATIC }, + { "STEP", 4, 4, STEP }, + { "SWITCH", 4, 6, DOSWITCH }, + { "TO", 2, 2, TO }, + { "WHILE", 4, 5, WHILE }, + { "WITH", 4, 4, WITH }, + { "AS", 2, 2, AS_TYPE }, + { "_HB_CLASS", 9, 9, DECLARE_CLASS }, + { "_HB_MEMBER", 10, 10, DECLARE_MEMBER } +}; + +#define _AS_ARRAY 1 +#define _AS_BLOCK 2 +#define _AS_CHARACTER 3 +#define _AS_CLASS 4 +#define _AS_DATE 5 +#define _AS_LOGICAL 6 +#define _AS_NUMERIC 7 +#define _AS_OBJECT 8 +#define _AS_VARIANT 9 + +static const int s_asTypes[] = +{ + 0, + AS_ARRAY, + AS_BLOCK, + AS_CHARACTER, + AS_CLASS, + AS_DATE, + AS_LOGICAL, + AS_NUMERIC, + AS_OBJECT, + AS_VARIANT +}; + +static const int s_asArrayTypes[] = +{ + 0, + AS_ARRAY_ARRAY, + AS_BLOCK_ARRAY, + AS_CHARACTER_ARRAY, + AS_CLASS_ARRAY, + AS_DATE_ARRAY, + AS_LOGICAL_ARRAY, + AS_NUMERIC_ARRAY, + AS_OBJECT_ARRAY, + AS_ARRAY +}; + +static const HB_LEX_KEY s_typetable[] = +{ + { "ARRAY", 4, 5, _AS_ARRAY }, + { "CODEBLOCK", 4, 9, _AS_BLOCK }, + { "STRING", 4, 6, _AS_CHARACTER }, + { "CHARACTER", 4, 9, _AS_CHARACTER }, + { "CLASS", 4, 5, _AS_CLASS }, + { "DATE", 4, 4, _AS_DATE }, + { "LOGICAL", 4, 7, _AS_LOGICAL }, + { "NUMERIC", 4, 7, _AS_NUMERIC }, + { "OBJECT", 4, 6, _AS_OBJECT }, + { "USUAL", 4, 5, _AS_VARIANT }, + { "ANYTYPE", 4, 7, _AS_VARIANT } +}; + +static int hb_comp_asType( PHB_PP_TOKEN pToken, BOOL fArray ) +{ + if( pToken && HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_KEYWORD ) + { + PHB_LEX_KEY pKey = ( PHB_LEX_KEY ) s_typetable; + int i = sizeof( s_typetable ) / sizeof( HB_LEX_KEY ); + + hb_pp_tokenUpper( pToken ); + do + { + if( pKey->minlen <= pToken->len && pToken->len <= pKey->maxlen && + memcmp( pKey->value, pToken->value, pToken->len ) == 0 ) + return ( fArray ? s_asArrayTypes : s_asTypes ) [ pKey->type ]; + ++pKey; + } + while( --i ); + } + return 0; +} + +static int hb_comp_keywordType( PHB_PP_TOKEN pToken ) +{ + PHB_LEX_KEY pKey = ( PHB_LEX_KEY ) s_keytable; + int i = sizeof( s_keytable ) / sizeof( HB_LEX_KEY ); + + do + { + if( pKey->minlen <= pToken->len && pToken->len <= pKey->maxlen && + memcmp( pKey->value, pToken->value, pToken->len ) == 0 ) + { + if( HB_PP_TOKEN_ALLOC( pToken->type ) && pToken->len == pKey->maxlen ) + { + hb_xfree( pToken->value ); + pToken->value = pKey->value; + pToken->type |= HB_PP_TOKEN_STATIC; + } + return pKey->type; + } + ++pKey; + } + while( --i ); + return IDENTIFIER; +} + +static char * hb_comp_tokenIdentifer( PHB_PP_TOKEN pToken ) +{ + if( HB_PP_TOKEN_ALLOC( pToken->type ) ) + { + pToken->value = hb_compIdentifierNew( pToken->value, FALSE ); + pToken->type |= HB_PP_TOKEN_STATIC; + } + + return pToken->value; +} + +//int hb_complex( YYSTYPE *yylval_ptr, HB_COMP_PTR pComp ) +int yylex( YYSTYPE *yylval_ptr, HB_COMP_PTR pComp ) +{ + PHB_COMP_LEX pLex = ( PHB_COMP_LEX ) pComp->pLex; + PHB_PP_TOKEN pToken = hb_pp_tokenGet( pLex->pPP ); + + if( !pToken ) + return 0; + + pLex->lasttok = pToken->value; + + switch( HB_PP_TOKEN_TYPE( pToken->type ) ) + { + case HB_PP_TOKEN_NUMBER: + { + HB_LONG lNumber; + double dNumber; + int iDec, iWidth; + + pLex->iState = LITERAL; + if( hb_compStrToNum( pToken->value, pToken->len, &lNumber, &dNumber, &iDec, &iWidth ) ) + { + yylval_ptr->valDouble.dNumber = dNumber; + yylval_ptr->valDouble.bDec = ( UCHAR ) iDec; + yylval_ptr->valDouble.bWidth = ( UCHAR ) iWidth; + return NUM_DOUBLE; + } + else + { + yylval_ptr->valLong.lNumber = lNumber; + yylval_ptr->valLong.bWidth = ( UCHAR ) iWidth; + return NUM_LONG; + } + } + case HB_PP_TOKEN_DATE: + pLex->iState = LITERAL; + if( pToken->len == 10 ) + { + int year, month, day; + hb_dateStrGet( pToken->value + 2, &year, &month, &day ); + yylval_ptr->valLong.lNumber = hb_dateEncode( year, month, day ); + } + else + yylval_ptr->valLong.lNumber = 0; + return NUM_DATE; + + case HB_PP_TOKEN_STRING: + pLex->iState = LITERAL; + pLex->lasttok = yylval_ptr->string = hb_comp_tokenIdentifer( pToken ); + return LITERAL; + + case HB_PP_TOKEN_LOGICAL: + pLex->iState = LITERAL; + return pToken->value[ 1 ] == 'T' ? TRUEVALUE : FALSEVALUE; + + case HB_PP_TOKEN_MACROVAR: + pLex->iState = MACROVAR; + hb_pp_tokenUpper( pToken ); + pLex->lasttok = yylval_ptr->string = hb_comp_tokenIdentifer( pToken ); + return MACROVAR; + + case HB_PP_TOKEN_MACROTEXT: + pLex->iState = MACROTEXT; + hb_pp_tokenUpper( pToken ); + pLex->lasttok = yylval_ptr->string = hb_comp_tokenIdentifer( pToken ); + return MACROTEXT; + + case HB_PP_TOKEN_LEFT_SB: + switch( pLex->iState ) + { + case OPERATOR: + case LSEPARATOR: + case LARRAY: + case IF: + case ELSEIF: + case CASE: + case BREAK: + case RETURN: + case WITH: + case WHILE: + pLex->iState = LITERAL; + hb_pp_tokenToString( pLex->pPP, pToken ); + pLex->lasttok = yylval_ptr->string = hb_comp_tokenIdentifer( pToken ); + return LITERAL; + + default: + pLex->iState = LINDEX; + return '['; + } + + case HB_PP_TOKEN_RIGHT_SB: + pLex->iState = RINDEX; + return ']'; + + case HB_PP_TOKEN_LEFT_CB: + if( pToken->pNext && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_PIPE ) + { + int iType = 0; + yylval_ptr->asCodeblock.string = + hb_strdup( hb_pp_tokenBlockString( pLex->pPP, pToken, &iType ) ); + yylval_ptr->asCodeblock.length = + strlen( yylval_ptr->asCodeblock.string ); + yylval_ptr->asCodeblock.isMacro = iType > 0; + yylval_ptr->asCodeblock.lateEval = iType > 1; + hb_pp_tokenGet( pLex->pPP ); + return CBSTART; + } + pLex->iState = LARRAY; + return '{'; + + case HB_PP_TOKEN_RIGHT_CB: + pLex->iState = RARRAY; + return '}'; + + case HB_PP_TOKEN_LEFT_PB: + pLex->iState = LSEPARATOR; + return '('; + + case HB_PP_TOKEN_RIGHT_PB: + pLex->iState = RSEPARATOR; + return ')'; + + case HB_PP_TOKEN_EPSILON: + pLex->iState = OPERATOR; + return EPSILON; + + case HB_PP_TOKEN_HASH: + case HB_PP_TOKEN_DIRECTIVE: + if( pLex->iState == LOOKUP && pToken->pNext && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && + hb_stricmp( "LINE", pToken->pNext->value ) == 0 ) + { + hb_pp_tokenGet( pLex->pPP ); + return LINE; + } + pLex->iState = OPERATOR; + return NE1; + + case HB_PP_TOKEN_NE: + pLex->iState = OPERATOR; + return NE2; + + case HB_PP_TOKEN_ASSIGN: + pLex->iState = OPERATOR; + return INASSIGN; + + case HB_PP_TOKEN_EQUAL: + pLex->iState = OPERATOR; + return EQ; + + case HB_PP_TOKEN_INC: + pLex->iState = OPERATOR; + return INC; + + case HB_PP_TOKEN_DEC: + pLex->iState = OPERATOR; + return DEC; + + case HB_PP_TOKEN_ALIAS: + pLex->iState = OPERATOR; + return ALIASOP; + + case HB_PP_TOKEN_LE: + pLex->iState = OPERATOR; + return LE; + + case HB_PP_TOKEN_GE: + pLex->iState = OPERATOR; + return GE; + + case HB_PP_TOKEN_PLUSEQ: + pLex->iState = OPERATOR; + return PLUSEQ; + + case HB_PP_TOKEN_MINUSEQ: + pLex->iState = OPERATOR; + return MINUSEQ; + + case HB_PP_TOKEN_MULTEQ: + pLex->iState = OPERATOR; + return MULTEQ; + + case HB_PP_TOKEN_DIVEQ: + pLex->iState = OPERATOR; + return DIVEQ; + + case HB_PP_TOKEN_MODEQ: + pLex->iState = OPERATOR; + return MODEQ; + + case HB_PP_TOKEN_EXPEQ: + pLex->iState = OPERATOR; + return EXPEQ; + + case HB_PP_TOKEN_POWER: + pLex->iState = OPERATOR; + return POWER; + + case HB_PP_TOKEN_AND: + pLex->iState = OPERATOR; + return AND; + + case HB_PP_TOKEN_OR: + pLex->iState = OPERATOR; + return OR; + + case HB_PP_TOKEN_NOT: + pLex->iState = OPERATOR; + return NOT; + + case HB_PP_TOKEN_SEND: + if( HB_PP_LEX_SELF( pToken ) ) + { + pLex->lasttok = yylval_ptr->string = "SELF"; + return IDENTIFIER; + } + /* no break */ + case HB_PP_TOKEN_EQ: + case HB_PP_TOKEN_PLUS: + case HB_PP_TOKEN_MINUS: + case HB_PP_TOKEN_MULT: + case HB_PP_TOKEN_DIV: + case HB_PP_TOKEN_MOD: + case HB_PP_TOKEN_IN: + case HB_PP_TOKEN_COMMA: + case HB_PP_TOKEN_PIPE: + case HB_PP_TOKEN_AMPERSAND: + case HB_PP_TOKEN_DOT: + case HB_PP_TOKEN_LT: + case HB_PP_TOKEN_GT: + case HB_PP_TOKEN_REFERENCE: + pLex->iState = OPERATOR; + return pToken->value[ 0 ]; + + case HB_PP_TOKEN_EOL: + case HB_PP_TOKEN_EOC: + pLex->iState = LOOKUP; + return pToken->value[ 0 ]; + + case HB_PP_TOKEN_KEYWORD: + { + int iType; + hb_pp_tokenUpper( pToken ); + iType = hb_comp_keywordType( pToken ); + pLex->lasttok = yylval_ptr->string = hb_comp_tokenIdentifer( pToken ); + switch( iType ) + { + case FUNCTION: + case PROCEDURE: + /* Clipper needs PROCEDURE in one context only */ + if( !pToken->pNext || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) != HB_PP_TOKEN_KEYWORD ) + hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_SYNTAX, + pToken->value, NULL ); + pLex->iState = iType; + return pLex->iState; + + case BEGINSEQ: + if( pLex->iState == LOOKUP && pToken->pNext && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && + pToken->pNext->len >= 4 && pToken->pNext->len <= 8 && + hb_strnicmp( "SEQUENCE", pToken->pNext->value, pToken->pNext->len ) == 0 ) + { + hb_pp_tokenGet( pLex->pPP ); + break; + } + iType = IDENTIFIER; + break; + + case RECOVER: + if( pLex->iState == LOOKUP ) + { + if( HB_PP_TOKEN_ISEOC( pToken->pNext ) ) + { + pLex->iState = RECOVER; + return RECOVER; + } + else if( pToken->pNext && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && + pToken->pNext->len >= 4 && pToken->pNext->len <= 5 && + hb_strnicmp( "USING", pToken->pNext->value, pToken->pNext->len ) == 0 ) + { + hb_pp_tokenGet( pLex->pPP ); + pLex->iState = RECOVERUSING; + return RECOVERUSING; + } + } + iType = IDENTIFIER; + break; + + case END: + if( pLex->iState == LOOKUP ) + { + if( pToken->pNext && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && + pToken->pNext->len >= 4 && pToken->pNext->len <= 8 && + hb_strnicmp( "SEQUENCE", pToken->pNext->value, pToken->pNext->len ) == 0 ) + { + if( hb_comp_wSeqCounter == 0 ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_ENDIF, NULL, NULL ); + hb_pp_tokenGet( pLex->pPP ); + pLex->iState = END; + return END; + } + else if( HB_PP_TOKEN_ISEOC( pToken->pNext ) || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == + HB_PP_TOKEN_KEYWORD ) + { + pLex->iState = END; + return END; + } + /* Clipper does not like end[], end(), end->, end-- & end++ at + the begining of line */ + if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_SB || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_INC || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_DEC || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_ALIAS ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_ENDIF, NULL, NULL ); + } + iType = IDENTIFIER; + break; + + case ELSE: + /* ELSE can be used in one context only */ + if( hb_comp_wIfCounter == 0 ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_UNMATCHED_ELSE, NULL, NULL ); + pLex->iState = ELSE; + return ELSE; + + case ELSEIF: + /* ELSEIF can be used in one context only */ + if( hb_comp_wIfCounter == 0 ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_UNMATCHED_ELSEIF, NULL, NULL ); + pLex->iState = ELSEIF; + return ELSEIF; + + case ENDIF: + /* ENDIF can be used in one context only */ + if( hb_comp_wIfCounter == 0 ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_ENDIF, NULL, NULL ); + break; + + case ENDCASE: + /* ENDCASE can be used in one context only */ + if( hb_comp_wCaseCounter == 0 ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_ENDCASE, NULL, NULL ); + break; + + case ENDDO: + /* ENDDO can be used in one context only */ + if( hb_comp_wWhileCounter == 0 ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_ENDDO, NULL, NULL ); + break; + + case INIT: + if( pLex->iState == LOOKUP && pToken->pNext && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && + pToken->pNext->len >= 4 && + ( hb_strnicmp( "FUNCTION", pToken->pNext->value, + pToken->pNext->len ) == 0 || + hb_strnicmp( "PROCEDURE", pToken->pNext->value, + pToken->pNext->len ) == 0 ) ) + { + pLex->iState = INIT; + return INIT; + } + iType = IDENTIFIER; + break; + + case FIELD: + if( pToken->pNext && + ( ( pLex->iState == LOOKUP && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD ) || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_ALIAS ) ) + { + pLex->iState = FIELD; + return FIELD; + } + iType = IDENTIFIER; + break; + + case BREAK: + /* NOTE: Clipper does not like break[] in any context + * There are no resons to limit this use in Harbour. + */ + if( pLex->iState == LOOKUP && + ( HB_PP_TOKEN_ISEOC( pToken->pNext ) || + !( HB_PP_LEX_NEEDLEFT( pToken->pNext ) || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == + HB_PP_TOKEN_LEFT_PB ) ) ) + { + pLex->iState = BREAK; + return BREAK; + } + iType = IDENTIFIER; + break; + + case CASE: + case OTHERWISE: + if( pLex->iState == LOOKUP && + ( HB_PP_TOKEN_ISEOC( pToken->pNext ) || + ( iType == CASE && !HB_PP_LEX_NEEDLEFT( pToken->pNext ) ) ) ) + { + if( hb_comp_wCaseCounter == 0 && hb_comp_wSwitchCounter == 0 ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_CASE, NULL, NULL ); + pLex->iState = iType; + return iType; + } + iType = IDENTIFIER; + break; + + case FOR: + if( pLex->iState == LOOKUP && + !HB_PP_TOKEN_ISEOC( pToken->pNext ) && + ( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD || + /* Clipper always assume FOR (somevar):=1 TO ... here */ + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB ) ) + { + if( pToken->pNext->pNext && + HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) != HB_PP_TOKEN_ASSIGN && + HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) != HB_PP_TOKEN_EQ && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && + hb_stricmp( "EACH", pToken->pNext->value ) == 0 ) + { + hb_pp_tokenGet( pLex->pPP ); + pLex->iState = FOREACH; + return FOREACH; + } + pLex->iState = FOR; + return FOR; + } + iType = IDENTIFIER; + break; + + case NEXT: + if( pLex->iState == LOOKUP ) + { + if( HB_PP_TOKEN_ISEOC( pToken->pNext ) || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD ) + { + if( hb_comp_wForCounter == 0 ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_NEXTFOR, NULL, NULL ); + pLex->iState = iType; + return iType; + } + /* Clipper does not like NEXT[], NEXT(), NEXT->, + NEXT++ & NEXT-- at the begining of line */ + if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_SB || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_INC || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_DEC || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_ALIAS ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_NEXTFOR, NULL, NULL ); + } + iType = IDENTIFIER; + break; + + case RETURN: + case DOSWITCH: + if( pLex->iState == LOOKUP && + ( HB_PP_TOKEN_ISEOC( pToken->pNext ) || + !HB_PP_LEX_NEEDLEFT( pToken->pNext ) ) ) + { + pLex->iState = iType; + return iType; + } + iType = IDENTIFIER; + break; + + case DECLARE: + if( pLex->iState == LOOKUP ) + { + if( !HB_PP_TOKEN_ISEOC( pToken->pNext ) && + ( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_MACROVAR || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_MACROTEXT || + ( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && + ( HB_PP_TOKEN_ISEOC( pToken->pNext->pNext ) || + HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) == HB_PP_TOKEN_LEFT_SB || + HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) == HB_PP_TOKEN_COMMA || + HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) == HB_PP_TOKEN_SEND || + ( HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) == HB_PP_TOKEN_KEYWORD && + hb_stricmp( "AS", pToken->pNext->pNext->value ) == 0 ) ) ) ) ) + { + pLex->iState = PRIVATE; + return PRIVATE; + } + pLex->iState = DECLARE; + return DECLARE; + } + iType = IDENTIFIER; + break; + + case DO: + if( pLex->iState == LOOKUP && !HB_PP_TOKEN_ISEOC( pToken->pNext ) ) + { + if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD ) + { + if( pToken->pNext->len == 4 && + hb_stricmp( "CASE", pToken->pNext->value ) == 0 ) + { + if( HB_PP_TOKEN_ISEOC( pToken->pNext->pNext ) ) + { + hb_pp_tokenGet( pLex->pPP ); + pLex->iState = DOCASE; + return DOCASE; + } + } + else if( pToken->pNext->len >= 4 && + pToken->pNext->len <= 5 && + hb_strnicmp( "WHILE", pToken->pNext->value, + pToken->pNext->len ) == 0 && + /* check if it's not DO while [WITH ] */ + !HB_PP_TOKEN_ISEOC( pToken->pNext->pNext ) && + ( HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) != HB_PP_TOKEN_KEYWORD || + pToken->pNext->pNext->len != 4 || + hb_stricmp( "WITH", pToken->pNext->pNext->value ) != 0 ) ) + { + /* DO WHILE */ + hb_pp_tokenGet( pLex->pPP ); + pLex->iState = WHILE; + return WHILE; + } + /* DO identifier [WITH ] */ + pToken = hb_pp_tokenGet( pLex->pPP ); + /* do not upper next token for case sensitive file systems */ + /* hb_pp_tokenUpper( pToken ); */ + pLex->lasttok = yylval_ptr->string = hb_comp_tokenIdentifer( pToken ); + pLex->iState = IDENTIFIER; + return DOIDENT; + } + else if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_MACROVAR || + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_MACROTEXT ) + { + /* DO &id WITH */ + pLex->iState = DO; + return DO; + } + } + iType = IDENTIFIER; + break; + + case WHILE: + if( pLex->iState == LOOKUP && + !HB_PP_TOKEN_ISEOC( pToken->pNext ) && + !HB_PP_LEX_NEEDLEFT( pToken->pNext ) ) + { + pLex->iState = WHILE; + return WHILE; + } + iType = IDENTIFIER; + break; + + case WITH: + if( !HB_PP_TOKEN_ISEOC( pToken->pNext ) ) + { + if( pLex->iState == LOOKUP && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && + ( pToken->pNext->pNext->len >= 4 || + hb_strnicmp( "OBJECT", pToken->pNext->value, + pToken->pNext->len ) != 0 ) ) + { + pLex->iState = WITHOBJECT; + return WITHOBJECT; + } + else if( pLex->iState == MACROVAR || + pLex->iState == MACROTEXT || + pLex->iState == IDENTIFIER ) + { + pLex->iState = WITH; + return WITH; + } + } + iType = IDENTIFIER; + break; + + case IIF: + if( pLex->iState == FUNCTION || pLex->iState == PROCEDURE || + HB_PP_TOKEN_ISEOC( pToken->pNext ) ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_SYNTAX, "IIF", NULL ); + else if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) != HB_PP_TOKEN_LEFT_PB ) + hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_SYNTAX, + pToken->pNext->value, NULL ); + else + { + pLex->iState = IIF; + return IIF; + } + iType = IDENTIFIER; + break; + + case IF: + if( pLex->iState == FUNCTION || pLex->iState == PROCEDURE || + HB_PP_TOKEN_ISEOC( pToken->pNext ) ) + hb_compGenError( hb_comp_szErrors, 'E', + HB_COMP_ERR_SYNTAX, "IF", NULL ); + else if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB ) + { + pLex->iState = pLex->iState == LOOKUP ? IF : IIF; + return pLex->iState; + } + else if( HB_PP_LEX_NEEDLEFT( pToken->pNext ) ) + hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_SYNTAX2, + pToken->pNext->value, "IF" ); + else + { + pLex->iState = IF; + return IF; + } + iType = IDENTIFIER; + break; + + case PROCREQ: + if( pToken->pNext && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB ) + { + hb_pp_tokenGet( pLex->pPP ); + pLex->iState = LSEPARATOR; + return PROCREQ; + } + iType = IDENTIFIER; + break; + + case SELF: + if( pToken->pNext && pToken->pNext->pNext && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB && + HB_PP_TOKEN_TYPE( pToken->pNext->pNext->type ) == HB_PP_TOKEN_RIGHT_PB ) + { + hb_pp_tokenGet( pLex->pPP ); + hb_pp_tokenGet( pLex->pPP ); + pLex->iState = RSEPARATOR; + return SELF; + } + iType = IDENTIFIER; + break; + + case AS_TYPE: + { + int iAs = hb_comp_asType( pToken->pNext, FALSE ); + if( iAs ) + { + pToken = hb_pp_tokenGet( pLex->pPP ); + if( iAs == AS_ARRAY && pToken->pNext && + HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD && + hb_stricmp( "OF", pToken->pNext->value ) == 0 ) + { + int iAsArray = hb_comp_asType( pToken->pNext->pNext, TRUE ); + if( iAsArray ) + { + hb_pp_tokenGet( pLex->pPP ); + hb_pp_tokenGet( pLex->pPP ); + return iAsArray; + } + } + return iAs; + } + iType = IDENTIFIER; + break; + } + case DECLARE_CLASS: + case DECLARE_MEMBER: + pLex->iState = OPERATOR; + return iType; + + case EXIT: + case IN: + case LOOP: + case NIL: + case STEP: + case TO: + case ANNOUNCE: + case OPTIONAL: + case DESCEND: + case EXTERN: + case LOCAL: + case MEMVAR: + case PARAMETERS: + case PRIVATE: + case PUBLIC: + case STATIC: + break; + } + pLex->iState = IDENTIFIER; + return iType; + } + default: + return pToken->value[ 0 ]; + } +} + +void hb_compParserStop( HB_COMP_PTR pComp ) +{ + HB_SYMBOL_UNUSED( pComp ); +} diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c index 78dcc47590..ce2a107256 100644 --- a/harbour/source/compiler/genc.c +++ b/harbour/source/compiler/genc.c @@ -59,7 +59,7 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou PCOMSYMBOL pSym = hb_comp_symbols.pFirst; FILE * yyc; /* file handle for C output */ PINLINE pInline = hb_comp_inlines.pFirst; - + BOOL bIsInlineFunction = FALSE; BOOL bIsInitStatics; BOOL bIsInitFunction; BOOL bIsExitFunction; @@ -140,7 +140,10 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou while( pInline ) { if( pInline->szName ) + { + bIsInlineFunction = TRUE; fprintf( yyc, "HB_FUNC_STATIC( %s );\n", pInline->szName ); + } pInline = pInline->pNext; } @@ -287,7 +290,7 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou /* Generate codeblocks data */ - if( hb_comp_cInlineID > '0' ) + if( bIsInlineFunction ) { fprintf( yyc, "#include \"hbapi.h\"\n" ); fprintf( yyc, "#include \"hbstack.h\"\n" ); diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index e33db1b0eb..079a4c26ff 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -71,7 +71,6 @@ static void hb_compInitVars( void ); static void hb_compGenOutput( int ); static void hb_compOutputFile( void ); -static void hb_compPpoFile( void ); static void hb_compCompileEnd( void ); static int hb_compCompile( char * szPrg, BOOL bSingleFile ); @@ -85,7 +84,6 @@ static void hb_compGenFieldPCode( BYTE , int, char *, PFUNCTION ); /* gener static void hb_compGenVariablePCode( BYTE , char * ); /* generates the pcode for undeclared variable */ static PFUNCTION hb_compFunctionNew( char *, HB_SYMBOLSCOPE ); /* creates and initialises the _FUNC structure */ -static PINLINE hb_compInlineNew( char * ); /* creates and initialises the _INLINE structure */ static void hb_compCheckDuplVars( PVAR pVars, char * szVarName ); /*checks for duplicate variables definitions */ static int hb_compProcessRSPFile( char * ); /* process response file */ @@ -95,7 +93,8 @@ static void hb_compOptimizeFrames( PFUNCTION pFunc ); static void hb_compDeclaredInit( void ); /* global variables */ -FILES hb_comp_files; +HB_COMP_PTR hb_comp_data; + FUNCTIONS hb_comp_functions; FUNCTIONS hb_comp_funcalls; SYMBOLS hb_comp_symbols; @@ -117,7 +116,6 @@ PHB_FNAME hb_comp_pFileName = NULL; PHB_FNAME hb_comp_pFilePpo = NULL; BOOL hb_comp_bPPO = FALSE; /* flag indicating, is ppo output needed */ -FILE * hb_comp_yyppo = NULL; /* output .ppo file */ BOOL hb_comp_bStartProc = TRUE; /* holds if we need to create the starting procedure */ BOOL hb_comp_bLineNumbers = TRUE; /* holds if we need pcodes with line numbers */ BOOL hb_comp_bQuiet = FALSE; /* quiet mode */ @@ -131,7 +129,6 @@ char hb_comp_szPrefix[ 20 ] = { '\0' }; /* holds the prefix ad int hb_comp_iGenCOutput = HB_COMPGENC_VERBOSE; /* C code generation should be verbose (use comments) or not */ BOOL hb_comp_bNoStartUp = FALSE ; /* C code generation embed HB_FS_FIRST or not */ int hb_comp_iExitLevel = HB_EXITLEVEL_DEFAULT; /* holds if there was any warning during the compilation process */ -HB_PATHNAMES * hb_comp_pIncludePath = NULL; int hb_comp_iFunctionCnt; int hb_comp_iErrorCount; char hb_comp_cVarType; /* current declared variable type */ @@ -180,7 +177,7 @@ static int hb_compAutoOpen( char * szPrg, BOOL * bSkipGen, BOOL bSingleFile ); /* -m Support */ static BOOL hb_compAutoOpenFind( char * szName ); -extern int yyparse( void ); /* main yacc parsing function */ +extern int yyparse( HB_COMP_PTR ); /* main yacc parsing function */ extern FILE *yyin ; extern FILE *yyout ; @@ -205,6 +202,8 @@ int main( int argc, char * argv[] ) HB_TRACE(HB_TR_DEBUG, ("main()")); + hb_comp_data = hb_comp_new(); + hb_comp_pOutPath = NULL; #if defined( HOST_OS_UNIX_COMPATIBLE ) @@ -265,18 +264,9 @@ int main( int argc, char * argv[] ) if( ! HB_ISOPTSEP( argv[ i ][ 0 ] ) ) { if( ! bAnyFiles ) - { bAnyFiles = TRUE; - /* do not call hb_pp_Init() because it was already called - * in hb_pp_SetRules - */ - } - else - { - /* Clear and reinitialize preprocessor state - */ - hb_pp_Init(); - } + else /* Clear and reinitialize preprocessor state */ + hb_pp_reset( hb_comp_data->pLex->pPP ); if( argv[ i ][ 0 ] == '@' ) iStatus = hb_compProcessRSPFile( argv[ i ] + 1 ); @@ -308,18 +298,12 @@ void hb_compMainExit( void ) if( inProcess ) return; - + inProcess = TRUE; - + hb_compCompileEnd(); - hb_pp_Free(); - hb_compIdentifierClose(); - if( hb_comp_pIncludePath ) - { - hb_fsFreeSearchPath( hb_comp_pIncludePath ); - hb_comp_pIncludePath = NULL; - } + hb_compParserStop( hb_comp_data ); if( hb_comp_pOutPath ) { @@ -332,7 +316,7 @@ void hb_compMainExit( void ) hb_xfree( hb_comp_pPpoPath ); hb_comp_pPpoPath = NULL; } - + while( hb_comp_pAutoOpen ) { PAUTOOPEN pAutoOpen = hb_comp_pAutoOpen; @@ -342,6 +326,8 @@ void hb_compMainExit( void ) hb_xfree( pAutoOpen ); } + hb_comp_free( hb_comp_data ); + hb_comp_data = NULL; hb_xexit(); } @@ -1913,7 +1899,7 @@ static PFUNCTION hb_compFunctionNew( char * szName, HB_SYMBOLSCOPE cScope ) return pFunc; } -static PINLINE hb_compInlineNew( char * szName ) +static PINLINE hb_compInlineNew( HB_COMP_PTR pComp, char * szName, int iLine ) { PINLINE pInline; @@ -1923,8 +1909,8 @@ static PINLINE hb_compInlineNew( char * szName ) pInline->pCode = NULL; pInline->lPCodeSize = 0; pInline->pNext = NULL; - pInline->szFileName = hb_strdup( hb_comp_files.pLast->szFileName ); - pInline->iLine = hb_comp_iLine - 1; + pInline->szFileName = hb_strdup( hb_pp_fileName( pComp->pLex->pPP ) ); + pInline->iLine = iLine; return pInline; } @@ -2011,25 +1997,22 @@ void hb_compFunctionAdd( char * szFunName, HB_SYMBOLSCOPE cScope, int iType ) if( hb_comp_bDebugInfo ) { BYTE * pBuffer; + char * szFile = hb_pp_fileName( hb_comp_data->pLex->pPP ); + int iLen = strlen( szFile ); - pBuffer = ( BYTE * ) hb_xgrab( 3 + strlen( hb_comp_files.pLast->szFileName ) + strlen( szFunName ) ); - + pBuffer = ( BYTE * ) hb_xgrab( 3 + iLen + strlen( szFunName ) ); pBuffer[0] = HB_P_MODULENAME; - - memcpy( ( BYTE * ) ( &( pBuffer[1] ) ), ( BYTE * ) hb_comp_files.pLast->szFileName, strlen( hb_comp_files.pLast->szFileName ) ); - - pBuffer[ strlen( hb_comp_files.pLast->szFileName ) + 1 ] = ':'; - - memcpy( ( BYTE * ) ( &( pBuffer[ strlen( hb_comp_files.pLast->szFileName ) + 2 ] ) ), ( BYTE * ) szFunName, strlen( szFunName ) + 1 ); - - hb_compGenPCodeN( pBuffer, 3 + strlen( hb_comp_files.pLast->szFileName ) + strlen( szFunName ), 0 ); + memcpy( pBuffer + 1, szFile, iLen ); + pBuffer[ iLen + 1 ] = ':'; + memcpy( &pBuffer[ iLen + 2 ], szFunName, strlen( szFunName ) + 1 ); + hb_compGenPCodeN( pBuffer, 3 + iLen + strlen( szFunName ), 0 ); hb_xfree( pBuffer ); } hb_comp_bDontGenLineNum = FALSE; /* reset the flag */ } -PINLINE hb_compInlineAdd( char * szFunName ) +PINLINE hb_compInlineAdd( HB_COMP_PTR pComp, char * szFunName, int iLine ) { PINLINE pInline; PCOMSYMBOL pSym; @@ -2046,7 +2029,7 @@ PINLINE hb_compInlineAdd( char * szFunName ) pSym->cScope |= HB_FS_STATIC; } } - pInline = hb_compInlineNew( szFunName ); + pInline = hb_compInlineNew( pComp, szFunName, iLine ); if( hb_comp_inlines.iCount == 0 ) { @@ -4275,11 +4258,12 @@ void hb_compStaticDefStart( void ) if( hb_comp_bDebugInfo ) { BYTE * pBuffer; - int iFileLen = strlen( hb_comp_files.pLast->szFileName ); + char * szFile = hb_pp_fileName( hb_comp_data->pLex->pPP ); + int iFileLen = strlen( szFile ); pBuffer = ( BYTE * ) hb_xgrab( 2 + iFileLen ); pBuffer[0] = HB_P_MODULENAME; - memcpy( ( BYTE * ) ( &( pBuffer[1] ) ), ( BYTE * ) hb_comp_files.pLast->szFileName, iFileLen+1 ); + memcpy( ( BYTE * ) ( &( pBuffer[1] ) ), ( BYTE * ) szFile, iFileLen + 1 ); hb_compGenPCodeN( pBuffer, 2 + iFileLen, 0 ); hb_xfree( pBuffer ); } @@ -4369,7 +4353,7 @@ void hb_compCodeBlockEnd( void ) wSize = ( USHORT ) pCodeblock->lPCodePos + 2; if( hb_comp_bDebugInfo ) { - wSize += (3 + strlen( hb_comp_files.pLast->szFileName ) + strlen( pFunc->szName )); + wSize += (3 + strlen( hb_pp_fileName( hb_comp_data->pLex->pPP ) ) + strlen( pFunc->szName )); wSize += wLocalsLen; } if( wSize <= 255 && pCodeblock->wParamCount == 0 && wLocals == 0 ) @@ -4400,13 +4384,15 @@ void hb_compCodeBlockEnd( void ) if( hb_comp_bDebugInfo ) { BYTE * pBuffer; + char * szFile = hb_pp_fileName( hb_comp_data->pLex->pPP ); + int iLen = strlen( szFile ); - pBuffer = ( BYTE * ) hb_xgrab( 3 + strlen( hb_comp_files.pLast->szFileName ) + strlen( pFunc->szName ) ); + pBuffer = ( BYTE * ) hb_xgrab( 3 + iLen + strlen( pFunc->szName ) ); pBuffer[0] = HB_P_MODULENAME; - memcpy( ( BYTE * ) ( &( pBuffer[1] ) ), ( BYTE * ) hb_comp_files.pLast->szFileName, strlen( hb_comp_files.pLast->szFileName ) ); - pBuffer[ strlen( hb_comp_files.pLast->szFileName ) + 1 ] = ':'; - memcpy( ( BYTE * ) ( &( pBuffer[ strlen( hb_comp_files.pLast->szFileName ) + 2 ] ) ), ( BYTE * ) pFunc->szName, strlen( pFunc->szName ) + 1 ); - hb_compGenPCodeN( pBuffer, 3 + strlen( hb_comp_files.pLast->szFileName ) + strlen( pFunc->szName ), 0 ); + memcpy( ( BYTE * ) ( &( pBuffer[1] ) ), ( BYTE * ) szFile, iLen ); + pBuffer[ iLen + 1 ] = ':'; + memcpy( ( BYTE * ) ( &( pBuffer[ iLen + 2 ] ) ), ( BYTE * ) pFunc->szName, strlen( pFunc->szName ) + 1 ); + hb_compGenPCodeN( pBuffer, 3 + iLen + strlen( pFunc->szName ), 0 ); hb_xfree( pBuffer ); /* generate the name of referenced local variables */ @@ -4543,8 +4529,6 @@ void hb_compCodeBlockRewind() /* initialize support variables */ static void hb_compInitVars( void ) { - hb_comp_files.iFiles = 0; - hb_comp_files.pLast = NULL; hb_comp_functions.iCount = 0; hb_comp_functions.pFirst = NULL; hb_comp_functions.pLast = NULL; @@ -4676,12 +4660,8 @@ int hb_compCompile( char * szPrg, BOOL bSingleFile ) hb_compPpoFile(); /*hb_comp_pFileName->szExtension = ".ppo";*/ hb_fsFNameMerge( szPpoName, hb_comp_pFilePpo ); - hb_comp_yyppo = fopen( szPpoName, "w" ); - if( ! hb_comp_yyppo ) - { - hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_CREATE_PPO, szPpoName, NULL ); + if( !hb_pp_outFile( hb_comp_data->pLex->pPP, szPpoName, NULL ) ) iStatus = EXIT_FAILURE; - } } if( iStatus == EXIT_SUCCESS ) @@ -4692,7 +4672,7 @@ int hb_compCompile( char * szPrg, BOOL bSingleFile ) /* Initialize support variables */ hb_compInitVars(); - if( hb_compInclude( szFileName, NULL ) ) + if( hb_pp_inFile( hb_comp_data->pLex->pPP, szFileName, FALSE, NULL, FALSE ) ) { BOOL bSkipGen = FALSE ; @@ -4722,13 +4702,8 @@ int hb_compCompile( char * szPrg, BOOL bSingleFile ) hb_compFunctionAdd( hb_compIdentifierNew( "", TRUE ), HB_FS_PUBLIC, FUN_PROCEDURE ); } - yyparse(); + yyparse( hb_comp_data ); - if( hb_comp_yyppo ) - { - fclose( hb_comp_yyppo ); - hb_comp_yyppo = NULL; - } if( hb_comp_pFilePpo ) { hb_xfree( hb_comp_pFilePpo ); @@ -4868,7 +4843,6 @@ int hb_compCompile( char * szPrg, BOOL bSingleFile ) hb_compGenOutput( hb_comp_iLanguage ); } - hb_compParserStop(); hb_compCompileEnd(); } else @@ -4909,35 +4883,12 @@ static void hb_compCompileEnd( void ) hb_comp_pFileName = NULL; } - if( hb_comp_yyppo ) - { - fclose( hb_comp_yyppo ); - hb_comp_yyppo = NULL; - } if( hb_comp_pFilePpo ) { hb_xfree( hb_comp_pFilePpo ); hb_comp_pFilePpo = NULL; } - while( hb_comp_files.pLast ) - { - PFILE pFile = hb_comp_files.pLast; - hb_xfree( pFile->szFileName ); - fclose( pFile->handle ); - if( pFile->pBuffer ) - { - hb_xfree( (void *) pFile->pBuffer ); - } - if( pFile->yyBuffer ) - { - hb_compParserStop(); /* uses hb_comp_files.pLast */ - } - hb_comp_files.pLast = ( PFILE ) pFile->pPrev; - hb_xfree( pFile ); - } - hb_comp_files.pLast = NULL; - if( hb_comp_functions.pFirst ) { PFUNCTION pFunc = hb_comp_functions.pFirst; @@ -5100,23 +5051,17 @@ int hb_compAutoOpen( char * szPrg, BOOL * pbSkipGen, BOOL bSingleFile ) { hb_comp_pFileName->szExtension = ".ppo"; hb_fsFNameMerge( szPpoName, hb_comp_pFileName ); - if( hb_comp_yyppo ) - fclose( hb_comp_yyppo ); - hb_comp_yyppo = fopen( szPpoName, "w" ); - if( ! hb_comp_yyppo ) - { - hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_CREATE_PPO, szPpoName, NULL ); + + if( !hb_pp_outFile( hb_comp_data->pLex->pPP, szPpoName, NULL ) ) iStatus = EXIT_FAILURE; - } } if( iStatus == EXIT_SUCCESS ) { /* Minimal Init. */ - hb_comp_files.iFiles = 0; hb_comp_iLine= 1; - if( hb_compInclude( szFileName, NULL ) ) + if( hb_pp_inFile( hb_comp_data->pLex->pPP, szFileName, FALSE, NULL, FALSE ) ) { if( ! hb_comp_bQuiet ) { @@ -5126,11 +5071,7 @@ int hb_compAutoOpen( char * szPrg, BOOL * pbSkipGen, BOOL bSingleFile ) printf( "Compiling module '%s'...\n", szFileName ); } - hb_pp_Init(); - - /* - yyrestart( yyin ); - */ + hb_pp_reset( hb_comp_data->pLex->pPP ); /* Generate the starting procedure frame */ if( hb_comp_bStartProc ) @@ -5142,13 +5083,8 @@ int hb_compAutoOpen( char * szPrg, BOOL * pbSkipGen, BOOL bSingleFile ) int i = hb_comp_iExitLevel ; BOOL b = hb_comp_bAnyWarning; - yyparse(); + yyparse( hb_comp_data ); - if( hb_comp_yyppo ) - { - fclose( hb_comp_yyppo ); - hb_comp_yyppo = NULL; - } if( hb_comp_pFilePpo ) { hb_xfree( hb_comp_pFilePpo ); @@ -5172,7 +5108,6 @@ int hb_compAutoOpen( char * szPrg, BOOL * pbSkipGen, BOOL bSingleFile ) printf( "\nNo code generated.\n" ); } } - hb_compParserStop(); } else { diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index 6a56944976..c9748f4989 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -1,3 +1,4 @@ +%option noyywrap %{ /* * $Id$ @@ -52,21 +53,19 @@ #undef free #define free hb_xfree +/* 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_COMP_PTR pComp ) + /* helper functions */ -static int yy_ConvertNumber( char * szBuffer ); -static int yy_ConvertDate( char * szBuffer ); +static int yy_ConvertNumber( YYSTYPE *yylval_ptr, char * szBuffer ); +static int yy_ConvertDate( YYSTYPE *yylval_ptr, char * szBuffer ); /* YACC functions */ -void yyerror( char * ); static void yyunput( int, char * ); -#undef yywrap /* to implement our own yywrap() funtion to handle EOFs */ -#ifdef __cplusplus -extern "C" int yywrap( void ); -#else -int yywrap( void ); -#endif #undef YY_INPUT /* to implement our own YY_INPUT function to manage PRGs without \n at the end */ -extern FILE * yyin; /* currently yacc parsed file */ /* Following two lines added for preprocessor */ int yy_lex_input( char *, int ); @@ -90,7 +89,9 @@ int yy_lex_input( char *, int ); #define LARRAY -32 #define RARRAY -64 static int hb_comp_iState = LOOKUP; -static int _iOpenBracket = 0; + +#define YY_OPERATOR_RET(t) hb_comp_iState = OPERATOR; pComp->pLex->lasttok = yytext; return (t) +#define YY_TOKEN_RET(s,t) hb_comp_iState = (s); pComp->pLex->lasttok = yytext; return (t) /* Stores a codeblock picture for late/early evaluation */ @@ -174,6 +175,7 @@ Separator {SpaceTab} else { hb_comp_iState = LINDEX; + pComp->pLex->lasttok = "["; return '['; } } @@ -183,7 +185,7 @@ Separator {SpaceTab} yytext[--yyleng] = '\0'; hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_STRING_TERMINATOR, yytext, NULL ); hb_comp_iState = LOOKUP; - + pComp->pLex->lasttok = yytext; return NIL; } @@ -194,7 +196,7 @@ Separator {SpaceTab} hb_strRemEscSeq( yytext, &len ); yyleng = len; } - yylval.string = hb_compIdentifierNew( yytext, TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( yytext, TRUE ); hb_comp_iState = LITERAL; return LITERAL; @@ -205,13 +207,14 @@ Separator {SpaceTab} yytext[--yyleng] = '\0'; hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_STRING_TERMINATOR, yytext, NULL ); hb_comp_iState = LOOKUP; + pComp->pLex->lasttok = yytext; return NIL; } [^\x27\n]*\x27 { BEGIN 0; yytext[--yyleng] = '\0'; - yylval.string = hb_compIdentifierNew( yytext, TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( yytext, TRUE ); hb_comp_iState = LITERAL; return LITERAL; @@ -219,7 +222,7 @@ Separator {SpaceTab} [^\x22\n]*\x22 { BEGIN 0; yytext[--yyleng] = '\0'; - yylval.string = hb_compIdentifierNew( yytext, TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( yytext, TRUE ); hb_comp_iState = LITERAL; return LITERAL; @@ -230,6 +233,7 @@ Separator {SpaceTab} yytext[--yyleng] = '\0'; hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_STRING_TERMINATOR, yytext, NULL ); hb_comp_iState = LOOKUP; + pComp->pLex->lasttok = yytext; return NIL; } @@ -264,7 +268,7 @@ Separator {SpaceTab} /* "] or '] terminator was found */ yyless( i+2 ); yytext[ i+1 ] = '\0'; - yylval.string = hb_compIdentifierNew( yytext, TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( yytext, TRUE ); hb_comp_iState = LITERAL; return LITERAL; @@ -276,7 +280,7 @@ Separator {SpaceTab} { yyless( iFirstPos+1 ); yytext[ iFirstPos ] = '\0'; - yylval.string = hb_compIdentifierNew( yytext, TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( yytext, TRUE ); hb_comp_iState = LITERAL; return LITERAL; @@ -292,7 +296,7 @@ Separator {SpaceTab} { yyless( i+1 ); yytext[ i ] = '\0'; - yylval.string = hb_compIdentifierNew( yytext, TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( yytext, TRUE ); hb_comp_iState = LITERAL; return LITERAL; @@ -304,6 +308,7 @@ Separator {SpaceTab} yytext[--yyleng] = '\0'; hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_STRING_TERMINATOR, yytext, NULL ); hb_comp_iState = LOOKUP; + pComp->pLex->lasttok = yytext; return NIL; } @@ -323,7 +328,7 @@ Separator {SpaceTab} /* ] terminator was found */ yyless( i+1 ); yytext[ i ] = '\0'; - yylval.string = hb_compIdentifierNew( yytext, TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( yytext, TRUE ); hb_comp_iState = LITERAL; return LITERAL; @@ -339,7 +344,7 @@ Separator {SpaceTab} unput( ')' ); yyleng -= 3; yytext[ yyleng ] = '\0'; - yylval.string = hb_compIdentifierNew( yytext, TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( yytext, TRUE ); hb_comp_iState = LITERAL; return LITERAL; @@ -362,6 +367,7 @@ Separator {SpaceTab} fflush( stdout ); } */ + pComp->pLex->lasttok = "\n"; return '\n'; } %{ @@ -374,6 +380,7 @@ Separator {SpaceTab} yy_set_bol(1); hb_comp_iState = LOOKUP; + pComp->pLex->lasttok = ";"; return ';'; } %{ @@ -381,13 +388,16 @@ Separator {SpaceTab} %} "announce"|"announc"|"announ"|"annou"|"anno" { hb_comp_iState =IDENTIFIER; - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); return ANNOUNCE; } %{ /* ************************************************************************ */ %} -"begin"{Separator}+"sequ"("ence"|"enc"|"en"|"e")? return BEGINSEQ; +"begin"{Separator}+"sequ"("ence"|"enc"|"en"|"e")? { + pComp->pLex->lasttok = yytext; + return BEGINSEQ; + } %{ /* ************************************************************************ */ %} @@ -395,7 +405,7 @@ Separator {SpaceTab} BEGIN BREAK_; else { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -413,7 +423,7 @@ Separator {SpaceTab} unput( yytext[ yyleng-1 ] ); if( HB_COMP_ISSUPPORTED( HB_COMPFLAG_HARBOUR ) ) { - yylval.string = hb_compIdentifierNew( "BREAK", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "BREAK", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -422,7 +432,7 @@ Separator {SpaceTab} } (":="|"+="|"-="|"->"|"*="|"/="|"^="|"==") { /* operators */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "BREAK", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "BREAK", TRUE ); unput( yytext[ yyleng-1 ] ); unput( yytext[ yyleng-2 ] ); hb_comp_iState =IDENTIFIER; @@ -434,7 +444,7 @@ Separator {SpaceTab} * For this reason we are allowing the BREAK statement only */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "BREAK", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "BREAK", TRUE ); unput( yytext[ yyleng-1 ] ); unput( yytext[ yyleng-2 ] ); hb_comp_iState =BREAK; @@ -442,7 +452,7 @@ Separator {SpaceTab} } [\=\(] { /* operators = ( */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "BREAK", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "BREAK", TRUE ); unput( yytext[ yyleng-1 ] ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; @@ -462,14 +472,14 @@ Separator {SpaceTab} {Separator}* ; [\:\=\|\$\%\*\,\/\]\)\}\^] { /* there is an operator after "case" */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "CASE", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "CASE", TRUE ); hb_comp_iState =IDENTIFIER; unput( yytext[ yyleng-1 ] ); return IDENTIFIER; } ("+="|"-="|"->") { /* operators */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "CASE", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "CASE", TRUE ); hb_comp_iState =IDENTIFIER; unput( yytext[ yyleng-1 ] ); unput( yytext[ yyleng-2 ] ); @@ -496,7 +506,7 @@ Separator {SpaceTab} } else { /* there is another item in line already */ - yylval.string = hb_compIdentifierNew( "CASE", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "CASE", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -505,7 +515,7 @@ Separator {SpaceTab} /* ************************************************************************ */ %} "_procreq_(" { - yylval.string = hb_compIdentifierNew( "_PROCREQ_", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "_PROCREQ_", TRUE ); hb_comp_iState =IDENTIFIER; return PROCREQ; } @@ -514,7 +524,7 @@ Separator {SpaceTab} %} "decl"|"decla"|"declar"|"declare" { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); if( hb_comp_iState == DO ) { hb_comp_iState = IDENTIFIER; @@ -564,7 +574,7 @@ Separator {SpaceTab} /* ************************************************************************ */ %} "opti"|"optio"|"option"|"optiona"|"optional" { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); return OPTIONAL; } %{ @@ -574,6 +584,7 @@ Separator {SpaceTab} {Separator}+"case" { /* DO CASE statement */ BEGIN 0; hb_comp_iState =DOCASE; + pComp->pLex->lasttok = yytext; return DOCASE; } {Separator}+"while" { /* DO WHILE found -move it to WHILE state */ @@ -598,11 +609,12 @@ Separator {SpaceTab} if( hb_comp_iState == LOOKUP ) { /* it is first item in the line */ hb_comp_iState =DO; + pComp->pLex->lasttok = yytext; return DO; } else { /* there is another item in line already */ - yylval.string = hb_compIdentifierNew( "DO", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "DO", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -615,7 +627,7 @@ Separator {SpaceTab} } else { /* there is another item in line already */ - yylval.string = hb_compIdentifierNew( "DO", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "DO", TRUE ); hb_comp_iState =IDENTIFIER; BEGIN 0; return IDENTIFIER; @@ -624,13 +636,13 @@ Separator {SpaceTab} {Separator}*(.|\n) { /* end of line or any operator */ BEGIN 0; unput( yytext[ yyleng-1 ] ); - yylval.string = hb_compIdentifierNew( "DO", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "DO", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } {Identifier} { /* DO identifier WITH */ BEGIN 0; - yylval.string = hb_compIdentifierNew( yytext, TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( yytext, TRUE ); hb_comp_iState =IDENTIFIER; return DOIDENT; } @@ -638,7 +650,7 @@ Separator {SpaceTab} /* ************************************************************************ */ %} "descend" { - yylval.string = hb_compIdentifierNew( "DESCEND", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "DESCEND", TRUE ); hb_comp_iState =IDENTIFIER; return DESCEND; } @@ -649,17 +661,20 @@ Separator {SpaceTab} if( hb_comp_wIfCounter == 0 ) hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_UNMATCHED_ELSE, NULL, NULL ); hb_comp_iState =ELSE; + pComp->pLex->lasttok = yytext; return ELSE; } "elseif" { /* ELSEIF can be used in one context only */ if( hb_comp_wIfCounter == 0 ) hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_UNMATCHED_ELSEIF, NULL, NULL ); hb_comp_iState =ELSEIF; + pComp->pLex->lasttok = yytext; return ELSEIF; } "end"{Separator}+"sequ"("ence"|"enc"|"en"|"e")? { if( hb_comp_wSeqCounter == 0 ) hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_ENDIF, NULL, NULL ); + pComp->pLex->lasttok = yytext; return END; } %{ @@ -669,16 +684,19 @@ Separator {SpaceTab} "endif"|"endi" { /* ENDIF can be used in one context only */ if( hb_comp_wIfCounter == 0 ) hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_ENDIF, NULL, NULL ); + pComp->pLex->lasttok = yytext; return ENDIF; } "endc"("ase"|"as"|"a")? { /* ENDCASE can be used in one context only */ if( hb_comp_wCaseCounter == 0 ) hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_ENDCASE, NULL, NULL ); + pComp->pLex->lasttok = yytext; return ENDCASE; } "enddo"|"endd" { /* ENDDO can be used in one context only */ if( hb_comp_wWhileCounter == 0 ) hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_ENDDO, NULL, NULL ); + pComp->pLex->lasttok = yytext; return ENDDO; } %{ @@ -692,7 +710,7 @@ Separator {SpaceTab} { /* Clipper does not like end[] & end() at the begining of line */ hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_ENDIF, NULL, NULL ); } - yylval.string = hb_compIdentifierNew( "END", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "END", TRUE ); hb_comp_iState =IDENTIFIER; unput( yytext[ yyleng-1 ] ); return IDENTIFIER; @@ -703,7 +721,7 @@ Separator {SpaceTab} { /* Clipper does not like end-> & end++ at the begining of line */ hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_ENDIF, NULL, NULL ); } - yylval.string = hb_compIdentifierNew( "END", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "END", TRUE ); hb_comp_iState =IDENTIFIER; unput( yytext[ yyleng-1 ] ); unput( yytext[ yyleng-2 ] ); @@ -711,7 +729,7 @@ Separator {SpaceTab} } [\+\-\:\=\|\$\%\*\,\/\[\]\)\}\^] { /* there is an operator after "end" */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "END", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "END", TRUE ); hb_comp_iState =IDENTIFIER; unput( yytext[ yyleng-1 ] ); return IDENTIFIER; @@ -726,7 +744,7 @@ Separator {SpaceTab} } else { /* there is another item in line already */ - yylval.string = hb_compIdentifierNew( "END", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "END", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -737,13 +755,14 @@ Separator {SpaceTab} "exit" { hb_comp_iState =IDENTIFIER; + pComp->pLex->lasttok = yytext; return EXIT; } %{ /* ************************************************************************ */ %} "exte"|"exter"|"extern"|"externa"|"external" { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState =IDENTIFIER; return EXTERN; } @@ -751,11 +770,11 @@ Separator {SpaceTab} /* ************************************************************************ */ %} "_fie"|"_fiel"|"_field" { BEGIN FIELD_; - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); } "fiel"|"field" { BEGIN FIELD_; - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); } {Separator}+[_a-zA-Z] { /* an identifier after the FIELD */ BEGIN 0; @@ -795,11 +814,13 @@ Separator {SpaceTab} if( hb_comp_iState == LOOKUP ) { hb_comp_iState =FOR; + pComp->pLex->lasttok = yytext; + pComp->pLex->lasttok = yytext; return FOR; } else { /* for example: DO for WITH variable */ - yylval.string = hb_compIdentifierNew( "FOR", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "FOR", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -810,18 +831,19 @@ Separator {SpaceTab} if( hb_comp_iState == LOOKUP ) { /* Clipper always assume FOR (somevar):=1 TO ... here */ hb_comp_iState =FOR; + pComp->pLex->lasttok = yytext; return FOR; } else { - yylval.string = hb_compIdentifierNew( "FOR", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "FOR", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } } .|\n { /* there is no identifier after "FOR" */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "FOR", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "FOR", TRUE ); unput( yytext[ yyleng-1 ] ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; @@ -831,12 +853,14 @@ Separator {SpaceTab} unput( yytext[ yyleng-1 ] ); unput( 'h' ); unput( 'c' ); unput( 'a' ); unput( 'e' ); hb_comp_iState = FOR; + pComp->pLex->lasttok = yytext; return FOR; } . { BEGIN 0; unput( yytext[ yyleng-1 ] ); hb_comp_iState = FOREACH; + pComp->pLex->lasttok = yytext; return FOREACH; } %{ @@ -847,6 +871,7 @@ Separator {SpaceTab} BEGIN 0; unput( yytext[ yyleng-1 ] ); hb_comp_iState=FUNCTION; + pComp->pLex->lasttok = yytext; return FUNCTION; } .|\n { /* Clipper needs FUNCTION in one context only */ @@ -861,11 +886,13 @@ Separator {SpaceTab} "hb_inline" { + HB_SYMBOL_UNUSED( pComp ); + /* NOTE: hb_compiLineINLINE is being RESET in ppcomp.c - hb_pp_Internal() */ if( ! HB_COMP_ISSUPPORTED( HB_COMPFLAG_HB_INLINE ) ) { - yylval.string = hb_compIdentifierNew( "HB_INLINE", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = "HB_INLINE"; hb_comp_iState = IDENTIFIER; return IDENTIFIER; } @@ -901,7 +928,7 @@ Separator {SpaceTab} break; } - pInline = hb_compInlineAdd( hb_compIdentifierNew( sInlineSym, TRUE ) ); + pInline = hb_compInlineAdd( pComp, hb_compIdentifierNew( sInlineSym, TRUE ), hb_pp_line( pComp->pLex->pPP ) + 1 ); DigestInline: @@ -1016,7 +1043,7 @@ Separator {SpaceTab} hb_comp_iLinePRG = hb_comp_iLine - 1; hb_comp_iLine = hb_comp_iLineINLINE; - yylval.string = hb_compIdentifierNew( sInlineSym, TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( sInlineSym, TRUE ); return IDENTIFIER; } } @@ -1041,6 +1068,7 @@ Separator {SpaceTab} BEGIN 0; unput( yytext[ yyleng-1 ] ); hb_comp_iState=IIF; + pComp->pLex->lasttok = yytext; return IIF; } [^\(] { @@ -1063,6 +1091,7 @@ Separator {SpaceTab} hb_comp_iState =IF; else hb_comp_iState =IIF; + pComp->pLex->lasttok = yytext; return hb_comp_iState; } [\)\]\/\^\*\%\=\$\@] { BEGIN 0; @@ -1080,12 +1109,14 @@ Separator {SpaceTab} . { BEGIN 0; unput( yytext[ yyleng-1 ] ); hb_comp_iState =IF; + pComp->pLex->lasttok = yytext; return IF; } %{ /* ************************************************************************ */ %} -"in" { hb_comp_iState =IDENTIFIER; return IN; } +"in" { hb_comp_iState =IDENTIFIER; pComp->pLex->lasttok = yytext; + return IN; } %{ /* ************************************************************************ */ %} @@ -1096,11 +1127,12 @@ Separator {SpaceTab} if( hb_comp_iState == LOOKUP ) { /* it is first item in the line */ hb_comp_iState =INIT; + pComp->pLex->lasttok = yytext; return INIT; } else { /* there is another item in line already */ - yylval.string = hb_compIdentifierNew( "INIT", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "INIT", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -1108,31 +1140,32 @@ Separator {SpaceTab} .|\n { /* any character (not identifier) after INIT */ BEGIN 0; unput( yytext[ yyleng-1 ] ); - yylval.string = hb_compIdentifierNew( "INIT", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "INIT", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } %{ /* ************************************************************************ */ %} -"#"{Separator}*"line" return LINE; +"#"{Separator}*"line" { pComp->pLex->lasttok = yytext; return LINE; } %{ /* ************************************************************************ */ %} "loca"|"local" { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState =IDENTIFIER; return LOCAL; } %{ /* ************************************************************************ */ %} -"loop" { hb_comp_iState =IDENTIFIER; return LOOP; } +"loop" { hb_comp_iState =IDENTIFIER; pComp->pLex->lasttok = yytext; + return LOOP; } %{ /* ************************************************************************ */ %} "memv"|"memva"|"memvar" { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState =IDENTIFIER; return MEMVAR; } @@ -1149,11 +1182,12 @@ Separator {SpaceTab} if( hb_comp_wForCounter == 0 ) hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_NEXTFOR, NULL, NULL ); hb_comp_iState =NEXT; + pComp->pLex->lasttok = yytext; return NEXT; } else { /* there is another item in line already */ - yylval.string = hb_compIdentifierNew( "NEXT", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "NEXT", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -1164,7 +1198,7 @@ Separator {SpaceTab} { /* Clipper does not like NEXT[] & NEXT() at the begining of line */ hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_NEXTFOR, NULL, NULL ); } - yylval.string = hb_compIdentifierNew( "NEXT", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "NEXT", TRUE ); hb_comp_iState =IDENTIFIER; unput( yytext[ yyleng-1 ] ); return IDENTIFIER; @@ -1173,9 +1207,9 @@ Separator {SpaceTab} BEGIN 0; if( hb_comp_iState == LOOKUP ) { /* Clipper does not like next-> & next++ at the begining of line */ - hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_NEXTFOR, NULL, NULL ); + hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_NEXTFOR, NULL, NULL ); } - yylval.string = hb_compIdentifierNew( "NEXT", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "NEXT", TRUE ); hb_comp_iState =IDENTIFIER; unput( yytext[ yyleng-1 ] ); unput( yytext[ yyleng-2 ] ); @@ -1183,7 +1217,7 @@ Separator {SpaceTab} } [^_a-zA-Z] { /* there is no identifier after "next" */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "NEXT", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "NEXT", TRUE ); unput( yytext[ yyleng-1 ] ); return IDENTIFIER; } @@ -1195,11 +1229,12 @@ Separator {SpaceTab} if( hb_comp_wForCounter == 0 ) hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_NEXTFOR, NULL, NULL ); hb_comp_iState =NEXT; + pComp->pLex->lasttok = yytext; return NEXT; } else { - yylval.string = hb_compIdentifierNew( "NEXT", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "NEXT", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -1207,12 +1242,13 @@ Separator {SpaceTab} %{ /* ************************************************************************ */ %} -"nil" hb_comp_iState =LITERAL; return NIL; +"nil" { hb_comp_iState =LITERAL; pComp->pLex->lasttok = yytext; + return NIL; } %{ /* ************************************************************************ */ %} "othe"|"other"|"otherw"|"otherwi"|"otherwis"|"otherwise" { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); BEGIN OTHERWISE_; } {Separator}* ; @@ -1242,7 +1278,7 @@ Separator {SpaceTab} /* ************************************************************************ */ %} "para"|"param"|"parame"|"paramet"|"paramete"|"parameter"|"parameters" { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState =IDENTIFIER; return PARAMETERS; } @@ -1250,7 +1286,7 @@ Separator {SpaceTab} /* ************************************************************************ */ %} "priv"("ate"|"at"|"a")? { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState =IDENTIFIER; return PRIVATE; } @@ -1262,6 +1298,7 @@ Separator {SpaceTab} BEGIN 0; unput( yytext[ yyleng-1 ] ); hb_comp_iState = PROCEDURE; + pComp->pLex->lasttok = yytext; return PROCEDURE; } .|\n { /* Clipper needs PROCEDURE in one context only */ @@ -1272,19 +1309,19 @@ Separator {SpaceTab} /* ************************************************************************ */ %} "publ"("ic"|"i")? { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState =IDENTIFIER; return PUBLIC; } %{ /* ************************************************************************ */ %} -"qself"{SpaceTab}*[(]{SpaceTab}*[)] return SELF; +"qself"{SpaceTab}*[(]{SpaceTab}*[)] { pComp->pLex->lasttok = yytext; return SELF; } %{ /* ************************************************************************ */ %} "reco"|"recov"|"recove"|"recover" { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); BEGIN RECOVER_; } {Separator}* ; @@ -1317,7 +1354,7 @@ Separator {SpaceTab} /* ************************************************************************ */ %} "retu"|"retur"|"return" { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); BEGIN RETURN_; } {Separator}* @@ -1389,7 +1426,7 @@ Separator {SpaceTab} /* ************************************************************************ */ %} "stat"|"stati"|"static" { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState = IDENTIFIER; return STATIC; } @@ -1404,14 +1441,14 @@ Separator {SpaceTab} {Separator}* ; [\:\=\|\$\%\*\,\/\]\)\}\^] { /* there is an operator after "switch" */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "SWITCH", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "SWITCH", TRUE ); hb_comp_iState =IDENTIFIER; unput( yytext[ yyleng-1 ] ); return IDENTIFIER; } ("+="|"-="|"->") { /* operators */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "SWITCH", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "SWITCH", TRUE ); hb_comp_iState =IDENTIFIER; unput( yytext[ yyleng-1 ] ); unput( yytext[ yyleng-2 ] ); @@ -1422,6 +1459,7 @@ Separator {SpaceTab} unput( yytext[ yyleng-1 ] ); unput( yytext[ yyleng-2 ] ); hb_comp_iState =DOSWITCH; + pComp->pLex->lasttok = yytext; return DOSWITCH; } (\n|.) { /* not operator */ @@ -1430,11 +1468,12 @@ Separator {SpaceTab} if( hb_comp_iState == LOOKUP ) { /* it is first item in the line */ hb_comp_iState =DOSWITCH; + pComp->pLex->lasttok = yytext; return DOSWITCH; } else { /* there is another item in line already */ - yylval.string = hb_compIdentifierNew( "SWITCH", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "SWITCH", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -1442,14 +1481,15 @@ Separator {SpaceTab} %{ /* ************************************************************************ */ %} -"to" { hb_comp_iState = IDENTIFIER; return TO; } +"to" { hb_comp_iState = IDENTIFIER; pComp->pLex->lasttok = yytext; + return TO; } %{ /* ************************************************************************ */ %} "while"|"whil" { BEGIN WHILE_; - /* store it for later use */ - yylval.string = hb_compIdentifierNew( yytext, TRUE ); - } + /* store it for later use */ + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( yytext, TRUE ); + } {Separator}* ; \n { /* end of line */ BEGIN 0; @@ -1460,19 +1500,19 @@ Separator {SpaceTab} } else { - yylval.string = hb_compIdentifierNew( "WHILE", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "WHILE", TRUE ); return IDENTIFIER; } } [\:\=\|\$\%\*\,\/\]\)\}\^] { /* there is an operator after "while" */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "WHILE", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "WHILE", TRUE ); unput( yytext[ yyleng-1 ] ); return IDENTIFIER; } ("+="|"-="|"->") { /* operators */ BEGIN 0; - yylval.string = hb_compIdentifierNew( "WHILE", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "WHILE", TRUE ); unput( yytext[ yyleng-1 ] ); unput( yytext[ yyleng-2 ] ); return IDENTIFIER; @@ -1494,7 +1534,7 @@ Separator {SpaceTab} } else { /* there is another item in line already */ - yylval.string = hb_compIdentifierNew( "WHILE", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "WHILE", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -1507,7 +1547,7 @@ Separator {SpaceTab} \n { /* at the end of line */ BEGIN 0; unput( '\n' ); - yylval.string = hb_compIdentifierNew( "WITH", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "WITH", TRUE ); return IDENTIFIER; } "with" { @@ -1516,12 +1556,13 @@ Separator {SpaceTab} if( hb_comp_iState == DO ) { /* DO with WITH */ hb_comp_iState =IDENTIFIER; - yylval.string = hb_compIdentifierNew( "WITH", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "WITH", TRUE ); return IDENTIFIER; } else { /* DO WITH with */ hb_comp_iState =WITH; + pComp->pLex->lasttok = yytext; return WITH; } } @@ -1530,12 +1571,14 @@ Separator {SpaceTab} if( hb_comp_iState == LOOKUP ) { hb_comp_iState = WITHOBJECT; + pComp->pLex->lasttok = yytext; return WITHOBJECT; } else { yyless( yyleng-6 ); hb_comp_iState =WITH; + pComp->pLex->lasttok = yytext; return WITH; } @@ -1544,7 +1587,7 @@ Separator {SpaceTab} BEGIN 0; unput( yytext[ yyleng-1 ] ); hb_comp_iState =IDENTIFIER; - yylval.string = hb_compIdentifierNew( "WITH", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "WITH", TRUE ); return IDENTIFIER; } . { @@ -1558,11 +1601,12 @@ Separator {SpaceTab} hb_comp_iState == RSEPARATOR ) { /* DO WITH */ hb_comp_iState =WITH; + pComp->pLex->lasttok = yytext; return WITH; } else { - yylval.string = hb_compIdentifierNew( "WITH", TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( "WITH", TRUE ); hb_comp_iState =IDENTIFIER; return IDENTIFIER; } @@ -1610,8 +1654,8 @@ Separator {SpaceTab} int iCode=1; char cMark='\0'; - yylval.asCodeblock.isMacro = FALSE; - yylval.asCodeblock.lateEval = FALSE; + yylval_ptr->asCodeblock.isMacro = FALSE; + yylval_ptr->asCodeblock.lateEval = FALSE; cText = yytext+1; iLen = 1; @@ -1630,12 +1674,12 @@ Separator {SpaceTab} iPos = iLen; else if( *cText == '&' && cMark == '\0' ) { - yylval.asCodeblock.isMacro = TRUE; + yylval_ptr->asCodeblock.isMacro = TRUE; ++cText; while( *cText == ' ' || *cText == '\t' ) ++cText; if( *cText == '(' ) - yylval.asCodeblock.lateEval = TRUE; + yylval_ptr->asCodeblock.lateEval = TRUE; --cText; } else if( *cText == '{' && cMark == '\0' ) @@ -1649,89 +1693,91 @@ Separator {SpaceTab} cText++; } cMark = yytext[ iLen ]; - yylval.asCodeblock.string = (char *)hb_xgrab( iLen+1 ); - memcpy( (void *)yylval.asCodeblock.string, (void *)yytext, iLen ); - yylval.asCodeblock.string[iLen] = '\0'; - yylval.asCodeblock.length = iLen; + yylval_ptr->asCodeblock.string = (char *)hb_xgrab( iLen+1 ); + memcpy( (void *)yylval_ptr->asCodeblock.string, (void *)yytext, iLen ); + yylval_ptr->asCodeblock.string[iLen] = '\0'; + yylval_ptr->asCodeblock.length = iLen; yyless( iPos ); /* restart scanning after '{|' */ - return CBSTART; + pComp->pLex->lasttok = yytext; + return CBSTART; } %{ /* ************************************************************************ */ %} -"as"{Separator}+("arra"|"array") { return AS_ARRAY; } -"as"{Separator}+("code"|"codeb"|"codebl"|"codeblo"|"codebloc"|"codeblock") { return AS_BLOCK; } -"as"{Separator}+("stri"|"strin"|"string") { return AS_CHARACTER; } -"as"{Separator}+("char"|"chara"|"charac"|"charact"|"characte"|"character") { return AS_CHARACTER; } -"as"{Separator}+("clas"|"class") { return AS_CLASS; } -"as"{Separator}+"date" { return AS_DATE; } -"as"{Separator}+("logi"|"logic"|"logica"|"logical") { return AS_LOGICAL; } -"as"{Separator}+("nume"|"numer"|"numeri"|"numeric") { return AS_NUMERIC; } -"as"{Separator}+("obje"|"objec"|"object") { return AS_OBJECT; } -"as"{Separator}+("usua"|"usual") { return AS_VARIANT; } -"as"{Separator}+("anyt"|"anytyp"|"anytype") { return AS_VARIANT; } +"as"{Separator}+("arra"|"array") { pComp->pLex->lasttok = yytext; return AS_ARRAY; } +"as"{Separator}+("code"|"codeb"|"codebl"|"codeblo"|"codebloc"|"codeblock") { pComp->pLex->lasttok = yytext; return AS_BLOCK; } +"as"{Separator}+("stri"|"strin"|"string") { pComp->pLex->lasttok = yytext; return AS_CHARACTER; } +"as"{Separator}+("char"|"chara"|"charac"|"charact"|"characte"|"character") { pComp->pLex->lasttok = yytext; return AS_CHARACTER; } +"as"{Separator}+("clas"|"class") { pComp->pLex->lasttok = yytext; return AS_CLASS; } +"as"{Separator}+"date" { pComp->pLex->lasttok = yytext; return AS_DATE; } +"as"{Separator}+("logi"|"logic"|"logica"|"logical") { pComp->pLex->lasttok = yytext; return AS_LOGICAL; } +"as"{Separator}+("nume"|"numer"|"numeri"|"numeric") { pComp->pLex->lasttok = yytext; return AS_NUMERIC; } +"as"{Separator}+("obje"|"objec"|"object") { pComp->pLex->lasttok = yytext; return AS_OBJECT; } +"as"{Separator}+("usua"|"usual") { pComp->pLex->lasttok = yytext; return AS_VARIANT; } +"as"{Separator}+("anyt"|"anytyp"|"anytype") { pComp->pLex->lasttok = yytext; return AS_VARIANT; } -"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("usua"|"usual") { return AS_ARRAY; } -"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("anyt"|"anytyp"|"anytype") { return AS_ARRAY; } -"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("arra"|"array") { return AS_ARRAY_ARRAY; } -"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("code"|"codeb"|"codebl"|"codeblo"|"codebloc"|"codeblock") { return AS_BLOCK_ARRAY; } -"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("stri"|"strin"|"string") { return AS_CHARACTER_ARRAY; } -"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("char"|"chara"|"charac"|"charact"|"characte"|"character") { return AS_CHARACTER_ARRAY; } -"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("clas"|"class") { return AS_CLASS_ARRAY; } -"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+"date" { return AS_DATE_ARRAY; } -"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("logi"|"logic"|"logica"|"logical") { return AS_LOGICAL_ARRAY; } -"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("nume"|"numer"|"numeri"|"numeric") { return AS_NUMERIC_ARRAY; } -"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("obje"|"objec"|"object") { return AS_OBJECT_ARRAY; } +"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("usua"|"usual") { pComp->pLex->lasttok = yytext; return AS_ARRAY; } +"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("anyt"|"anytyp"|"anytype") { pComp->pLex->lasttok = yytext; return AS_ARRAY; } +"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("arra"|"array") { pComp->pLex->lasttok = yytext; return AS_ARRAY_ARRAY; } +"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("code"|"codeb"|"codebl"|"codeblo"|"codebloc"|"codeblock") { pComp->pLex->lasttok = yytext; return AS_BLOCK_ARRAY; } +"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("stri"|"strin"|"string") { pComp->pLex->lasttok = yytext; return AS_CHARACTER_ARRAY; } +"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("char"|"chara"|"charac"|"charact"|"characte"|"character") { pComp->pLex->lasttok = yytext; return AS_CHARACTER_ARRAY; } +"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("clas"|"class") { pComp->pLex->lasttok = yytext; return AS_CLASS_ARRAY; } +"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+"date" { pComp->pLex->lasttok = yytext; return AS_DATE_ARRAY; } +"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("logi"|"logic"|"logica"|"logical") { pComp->pLex->lasttok = yytext; return AS_LOGICAL_ARRAY; } +"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("nume"|"numer"|"numeri"|"numeric") { pComp->pLex->lasttok = yytext; return AS_NUMERIC_ARRAY; } +"as"{Separator}+("arra"|"array"){Separator}+"of"{Separator}+("obje"|"objec"|"object") { pComp->pLex->lasttok = yytext; return AS_OBJECT_ARRAY; } -"_hb_class" { hb_comp_iState = OPERATOR; return DECLARE_CLASS; } -"_hb_member" { hb_comp_iState = OPERATOR; return DECLARE_MEMBER; } +"_hb_class" { YY_OPERATOR_RET( DECLARE_CLASS ); } +"_hb_member" { YY_OPERATOR_RET( DECLARE_MEMBER ); } %{ /* ************************************************************************ */ %} -"#" hb_comp_iState =OPERATOR; return NE1; -"=" hb_comp_iState =OPERATOR; return yytext[ 0 ]; -"+" hb_comp_iState =OPERATOR; return yytext[ 0 ]; -"-" hb_comp_iState =OPERATOR; return yytext[ 0 ]; -"*" hb_comp_iState =OPERATOR; return yytext[ 0 ]; -[\/] hb_comp_iState =OPERATOR; return yytext[ 0 ]; -"%" hb_comp_iState =OPERATOR; return yytext[ 0 ]; -"$" hb_comp_iState =OPERATOR; return yytext[ 0 ]; -"<>"|"!=" hb_comp_iState =OPERATOR; return NE2; -":=" hb_comp_iState =OPERATOR; return INASSIGN; -"==" hb_comp_iState =OPERATOR; return EQ; -"++" hb_comp_iState =OPERATOR; return INC; -"--" hb_comp_iState =OPERATOR; return DEC; -"->" hb_comp_iState =OPERATOR; return ALIASOP; -"<=" hb_comp_iState =OPERATOR; return LE; -">=" hb_comp_iState =OPERATOR; return GE; -"+=" hb_comp_iState =OPERATOR; return PLUSEQ; -"-=" hb_comp_iState =OPERATOR; return MINUSEQ; -"*=" hb_comp_iState =OPERATOR; return MULTEQ; -"/=" hb_comp_iState =OPERATOR; return DIVEQ; -"^=" hb_comp_iState =OPERATOR; return EXPEQ; -"%=" hb_comp_iState =OPERATOR; return MODEQ; -"**"|"^" hb_comp_iState =OPERATOR; return POWER; -".and." hb_comp_iState =OPERATOR; return AND; -".or." hb_comp_iState =OPERATOR; return OR; -"!"|".not." hb_comp_iState =OPERATOR; return NOT; +"#" YY_OPERATOR_RET( NE1 ); +"=" YY_OPERATOR_RET( yytext[ 0 ] ); +"+" YY_OPERATOR_RET( yytext[ 0 ] ); +"-" YY_OPERATOR_RET( yytext[ 0 ] ); +"*" YY_OPERATOR_RET( yytext[ 0 ] ); +[\/] YY_OPERATOR_RET( yytext[ 0 ] ); +"%" YY_OPERATOR_RET( yytext[ 0 ] ); +"$" YY_OPERATOR_RET( yytext[ 0 ] ); +"<>"|"!=" YY_OPERATOR_RET( NE2 ); +":=" YY_OPERATOR_RET( INASSIGN ); +"==" YY_OPERATOR_RET( EQ ); +"++" YY_OPERATOR_RET( INC ); +"--" YY_OPERATOR_RET( DEC ); +"->" YY_OPERATOR_RET( ALIASOP ); +"<=" YY_OPERATOR_RET( LE ); +">=" YY_OPERATOR_RET( GE ); +"+=" YY_OPERATOR_RET( PLUSEQ ); +"-=" YY_OPERATOR_RET( MINUSEQ ); +"*=" YY_OPERATOR_RET( MULTEQ ); +"/=" YY_OPERATOR_RET( DIVEQ ); +"^=" YY_OPERATOR_RET( EXPEQ ); +"%=" YY_OPERATOR_RET( MODEQ ); +"**"|"^" YY_OPERATOR_RET( POWER ); +".and." YY_OPERATOR_RET( AND ); +".or." YY_OPERATOR_RET( OR ); +"!"|".not." YY_OPERATOR_RET( NOT ); "::" unput( ':' ); unput( 'f' ); unput( 'l' ); unput( 'e' ); unput( 'S' ); -"..." hb_comp_iState = OPERATOR; return EPSILON; -[,\|\#\&\.\:\<\>\@] hb_comp_iState =OPERATOR; return yytext[ 0 ]; -[\{] hb_comp_iState =LARRAY; return yytext[ 0 ]; -[\}] hb_comp_iState =RARRAY; return yytext[ 0 ]; -[\]] hb_comp_iState =RINDEX; return yytext[ 0 ]; -[\(] ++_iOpenBracket; hb_comp_iState =LSEPARATOR; return yytext[ 0 ]; -[\)] --_iOpenBracket; hb_comp_iState =RSEPARATOR; return yytext[ 0 ]; +"..." YY_OPERATOR_RET( EPSILON ); +[,\|\#\&\.\:\<\>\@] YY_OPERATOR_RET( yytext[ 0 ] ); +[\{] YY_TOKEN_RET( LARRAY, yytext[ 0 ] ); +[\}] YY_TOKEN_RET( RARRAY, yytext[ 0 ] ); +[\]] YY_TOKEN_RET( RINDEX, yytext[ 0 ] ); +[\(] YY_TOKEN_RET( LSEPARATOR, yytext[ 0 ] ); +[\)] YY_TOKEN_RET( RSEPARATOR, yytext[ 0 ] ); -[\x00-\x1F] return yytext[ 0 ]; /* see below */ -[\~\`\?\_\\] return yytext[ 0 ]; /* see below */ +[\x00-\x1F] pComp->pLex->lasttok = yytext; return yytext[ 0 ]; /* see below */ +[\~\`\?\_\\] pComp->pLex->lasttok = yytext; return yytext[ 0 ]; /* see below */ [\x7F-\xFF] { /* This have to be the last rule - any nonstandard and not handled * characters should go to grammar analyser instead of printing it * on stdout. */ + pComp->pLex->lasttok = yytext; return yytext[ 0 ]; } @@ -1739,54 +1785,58 @@ Separator {SpaceTab} /* ************************************************************************ */ %} -{InvalidNumber} BEGIN INVALIDNUM_; yylval.string = hb_strdup( yytext ); +{InvalidNumber} BEGIN INVALIDNUM_; pComp->pLex->lasttok = yylval_ptr->string = hb_strdup( yytext ); ("."|{Separator}+) { BEGIN 0; - hb_xfree( yylval.string ); + hb_xfree( yylval_ptr->string ); + pComp->pLex->lasttok = NULL; hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_NUMERIC_FORMAT, NULL, NULL ); } . { int iRet; - char *pTmp = yylval.string; + char *pTmp = yylval_ptr->string; BEGIN 0; unput( yytext[ yyleng-1 ] ); unput( '.' ); - yylval.string[ strlen(yylval.string) - 1 ] = '\0'; - iRet = yy_ConvertNumber( yylval.string ); + yylval_ptr->string[ strlen(yylval_ptr->string) - 1 ] = '\0'; + pComp->pLex->lasttok = yylval_ptr->string; + iRet = yy_ConvertNumber( yylval_ptr, yylval_ptr->string ); hb_xfree( pTmp ); return iRet; } -{Number} { return yy_ConvertNumber( yytext ); } +{Number} { pComp->pLex->lasttok = yytext; + return yy_ConvertNumber( yylval_ptr, yytext ); } -{TrueValue} { hb_comp_iState =RSEPARATOR; return TRUEVALUE; } -{FalseValue} { hb_comp_iState =RSEPARATOR; return FALSEVALUE; } +{TrueValue} { YY_TOKEN_RET( RSEPARATOR, TRUEVALUE ); } +{FalseValue} { YY_TOKEN_RET( RSEPARATOR, FALSEVALUE ); } -{Date} { return yy_ConvertDate( yytext ); } +{Date} { pComp->pLex->lasttok = yytext; + return yy_ConvertDate( yylval_ptr, yytext ); } {MacroVar} { if( yytext[ yyleng-1 ] == '.' ) yytext[ yyleng-1 ] = '\0'; - yylval.string = hb_compIdentifierNew( hb_strupr( yytext+1 ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext+1 ), TRUE ); hb_comp_iState = MACROVAR; return MACROVAR; } {MacroEnd} { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState = MACROTEXT; return MACROTEXT; } {MacroId} { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState = MACROTEXT; return MACROTEXT; } {MacroTxt} { - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState = MACROTEXT; return MACROTEXT; } @@ -1798,7 +1848,7 @@ Separator {SpaceTab} yytext[ HB_SYMBOL_NAME_LEN ] = '\0'; yyleng = HB_SYMBOL_NAME_LEN; } - yylval.string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); + pComp->pLex->lasttok = yylval_ptr->string = hb_compIdentifierNew( hb_strupr( yytext ), TRUE ); hb_comp_iState = IDENTIFIER; return IDENTIFIER; } @@ -1816,10 +1866,10 @@ int yy_lex_input( char *buffer, int iBufferSize ) { HB_SYMBOL_UNUSED( iBufferSize ); - return hb_pp_Internal( hb_comp_bPPO ? hb_comp_yyppo : NULL, buffer ); + return hb_pp_Internal( buffer ); } -static int yy_ConvertNumber( char * szBuffer ) +static int yy_ConvertNumber( YYSTYPE *yylval_ptr, char * szBuffer ) { HB_LONG lNumber; double dNumber; @@ -1827,34 +1877,40 @@ static int yy_ConvertNumber( char * szBuffer ) if( hb_compStrToNum( szBuffer, strlen( szBuffer ), &lNumber, &dNumber, &iDec, &iWidth ) ) { - yylval.valDouble.dNumber = dNumber; - yylval.valDouble.bDec = iDec; - yylval.valDouble.bWidth = iWidth; - yylval.valDouble.szValue = szBuffer; + yylval_ptr->valDouble.dNumber = dNumber; + yylval_ptr->valDouble.bDec = iDec; + yylval_ptr->valDouble.bWidth = iWidth; + yylval_ptr->valDouble.szValue = szBuffer; return NUM_DOUBLE; } else if( HB_LIM_INT16( lNumber ) ) { - yylval.valInteger.iNumber = ( int ) lNumber; - yylval.valInteger.szValue = szBuffer; + yylval_ptr->valInteger.iNumber = ( int ) lNumber; + yylval_ptr->valInteger.szValue = szBuffer; return NUM_INTEGER; } else { - yylval.valLong.lNumber = lNumber; - yylval.valLong.szValue = szBuffer; + yylval_ptr->valLong.lNumber = lNumber; + yylval_ptr->valLong.szValue = szBuffer; return NUM_LONG; } } -static int yy_ConvertDate( char * szBuffer ) +static int yy_ConvertDate( YYSTYPE *yylval_ptr, char * szBuffer ) { int year, month, day; hb_dateStrGet( szBuffer+2, &year, &month, &day ); - yylval.valLong.lNumber = hb_dateEncode( year, month, day ); - yylval.valLong.szValue = szBuffer; + yylval_ptr->valLong.lNumber = hb_dateEncode( year, month, day ); + yylval_ptr->valLong.szValue = szBuffer; return NUM_DATE; } +void hb_compParserStop( HB_COMP_PTR pComp ) +{ + HB_SYMBOL_UNUSED( pComp ); + + yy_delete_buffer( yy_current_buffer ); +} diff --git a/harbour/source/compiler/harbour.slx b/harbour/source/compiler/harbour.slx index 1acdf6a4ce..423d81656e 100644 --- a/harbour/source/compiler/harbour.slx +++ b/harbour/source/compiler/harbour.slx @@ -1135,7 +1135,7 @@ int yy_lex_input( char *buffer, int iBufferSize ) fflush( stdout ); } - return hb_pp_Internal( hb_comp_bPPO ? hb_comp_yyppo : NULL, buffer ); + return hb_pp_Internal( buffer ); } char * hb_comp_SLX_LastBlock( BOOL bReset ) diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 39c9a5e270..3778e4f498 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -1,3 +1,6 @@ +%pure-parser +%parse-param { HB_COMP_PTR pComp } +%lex-param { HB_COMP_PTR pComp } %{ /* * $Id$ @@ -44,38 +47,6 @@ /* Compile using: bison -d -v harbour.y */ -extern FILE *yyin; /* currently yacc parsed file */ -extern char *yytext; - -#ifdef __cplusplus -typedef struct yy_buffer_state *YY_BUFFER_STATE; -extern YY_BUFFER_STATE yy_create_buffer( FILE *, int ); /* yacc functions to manage multiple files */ -extern void yy_switch_to_buffer( YY_BUFFER_STATE ); /* yacc functions to manage multiple files */ -extern void yy_delete_buffer( YY_BUFFER_STATE ); /* yacc functions to manage multiple files */ -#else -extern void * yy_create_buffer( FILE *, int ); /* yacc functions to manage multiple files */ -extern void yy_switch_to_buffer( void * ); /* yacc functions to manage multiple files */ -extern void yy_delete_buffer( void * ); /* yacc functions to manage multiple files */ -#endif - -/* lex & yacc related prototypes */ -#if !defined(__GNUC__) && !defined(__IBMCPP__) - #if 0 - /* This makes BCC 551 fail with Bison 1.30, even with the - supplied harbour.simple file, which makes Bison 1.30 blow. - [vszakats] */ - void __yy_memcpy ( char*, const char*, unsigned int ); /* to satisfy Borland compiler */ - #endif -#endif -extern int yyparse( void ); /* main yacc parsing function */ -extern void yyerror( char * ); /* parsing error management function */ -extern int yylex( void ); /* main lex token function, called by yyparse() */ -#ifdef __cplusplus -extern "C" int yywrap( void ); -#else -extern int yywrap( void ); /* manages the EOF of current processed file */ -#endif - static void hb_compLoopStart( void ); static void hb_compLoopEnd( void ); static void hb_compLoopLoop( void ); @@ -161,8 +132,6 @@ USHORT hb_comp_wWithObjectCnt= 0; BOOL hb_comp_long_optimize = TRUE; BOOL hb_comp_bTextSubst = TRUE; -char * hb_comp_buffer; /* yacc input buffer */ - static HB_LOOPEXIT_PTR hb_comp_pLoops = NULL; static HB_RTVAR_PTR hb_comp_rtvars = NULL; static HB_SWITCHCMD_PTR hb_comp_pSwitch = NULL; @@ -193,15 +162,16 @@ static void hb_compDebugStart( void ) { }; } valInteger; struct { - HB_LONG lNumber; /* to hold a long number returned by lex */ - char * szValue; + HB_LONG lNumber; /* to hold a long number returned by lex */ + UCHAR bWidth; /* to hold the width of the value */ + char * szValue; } valLong; struct { - double dNumber; /* to hold a double number returned by lex */ + double dNumber; /* to hold a double number returned by lex */ /* NOTE: Intentionally using "unsigned char" instead of "BYTE" */ - unsigned char bWidth; /* to hold the width of the value */ - unsigned char bDec; /* to hold the number of decimal points in the value */ + UCHAR bWidth; /* to hold the width of the value */ + UCHAR bDec; /* to hold the number of decimal points in the value */ char * szValue; } valDouble; HB_EXPR_PTR asExpr; @@ -224,6 +194,16 @@ static void hb_compDebugStart( void ) { }; 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 + */ +extern int yylex( YYSTYPE *, HB_COMP_PTR ); /* main lex token function, called by yyparse() */ +extern int yyparse( HB_COMP_PTR ); /* main yacc parsing function */ +extern void yyerror( HB_COMP_PTR, char * ); /* parsing error management function */ +%} + + %token FUNCTION PROCEDURE IDENTIFIER RETURN NIL NUM_DOUBLE INASSIGN NUM_INTEGER NUM_LONG %token LOCAL STATIC IIF IF ELSE ELSEIF END ENDIF LITERAL TRUEVALUE FALSEVALUE %token ANNOUNCE EXTERN INIT EXIT AND OR NOT PUBLIC EQ NE1 NE2 @@ -1952,97 +1932,6 @@ Crlf : '\n' { hb_comp_bError = FALSE; } #endif #endif -void yyerror( char * s ) -{ - if( yytext[ 0 ] == '\n' ) - { - hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_YACC, s, "" ); - } - else - hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_YACC, s, yytext ); -} - - -BOOL hb_compInclude( char * szFileName, HB_PATHNAMES * pSearch ) -{ - PFILE pFile; - - HB_TRACE(HB_TR_DEBUG, ("hb_pp_compInclude(%s,%p)", szFileName, pSearch)); - - yyin = fopen( szFileName, "r" ); - if( ! yyin ) - { - if( pSearch ) - { - PHB_FNAME pFileName = hb_fsFNameSplit( szFileName ); - - while( pSearch && !yyin ) - { - char szFName[ _POSIX_PATH_MAX ]; /* filename to parse */ - - pFileName->szPath = pSearch->szPath; - hb_fsFNameMerge( szFName, pFileName ); - yyin = fopen( szFName, "r" ); - if( ! yyin ) - { - pSearch = pSearch->pNext; - if( ! pSearch ) - return FALSE; - } - } - - hb_xfree( ( void * ) pFileName ); - } - else - return FALSE; - } - - pFile = ( PFILE ) hb_xgrab( sizeof( _FILE ) ); - pFile->handle = yyin; - pFile->pBuffer = hb_xgrab( HB_PP_BUFF_SIZE ); - pFile->iBuffer = pFile->lenBuffer = 10; - pFile->szFileName = hb_strdup( szFileName ); - pFile->iLine = 0; - pFile->pPrev = hb_comp_files.pLast; - - hb_comp_files.pLast = pFile; - -#ifdef __cplusplus - yy_switch_to_buffer( ( YY_BUFFER_STATE ) ( pFile->yyBuffer = ( char * ) yy_create_buffer( yyin, 8192 * 2 ) ) ); -#else - yy_switch_to_buffer( pFile->yyBuffer = yy_create_buffer( yyin, 8192 * 2 ) ); -#endif - hb_comp_files.iFiles++; - - return TRUE; -} - -int yywrap( void ) /* handles the EOF of the currently processed file */ -{ - HB_TRACE(HB_TR_DEBUG, ("yywrap()")); - - if( hb_comp_files.iFiles == 1 ) - { - hb_xfree( hb_comp_files.pLast->pBuffer ); - hb_comp_files.pLast->pBuffer = NULL; - return 1; /* we have reached the main EOF */ - } - - return 0; -} - -void hb_compParserStop( void ) -{ - if( hb_comp_files.pLast && hb_comp_files.pLast->yyBuffer ) - { -#ifdef __cplusplus - yy_delete_buffer( (YY_BUFFER_STATE) hb_comp_files.pLast->yyBuffer ); -#else - yy_delete_buffer( (void *) hb_comp_files.pLast->yyBuffer ); -#endif - hb_comp_files.pLast->yyBuffer = NULL; - } -} /* ************************************************************************* */ @@ -2714,3 +2603,15 @@ static HB_EXPR_PTR hb_compCheckPassByRef( HB_EXPR_PTR pExpr ) } return pExpr; } + +/* ************************************************************************* */ + +void yyerror( HB_COMP_PTR pComp, char * s ) +{ + HB_SYMBOL_UNUSED( pComp ); + + if( !pComp->pLex->lasttok || pComp->pLex->lasttok[ 0 ] == '\n' ) + hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_YACC, s, "" ); + else + hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_YACC, s, pComp->pLex->lasttok ); +} diff --git a/harbour/source/compiler/hbgenerr.c b/harbour/source/compiler/hbgenerr.c index f02617a609..6d95cf21c4 100644 --- a/harbour/source/compiler/hbgenerr.c +++ b/harbour/source/compiler/hbgenerr.c @@ -137,13 +137,14 @@ char * hb_comp_szWarnings[] = void hb_compGenError( char * szErrors[], char cPrefix, int iError, const char * szError1, const char * szError2 ) { - int iLine = hb_comp_iLine - 1; + int iLine = hb_pp_line( hb_comp_data->pLex->pPP ); + char * szFile = hb_pp_fileName( hb_comp_data->pLex->pPP ); if( cPrefix != 'F' && hb_comp_bError ) return; - if( hb_comp_files.pLast && hb_comp_files.pLast->szFileName ) - fprintf( hb_comp_errFile, "\r%s(%i) ", hb_comp_files.pLast->szFileName, iLine ); + if( szFile ) + fprintf( hb_comp_errFile, "\r%s(%i) ", szFile, iLine ); fprintf( hb_comp_errFile, "Error %c%04i ", cPrefix, iError ); fprintf( hb_comp_errFile, szErrors[ iError - 1 ], szError1, szError2 ); @@ -163,12 +164,13 @@ void hb_compGenError( char * szErrors[], char cPrefix, int iError, const char * void hb_compGenWarning( char * szWarnings[], char cPrefix, int iWarning, const char * szWarning1, const char * szWarning2) { char * szText = szWarnings[ iWarning - 1 ]; - int iLine = hb_comp_iLine - 1; + int iLine = hb_pp_line( hb_comp_data->pLex->pPP ); if( ( szText[ 0 ] - '0' ) <= hb_comp_iWarnings ) { - if( hb_comp_files.pLast && hb_comp_files.pLast->szFileName ) - fprintf( hb_comp_errFile, "\r%s(%i) ", hb_comp_files.pLast->szFileName, iLine ); + char * szFile = hb_pp_fileName( hb_comp_data->pLex->pPP ); + if( szFile ) + fprintf( hb_comp_errFile, "\r%s(%i) ", szFile, iLine ); fprintf( hb_comp_errFile, "Warning %c%04i ", cPrefix, iWarning ); fprintf( hb_comp_errFile, szText + 1, szWarning1, szWarning2 ); diff --git a/harbour/source/compiler/hbident.c b/harbour/source/compiler/hbident.c index 5832a00f55..52517554d9 100644 --- a/harbour/source/compiler/hbident.c +++ b/harbour/source/compiler/hbident.c @@ -52,6 +52,8 @@ char * hb_compIdentifierNew( char * szName, BOOL bCopy ) hb_hashTableAdd( s_comp_Identifiers, (void *)szIdent, (void *)szIdent ); } + else if( !bCopy ) + hb_xfree( szName ); return szIdent; } diff --git a/harbour/source/compiler/ppcomp.c b/harbour/source/compiler/ppcomp.c index dec2dc90a5..6d9e5250fb 100644 --- a/harbour/source/compiler/ppcomp.c +++ b/harbour/source/compiler/ppcomp.c @@ -30,8 +30,6 @@ #include "hbcomp.h" #include -static PHB_PP_STATE s_pp_state = NULL; - BOOL hb_pp_NestedLiteralString = FALSE; BOOL hb_pp_LiteralEscSeq = FALSE; int hb_pp_StreamBlock = 0; @@ -40,14 +38,17 @@ char *hb_pp_STD_CH = NULL; -static void hb_pp_ErrorGen( char * szMsgTable[], char cPrefix, int iErrorCode, +static void hb_pp_ErrorGen( void * cargo, + char * szMsgTable[], char cPrefix, int iErrorCode, const char * szParam1, const char * szParam2 ) { int iLine = hb_comp_iLine; + HB_SYMBOL_UNUSED( cargo ); + /* I do not know why but compiler expect line number 1 bigger then real line number */ - hb_comp_iLine = hb_pp_line( s_pp_state ) + 1; + hb_comp_iLine = hb_pp_line( hb_comp_data->pLex->pPP ) + 1; if( cPrefix == 'W' ) hb_compGenWarning( szMsgTable, cPrefix, iErrorCode, szParam1, szParam2 ); else @@ -55,135 +56,46 @@ static void hb_pp_ErrorGen( char * szMsgTable[], char cPrefix, int iErrorCode, hb_comp_iLine = iLine; } -static FILE * hb_pp_IncludeOpen( char *szFileName, BOOL fSysFile, char * szFNameBuf ) +static void hb_pp_PragmaDump( void * cargo, char * pBuffer, ULONG ulSize, + int iLine ) { - PHB_FNAME pFileName; - FILE *file = NULL; - PFILE pFile; - BOOL fPath; - - pFileName = hb_fsFNameSplit( szFileName ); - fPath = pFileName->szPath && pFileName->szPath[ 0 ]; - errno = 0; - if( !fSysFile ) - { - if( !fPath && hb_comp_pFileName ) - pFileName->szPath = hb_comp_pFileName->szPath; - - hb_fsFNameMerge( szFNameBuf, pFileName ); - - file = fopen( szFNameBuf, "r" ); - } - - if( !file && errno != EMFILE && hb_comp_pIncludePath ) - { - HB_PATHNAMES * pSearch = hb_comp_pIncludePath; - - pFileName->szName = szFileName; - pFileName->szExtension = NULL; - while( pSearch && !file ) - { - pFileName->szPath = pSearch->szPath; - hb_fsFNameMerge( szFNameBuf, pFileName ); - file = fopen( szFNameBuf, "r" ); - pSearch = pSearch->pNext; - } - } - hb_xfree( pFileName ); - - if( file ) - { - pFile = ( PFILE ) hb_xgrab( sizeof( _FILE ) ); - pFile->handle = file; - pFile->pBuffer = hb_xgrab( HB_PP_BUFF_SIZE ); - pFile->iBuffer = pFile->lenBuffer = 10; - pFile->yyBuffer = NULL; - pFile->szFileName = hb_strdup( szFNameBuf ); - if( hb_comp_files.pLast ) - hb_comp_files.pLast->iLine = hb_comp_iLine; - hb_comp_iLine = 1; - pFile->iLine = 1; - pFile->pPrev = hb_comp_files.pLast; - hb_comp_files.pLast = pFile; - hb_comp_files.iFiles++; - } - - return file; -} - -static void hb_pp_IncludeClose( FILE * file ) -{ - if( hb_comp_files.iFiles > 0 && hb_comp_files.pLast && - file == hb_comp_files.pLast->handle ) - { - PFILE pFile; - fclose( hb_comp_files.pLast->handle ); - hb_xfree( hb_comp_files.pLast->pBuffer ); - hb_xfree( hb_comp_files.pLast->szFileName ); - pFile = ( PFILE ) ( ( PFILE ) hb_comp_files.pLast )->pPrev; -#if 0 - if( hb_comp_files.pLast->yyBuffer && hb_comp_files.iFiles == 1 ) - hb_compParserStop(); /* uses hb_comp_files.pLast */ -#endif - hb_xfree( hb_comp_files.pLast ); - hb_comp_files.pLast = pFile; - if( hb_comp_files.pLast ) - hb_comp_iLine = hb_comp_files.pLast->iLine; - hb_comp_files.iFiles--; - } -} - -static void hb_pp_PragmaDump( char * pBuffer, ULONG ulSize, int iLine ) -{ - int iSaveLine = hb_comp_iLine; PINLINE pInline; - /* I do not know why but compiler expect line number 1 bigger then - real line number */ - hb_comp_iLine = iLine + 1; + HB_SYMBOL_UNUSED( cargo ); - pInline = hb_compInlineAdd( NULL ); + pInline = hb_compInlineAdd( ( HB_COMP_PTR ) cargo, NULL, iLine ); pInline->pCode = ( BYTE * ) hb_xgrab( ulSize + 1 ); memcpy( pInline->pCode, pBuffer, ulSize ); pInline->pCode[ ulSize ] = '\0'; pInline->lPCodeSize = ulSize; - - hb_comp_iLine = iSaveLine; } -static void hb_pp_hb_inLine( char * szFunc, char * pBuffer, ULONG ulSize, int iLine ) +static void hb_pp_hb_inLine( void * cargo, char * szFunc, + char * pBuffer, ULONG ulSize, int iLine ) { - int iSaveLine = hb_comp_iLine; - - /* I do not know why but compiler expect line number 1 bigger then - real line number */ - hb_comp_iLine = iLine + 1; - if( hb_comp_iLanguage != LANG_C && hb_comp_iLanguage != LANG_OBJ_MODULE ) { hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_REQUIRES_C, NULL, NULL ); } else { - PINLINE pInline = hb_compInlineAdd( hb_compIdentifierNew( szFunc, TRUE ) ); + PINLINE pInline = hb_compInlineAdd( ( HB_COMP_PTR ) cargo, + hb_compIdentifierNew( szFunc, TRUE ), iLine ); pInline->pCode = ( BYTE * ) hb_xgrab( ulSize + 1 ); memcpy( pInline->pCode, pBuffer, ulSize ); pInline->pCode[ ulSize ] = '\0'; pInline->lPCodeSize = ulSize; - /* - * inform genc.c that hb_inLine function was generated to - * generate #include ... with additional header files - */ - hb_comp_cInlineID = '1'; } - hb_comp_iLine = iSaveLine; } -static BOOL hb_pp_CompilerSwitch( const char * szSwitch, int iValue ) +static BOOL hb_pp_CompilerSwitch( void * cargo, const char * szSwitch, + int iValue ) { BOOL fError = FALSE; int i = strlen( szSwitch ); + HB_SYMBOL_UNUSED( cargo ); + if( i > 1 && szSwitch[ i - 1 ] - '0' == iValue ) --i; @@ -273,33 +185,30 @@ void hb_pp_SetRules( BOOL fQuiet, int argc, char * argv[] ) if( szStdCh && * szStdCh <= ' ' ) szStdCh = ""; - hb_pp_Free(); - s_pp_state = hb_pp_new(); - if( s_pp_state ) + if( hb_comp_data->pLex->pPP ) { - hb_pp_init( s_pp_state, fQuiet, - hb_pp_IncludeOpen, hb_pp_IncludeClose, + hb_pp_init( hb_comp_data->pLex->pPP, fQuiet, hb_comp_data, NULL, NULL, hb_pp_ErrorGen, NULL, hb_pp_PragmaDump, HB_COMP_ISSUPPORTED( HB_COMPFLAG_HB_INLINE_PP ) ? hb_pp_hb_inLine : NULL, hb_pp_CompilerSwitch ); if( !szStdCh ) - hb_pp_setStdRules( s_pp_state ); + hb_pp_setStdRules( hb_comp_data->pLex->pPP ); else if( *szStdCh ) - hb_pp_readRules( s_pp_state, szStdCh ); + hb_pp_readRules( hb_comp_data->pLex->pPP, szStdCh ); else { printf( "Standard command definitions excluded.\n" ); fflush( stdout ); } - hb_pp_initDynDefines( s_pp_state ); + hb_pp_initDynDefines( hb_comp_data->pLex->pPP ); /* Add /D and /undef: command line or envvar defines */ hb_compChkDefines( argc, argv ); /* mark current rules as standard ones */ - hb_pp_setStdBase( s_pp_state ); + hb_pp_setStdBase( hb_comp_data->pLex->pPP ); } if( hb_comp_pFileName ) @@ -314,39 +223,9 @@ void hb_pp_SetRules( BOOL fQuiet, int argc, char * argv[] ) } } -void hb_pp_Init( void ) -{ - HB_TRACE( HB_TR_DEBUG, ( "hb_pp_Init()" ) ); - - if( s_pp_state ) - { - hb_pp_reset( s_pp_state ); - } -} - -void hb_pp_Free( void ) -{ - if( s_pp_state ) - { - hb_pp_free( s_pp_state ); - s_pp_state = NULL; - } -} - -void hb_pp_AddDefine( char *defname, char *value ) -{ - if( s_pp_state ) - hb_pp_addDefine( s_pp_state, defname, value ); -} - -void hb_pp_ParseDirective( char * szLine ) -{ - if( s_pp_state && szLine ) - hb_pp_parseLine( s_pp_state, szLine, NULL ); -} - -int hb_pp_Internal( FILE * handl_o, char * sOut ) +int hb_pp_Internal( char * sOut ) { + char * szLine; ULONG ulLen = 0; HB_TRACE(HB_TR_DEBUG, ("hb_pp_Internal(%p, %s)", handl_o, sOut)); @@ -354,48 +233,20 @@ int hb_pp_Internal( FILE * handl_o, char * sOut ) hb_pp_NestedLiteralString = FALSE; hb_pp_LiteralEscSeq = FALSE; - if( s_pp_state && hb_comp_files.iFiles > 0 ) - { - char * szLine; + if( hb_pp_StreamBlock == HB_PP_STREAM_DUMP_C ) + hb_pp_setStream( hb_comp_data->pLex->pPP, HB_PP_STREAM_INLINE_C ); - if( ! hb_pp_fileName( s_pp_state ) ) - { - hb_pp_inFile( s_pp_state, hb_comp_files.pLast->szFileName, - hb_comp_files.pLast->handle ); - } - if( handl_o && ! hb_pp_outFileName( s_pp_state ) ) - { - char szOutFileName[ _POSIX_PATH_MAX + 1 ]; - if( hb_comp_pFilePpo ) - hb_fsFNameMerge( szOutFileName, hb_comp_pFilePpo ); - else - szOutFileName[ 0 ] = '\0'; - hb_pp_outFile( s_pp_state, szOutFileName, handl_o ); - /* dirty hack but works as workaround for pure PP and compiler - API integration */ - if( handl_o == hb_comp_yyppo ) - hb_comp_yyppo = NULL; - } + szLine = hb_pp_nextLine( hb_comp_data->pLex->pPP, &ulLen ); + /* I do not know why but compiler expect line number 1 bigger then + real line number */ + hb_comp_iLine = hb_pp_line( hb_comp_data->pLex->pPP ) + 1; - if( hb_pp_StreamBlock == HB_PP_STREAM_DUMP_C ) - hb_pp_setStream( s_pp_state, HB_PP_STREAM_INLINE_C ); - - szLine = hb_pp_nextLine( s_pp_state, &ulLen ); - /* I do not know why but compiler expect line number 1 bigger then - real line number */ - hb_comp_iLine = hb_pp_line( s_pp_state ) + 1; - - if( ulLen >= HB_PP_STR_SIZE ) - hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BUFFER_OVERFLOW, NULL, NULL ); - else if( szLine ) - memcpy( sOut, szLine, ulLen + 1 ); - else - * sOut = '\0'; - } + if( ulLen >= HB_PP_STR_SIZE ) + hb_compGenError( hb_comp_szErrors, 'F', HB_COMP_ERR_BUFFER_OVERFLOW, NULL, NULL ); + else if( szLine ) + memcpy( sOut, szLine, ulLen + 1 ); else - { * sOut = '\0'; - } if( hb_comp_iLineINLINE && hb_pp_StreamBlock == 0 ) { diff --git a/harbour/source/macro/Makefile b/harbour/source/macro/Makefile index fc5b31d45d..a925dfa7e2 100644 --- a/harbour/source/macro/Makefile +++ b/harbour/source/macro/Makefile @@ -4,7 +4,7 @@ ROOT = ../../ -YACC_FLAGS = -p hb_comp +YACC_FLAGS = -p hb_macro YACC_SOURCE=macro.y @@ -29,7 +29,7 @@ else # -Ce # -Cem - slowest/smallest # see Flex documentation for full set of switches -LEX_FLAGS = -Phb_comp -C +LEX_FLAGS = -Phb_macro -C #LEX_SOURCE=macro.l diff --git a/harbour/source/macro/macro.l b/harbour/source/macro/macro.l index 78b9f0648a..3df2307d28 100644 --- a/harbour/source/macro/macro.l +++ b/harbour/source/macro/macro.l @@ -106,6 +106,14 @@ NOTE: -C controls the speed/size ratio of generated scanner #define LOOKUP 0 /* scan from the begining of line */ #define SEPARATOR -1 +#define HB_FLEX_STATE ( ( PHB_MACRO_FLEX ) pMacro->pLex )->FlexState +typedef struct +{ + ULONG pos; /* current position inside of compiled string */ + int FlexState; /* internal flex state during parsing */ + YY_BUFFER_STATE pBuffer; /* FLEX buffer */ +} +HB_MACRO_FLEX, * PHB_MACRO_FLEX; %} @@ -138,7 +146,7 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ \" BEGIN STRING2; \[ { - if( pMacro->FlexState == SEPARATOR ) + if( HB_FLEX_STATE == SEPARATOR ) BEGIN STRING3; else return '['; @@ -150,7 +158,7 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ [^\]]*\n { hb_macroError( EG_SYNTAX, YYLEX_PARAM ); BEGIN 0; } [^']*' { BEGIN 0; - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; yyleng--; yytext[yyleng] = 0; yylval_ptr->string = hb_strdup( yytext ); @@ -158,7 +166,7 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ } [^\"]*\" { BEGIN 0; - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; yyleng--; yytext[yyleng] = 0; yylval_ptr->string = hb_strdup( yytext ); @@ -166,7 +174,7 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ } [^\]]*\] { BEGIN 0; - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; yyleng--; yytext[yyleng] = 0; yylval_ptr->string = hb_strdup( yytext ); @@ -175,65 +183,65 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ {SpaceTab} ; -\n { pMacro->FlexState = LOOKUP; return '\n'; } +\n { HB_FLEX_STATE = LOOKUP; return '\n'; } %{ /* ************************************************************************ */ %} "_fie"|"_fiel"|"_field" { - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; return FIELD; } "fiel"|"field" { - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; return FIELD; } "iif" { - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; return IIF; } "if" { - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; return IF; } -"nil" { pMacro->FlexState = LOOKUP; return NIL; } +"nil" { HB_FLEX_STATE = LOOKUP; return NIL; } -"qself"{SpaceTab}*\({SpaceTab}*\) { pMacro->FlexState = LOOKUP; return SELF; } +"qself"{SpaceTab}*\({SpaceTab}*\) { HB_FLEX_STATE = LOOKUP; return SELF; } %{ /* ************************************************************************ */ %} -"#" { pMacro->FlexState = SEPARATOR; return NE1; } -"<>"|"!=" { pMacro->FlexState = SEPARATOR; return NE2; } -":=" { pMacro->FlexState = SEPARATOR; return INASSIGN; } -"==" { pMacro->FlexState = SEPARATOR; return EQ; } -"++" { pMacro->FlexState = SEPARATOR; return INC; } -"--" { pMacro->FlexState = SEPARATOR; return DEC; } -"->" { pMacro->FlexState = SEPARATOR; return ALIASOP; } -"<=" { pMacro->FlexState = SEPARATOR; return LE; } -">=" { pMacro->FlexState = SEPARATOR; return GE; } -"+=" { pMacro->FlexState = SEPARATOR; return PLUSEQ; } -"-=" { pMacro->FlexState = SEPARATOR; return MINUSEQ; } -"*=" { pMacro->FlexState = SEPARATOR; return MULTEQ; } -"/=" { pMacro->FlexState = SEPARATOR; return DIVEQ; } -"^=" { pMacro->FlexState = SEPARATOR; return EXPEQ; } -"%=" { pMacro->FlexState = SEPARATOR; return MODEQ; } -"**"|"^" { pMacro->FlexState = SEPARATOR; return POWER; } -".and." { pMacro->FlexState = SEPARATOR; return AND; } -".or." { pMacro->FlexState = SEPARATOR; return OR; } -"."[t|y]"." { pMacro->FlexState = SEPARATOR; return TRUEVALUE; } -"."[f|n]"." { pMacro->FlexState = SEPARATOR; return FALSEVALUE; } -"!"|".not." { pMacro->FlexState = SEPARATOR; return NOT; } -"::" { pMacro->FlexState = SEPARATOR; unput( ':' ); unput( 'f' ); unput( 'l' ); unput( 'e' ); unput( 'S' ); } -[\{\(] { pMacro->FlexState = SEPARATOR; return yytext[ 0 ]; } -[\=\+\-\*\/\%\$\,\|\#\&\.\:\<\>\@] { pMacro->FlexState = SEPARATOR; return yytext[ 0 ]; } -[\]\}\)] { pMacro->FlexState = LOOKUP; return yytext[ 0 ]; } +"#" { HB_FLEX_STATE = SEPARATOR; return NE1; } +"<>"|"!=" { HB_FLEX_STATE = SEPARATOR; return NE2; } +":=" { HB_FLEX_STATE = SEPARATOR; return INASSIGN; } +"==" { HB_FLEX_STATE = SEPARATOR; return EQ; } +"++" { HB_FLEX_STATE = SEPARATOR; return INC; } +"--" { HB_FLEX_STATE = SEPARATOR; return DEC; } +"->" { HB_FLEX_STATE = SEPARATOR; return ALIASOP; } +"<=" { HB_FLEX_STATE = SEPARATOR; return LE; } +">=" { HB_FLEX_STATE = SEPARATOR; return GE; } +"+=" { HB_FLEX_STATE = SEPARATOR; return PLUSEQ; } +"-=" { HB_FLEX_STATE = SEPARATOR; return MINUSEQ; } +"*=" { HB_FLEX_STATE = SEPARATOR; return MULTEQ; } +"/=" { HB_FLEX_STATE = SEPARATOR; return DIVEQ; } +"^=" { HB_FLEX_STATE = SEPARATOR; return EXPEQ; } +"%=" { HB_FLEX_STATE = SEPARATOR; return MODEQ; } +"**"|"^" { HB_FLEX_STATE = SEPARATOR; return POWER; } +".and." { HB_FLEX_STATE = SEPARATOR; return AND; } +".or." { HB_FLEX_STATE = SEPARATOR; return OR; } +"."[t|y]"." { HB_FLEX_STATE = SEPARATOR; return TRUEVALUE; } +"."[f|n]"." { HB_FLEX_STATE = SEPARATOR; return FALSEVALUE; } +"!"|".not." { HB_FLEX_STATE = SEPARATOR; return NOT; } +"::" { HB_FLEX_STATE = SEPARATOR; unput( ':' ); unput( 'f' ); unput( 'l' ); unput( 'e' ); unput( 'S' ); } +[\{\(] { HB_FLEX_STATE = SEPARATOR; return yytext[ 0 ]; } +[\=\+\-\*\/\%\$\,\|\#\&\.\:\<\>\@] { HB_FLEX_STATE = SEPARATOR; return yytext[ 0 ]; } +[\]\}\)] { HB_FLEX_STATE = LOOKUP; return yytext[ 0 ]; } [\x00-\x1F] return yytext[ 0 ]; /* see below */ [\~\`\?\_\\] return yytext[ 0 ]; /* see below */ @@ -254,7 +262,7 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ double dNumber; int iDec, iWidth; - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; if( hb_compStrToNum( yytext, strlen( yytext ), &lNumber, &dNumber, &iDec, &iWidth ) ) { @@ -285,28 +293,28 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ if( yytext[ yyleng-1 ] == '.' ) yytext[ yyleng-1 ] = '\0'; yylval_ptr->string = hb_strupr( hb_strdup( yytext+1 ) ); - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; return MACROVAR; } {MacroEnd} { HB_TRACE(HB_TR_DEBUG, ("{MacroEnd}(%s)", yytext)); yylval_ptr->string = hb_strupr( hb_strdup( yytext ) ); - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; return MACROTEXT; } {MacroId} { HB_TRACE(HB_TR_DEBUG, ("{MacroId}(%s)", yytext)); yylval_ptr->string = hb_strupr( hb_strdup( yytext ) ); - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; return MACROTEXT; } {MacroTxt} { HB_TRACE(HB_TR_DEBUG, ("{MacroTxt}(%s)", yytext)); yylval_ptr->string = hb_strupr( hb_strdup( yytext ) ); - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; return MACROTEXT; } @@ -318,7 +326,7 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ yyleng = YYLEX_PARAM->uiNameLen; } yylval_ptr->string = hb_strupr( hb_strdup( yytext ) ); - pMacro->FlexState = LOOKUP; + HB_FLEX_STATE = LOOKUP; return IDENTIFIER; } @@ -332,15 +340,27 @@ MacroTxt ({MacroVar}|{MacroEnd}|{MacroId})+ BOOL hb_macroLexNew( HB_MACRO_PTR pMacro ) { + PHB_MACRO_FLEX pLex; + YY_BUFFER_STATE pBuffer; + + HB_TRACE(HB_TR_DEBUG, ("hb_compFlexNew(%s, %i)", pMacro->string, pMacro->length)); + /* 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 */ - HB_TRACE(HB_TR_DEBUG, ("hb_compFlexNew(%s, %i)", pMacro->string, pMacro->length)); - pMacro->FlexState = LOOKUP; - pMacro->pLex = ( void * ) yy_scan_bytes( pMacro->string, pMacro->length ); + pBuffer = yy_scan_bytes( pMacro->string, pMacro->length ); + if( pBuffer ) + { + pLex = ( PHB_MACRO_FLEX ) hb_xgrab( sizeof( HB_MACRO_FLEX ) ); + pLex->pos = 0; + pLex->FlexState = LOOKUP; + pLex->pBuffer = pBuffer; + pMacro->pLex = ( void * ) pLex; + } + return pMacro->pLex != NULL; } @@ -348,46 +368,9 @@ void hb_macroLexDelete( HB_MACRO_PTR pMacro ) { if( pMacro->pLex ) { - yy_delete_buffer( ( YY_BUFFER_STATE ) pMacro->pLex ); + PHB_MACRO_FLEX pLex = ( PHB_MACRO_FLEX ) pMacro->pLex; pMacro->pLex = NULL; + yy_delete_buffer( pLex->pBuffer ); + hb_xfree( pLex ); } } - -/* -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; -} -*/ - diff --git a/harbour/source/macro/macro.y b/harbour/source/macro/macro.y index 0381173fae..6580a9c13c 100644 --- a/harbour/source/macro/macro.y +++ b/harbour/source/macro/macro.y @@ -1,4 +1,7 @@ %pure_parser +%parse-param { HB_MACRO_PTR pMacro } +%lex-param { HB_MACRO_PTR pMacro } + %{ /* * $Id$ @@ -85,27 +88,9 @@ #undef YYMALLOC #define YYMALLOC hb_xgrab -/* This is workaround of yyparse() declaration bug in bison.simple -*/ - -#if !defined(__GNUC__) && !defined(__IBMCPP__) - #if 0 - /* This makes BCC 551 fail with Bison 1.30, even with the - supplied harbour.simple file, which makes Bison 1.30 blow. - [vszakats] */ - void __yy_memcpy ( char*, const char*, unsigned int ); /* to satisfy Borland compiler */ - #endif -#endif - /* 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 int yyparse( void * ); /* to make happy some purist compiler */ -extern void yyerror( char * ); /* parsing error management function */ /* Standard checking for valid expression creation */ @@ -155,7 +140,9 @@ extern void yyerror( char * ); /* parsing error management function */ /* This must be placed after the above union - the union is * typedef-ined to YYSTYPE */ -int yylex( YYSTYPE *, HB_MACRO_PTR ); +extern int yylex( YYSTYPE *, HB_MACRO_PTR ); /* main lex token function, called by yyparse() */ +extern int yyparse( HB_MACRO_PTR ); /* main yacc parsing function */ +extern void yyerror( HB_MACRO_PTR, char * ); /* parsing error management function */ %} %{ @@ -507,13 +494,13 @@ RootParamList : EmptyExpression ',' { } } EmptyExpression { - HB_MACRO_DATA->iListElements = 1; + HB_MACRO_DATA->uiListElements = 1; $$ = hb_compExprAddListExpr( ( HB_MACRO_DATA->Flags & HB_MACRO_GEN_PARE ) ? hb_compExprNewList( $1 ) : hb_compExprNewArgList( $1 ), $4 ); } ; AsParamList : RootParamList { $$ = $1; } - | AsParamList ',' EmptyExpression { HB_MACRO_DATA->iListElements++; + | AsParamList ',' EmptyExpression { HB_MACRO_DATA->uiListElements++; $$ = hb_compExprAddListExpr( $1, $3 ); } ; @@ -814,8 +801,9 @@ IfInline : IIF '(' Expression ',' EmptyExpression ',' ** ------------------------------------------------------------------------ ** */ -void yyerror( char * s ) +void yyerror( HB_MACRO_PTR pMacro, char * s ) { + HB_SYMBOL_UNUSED( pMacro ); HB_SYMBOL_UNUSED( s ); } @@ -830,7 +818,7 @@ int hb_macroYYParse( HB_MACRO_PTR pMacro ) pMacro->status = HB_MACRO_CONT; /* NOTE: bison requires (void *) pointer */ - iResult = yyparse( ( void * ) pMacro ); + iResult = yyparse( pMacro ); /* TODO: we should free HB_EXPR list here when it will be bound with one of pMacro structure member not with static @@ -863,9 +851,9 @@ void hb_macroLexDelete( HB_MACRO_PTR pMacro ) } } -int hb_complex( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro ) +int hb_macrolex( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro ) { - PHB_PP_TOKEN pToken = hb_pp_lex( ( PHB_PP_STATE ) pMacro->pLex ); + PHB_PP_TOKEN pToken = hb_pp_lexGet( ( PHB_PP_STATE ) pMacro->pLex ); if( !pToken ) return 0; @@ -934,7 +922,7 @@ int hb_complex( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro ) return LITERAL; case HB_PP_TOKEN_LOGICAL: - return pToken->value[ 1 ] == 'Y' ? TRUEVALUE : FALSEVALUE; + return pToken->value[ 1 ] == 'T' ? TRUEVALUE : FALSEVALUE; case HB_PP_TOKEN_HASH: case HB_PP_TOKEN_DIRECTIVE: diff --git a/harbour/source/macro/macrolex.c b/harbour/source/macro/macrolex.c index 1582b1e513..e4ae5364b7 100644 --- a/harbour/source/macro/macrolex.c +++ b/harbour/source/macro/macrolex.c @@ -171,7 +171,7 @@ static int hb_lexNumConv( YYSTYPE *yylval_ptr, PHB_MACRO_LEX pLex, ULONG ulLen ) } } -int hb_complex( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro ) +int hb_macrolex( YYSTYPE *yylval_ptr, HB_MACRO_PTR pMacro ) { PHB_MACRO_LEX pLex = ( PHB_MACRO_LEX ) pMacro->pLex; diff --git a/harbour/source/pp/ppcore.c b/harbour/source/pp/ppcore.c index a72b1cf6cb..10772ab02d 100644 --- a/harbour/source/pp/ppcore.c +++ b/harbour/source/pp/ppcore.c @@ -148,6 +148,9 @@ static const HB_PP_OPERATOR s_operators[] = { ".NOT.", 5, "!" , HB_PP_TOKEN_NOT | HB_PP_TOKEN_STATIC }, { ".AND.", 5, ".AND.", HB_PP_TOKEN_AND | HB_PP_TOKEN_STATIC }, { ".OR." , 4, ".OR." , HB_PP_TOKEN_OR | HB_PP_TOKEN_STATIC }, +#ifndef HB_C52_STRICT + { "..." , 3, "..." , HB_PP_TOKEN_EPSILON | HB_PP_TOKEN_STATIC }, +#endif { "**=" , 3, "^=" , HB_PP_TOKEN_EXPEQ | HB_PP_TOKEN_STATIC }, { "**" , 2, "^" , HB_PP_TOKEN_POWER | HB_PP_TOKEN_STATIC }, { "++" , 2, "++" , HB_PP_TOKEN_INC | HB_PP_TOKEN_STATIC }, @@ -203,7 +206,7 @@ static void hb_pp_disp( PHB_PP_STATE pState, const char * szMessage ) fflush( stdout ); } else - ( pState->pDispFunc )( szMessage ); + ( pState->pDispFunc )( pState->cargo, szMessage ); } static void hb_pp_error( PHB_PP_STATE pState, char type, int iError, const char * szParam ) @@ -214,7 +217,7 @@ static void hb_pp_error( PHB_PP_STATE pState, char type, int iError, const char { if( !pState->fError ) { - ( pState->pErrorFunc )( szMsgTable, type, iError, szParam, NULL ); + ( pState->pErrorFunc )( pState->cargo, szMsgTable, type, iError, szParam, NULL ); if( type != 'W' ) pState->fError = TRUE; } @@ -612,7 +615,7 @@ static void hb_pp_readLine( PHB_PP_STATE pState ) char szLine[ 12 ]; pState->pFile->iLastDisp = iLine; - sprintf( szLine, "\r%i00", iLine ); + sprintf( szLine, "\r%i00\r", iLine ); hb_pp_disp( pState, szLine ); } } @@ -685,7 +688,8 @@ static void hb_pp_dumpEnd( PHB_PP_STATE pState ) pState->iStreamDump = HB_PP_STREAM_OFF; if( pState->pDumpFunc ) { - ( pState->pDumpFunc )( hb_membufPtr( pState->pDumpBuffer ), + ( pState->pDumpFunc )( pState->cargo, + hb_membufPtr( pState->pDumpBuffer ), hb_membufLen( pState->pDumpBuffer ), pState->iDumpLine ); @@ -857,7 +861,7 @@ static void hb_pp_getLine( PHB_PP_STATE pState ) sprintf( szFunc, "HB_INLINE_%03d", ++pState->iInLineCount ); if( pInLinePtr && * pInLinePtr ) hb_pp_tokenSetValue( *pInLinePtr, szFunc, strlen( szFunc ) ); - pState->pInLineFunc( szFunc, + pState->pInLineFunc( pState->cargo, szFunc, hb_membufPtr( pState->pStreamBuffer ), hb_membufLen( pState->pStreamBuffer ), pState->iDumpLine ); @@ -1520,7 +1524,7 @@ static void hb_pp_defineDel( PHB_PP_STATE pState, PHB_PP_TOKEN pToken ) static PHB_PP_FILE hb_pp_FileNew( PHB_PP_STATE pState, char * szFileName, BOOL fSysFile, FILE * file_in, - PHB_PP_OPEN_FUNC pOpenFunc ) + BOOL fSearchPath, PHB_PP_OPEN_FUNC pOpenFunc ) { char szFileNameBuf[ _POSIX_PATH_MAX + 1 ]; PHB_PP_FILE pFile; @@ -1529,7 +1533,7 @@ static PHB_PP_FILE hb_pp_FileNew( PHB_PP_STATE pState, char * szFileName, { if( pOpenFunc ) { - file_in = ( pOpenFunc )( szFileName, fSysFile, szFileNameBuf ); + file_in = ( pOpenFunc )( pState->cargo, szFileName, fSysFile, szFileNameBuf ); szFileName = szFileNameBuf; } else @@ -1564,7 +1568,7 @@ static PHB_PP_FILE hb_pp_FileNew( PHB_PP_STATE pState, char * szFileName, file_in = fopen( szFileName, "r" ); } - if( !file_in && errno != EMFILE && pState->pIncludePath ) + if( !file_in && errno != EMFILE && pState->pIncludePath && fSearchPath ) { HB_PATHNAMES * pPath = pState->pIncludePath; @@ -1606,12 +1610,13 @@ static PHB_PP_FILE hb_pp_FileBufNew( char * pLineBuf, ULONG ulLineBufLen ) return pFile; } -static void hb_pp_FileFree( PHB_PP_FILE pFile, PHB_PP_CLOSE_FUNC pCloseFunc ) +static void hb_pp_FileFree( PHB_PP_STATE pState, PHB_PP_FILE pFile, + PHB_PP_CLOSE_FUNC pCloseFunc ) { if( pFile->file_in ) { if( pCloseFunc ) - ( pCloseFunc )( pFile->file_in ); + ( pCloseFunc )( pState->cargo, pFile->file_in ); else fclose( pFile->file_in ); } @@ -1644,7 +1649,7 @@ static void hb_pp_InFileFree( PHB_PP_STATE pState ) { PHB_PP_FILE pFile = pState->pFile; pState->pFile = pFile->pPrev; - hb_pp_FileFree( pFile, pState->pCloseFunc ); + hb_pp_FileFree( pState, pFile, pState->pCloseFunc ); } } @@ -1705,7 +1710,8 @@ static void hb_pp_includeFile( PHB_PP_STATE pState, char * szFileName, BOOL fSys } else { - PHB_PP_FILE pFile = hb_pp_FileNew( pState, szFileName, fSysFile, NULL, pState->pOpenFunc ); + PHB_PP_FILE pFile = hb_pp_FileNew( pState, szFileName, fSysFile, NULL, + TRUE, pState->pOpenFunc ); if( pFile ) { pFile->pPrev = pState->pFile; @@ -1729,7 +1735,7 @@ static void hb_pp_includeClose( PHB_PP_STATE pState ) if( pState->pFile ) pState->pFile->fGenLineInfo = TRUE; - hb_pp_FileFree( pFile, pState->pCloseFunc ); + hb_pp_FileFree( pState, pFile, pState->pCloseFunc ); } static PHB_PP_TOKEN hb_pp_streamFuncGet( PHB_PP_TOKEN pToken, PHB_PP_TOKEN * pFuncPtr ) @@ -1859,7 +1865,7 @@ static BOOL hb_pp_setCompilerSwitch( PHB_PP_STATE pState, char * szSwitch, } if( pState->pSwitchFunc ) - fError = ( pState->pSwitchFunc )( szSwitch, iValue ); + fError = ( pState->pSwitchFunc )( pState->cargo, szSwitch, iValue ); return fError; } @@ -2293,8 +2299,14 @@ static BOOL hb_pp_matchMarkerNew( PHB_PP_TOKEN * pTokenPtr, int i = 3; do { - if( !hb_pp_tokenUnQuotedGet( &pTokenPtr, &fQuoted, TRUE ) || fQuoted || - HB_PP_TOKEN_TYPE( ( * pTokenPtr )->type ) != HB_PP_TOKEN_DOT ) + if( !hb_pp_tokenUnQuotedGet( &pTokenPtr, &fQuoted, TRUE ) || fQuoted ) + break; + if( i == 3 && HB_PP_TOKEN_TYPE( ( * pTokenPtr )->type ) == HB_PP_TOKEN_EPSILON ) + { + i = 0; + break; + } + if( HB_PP_TOKEN_TYPE( ( * pTokenPtr )->type ) != HB_PP_TOKEN_DOT ) break; } while( --i > 0 ); @@ -4326,21 +4338,6 @@ static void hb_pp_preprocesToken( PHB_PP_STATE pState ) } } -static PHB_PP_TOKEN hb_pp_getToken( PHB_PP_STATE pState ) -{ - if( pState->pTokenOut ) - { - PHB_PP_TOKEN pToken = pState->pTokenOut; - pState->pTokenOut = pToken->pNext; - hb_pp_tokenFree( pToken ); - } - - if( !pState->pTokenOut ) - hb_pp_preprocesToken( pState ); - - return pState->pTokenOut; -} - /* * exported functions */ @@ -4384,6 +4381,25 @@ void hb_pp_initRules( PHB_PP_RULE * pRulesPtr, int * piRules, } +/* + * get preprocessed token + */ +PHB_PP_TOKEN hb_pp_tokenGet( PHB_PP_STATE pState ) +{ + if( pState->pTokenOut ) + { + PHB_PP_TOKEN pToken = pState->pTokenOut; + pState->pTokenOut = pToken->pNext; + hb_pp_tokenFree( pToken ); + } + + if( !pState->pTokenOut ) + hb_pp_preprocesToken( pState ); + + return pState->pTokenOut; +} + + /* * create new PP context */ @@ -4403,13 +4419,14 @@ void hb_pp_free( PHB_PP_STATE pState ) /* * initialize PP context */ -void hb_pp_init( PHB_PP_STATE pState, BOOL fQuiet, +void hb_pp_init( PHB_PP_STATE pState, BOOL fQuiet, void * cargo, PHB_PP_OPEN_FUNC pOpenFunc, PHB_PP_CLOSE_FUNC pCloseFunc, PHB_PP_ERROR_FUNC pErrorFunc, PHB_PP_DISP_FUNC pDispFunc, PHB_PP_DUMP_FUNC pDumpFunc, PHB_PP_INLINE_FUNC pInLineFunc, PHB_PP_SWITCH_FUNC pSwitchFunc ) { pState->fQuiet = fQuiet; + pState->cargo = cargo; pState->pOpenFunc = pOpenFunc; pState->pCloseFunc = pCloseFunc; pState->pErrorFunc = pErrorFunc; @@ -4560,7 +4577,8 @@ void hb_pp_readRules( PHB_PP_STATE pState, char * szRulesFile ) hb_fsFNameMerge( szFileName, pFileName ); hb_xfree( pFileName ); - pState->pFile = hb_pp_FileNew( pState, szFileName, FALSE, NULL, pState->pOpenFunc ); + pState->pFile = hb_pp_FileNew( pState, szFileName, FALSE, NULL, + TRUE, pState->pOpenFunc ); if( !pState->pFile ) { pState->pFile = pFile; @@ -4569,10 +4587,10 @@ void hb_pp_readRules( PHB_PP_STATE pState, char * szRulesFile ) else { pState->iFiles++; - while( hb_pp_getToken( pState ) ); + while( hb_pp_tokenGet( pState ) ); if( pState->pFile ) { - hb_pp_FileFree( pState->pFile, pState->pCloseFunc ); + hb_pp_FileFree( pState, pState->pFile, pState->pCloseFunc ); pState->iFiles--; } pState->pFile = pFile; @@ -4582,29 +4600,35 @@ void hb_pp_readRules( PHB_PP_STATE pState, char * szRulesFile ) /* * close all open input files and set the given one as new */ -void hb_pp_inFile( PHB_PP_STATE pState, char * szFileName, FILE * file_in ) +BOOL hb_pp_inFile( PHB_PP_STATE pState, char * szFileName, BOOL fSearchPath, + FILE * file_in, BOOL fError ) { hb_pp_InFileFree( pState ); pState->fError = FALSE; - pState->pFile = hb_pp_FileNew( pState, szFileName, FALSE, file_in, NULL ); - if( ! pState->pFile ) - hb_pp_error( pState, 'F', HB_PP_ERR_CANNOT_OPEN_INPUT, szFileName ); - else + pState->pFile = hb_pp_FileNew( pState, szFileName, FALSE, file_in, + fSearchPath, NULL ); + if( pState->pFile ) + { pState->iFiles++; + return TRUE; + } + if( fError ) + hb_pp_error( pState, 'F', HB_PP_ERR_CANNOT_OPEN_INPUT, szFileName ); + return FALSE; } /* * set output (.ppo) file handle */ -void hb_pp_outFile( PHB_PP_STATE pState, char * szOutFileName, FILE * file_out ) +BOOL hb_pp_outFile( PHB_PP_STATE pState, char * szOutFileName, FILE * file_out ) { + pState->fError = FALSE; hb_pp_OutFileFree( pState ); if( szOutFileName ) { - pState->fError = FALSE; if( file_out ) pState->file_out = file_out; @@ -4621,6 +4645,15 @@ void hb_pp_outFile( PHB_PP_STATE pState, char * szOutFileName, FILE * file_out ) hb_pp_error( pState, 'F', HB_PP_ERR_CANNOT_CREATE_FILE, szOutFileName ); } } + return !pState->fError; +} + +/* + * check error status of last PP operation + */ +BOOL hb_pp_lasterror( PHB_PP_STATE pState ) +{ + return pState->fError; } /* @@ -4696,7 +4729,7 @@ void hb_pp_addDefine( PHB_PP_STATE pState, char * szDefName, char * szDefValue ) hb_pp_defineAdd( pState, HB_PP_CMP_CASE, 0, NULL, pMatch, pResult ); } pState->pFile = pFile->pPrev; - hb_pp_FileFree( pFile, NULL ); + hb_pp_FileFree( pState, pFile, NULL ); pState->iFiles--; } @@ -4762,7 +4795,7 @@ char * hb_pp_nextLine( PHB_PP_STATE pState, ULONG * pulLen ) else hb_membufFlush( pState->pOutputBuffer ); - while( ( pToken = hb_pp_getToken( pState ) ) != NULL ) + while( ( pToken = hb_pp_tokenGet( pState ) ) != NULL ) { #if defined( HB_PP_NO_LINEINFO_TOKEN ) int iLine; @@ -4845,7 +4878,7 @@ char * hb_pp_parseLine( PHB_PP_STATE pState, char * pLine, ULONG * pulLen ) pState->pFile = pFile; pState->iFiles++; - while( ( pToken = hb_pp_getToken( pState ) ) != NULL ) + while( ( pToken = hb_pp_tokenGet( pState ) ) != NULL ) { hb_pp_tokenStr( pToken, pState->pOutputBuffer, TRUE, TRUE, ltype ); ltype = HB_PP_TOKEN_TYPE( pToken->type ); @@ -4866,7 +4899,7 @@ char * hb_pp_parseLine( PHB_PP_STATE pState, char * pLine, ULONG * pulLen ) if( pState->pFile == pFile ) { pState->pFile = pFile->pPrev; - hb_pp_FileFree( pFile, NULL ); + hb_pp_FileFree( pState, pFile, NULL ); pState->iFiles--; } @@ -4885,7 +4918,7 @@ PHB_PP_STATE hb_pp_lexNew( char * pMacroString, ULONG ulLen ) hb_pp_getLine( pState ); pState->pTokenOut = pState->pFile->pTokenList; pState->pFile->pTokenList = NULL; - hb_pp_FileFree( pState->pFile, NULL ); + hb_pp_FileFree( pState, pState->pFile, NULL ); pState->pFile = NULL; if( pState->fError ) { @@ -4898,7 +4931,7 @@ PHB_PP_STATE hb_pp_lexNew( char * pMacroString, ULONG ulLen ) return pState; } -PHB_PP_TOKEN hb_pp_lex( PHB_PP_STATE pState ) +PHB_PP_TOKEN hb_pp_lexGet( PHB_PP_STATE pState ) { PHB_PP_TOKEN pToken = * pState->pNextTokenPtr; @@ -4917,20 +4950,110 @@ void hb_pp_tokenUpper( PHB_PP_TOKEN pToken ) if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR ) { char * value; - if( pToken->value[ pToken->len - 1 ] == '.' ) + if( pToken->len > HB_SYMBOL_NAME_LEN ) + pToken->len = HB_SYMBOL_NAME_LEN; + else if( pToken->value[ pToken->len - 1 ] == '.' ) pToken->len--; value = ( char * ) hb_xgrab( pToken->len ); - memcpy( value, pToken->value + 1, pToken->len - 1 ); + memcpy( value, pToken->value + 1, --pToken->len ); value[ pToken->len ] = '\0'; if( HB_PP_TOKEN_ALLOC( pToken->type ) ) hb_xfree( pToken->value ); + else + pToken->type &= ~HB_PP_TOKEN_STATIC; pToken->value = value; } - else if( !HB_PP_TOKEN_ALLOC( pToken->type ) ) + else { - char * value = ( char * ) hb_xgrab( pToken->len + 1 ); - memcpy( value, pToken->value, pToken->len + 1 ); - pToken->value = value; + if( !HB_PP_TOKEN_ALLOC( pToken->type ) ) + { + char * value = ( char * ) hb_xgrab( pToken->len + 1 ); + memcpy( value, pToken->value, pToken->len + 1 ); + pToken->value = value; + pToken->type &= ~HB_PP_TOKEN_STATIC; + } + if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_KEYWORD && + pToken->len > HB_SYMBOL_NAME_LEN ) + { + pToken->len = HB_SYMBOL_NAME_LEN; + pToken->value[ HB_SYMBOL_NAME_LEN ] = '\0'; + } } hb_strupr( pToken->value ); } + +/* + * convert tokens between '[' and ']' tokens into single string token + * and replace the converted tokens with the new string + */ +void hb_pp_tokenToString( PHB_PP_STATE pState, PHB_PP_TOKEN pToken ) +{ + BOOL fError = TRUE; + + hb_membufFlush( pState->pBuffer ); + if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_LEFT_SB ) + { + PHB_PP_TOKEN pTok, pFirst, pLast = NULL; + pFirst = pTok = pToken->pNext; + while( !HB_PP_TOKEN_ISEOC( pTok ) ) + { + pLast = pTok; + if( HB_PP_TOKEN_TYPE( pTok->type ) == HB_PP_TOKEN_RIGHT_SB ) + { + fError = FALSE; + pTok = pTok->pNext; + break; + } + hb_pp_tokenStr( pTok, pState->pBuffer, TRUE, FALSE, 0 ); + pTok = pTok->pNext; + } + if( pLast ) + { + pLast->pNext = NULL; + pToken->pNext = pTok; + hb_pp_tokenListFree( &pFirst ); + } + hb_pp_tokenSetValue( pToken, hb_membufPtr( pState->pBuffer ), + hb_membufLen( pState->pBuffer ) ); + HB_PP_TOKEN_SETTYPE( pToken, HB_PP_TOKEN_STRING ); + } + + if( fError ) + { + hb_membufAddCh( pState->pBuffer, '\0' ); + hb_pp_error( pState, 'E', HB_PP_ERR_STRING_TERMINATOR, + hb_membufPtr( pState->pBuffer ) ); + } +} + +char * hb_pp_tokenBlockString( PHB_PP_STATE pState, PHB_PP_TOKEN pToken, + int * piType ) +{ + * piType = 0; + hb_membufFlush( pState->pBuffer ); + if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_LEFT_CB ) + { + int iBraces = 1; + pToken = pToken->pNext; + while( iBraces && !HB_PP_TOKEN_ISEOC( pToken ) ) + { + if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_AMPERSAND ) + { + if( pToken->pNext && + HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_LEFT_PB ) + * piType |= 2; + } + else if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROVAR || + HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_MACROTEXT ) + * piType |= 1; + else if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_RIGHT_CB ) + --iBraces; + else if( HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_LEFT_CB ) + ++iBraces; + hb_pp_tokenStr( pToken, pState->pBuffer, TRUE, FALSE, 0 ); + pToken = pToken->pNext; + } + } + hb_membufAddCh( pState->pBuffer, '\0' ); + return hb_membufPtr( pState->pBuffer ); +} diff --git a/harbour/source/pp/ppgen.c b/harbour/source/pp/ppgen.c index 9e17b618fe..7a50820f4a 100644 --- a/harbour/source/pp/ppgen.c +++ b/harbour/source/pp/ppgen.c @@ -364,21 +364,25 @@ int main( int argc, char * argv[] ) if( szFile ) { - hb_pp_init( pState, fQuiet, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); - hb_pp_inFile( pState, szFile, NULL ); - if( fWrite ) + hb_pp_init( pState, fQuiet, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); + if( hb_pp_inFile( pState, szFile, TRUE, NULL, TRUE ) ) { - char szFileName[ _POSIX_PATH_MAX + 1 ]; - PHB_FNAME pFileName; + if( fWrite ) + { + char szFileName[ _POSIX_PATH_MAX + 1 ]; + PHB_FNAME pFileName; - pFileName = hb_fsFNameSplit( szFile ); - pFileName->szExtension = ".ppo"; - hb_fsFNameMerge( szFileName, pFileName ); - hb_xfree( pFileName ); + pFileName = hb_fsFNameSplit( szFile ); + pFileName->szExtension = ".ppo"; + hb_fsFNameMerge( szFileName, pFileName ); + hb_xfree( pFileName ); - hb_pp_outFile( pState, szFileName, NULL ); + hb_pp_outFile( pState, szFileName, NULL ); + } + iResult = hb_pp_preprocesfile( pState, szRuleFile ); } - iResult = hb_pp_preprocesfile( pState, szRuleFile ); + else + iResult = 1; } else { diff --git a/harbour/source/pp/pplib.c b/harbour/source/pp/pplib.c index 7679e67757..e8cb964d02 100644 --- a/harbour/source/pp/pplib.c +++ b/harbour/source/pp/pplib.c @@ -58,10 +58,13 @@ #include "hbapierr.h" #include "hbvm.h" -static void hb_pp_ErrorMessage( char * szMsgTable[], char cPrefix, int iCode, +static void hb_pp_ErrorMessage( void * cargo, char * szMsgTable[], + char cPrefix, int iCode, const char * szParam1, const char * szParam2 ) { - HB_TRACE(HB_TR_DEBUG, ("hb_pp_ErrorGen(%p, %c, %d, %s, %s)", szMsgTable, cPrefix, iCode, szParam1, szParam2)); + HB_TRACE(HB_TR_DEBUG, ("hb_pp_ErrorGen(%p, %p, %c, %d, %s, %s)", cargo, szMsgTable, cPrefix, iCode, szParam1, szParam2)); + + HB_SYMBOL_UNUSED( cargo ); /* ignore warning messages */ if( cPrefix != 'W' ) @@ -76,9 +79,10 @@ static void hb_pp_ErrorMessage( char * szMsgTable[], char cPrefix, int iCode, } } -static void hb_pp_Disp( const char * szMessage ) +static void hb_pp_Disp( void * cargo, const char * szMessage ) { /* ignore stdout messages when PP used as library */ + HB_SYMBOL_UNUSED( cargo ); HB_SYMBOL_UNUSED( szMessage ); } @@ -138,7 +142,7 @@ HB_FUNC( __PP_INIT ) { char * szPath = hb_parc( 1 ), * szStdCh = hb_parc( 2 ); - hb_pp_init( pState, TRUE, NULL, NULL, + hb_pp_init( pState, TRUE, NULL, NULL, NULL, hb_pp_ErrorMessage, hb_pp_Disp, NULL, NULL, NULL ); if( szPath ) diff --git a/harbour/source/vm/macro.c b/harbour/source/vm/macro.c index 398c5ed5cc..e2df631b8e 100644 --- a/harbour/source/vm/macro.c +++ b/harbour/source/vm/macro.c @@ -80,9 +80,6 @@ typedef struct HB_MEXPR_ { static ULONG s_macroFlags = HB_SM_SHORTCUTS; static HB_MEXPR_PTR s_macroAlloc = NULL; -static void hb_macroUseAliased( HB_ITEM_PTR, HB_ITEM_PTR, int, BYTE ); -static void hb_compMemvarCheck( char * szVarName, HB_MACRO_DECL ); - /* ************************************************************************* */ /* Allocates memory for Expression holder structure and stores it @@ -127,9 +124,7 @@ static int hb_macroParse( HB_MACRO_PTR pMacro, char * szString ) /* initialize the input buffer - it will be scanned by lex */ pMacro->string = szString; pMacro->length = strlen( szString ); - pMacro->pos = 0; - pMacro->bShortCuts = hb_comp_bShortCuts; - pMacro->pError = NULL; + pMacro->pError = NULL; HB_TRACE(HB_TR_DEBUG, ("hb_macroParse(%p, %s)", pMacro, szString)); @@ -526,11 +521,11 @@ void hb_macroGetValue( HB_ITEM_PTR pItem, BYTE iContext, BYTE flags ) char * pText; char * pOut; #endif - struMacro.Flags = HB_MACRO_GEN_PUSH; - struMacro.uiNameLen = HB_SYMBOL_NAME_LEN; - struMacro.status = HB_MACRO_CONT; - struMacro.iListElements = 0; - struMacro.supported = (flags & HB_SM_RT_MACRO) ? s_macroFlags : flags; + struMacro.Flags = HB_MACRO_GEN_PUSH; + struMacro.uiNameLen = HB_SYMBOL_NAME_LEN; + struMacro.status = HB_MACRO_CONT; + struMacro.uiListElements = 0; + struMacro.supported = (flags & HB_SM_RT_MACRO) ? s_macroFlags : flags; if( iContext != 0 ) { @@ -598,11 +593,11 @@ void hb_macroGetValue( HB_ITEM_PTR pItem, BYTE iContext, BYTE flags ) { if( iContext == HB_P_MACROPUSHLIST ) { - hb_vmPushLong( struMacro.iListElements + 1 ); + hb_vmPushLong( struMacro.uiListElements + 1 ); } else if( iContext == HB_P_MACROPUSHINDEX ) { - hb_vmPushLong( struMacro.iListElements ); + hb_vmPushLong( struMacro.uiListElements ); } } } @@ -642,30 +637,6 @@ void hb_macroSetValue( HB_ITEM_PTR pItem, BYTE flags ) } } -/* Compiles and run an aliased macro expression - generated pcode - * pops a value from the stack - * &alias->var := any - * alias->&var := any - */ -void hb_macroPopAliasedValue( HB_ITEM_PTR pAlias, HB_ITEM_PTR pVar, BYTE flags ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_macroPopAliasedValue(%p, %p)", pAlias, pVar)); - - hb_macroUseAliased( pAlias, pVar, HB_MACRO_GEN_POP, flags ); -} - -/* Compiles and run an aliased macro expression - generated pcode - * pushes a value onto the stack - * any := &alias->var - * any := alias->&var - */ -void hb_macroPushAliasedValue( HB_ITEM_PTR pAlias, HB_ITEM_PTR pVar, BYTE flags ) -{ - HB_TRACE(HB_TR_DEBUG, ("hb_macroPushAliasedValue(%p, %p)", pAlias, pVar)); - - hb_macroUseAliased( pAlias, pVar, HB_MACRO_GEN_PUSH, flags ); -} - /* * Compile and run: * &alias->var or @@ -740,6 +711,30 @@ static void hb_macroUseAliased( HB_ITEM_PTR pAlias, HB_ITEM_PTR pVar, int iFlag, } } +/* Compiles and run an aliased macro expression - generated pcode + * pops a value from the stack + * &alias->var := any + * alias->&var := any + */ +void hb_macroPopAliasedValue( HB_ITEM_PTR pAlias, HB_ITEM_PTR pVar, BYTE flags ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_macroPopAliasedValue(%p, %p)", pAlias, pVar)); + + hb_macroUseAliased( pAlias, pVar, HB_MACRO_GEN_POP, flags ); +} + +/* Compiles and run an aliased macro expression - generated pcode + * pushes a value onto the stack + * any := &alias->var + * any := alias->&var + */ +void hb_macroPushAliasedValue( HB_ITEM_PTR pAlias, HB_ITEM_PTR pVar, BYTE flags ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_macroPushAliasedValue(%p, %p)", pAlias, pVar)); + + hb_macroUseAliased( pAlias, pVar, HB_MACRO_GEN_PUSH, flags ); +} + /* Check for '&' operator and replace it with a macro variable value * Returns: the passed string if there is no '&' operator (pbNewString:=FALSE) * new string if a valid macro text substitution was found (and sets diff --git a/harbour/utils/hbpp/hbpp.c b/harbour/utils/hbpp/hbpp.c index 28bac703b6..db8c592794 100644 --- a/harbour/utils/hbpp/hbpp.c +++ b/harbour/utils/hbpp/hbpp.c @@ -252,7 +252,7 @@ int main( int argc, char * argv[] ) } hb_buffer = ( char* ) hb_xgrab( HB_PP_STR_SIZE ); - while( hb_pp_Internal( handl_o,hb_buffer ) > 0 ); + while( hb_pp_Internal_( handl_o,hb_buffer ) > 0 ); fclose( hb_comp_files.pLast->handle ); hb_xfree( hb_comp_files.pLast->pBuffer ); hb_xfree( hb_comp_files.pLast ); @@ -535,14 +535,3 @@ BOOL hb_pp_fopen( char * szFileName ) return TRUE; } - -PINLINE hb_compInlineAdd( char * szFunName ) -{ - HB_SYMBOL_UNUSED( szFunName ); - return NULL; -} - -void hb_compParserStop( void ) -{ - ; -} diff --git a/harbour/utils/hbpp/hbpp.h b/harbour/utils/hbpp/hbpp.h index 2a1a9cda66..f816ffef12 100644 --- a/harbour/utils/hbpp/hbpp.h +++ b/harbour/utils/hbpp/hbpp.h @@ -60,6 +60,9 @@ HB_EXTERN_BEGIN +typedef void * PHB_PP_STATE; +typedef void * PHB_PP_TOKEN; + struct _DEFINES; typedef struct _DEFINES { @@ -82,6 +85,28 @@ typedef struct _COMMANDS struct _COMMANDS * last; } COMMANDS; +/* #include support */ +typedef struct +{ + FILE * handle; /* handle of the opened file */ + void * pBuffer; /* file buffer */ + char * yyBuffer; /* buffer used by yyac */ + int iBuffer; /* current position in file buffer */ + int lenBuffer; /* current length of data in file buffer */ + char * szFileName; /* name of the file */ + void * pPrev; /* pointer to the previous opened file */ + void * pNext; /* pointer to the next opened file */ + int iLine; /* currently processed line number */ +} _FILE, * PFILE; /* structure to hold an opened PRG or CH */ + +/* structure to control several opened PRGs and CHs */ +typedef struct +{ + PFILE pLast; /* pointer to the last opened file */ + int iFiles; /* number of files currently opened */ +} FILES; + + #define HB_PP_STR_SIZE 12288 #define HB_PP_BUFF_SIZE 4096 @@ -116,11 +141,14 @@ extern int hb_pp_LastOutLine; extern int hb_pp_StreamBlock; extern BOOL hb_pp_NestedLiteralString; extern BOOL hb_pp_LiteralEscSeq; -extern unsigned int hb_pp_MaxTranslateCycles; +extern unsigned int hb_pp_MaxTranslateCycles; +extern HB_PATHNAMES * hb_comp_pIncludePath; +extern FILES hb_comp_files; +extern BOOL hb_comp_bPPO; +extern FILE * hb_comp_yyppo; /* PPCOMP.C exported functions */ - -extern int hb_pp_Internal( FILE *, char * ); +extern int hb_pp_Internal_( FILE *, char * ); extern void hb_pp_InternalFree( void ); #if 0 diff --git a/harbour/utils/hbpp/hbppcomp.c b/harbour/utils/hbpp/hbppcomp.c index 064ac19d58..3db4912c2c 100644 --- a/harbour/utils/hbpp/hbppcomp.c +++ b/harbour/utils/hbpp/hbppcomp.c @@ -118,7 +118,7 @@ void hb_pp_InternalFree( void ) } } -int hb_pp_Internal( FILE * handl_o, char * sOut ) +int hb_pp_Internal_( FILE * handl_o, char * sOut ) { PFILE pFile; char * ptr, * ptrOut, * tmpPtr; @@ -127,7 +127,7 @@ int hb_pp_Internal( FILE * handl_o, char * sOut ) ULONG lens; int lLine = 0; - HB_TRACE(HB_TR_DEBUG, ("hb_pp_Internal(%p, %s)", handl_o, sOut)); + HB_TRACE(HB_TR_DEBUG, ("hb_pp_Internal_(%p, %s)", handl_o, sOut)); #if defined(HB_PP_DEBUG_MEMORY) if( ! s_szLine ) diff --git a/harbour/utils/hbpp/hbppcore.c b/harbour/utils/hbpp/hbppcore.c index cfc4a45ef2..785ad61a4d 100644 --- a/harbour/utils/hbpp/hbppcore.c +++ b/harbour/utils/hbpp/hbppcore.c @@ -59,7 +59,7 @@ * * Copyright 2000 Ron Pinkas * - * hb_pp_SetRules() and related code for supportting + * hb_pp_SetRules_() and related code for supportting * replaceable rules with -w switch * * See doc/license.txt for licensing terms. @@ -276,10 +276,6 @@ void hb_pp_SetRules_( HB_INCLUDE_FUNC_PTR pIncludeFunc, BOOL bQuiet ) fclose( hb_comp_files.pLast->handle ); hb_xfree( hb_comp_files.pLast->pBuffer ); hb_xfree( hb_comp_files.pLast->szFileName ); - if( hb_comp_files.pLast->yyBuffer ) - { - hb_compParserStop( ); /* uses hb_comp_files.pLast */ - } hb_xfree( hb_comp_files.pLast ); hb_comp_files.pLast = NULL; hb_comp_files.iFiles = 0; @@ -362,7 +358,7 @@ void hb_pp_Free( void ) hb_xfree( ( void * ) hb_pp_aCondCompile ); hb_pp_aCondCompile = NULL; } - hb_pp_InternalFree( ); + hb_pp_InternalFree(); if( s_expreal ) { diff --git a/harbour/utils/hbpp/hbpplib.c b/harbour/utils/hbpp/hbpplib.c index 206495daed..f896bf6573 100644 --- a/harbour/utils/hbpp/hbpplib.c +++ b/harbour/utils/hbpp/hbpplib.c @@ -250,16 +250,5 @@ void hb_compGenWarning( char * szWarnings[], char cPrefix, int iWarning, const c HB_SYMBOL_UNUSED( szWarning2 ); } -PINLINE hb_compInlineAdd( char * szFunName ) -{ - HB_SYMBOL_UNUSED( szFunName ); - return NULL; -} - -void hb_compParserStop( void ) -{ - ; -} - #endif diff --git a/harbour/utils/hbpp/pragma.c b/harbour/utils/hbpp/pragma.c index ee86260999..f49d692fa4 100644 --- a/harbour/utils/hbpp/pragma.c +++ b/harbour/utils/hbpp/pragma.c @@ -71,6 +71,12 @@ static BOOL s_bTracePragma = FALSE; RequestLib /R */ +static PINLINE hb_compInlineAdd_( char * szFunName ) +{ + HB_SYMBOL_UNUSED( szFunName ); + return NULL; +} + BOOL hb_pp_ParsePragma( char * szLine ) { BOOL bIgnore = TRUE; @@ -199,11 +205,11 @@ BOOL hb_pp_ParsePragma( char * szLine ) hb_pp_StreamBlock = HB_PP_STREAM_DUMP_C; - pInline = hb_compInlineAdd( NULL ); + pInline = hb_compInlineAdd_( NULL ); DigestInline : - iSize = hb_pp_Internal( hb_comp_bPPO ? hb_comp_yyppo : NULL, sBuffer ); + iSize = hb_pp_Internal_( hb_comp_bPPO ? hb_comp_yyppo : NULL, sBuffer ); if( iSize == 0 ) { hb_pp_StreamBlock = 0;