* harbour/include/std.ch
* cover ENDSEQUENCE translation with HB_C52_STRICT macro
+ added translations for END SWITCH, END WITH, END OBJECT
* harbour/source/compiler/complex.c
* harbour/source/compiler/harbour.y
* harbour/source/compiler/harbour.yyc
* harbour/source/compiler/harbour.yyh
+ added support for ENDSEQ[UENCE], ENDSW[ITCH] and ENDW[ITH]
* harbour/source/rtl/hbgtcore.c
! changed string to color number translation to be fully Clipper
compatible. Now I do not know any examples which we translate
differently - if someone will find any them then please inform me.
The only one intentional difference between Harbour and Clipper
is in color number to string translation and background highlighting
attribute "*", Clipper put it just before "/" as part of foreground
color (f.e.: 248 => "N*+/W") but Harbour as part background color
(f.e.: 248 => "N+/W*") - Clipper compatible behavior is enabled when
Harbour is compiled with HB_C52_STRICT macro
* harbour/utils/hbtest/rt_misc.prg
* control the position of background highlighting attribute (*) in
expected results depending on HB_C52_STRICT. Harbour passes correctly
all included color translation tests.
1139 lines
41 KiB
C
1139 lines
41 KiB
C
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* 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>
|
|
* www - http://www.harbour-project.org
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, 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. If not, write to
|
|
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
* Boston, MA 02111-1307 USA (or visit the web site http://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
|
|
|
|
|
|
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[] =
|
|
{
|
|
{ "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 },
|
|
{ "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_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[] =
|
|
{
|
|
{ "ANYTYPE", 4, 7, _AS_VARIANT },
|
|
{ "ARRAY", 4, 5, _AS_ARRAY },
|
|
{ "CHARACTER", 4, 9, _AS_CHARACTER },
|
|
{ "CLASS", 4, 5, _AS_CLASS },
|
|
{ "CODEBLOCK", 4, 9, _AS_BLOCK },
|
|
{ "DATE", 4, 4, _AS_DATE },
|
|
{ "LOGICAL", 4, 7, _AS_LOGICAL },
|
|
{ "NUMERIC", 4, 7, _AS_NUMERIC },
|
|
{ "OBJECT", 4, 6, _AS_OBJECT },
|
|
{ "STRING", 4, 6, _AS_CHARACTER },
|
|
{ "USUAL", 4, 5, _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( 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 char * hb_comp_tokenString( YYSTYPE *yylval_ptr, HB_COMP_DECL, PHB_PP_TOKEN pToken )
|
|
{
|
|
yylval_ptr->valChar.length = pToken->len;
|
|
yylval_ptr->valChar.string = pToken->value;
|
|
yylval_ptr->valChar.dealloc = FALSE;
|
|
if( HB_PP_TOKEN_ALLOC( pToken->type ) )
|
|
{
|
|
yylval_ptr->valChar.dealloc = ( ULONG ) 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 = pToken->value;
|
|
pToken->type |= HB_PP_TOKEN_STATIC;
|
|
}
|
|
return pToken->value;
|
|
}
|
|
|
|
int hb_complex( 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 = 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_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;
|
|
|
|
if( yylval_ptr->valLong.lNumber == 0 &&
|
|
strcmp( pToken->value + 2, "0" ) != 0 &&
|
|
strcmp( pToken->value + 2, "00000000" ) != 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_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 WITH:
|
|
case WHILE:
|
|
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 &&
|
|
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;
|
|
}
|
|
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 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;
|
|
}
|
|
/* no break */
|
|
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:
|
|
pLex->fEol = TRUE;
|
|
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( HB_COMP_PARAM, pToken );
|
|
switch( iType )
|
|
{
|
|
case FUNCTION:
|
|
case PROCEDURE:
|
|
if( HB_SUPPORT_HARBOUR && ( pLex->iState != LOOKUP ||
|
|
( !HB_PP_TOKEN_ISEOC( pToken->pNext ) &&
|
|
HB_PP_LEX_NEEDLEFT( pToken->pNext ) ) ) &&
|
|
pLex->iState != INIT && pLex->iState != EXIT &&
|
|
pLex->iState != STATIC )
|
|
{
|
|
iType = IDENTIFIER;
|
|
break;
|
|
}
|
|
/* Clipper accepts FUNCTION and PROCEDURE in one context only */
|
|
if( !pToken->pNext ||
|
|
HB_PP_TOKEN_TYPE( pToken->pNext->type ) != HB_PP_TOKEN_KEYWORD )
|
|
hb_compGenError( HB_COMP_PARAM, 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 )
|
|
{
|
|
if( 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 ALWAYS:
|
|
if( pLex->iState == LOOKUP && HB_PP_TOKEN_ISEOC( pToken->pNext ) )
|
|
{
|
|
pLex->iState = ALWAYS;
|
|
return ALWAYS;
|
|
}
|
|
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_PARAM->wSeqCounter == 0 )
|
|
hb_compGenError( HB_COMP_PARAM, 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;
|
|
}
|
|
if( !HB_SUPPORT_HARBOUR )
|
|
{
|
|
/* 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 )
|
|
{
|
|
if( pLex->iState != LOOKUP ||
|
|
!HB_PP_TOKEN_ISEOC( pToken->pNext ) )
|
|
{
|
|
iType = IDENTIFIER;
|
|
break;
|
|
}
|
|
}
|
|
/* Clipper accepts ELSE in one context only */
|
|
if( HB_COMP_PARAM->wIfCounter == 0 )
|
|
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E',
|
|
HB_COMP_ERR_UNMATCHED_ELSE, NULL, NULL );
|
|
pLex->iState = ELSE;
|
|
return ELSE;
|
|
|
|
case ELSEIF:
|
|
if( HB_SUPPORT_HARBOUR )
|
|
{
|
|
if( pLex->iState != LOOKUP ||
|
|
( !HB_PP_TOKEN_ISEOC( pToken->pNext ) &&
|
|
HB_PP_LEX_NEEDLEFT( pToken->pNext ) ) )
|
|
{
|
|
iType = IDENTIFIER;
|
|
break;
|
|
}
|
|
}
|
|
/* Clipper accepts ELSEIF in one context only */
|
|
if( HB_COMP_PARAM->wIfCounter == 0 )
|
|
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E',
|
|
HB_COMP_ERR_UNMATCHED_ELSEIF, NULL, NULL );
|
|
pLex->iState = ELSEIF;
|
|
return ELSEIF;
|
|
|
|
case ENDIF:
|
|
if( HB_SUPPORT_HARBOUR )
|
|
{
|
|
if( pLex->iState != LOOKUP ||
|
|
!HB_PP_TOKEN_ISEOC( pToken->pNext ) )
|
|
{
|
|
iType = IDENTIFIER;
|
|
break;
|
|
}
|
|
}
|
|
/* Clipper accepts ENDIF in one context only */
|
|
if( HB_COMP_PARAM->wIfCounter == 0 )
|
|
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E',
|
|
HB_COMP_ERR_ENDIF, NULL, NULL );
|
|
break;
|
|
|
|
case ENDCASE:
|
|
if( HB_SUPPORT_HARBOUR )
|
|
{
|
|
if( pLex->iState != LOOKUP ||
|
|
!HB_PP_TOKEN_ISEOC( pToken->pNext ) )
|
|
{
|
|
iType = IDENTIFIER;
|
|
break;
|
|
}
|
|
}
|
|
/* Clipper accepts ENDCASE in one context only */
|
|
if( HB_COMP_PARAM->wCaseCounter == 0 )
|
|
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E',
|
|
HB_COMP_ERR_ENDCASE, NULL, NULL );
|
|
break;
|
|
|
|
case ENDDO:
|
|
if( HB_SUPPORT_HARBOUR )
|
|
{
|
|
if( pLex->iState != LOOKUP ||
|
|
!HB_PP_TOKEN_ISEOC( pToken->pNext ) )
|
|
{
|
|
iType = IDENTIFIER;
|
|
break;
|
|
}
|
|
}
|
|
/* Clipper accepts ENDDO in one context only */
|
|
if( HB_COMP_PARAM->wWhileCounter == 0 )
|
|
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E',
|
|
HB_COMP_ERR_ENDDO, NULL, NULL );
|
|
break;
|
|
|
|
case ENDSEQ:
|
|
case ENDSWITCH:
|
|
case ENDWITH:
|
|
if( pLex->iState != LOOKUP || !HB_PP_TOKEN_ISEOC( pToken->pNext ) )
|
|
iType = IDENTIFIER;
|
|
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_PARAM->wCaseCounter == 0 && HB_COMP_PARAM->wSwitchCounter == 0 )
|
|
hb_compGenError( HB_COMP_PARAM, 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_PARAM->wForCounter == 0 )
|
|
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E',
|
|
HB_COMP_ERR_NEXTFOR, NULL, NULL );
|
|
pLex->iState = iType;
|
|
return iType;
|
|
}
|
|
if( ! HB_SUPPORT_HARBOUR )
|
|
{
|
|
/* 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 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 )
|
|
{
|
|
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 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->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 = 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( 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( 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( 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 STATIC:
|
|
if( pLex->iState == LOOKUP )
|
|
{
|
|
pLex->iState = iType;
|
|
return iType;
|
|
}
|
|
break;
|
|
|
|
case IN:
|
|
case LOOP:
|
|
case NIL:
|
|
case STEP:
|
|
case TO:
|
|
case ANNOUNCE:
|
|
case OPTIONAL:
|
|
case DESCEND:
|
|
case DYNAMIC:
|
|
case EXTERN:
|
|
case LOCAL:
|
|
case MEMVAR:
|
|
case PARAMETERS:
|
|
case PRIVATE:
|
|
case PUBLIC:
|
|
break;
|
|
}
|
|
pLex->iState = IDENTIFIER;
|
|
return iType;
|
|
}
|
|
default:
|
|
return pToken->value[ 0 ];
|
|
}
|
|
}
|
|
|
|
void hb_compParserStop( HB_COMP_DECL )
|
|
{
|
|
HB_SYMBOL_UNUSED( HB_COMP_PARAM );
|
|
}
|