Files
harbour-core/src/compiler/complex.c
Przemysław Czerpak d1a58966c8 2017-05-09 09:12 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* contrib/hbct/charswap.c
  * contrib/hbct/token1.c
  * contrib/hbnetio/netiosrv.c
  * contrib/hbssl/ssl_sock.c
  * contrib/rddads/ads1.c
  * include/hbexprb.c
  * src/common/hbprintf.c
  * src/compiler/cmdcheck.c
  * src/compiler/complex.c
  * src/compiler/gencc.c
  * src/compiler/hbmain.c
  * src/compiler/hbopt.c
  * src/pp/ppcore.c
  * src/rdd/dbf1.c
  * src/rdd/dbfcdx/dbfcdx1.c
  * src/rdd/dbffpt/dbffpt1.c
  * src/rdd/dbfntx/dbfntx1.c
  * src/rdd/hsx/hsx.c
  * src/rdd/workarea.c
  * src/rtl/dates.c
  * src/rtl/gtclip.c
  * src/rtl/gtwin/gtwin.c
  * src/rtl/gtwvt/gtwvt.c
  * src/rtl/hbgtcore.c
  * src/rtl/itemseri.c
  * src/rtl/strtoexp.c
  * src/vm/classes.c
  * src/vm/task.c
    * added and verified (following Viktor's patch)
      /* fallthrough */ comment for GCC >= 7.
    ; I haven't found any errors in existing code.
      /cc @vszakats

  * src/rdd/dbf1.c
    * minor improvement in dbf1.c
2017-05-09 09:12:35 +02:00

1381 lines
49 KiB
C

/*
* compiler lexer which converts PP tokens to the ones which
* grammar parser generated by bison can understand
*
* Copyright 2006 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file COPYING.txt. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA (or visit the web site https://www.gnu.org/).
*
* As a special exception, the Harbour Project gives permission for
* additional uses of the text contained in its release of Harbour.
*
* The exception is that, if you link the Harbour libraries with other
* files to produce an executable, this does not by itself cause the
* resulting executable to be covered by the GNU General Public License.
* Your use of that executable is in no way restricted on account of
* linking the Harbour library code into it.
*
* This exception does not however invalidate any other reasons why
* the executable file might be covered by the GNU General Public License.
*
* This exception applies only to the code released by the Harbour
* Project under the name Harbour. If you copy code from other
* Harbour Project or Free Software Foundation releases into a copy of
* Harbour, as the General Public License permits, the exception does
* not apply to the code that you add in this way. To avoid misleading
* anyone as to the status of such modified files, you must delete
* this exception notice from them.
*
* If you write modifications of your own for Harbour, it is your choice
* whether to permit this exception to apply to your modifications.
* If you do not wish that, delete this exception notice.
*
*/
#include "hbpp.h"
#include "hbcomp.h"
#include "hbdate.h"
#include "harboury.h"
#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 && \
(t)->spaces == 0 && ! 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
#define DECLARE_TYPE -10
typedef struct
{
const char * value; /* keyword name */
HB_SIZE minlen; /* minimal length */
HB_SIZE maxlen; /* maximal length */
int type; /* terminal symbol code */
}
HB_LEX_KEY;
static const HB_LEX_KEY s_keytable[] =
{
{ "ALWAYS", 4, 6, ALWAYS },
{ "ANNOUNCE", 4, 8, ANNOUNCE },
{ "AS", 2, 2, AS_TYPE },
{ "BEGIN", 4, 5, BEGINSEQ },
{ "BREAK", 4, 5, BREAK },
{ "CASE", 4, 4, CASE },
{ "DECLARE", 4, 7, DECLARE },
{ "DESCEND", 7, 7, DESCEND },
{ "DO", 2, 2, DO },
{ "DYNAMIC", 7, 7, DYNAMIC },
{ "ELSE", 4, 4, ELSE },
{ "ELSEIF", 5, 6, ELSEIF },
{ "END", 3, 3, END },
{ "ENDCASE", 4, 7, ENDCASE },
{ "ENDDO", 4, 5, ENDDO },
{ "ENDIF", 4, 5, ENDIF },
{ "ENDSEQUENCE", 6, 11, ENDSEQ },
{ "ENDSWITCH", 5, 9, ENDSWITCH },
{ "ENDWITH", 4, 7, ENDWITH },
{ "EXIT", 4, 4, EXIT },
{ "EXTERNAL", 4, 8, EXTERN },
{ "FIELD", 4, 5, FIELD },
{ "FOR", 3, 3, FOR },
{ "FUNCTION", 4, 8, FUNCTION },
{ "IF", 2, 2, IF },
{ "IIF", 3, 3, IIF },
{ "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 },
{ "OPTIONAL", 4, 8, OPTIONAL },
{ "OTHERWISE", 4, 9, OTHERWISE },
{ "PARAMETERS", 4, 10, PARAMETERS },
{ "PRIVATE", 4, 7, PRIVATE },
{ "PROCEDURE", 4, 9, PROCEDURE },
{ "PUBLIC", 4, 6, PUBLIC },
{ "QSELF", 5, 5, SELF },
{ "RECOVER", 4, 7, RECOVER },
{ "RETURN", 4, 6, RETURN },
{ "STATIC", 4, 6, STATIC },
{ "STEP", 4, 4, STEP },
{ "SWITCH", 4, 6, DOSWITCH },
{ "THREAD", 4, 6, THREAD },
{ "TO", 2, 2, TO },
{ "WHILE", 4, 5, WHILE },
{ "WITH", 4, 4, WITH },
{ "_FIELD", 4, 6, FIELD },
{ "_HB_CLASS", 9, 9, DECLARE_CLASS },
{ "_HB_MEMBER", 10, 10, DECLARE_MEMBER },
{ "_PROCREQ_", 9, 9, PROCREQ }
};
#define _AS_ARRAY 1
#define _AS_BLOCK 2
#define _AS_CHARACTER 3
#define _AS_CLASS 4
#define _AS_DATE 5
#define _AS_DATETIME 5
#define _AS_HASH 9
#define _AS_LOGICAL 6
#define _AS_NUMERIC 7
#define _AS_OBJECT 8
#define _AS_POINTER 9
#define _AS_SYMBOL 9
#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[] =
{
{ "ANYTYPE", 4, 7, _AS_VARIANT },
{ "ARRAY", 4, 5, _AS_ARRAY },
{ "BLOCK", 4, 5, _AS_BLOCK },
{ "CHARACTER", 4, 9, _AS_CHARACTER },
{ "CLASS", 4, 5, _AS_CLASS },
{ "CODEBLOCK", 4, 9, _AS_BLOCK },
{ "DATE", 4, 4, _AS_DATE },
{ "DATETIME", 5, 8, _AS_DATETIME },
{ "HASH", 4, 4, _AS_HASH },
{ "LOGICAL", 4, 7, _AS_LOGICAL },
{ "NUMERIC", 4, 7, _AS_NUMERIC },
{ "OBJECT", 4, 6, _AS_OBJECT },
{ "POINTER", 4, 7, _AS_POINTER },
{ "STRING", 4, 6, _AS_CHARACTER },
{ "SYMBOL", 4, 6, _AS_SYMBOL },
{ "TIMESTAMP", 4, 8, _AS_DATETIME },
{ "USUAL", 4, 5, _AS_VARIANT }
};
static int hb_comp_asType( PHB_PP_TOKEN pToken, HB_BOOL fArray )
{
if( pToken && HB_PP_TOKEN_TYPE( pToken->type ) == HB_PP_TOKEN_KEYWORD )
{
const HB_LEX_KEY * pKey = s_typetable;
int i = HB_SIZEOFARRAY( s_typetable );
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 )
{
const HB_LEX_KEY * pKey = s_keytable;
int i = HB_SIZEOFARRAY( s_keytable );
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( HB_UNCONST( pToken->value ) );
pToken->value = pKey->value;
pToken->type |= HB_PP_TOKEN_STATIC;
}
return pKey->type;
}
++pKey;
}
while( --i );
return IDENTIFIER;
}
static const char * hb_comp_tokenIdentifer( HB_COMP_DECL, PHB_PP_TOKEN pToken )
{
if( HB_PP_TOKEN_ALLOC( pToken->type ) )
{
pToken->value = hb_compIdentifierNew( HB_COMP_PARAM, pToken->value, HB_IDENT_FREE );
pToken->type |= HB_PP_TOKEN_STATIC;
}
return pToken->value;
}
static const char * hb_comp_tokenString( YYSTYPE * yylval_ptr, HB_COMP_DECL, PHB_PP_TOKEN pToken )
{
yylval_ptr->valChar.length = pToken->len;
yylval_ptr->valChar.string = ( char * ) HB_UNCONST( pToken->value );
yylval_ptr->valChar.dealloc = HB_FALSE;
if( HB_PP_TOKEN_ALLOC( pToken->type ) )
{
yylval_ptr->valChar.dealloc = pToken->len != strlen( pToken->value );
pToken->value = hb_compIdentifierNew( HB_COMP_PARAM, pToken->value,
yylval_ptr->valChar.dealloc ? HB_IDENT_COPY : HB_IDENT_FREE );
if( ! yylval_ptr->valChar.dealloc )
yylval_ptr->valChar.string = ( char * ) HB_UNCONST( pToken->value );
pToken->type |= HB_PP_TOKEN_STATIC;
}
return pToken->value;
}
#if defined( HB_COMPAT_FOXPRO ) || 1
static HB_BOOL hb_comp_timeDecode( PHB_PP_TOKEN pTime, long * plTime )
{
HB_MAXINT lHour, lMinute, lMilliSec;
double dNumber;
int iDec, iWidth;
if( ! pTime || HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_NUMBER ||
hb_compStrToNum( pTime->value, pTime->len, &lHour, &dNumber,
&iDec, &iWidth ) || lHour < 0 || lHour >= 24 )
return HB_FALSE;
pTime = pTime->pNext;
if( ! pTime || HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_SEND )
return HB_FALSE;
pTime = pTime->pNext;
if( ! pTime || HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_NUMBER ||
hb_compStrToNum( pTime->value, pTime->len, &lMinute, &dNumber,
&iDec, &iWidth ) || lMinute < 0 || lMinute >= 60 )
return HB_FALSE;
pTime = pTime->pNext;
if( ! pTime )
return HB_FALSE;
if( HB_PP_TOKEN_TYPE( pTime->type ) == HB_PP_TOKEN_SEND )
{
pTime = pTime->pNext;
if( ! pTime || HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_NUMBER )
return HB_FALSE;
if( hb_compStrToNum( pTime->value, pTime->len, &lMilliSec, &dNumber,
&iDec, &iWidth ) )
{
if( dNumber < 0.0 || dNumber >= 60.0 )
return HB_FALSE;
lMilliSec = ( HB_MAXINT ) ( dNumber * 1000 + 0.05 / HB_MILLISECS_PER_DAY );
if( lMilliSec == 60000 )
--lMilliSec;
}
else if( lMilliSec < 0 || lMilliSec >= 60 )
return HB_FALSE;
else
lMilliSec *= 1000;
pTime = pTime->pNext;
}
else
lMilliSec = 0;
if( HB_PP_TOKEN_TYPE( pTime->type ) == HB_PP_TOKEN_KEYWORD &&
lHour > 0 && lHour <= 12 )
{
if( ( pTime->len == 1 &&
( pTime->value[ 0 ] == 'A' || pTime->value[ 0 ] == 'a' ) ) ||
( pTime->len == 2 && hb_stricmp( pTime->value, "AM" ) == 0 ) )
{
if( lHour == 12 )
lHour = 0;
pTime = pTime->pNext;
}
else if( ( pTime->len == 1 &&
( pTime->value[ 0 ] == 'P' || pTime->value[ 0 ] == 'p' ) ) ||
( pTime->len == 2 && hb_stricmp( pTime->value, "PM" ) == 0 ) )
{
if( lHour < 12 )
lHour += 12;
pTime = pTime->pNext;
}
}
if( ! pTime || HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_RIGHT_CB )
return HB_FALSE;
*plTime = ( long ) ( ( lHour * 60 + lMinute ) * 60000 + lMilliSec );
return HB_TRUE;
}
static int hb_comp_dayTimeDecode( PHB_COMP_LEX pLex, PHB_PP_TOKEN pToken,
YYSTYPE * yylval_ptr )
{
/* TODO: decode datetime in VFP strict date form:
* {^YYYY/MM/DD[,][HH[:MM[:SS][.CCC]][A|P]]}
* VFP accepts slash, dot or hyphen as date delimiter and
* 12 or 24-hour formatted time,
* If only hours are included in time part then comma have to
* be used to separate date and time parts or it's necesary
* to follow the hours with a colon.
* { ^ <YEAR> <sep:/.-> <MONTH> <sep:/.-> <DAY> [[<sep2:,>]
* [ <HOUR> [ : <MIN> [ : <SEC> [ . <FRAQ> ] ] ] [AM|PP] ] }
*/
PHB_PP_TOKEN pYear, pMonth, pDay, pTime = NULL;
HB_MAXINT lYear = 0, lMonth = 0, lDay = 0;
long lDate = 0, lTime = 0;
double dNumber;
int iDec, iWidth, iType = 0;
pYear = pToken->pNext->pNext;
if( pYear && HB_PP_TOKEN_TYPE( pYear->type ) == HB_PP_TOKEN_NUMBER &&
pYear->pNext )
{
if( ( HB_PP_TOKEN_TYPE( pYear->pNext->type ) == HB_PP_TOKEN_DIV ||
HB_PP_TOKEN_TYPE( pYear->pNext->type ) == HB_PP_TOKEN_MINUS ) &&
! hb_compStrToNum( pYear->value, pYear->len, &lYear, &dNumber,
&iDec, &iWidth ) )
{
pMonth = pYear->pNext->pNext;
if( pMonth && HB_PP_TOKEN_TYPE( pMonth->type ) == HB_PP_TOKEN_NUMBER &&
pMonth->pNext && HB_PP_TOKEN_TYPE( pYear->pNext->type ) ==
HB_PP_TOKEN_TYPE( pMonth->pNext->type ) &&
! hb_compStrToNum( pMonth->value, pMonth->len, &lMonth, &dNumber,
&iDec, &iWidth ) )
{
pDay = pMonth->pNext->pNext;
if( pDay && HB_PP_TOKEN_TYPE( pDay->type ) == HB_PP_TOKEN_NUMBER &&
pDay->pNext &&
! hb_compStrToNum( pDay->value, pDay->len, &lDay, &dNumber,
&iDec, &iWidth ) )
{
pTime = pDay->pNext;
}
}
}
else if( HB_PP_TOKEN_TYPE( pYear->pNext->type ) == HB_PP_TOKEN_NUMBER &&
pYear->pNext->pNext )
{
if( hb_compStrToNum( pYear->value, pYear->len, &lYear, &dNumber,
&iDec, &iWidth ) )
{
if( iDec == 2 )
{
lYear = ( HB_MAXINT ) dNumber;
lMonth = ( HB_MAXINT ) ( dNumber * 100 + 0.1 ) % 100;
pDay = pYear->pNext;
if( hb_compStrToNum( pDay->value, pDay->len, &lDay, &dNumber,
&iDec, &iWidth ) )
{
if( iDec == 2 )
{
lDay = ( HB_MAXINT ) ( dNumber * 100 + 0.1 );
pTime = pDay->pNext;
}
}
}
}
}
if( pTime )
{
lDate = hb_dateEncode( ( int ) lYear, ( int ) lMonth, ( int ) lDay );
if( lDate != 0 || ( lYear == 0 && lMonth == 0 && lDay == 0 ) )
{
iType = NUM_DATE;
if( HB_PP_TOKEN_TYPE( pTime->type ) != HB_PP_TOKEN_RIGHT_CB )
{
if( HB_PP_TOKEN_TYPE( pTime->type ) == HB_PP_TOKEN_COMMA )
pTime = pTime->pNext;
iType = hb_comp_timeDecode( pTime, &lTime ) ? TIMESTAMP : 0;
}
}
}
else if( hb_comp_timeDecode( pYear, &lTime ) )
iType = TIMESTAMP;
}
if( iType )
{
while( HB_PP_TOKEN_TYPE( pToken->type ) != HB_PP_TOKEN_RIGHT_CB )
pToken = hb_pp_tokenGet( pLex->pPP );
if( iType == TIMESTAMP )
{
yylval_ptr->valTimeStamp.date = lDate;
yylval_ptr->valTimeStamp.time = lTime;
}
else
yylval_ptr->valLong.lNumber = lDate;
pLex->iState = LITERAL;
}
return iType;
}
#endif
extern int hb_comp_yylex( YYSTYPE * yylval_ptr, HB_COMP_DECL );
int hb_comp_yylex( YYSTYPE * yylval_ptr, HB_COMP_DECL )
{
PHB_COMP_LEX pLex = HB_COMP_PARAM->pLex;
PHB_PP_TOKEN pToken = hb_pp_tokenGet( pLex->pPP );
if( pLex->fEol )
{
pLex->fEol = HB_FALSE;
HB_COMP_PARAM->currLine++;
}
if( ! pToken || HB_COMP_PARAM->fExit )
{
pLex->lasttok = NULL;
return 0;
}
pLex->lasttok = pToken->value;
switch( HB_PP_TOKEN_TYPE( pToken->type ) )
{
case HB_PP_TOKEN_NUMBER:
{
HB_MAXINT 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 = ( HB_UCHAR ) iDec;
yylval_ptr->valDouble.bWidth = ( HB_UCHAR ) iWidth;
return NUM_DOUBLE;
}
else
{
yylval_ptr->valLong.lNumber = lNumber;
yylval_ptr->valLong.bWidth = ( HB_UCHAR ) iWidth;
return NUM_LONG;
}
}
case HB_PP_TOKEN_DATE:
{
int iYear, iMonth, iDay;
pLex->iState = LITERAL;
if( pToken->value[ 0 ] == '0' &&
( pToken->value[ 1 ] == 'D' || pToken->value[ 1 ] == 'd' ) )
{
if( pToken->len == 10 )
{
hb_dateStrGet( pToken->value + 2, &iYear, &iMonth, &iDay );
}
else
{
iYear = iMonth = iDay = 0;
if( pToken->len != 3 || pToken->value[ 2 ] != '0' )
iYear = -1;
}
}
else if( ! hb_timeStampStrGet( pToken->value, &iYear, &iMonth, &iDay, NULL, NULL, NULL, NULL ) )
iYear = -1;
yylval_ptr->valLong.lNumber = hb_dateEncode( iYear, iMonth, iDay );
if( yylval_ptr->valLong.lNumber == 0 &&
( iYear != 0 || iMonth != 0 || iDay != 0 ) )
{
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_DATE, pToken->value, NULL );
}
return NUM_DATE;
}
case HB_PP_TOKEN_TIMESTAMP:
pLex->iState = LITERAL;
if( ! hb_timeStampStrGetDT( pToken->value,
&yylval_ptr->valTimeStamp.date,
&yylval_ptr->valTimeStamp.time ) )
{
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_TIMESTAMP, pToken->value, NULL );
}
return TIMESTAMP;
case HB_PP_TOKEN_STRING:
pLex->iState = LITERAL;
pLex->lasttok = hb_comp_tokenString( yylval_ptr, HB_COMP_PARAM, 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( HB_COMP_PARAM, pToken );
return MACROVAR;
case HB_PP_TOKEN_MACROTEXT:
pLex->iState = MACROTEXT;
hb_pp_tokenUpper( pToken );
pLex->lasttok = yylval_ptr->string =
hb_comp_tokenIdentifer( HB_COMP_PARAM, 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 IN:
case WITH:
case WHILE:
case DOSWITCH:
case WITHOBJECT:
pLex->iState = LITERAL;
hb_pp_tokenToString( pLex->pPP, pToken );
pLex->lasttok = hb_comp_tokenString( yylval_ptr, HB_COMP_PARAM,
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 )
{
if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_PIPE )
{
yylval_ptr->asCodeblock.string = hb_strdup(
hb_pp_tokenBlockString( pLex->pPP, pToken,
&yylval_ptr->asCodeblock.flags,
&yylval_ptr->asCodeblock.length ) );
hb_pp_tokenGet( pLex->pPP );
return CBSTART;
}
#if defined( HB_COMPAT_FOXPRO ) || 1
else if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_POWER )
{
int iType = hb_comp_dayTimeDecode( pLex, pToken, yylval_ptr );
if( iType )
return iType;
}
#endif
}
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";
pLex->iState = IDENTIFIER;
return IDENTIFIER;
}
pLex->iState = OPERATOR;
return ( HB_UCHAR ) pToken->value[ 0 ];
case HB_PP_TOKEN_EQ:
if( HB_SUPPORT_HARBOUR && pToken->pNext && pToken->pNext->spaces == 0 &&
HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_GT )
{
hb_pp_tokenGet( pLex->pPP );
pLex->iState = OPERATOR;
return HASHOP;
}
/* fallthrough */
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 ( HB_UCHAR ) pToken->value[ 0 ];
case HB_PP_TOKEN_EOL:
pLex->fEol = HB_TRUE;
case HB_PP_TOKEN_EOC:
pLex->iState = LOOKUP;
return ( HB_UCHAR ) 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( HB_COMP_PARAM, pToken );
switch( iType )
{
case FUNCTION:
case PROCEDURE:
if( HB_SUPPORT_HARBOUR &&
( ( pLex->iState != LOOKUP && pLex->iState != STATIC &&
pLex->iState != INIT && pLex->iState != EXIT ) ||
HB_PP_TOKEN_ISEOC( pToken->pNext ) ||
HB_PP_TOKEN_TYPE( pToken->pNext->type ) != HB_PP_TOKEN_KEYWORD ) )
{
iType = IDENTIFIER;
break;
}
pLex->iState = iType;
return pLex->iState;
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 BEGINSEQ:
if( pLex->iState == LOOKUP && pToken->pNext &&
HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD )
{
if( pToken->pNext->len >= 4 && pToken->pNext->len <= 8 &&
hb_strnicmp( "SEQUENCE", pToken->pNext->value, pToken->pNext->len ) == 0 )
{
hb_pp_tokenGet( pLex->pPP );
pLex->iState = BEGINSEQ;
return BEGINSEQ;
}
}
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( HB_PP_TOKEN_ISEOC( pToken->pNext ) )
{
pLex->iState = END;
return END;
}
else if( 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 );
pLex->iState = ENDSEQ;
return ENDSEQ;
}
if( ! HB_SUPPORT_HARBOUR && HB_COMP_PARAM->iSyntaxCheckOnly < 2 )
{
/* 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_PARAM, hb_comp_szErrors, 'E',
HB_COMP_ERR_ENDIF, NULL, NULL );
}
}
iType = IDENTIFIER;
break;
case ELSE:
if( HB_SUPPORT_HARBOUR &&
( pLex->iState != LOOKUP ||
! HB_PP_TOKEN_ISEOC( pToken->pNext ) ) )
{
iType = IDENTIFIER;
break;
}
pLex->iState = ELSE;
return ELSE;
case ELSEIF:
case CASE:
if( HB_SUPPORT_HARBOUR &&
( pLex->iState != LOOKUP ||
HB_PP_TOKEN_ISEOC( pToken->pNext ) ||
HB_PP_LEX_NEEDLEFT( pToken->pNext ) ) )
{
iType = IDENTIFIER;
break;
}
pLex->iState = iType;
return iType;
case ENDIF:
case ENDCASE:
case ENDDO:
if( HB_SUPPORT_HARBOUR &&
( pLex->iState != LOOKUP ||
! HB_PP_TOKEN_ISEOC( pToken->pNext ) ) )
{
iType = IDENTIFIER;
break;
}
pLex->iState = iType;
return iType;
case OTHERWISE:
case ENDSEQ:
case ENDSWITCH:
case ENDWITH:
case ALWAYS:
if( pLex->iState == LOOKUP && HB_PP_TOKEN_ISEOC( pToken->pNext ) )
{
pLex->iState = iType;
return iType;
}
iType = IDENTIFIER;
break;
case FOR:
if( pLex->iState == LOOKUP &&
! HB_PP_TOKEN_ISEOC( pToken->pNext ) )
{
PHB_PP_TOKEN pNext = pToken->pNext;
if( HB_PP_TOKEN_TYPE( pNext->type ) == HB_PP_TOKEN_KEYWORD &&
pNext->pNext &&
HB_PP_TOKEN_TYPE( pNext->pNext->type ) == HB_PP_TOKEN_KEYWORD &&
hb_stricmp( "EACH", pNext->value ) == 0 )
{
hb_pp_tokenGet( pLex->pPP );
pLex->iState = FOREACH;
return FOREACH;
}
if( ! hb_pp_tokenNextExp( &pNext ) && pNext &&
HB_PP_TOKEN_TYPE( pNext->type ) == HB_PP_TOKEN_KEYWORD &&
hb_stricmp( "TO", pNext->value ) == 0 )
{
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 &&
HB_PP_TOKEN_ISEOC( pToken->pNext->pNext ) ) )
{
pLex->iState = iType;
return iType;
}
if( ! HB_SUPPORT_HARBOUR && HB_COMP_PARAM->iSyntaxCheckOnly < 2 )
{
/* 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_PARAM, hb_comp_szErrors, 'E',
HB_COMP_ERR_NEXTFOR, NULL, NULL );
}
}
iType = IDENTIFIER;
break;
case RETURN:
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 ) ) )
{
pLex->iState = iType;
return iType;
}
iType = IDENTIFIER;
break;
case WHILE:
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 &&
! HB_PP_TOKEN_ISEOC( pToken->pNext ) )
{
if( 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_AMPERSAND )
{
pLex->iState = PRIVATE;
return PRIVATE;
}
else if( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD )
{
if( 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_ASSIGN ||
( 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 <args>] */
! 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 <exp> */
hb_pp_tokenGet( pLex->pPP );
pLex->iState = WHILE;
return WHILE;
}
/* DO identifier [WITH <args>] */
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( HB_COMP_PARAM, 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 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->len >= 4 &&
hb_strnicmp( "OBJECT", pToken->pNext->value,
pToken->pNext->len ) == 0 )
{
hb_pp_tokenGet( pLex->pPP );
pLex->iState = WITHOBJECT;
return WITHOBJECT;
}
else if( pLex->iState == MACROVAR ||
pLex->iState == MACROTEXT ||
pLex->iState == IDENTIFIER ||
pLex->iState == BEGINSEQ )
{
pLex->iState = WITH;
return WITH;
}
}
iType = IDENTIFIER;
break;
case IIF:
if( pLex->iState == FUNCTION || pLex->iState == PROCEDURE ||
( ! HB_SUPPORT_HARBOUR && HB_PP_TOKEN_ISEOC( pToken->pNext ) ) )
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E',
HB_COMP_ERR_SYNTAX, "IIF", NULL );
else if( pToken->pNext &&
HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB )
{
pLex->iState = IIF;
return IIF;
}
else if( ! HB_SUPPORT_HARBOUR )
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E',
HB_COMP_ERR_SYNTAX, pToken->pNext->value, NULL );
else
iType = IDENTIFIER;
break;
case IF:
if( pLex->iState == FUNCTION || pLex->iState == PROCEDURE ||
( ! HB_SUPPORT_HARBOUR && HB_PP_TOKEN_ISEOC( pToken->pNext ) ) )
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E',
HB_COMP_ERR_SYNTAX, "IF", NULL );
else if( pToken->pNext &&
HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_PB )
{
if( pLex->iState == LOOKUP )
{
PHB_PP_TOKEN pNext = pToken->pNext->pNext; /* COND EXP */
pLex->iState = IF;
if( hb_pp_tokenNextExp( &pNext ) ) /* TRUE EXP */
{
if( hb_pp_tokenNextExp( &pNext ) ) /* FALSE EXP */
{
if( ! hb_pp_tokenNextExp( &pNext ) && pNext &&
HB_PP_TOKEN_TYPE( pNext->type ) == HB_PP_TOKEN_RIGHT_PB )
pLex->iState = IIF;
}
}
}
else
pLex->iState = IIF;
return pLex->iState;
}
else if( HB_PP_LEX_NEEDLEFT( pToken->pNext ) || pLex->iState != LOOKUP )
{
if( ! HB_SUPPORT_HARBOUR )
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E',
HB_COMP_ERR_SYNTAX2, pToken->pNext->value, "IF" );
}
else
{
pLex->iState = IF;
return IF;
}
iType = IDENTIFIER;
break;
case PROCREQ:
if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( 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 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 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, HB_FALSE );
if( iAs )
{
pLex->iState = DECLARE_TYPE;
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, HB_TRUE );
if( iAsArray )
{
hb_pp_tokenGet( pLex->pPP );
hb_pp_tokenGet( pLex->pPP );
return iAsArray;
}
}
return iAs;
}
iType = IDENTIFIER;
break;
}
case DECLARE_CLASS:
if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( pToken->pNext ) &&
HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD )
{
pLex->iState = DECLARE_TYPE;
return DECLARE_CLASS;
}
iType = IDENTIFIER;
break;
case DECLARE_MEMBER:
if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( pToken->pNext ) &&
( HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD ||
HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_LEFT_CB ) )
{
pLex->iState = OPERATOR;
return DECLARE_MEMBER;
}
iType = IDENTIFIER;
break;
case THREAD:
if( pLex->iState == LOOKUP && ! HB_PP_TOKEN_ISEOC( pToken->pNext ) &&
HB_PP_TOKEN_TYPE( pToken->pNext->type ) == HB_PP_TOKEN_KEYWORD &&
pToken->pNext->len >= 4 &&
hb_strnicmp( "STATIC", pToken->pNext->value,
pToken->pNext->len ) == 0 )
{
pLex->iState = LOOKUP;
return iType;
}
iType = IDENTIFIER;
break;
case IN:
if( pLex->iState == IDENTIFIER )
{
pLex->iState = iType;
return iType;
}
break;
case NIL:
if( pLex->iState == DECLARE_TYPE )
iType = IDENTIFIER;
break;
case EXIT:
case LOOP:
case LOCAL:
case STATIC:
case MEMVAR:
case PUBLIC:
case PRIVATE:
case PARAMETERS:
case EXTERN:
case DYNAMIC:
case ANNOUNCE:
if( pLex->iState == LOOKUP )
{
pLex->iState = iType;
return iType;
}
break;
case TO:
case STEP:
case OPTIONAL:
case DESCEND:
break;
}
pLex->iState = IDENTIFIER;
return iType;
}
default:
return ( HB_UCHAR ) pToken->value[ 0 ];
}
}
void hb_compParserRun( HB_COMP_DECL )
{
YYSTYPE yylval;
int iToken;
while( ! HB_COMP_PARAM->fExit && HB_COMP_PARAM->iErrorCount == 0 )
{
if( HB_COMP_PARAM->fSingleModule )
{
PHB_PP_TOKEN pToken = hb_pp_tokenGet( HB_COMP_PARAM->pLex->pPP );
if( ! pToken )
break;
}
else
{
iToken = hb_comp_yylex( &yylval, HB_COMP_PARAM );
if( iToken == 0 )
break;
if( iToken == DOIDENT )
hb_compModuleAdd( HB_COMP_PARAM, yylval.string, HB_FALSE );
else if( iToken == PROCREQ )
{
iToken = hb_comp_yylex( &yylval, HB_COMP_PARAM );
if( iToken == LITERAL )
{
const char * szFile, * szExt = NULL;
if( yylval.valChar.dealloc )
szFile = hb_compIdentifierNew( HB_COMP_PARAM, yylval.valChar.string, HB_IDENT_FREE );
else
szFile = yylval.valChar.string;
iToken = hb_comp_yylex( &yylval, HB_COMP_PARAM );
if( iToken == '+' )
{
iToken = hb_comp_yylex( &yylval, HB_COMP_PARAM );
if( iToken == LITERAL )
{
if( yylval.valChar.dealloc )
szExt = hb_compIdentifierNew( HB_COMP_PARAM, yylval.valChar.string, HB_IDENT_FREE );
else
szExt = yylval.valChar.string;
}
iToken = hb_comp_yylex( &yylval, HB_COMP_PARAM );
}
if( iToken == ')' )
{
if( szExt && *szExt )
szFile = hb_compIdentifierNew( HB_COMP_PARAM,
hb_xstrcpy( NULL, szFile, szExt, NULL ), HB_IDENT_FREE );
hb_compModuleAdd( HB_COMP_PARAM, szFile, HB_FALSE );
}
}
}
}
}
}
void hb_compParserStop( HB_COMP_DECL )
{
HB_SYMBOL_UNUSED( HB_COMP_PARAM );
}