Esempio n. 1
0
static int hb_lexDateGet( YYSTYPE * yylval_ptr, HB_MACRO_PTR pMacro,
                          PHB_MACRO_LEX pLex )
{
   HB_BOOL fOK = HB_FALSE;
   char * dst = pLex->pDst;
   int iYear, iMonth, iDay;

   pLex->quote = HB_FALSE;
   while( pLex->nSrc < pLex->nLen )
   {
      char ch = pLex->pString[ pLex->nSrc++ ];
      if( ch == '"' )
      {
         fOK = HB_TRUE;
         break;
      }
      *dst++ = ch;
   }
   *dst = '\0';
   if( fOK && hb_timeStampStrGet( pLex->pDst, &iYear, &iMonth, &iDay, NULL, NULL, NULL, NULL ) )
   {
      yylval_ptr->valLong.lNumber = hb_dateEncode( iYear, iMonth, iDay );
   }
   else
   {
      yylval_ptr->valLong.lNumber = 0;
      hb_macroError( EG_SYNTAX, pMacro );
   }

   return NUM_DATE;
}
Esempio n. 2
0
static int hb_lexTimestampGet( YYSTYPE * yylval_ptr, HB_MACRO_PTR pMacro,
                               PHB_MACRO_LEX pLex )
{
   HB_BOOL fOK = HB_FALSE;
   char * dst = pLex->pDst;

   pLex->quote = HB_FALSE;
   while( pLex->nSrc < pLex->nLen )
   {
      char ch = pLex->pString[ pLex->nSrc++ ];
      if( ch == '"' )
      {
         fOK = HB_TRUE;
         break;
      }
      *dst++ = ch;
   }
   *dst = '\0';
   if( ! hb_timeStampStrGetDT( pLex->pDst,
                               &yylval_ptr->valTimeStamp.date,
                               &yylval_ptr->valTimeStamp.time ) )
      fOK = HB_FALSE;
   if( ! fOK )
      hb_macroError( EG_SYNTAX, pMacro );
   return TIMESTAMP;
}
Esempio n. 3
0
static int hb_lexStringCopy( YYSTYPE * yylval_ptr, HB_MACRO_PTR pMacro,
                             PHB_MACRO_LEX pLex, char cDelim )
{
   pLex->quote = HB_FALSE;
   yylval_ptr->valChar.string = pLex->pDst;
   while( pLex->nSrc < pLex->nLen )
   {
      char ch = pLex->pString[ pLex->nSrc++ ];
      if( ch == cDelim )
      {
         yylval_ptr->valChar.length = pLex->pDst - yylval_ptr->valChar.string;
         *pLex->pDst++ = '\0';
         return LITERAL;
      }
      *pLex->pDst++ = ch;
   }
   yylval_ptr->valChar.length = pLex->pDst - yylval_ptr->valChar.string;
   *pLex->pDst++ = '\0';
   hb_macroError( EG_SYNTAX, pMacro );
   return LITERAL;
}
Esempio n. 4
0
static int hb_lexStringExtCopy( YYSTYPE * yylval_ptr, HB_MACRO_PTR pMacro,
                                PHB_MACRO_LEX pLex )
{
   HB_SIZE nLen;
   char * string;

   pLex->quote = HB_FALSE;
   string = pLex->pDst;
   while( pLex->nSrc < pLex->nLen )
   {
      char ch = pLex->pString[ pLex->nSrc++ ];
      if( ch == '\\' )
      {
         if( pLex->nSrc < pLex->nLen )
         {
            *pLex->pDst++ = ch;
            ch = pLex->pString[ pLex->nSrc++ ];
         }
      }
      else if( ch == '"' )
      {
         nLen = pLex->pDst - string;
         *pLex->pDst++ = '\0';
         hb_strRemEscSeq( string, &nLen );
         yylval_ptr->valChar.length = nLen;
         yylval_ptr->valChar.string = string;
         return LITERAL;
      }
      *pLex->pDst++ = ch;
   }
   nLen = pLex->pDst - string;
   *pLex->pDst++ = '\0';
   hb_strRemEscSeq( string, &nLen );
   yylval_ptr->valChar.length = nLen;
   yylval_ptr->valChar.string = string;
   hb_macroError( EG_SYNTAX, pMacro );
   return LITERAL;
}
Esempio n. 5
0
PHB_EXPR hb_compExprNewFunCall( PHB_EXPR pName, PHB_EXPR pParms, HB_COMP_DECL )
#endif
{
   PHB_EXPR pExpr;

#ifdef HB_MACRO_SUPPORT
   if( pName->ExprType == HB_ET_VARIABLE )
   {
      /* My&var.1() executed by macro compiler
       */
      /* NOTE: direct type change */
      pName->ExprType = HB_ET_FUNNAME;
      pName->value.asSymbol.name =
                              hb_compGetFuncID( pName->value.asSymbol.name,
                                                &pName->value.asSymbol.funcid,
                                                &pName->value.asSymbol.flags );
   }
#endif

   if( pName->ExprType == HB_ET_FUNNAME )
   {
      /* The name of a function is specified at compile time
       * e.g. MyFunc()
       *
       * NOTE:  'pName' can be a macro expression that will be resolved
       * at runtime - in this case pName is an expression of HB_ET_MACRO type
       * e.g. &MyVar()
       */

      HB_TRACE( HB_TR_DEBUG, ( "hb_compExprNewFunCall(%s)", pName->value.asSymbol.name ) );

#if ! defined( HB_MACRO_SUPPORT ) && defined( HB_USE_ENUM_FUNCTIONS )
      {
         int iLen = strlen( pName->value.asSymbol.name );
         if( iLen >= 10 && iLen <= 14 && memcmp( "HB_ENUM", pName->value.asSymbol.name, 7 ) == 0 )
         {
            const char * szMessage = pName->value.asSymbol.name + 7;

            if( iLen == 12 && memcmp( "INDEX", szMessage, 5 ) == 0 )
               szMessage = "__ENUMINDEX";
            else if( iLen == 12 && memcmp( "VALUE", szMessage, 5 ) == 0 )
               szMessage = "__ENUMVALUE";
            else if( iLen == 11 && memcmp( "BASE", szMessage, 4 ) == 0 )
               szMessage = "__ENUMBASE";
            else if( iLen == 10 && memcmp( "KEY", szMessage, 3 ) == 0 )
               szMessage = "__ENUMKEY";
            else if( iLen == 14 && memcmp( "ISFIRST", szMessage, 7 ) == 0 )
               szMessage = "__ENUMISFIRST";
            else if( iLen == 13 && memcmp( "ISLAST", szMessage, 6 ) == 0 )
               szMessage = "__ENUMISLAST";
            else
               szMessage = NULL;

            if( szMessage )
            {
               int iCount = ( int ) hb_compExprParamListLen( pParms );
               PHB_ENUMERATOR pForVar, pEnumVar = NULL;

               pForVar = HB_COMP_PARAM->functions.pLast->pEnum;

               if( iCount == 0 )
               {
                  while( pForVar )
                  {
                     if( pForVar->iForEachDir != 0 )
                        pEnumVar = pForVar;
                     pForVar = pForVar->pNext;
                  }
               }
               else if( iCount == 1 )
               {
                  if( pParms->value.asList.pExprList->ExprType == HB_ET_VARIABLE ||
                      pParms->value.asList.pExprList->ExprType == HB_ET_VARREF )
                  {
                     const char * szName = pParms->value.asList.pExprList->value.asSymbol.name;

                     while( pForVar )
                     {
                        if( pForVar->iForEachDir != 0 &&
                            strcmp( pEnumVar->szName, szName ) == 0 )
                        {
                           pEnumVar = pForVar;
                           break;
                        }
                        pForVar = pForVar->pNext;
                     }
                  }
               }
               if( pEnumVar )
               {
#if 0
                  if( pEnumVar->iForEachDir < 0 )
                  {
                     if( strcmp( "__ENUMISFIRST", szMessage ) == 0 )
                        szMessage = "__ENUMISLAST";
                     else if( strcmp( "__ENUMISLAST",  szMessage ) == 0 )
                        szMessage = "__ENUMISFIRST";
                  }
#endif
                  if( pParms )
                     HB_COMP_EXPR_FREE( pParms );
                  HB_COMP_EXPR_FREE( pName );
                  return hb_compExprNewMethodObject(
                                 hb_compExprNewSend( szMessage, HB_COMP_PARAM ),
                                 hb_compExprNewVar( pEnumVar->szName, HB_COMP_PARAM ) );
               }
            }
         }
      }
#endif
      if( pName->value.asSymbol.funcid == HB_F_EVAL &&
          hb_compExprParamListLen( pParms ) != 0 )
      {
         /* Optimize Eval( bBlock, [ArgList] ) to: bBlock:Eval( [ArgList] ) */
         PHB_EXPR pEval;

         pEval = hb_compExprNewMethodCall(
                        hb_compExprNewMethodObject(
                              hb_compExprNewSend( "EVAL", HB_COMP_PARAM ),
                              pParms->value.asList.pExprList ),
                        hb_compExprNewArgList(
                              pParms->value.asList.pExprList->pNext,
                              HB_COMP_PARAM ) );
#if ! defined( HB_MACRO_SUPPORT )
         /* force reduction */
         pEval->nLength = 1;
#endif
         pParms->value.asList.pExprList = NULL;
         HB_COMP_EXPR_FREE( pParms );
         HB_COMP_EXPR_FREE( pName );
         return pEval;
      }
      else if( pName->value.asSymbol.funcid == HB_F__GET_ &&
               hb_compExprParamListLen( pParms ) != 0 )
      {
         /* Reserved Clipper function used to handle GET variables
          */
         PHB_EXPR pArg, pNext;

         /* pArg has to be reduced to eliminate possible problems with
          * cloned expressions in SETGET block
          */
         if( HB_SUPPORT_HARBOUR )
         {
            pParms = HB_EXPR_USE( pParms, HB_EA_REDUCE );
            pArg = pParms->value.asList.pExprList;
         }
         else
         {
            pArg = pParms->value.asList.pExprList;
            pNext = pArg->pNext;
            pArg->pNext = NULL;
            pArg = hb_compExprListStrip( HB_EXPR_USE( pArg, HB_EA_REDUCE ), HB_COMP_PARAM );
            pArg->pNext = pNext;
            pParms->value.asList.pExprList = pArg;
         }

         if( pArg->ExprType == HB_ET_ARRAYAT )
         {
            HB_USHORT uiCount;

            /* replace:
               _GET_( a[1], "a[1]", , , )
               into:
               __GetA( {||a }, "a", , , , { 1 } )
             */
            PHB_EXPR pIndex, pVar;
            PHB_EXPR pBase;

            pName->value.asSymbol.name = "__GETA";
            /* NOTE: a[ i, j ] is stored as: (pExprList)->(pIndex)
             * ( ( a->[ i ] )->[ j ] )
             */
            pVar = HB_EXPR_USE( pArg->value.asList.pExprList, HB_EA_REDUCE );
            pBase = pVar->ExprType == HB_ET_ARRAYAT ? pVar : NULL;
            pIndex = HB_EXPR_USE( pArg->value.asList.pIndex, HB_EA_REDUCE );
            pIndex->pNext = NULL;
            while( pVar->ExprType == HB_ET_ARRAYAT )
            {
               /* traverse back to a leftmost expression and build a list
                * of index expressions
                */
               pVar->value.asList.pIndex->pNext = pIndex;
               pIndex = pVar->value.asList.pIndex;
               pVar = pVar->value.asList.pExprList;
            }

            /* create a set only codeblock */
            if( pVar->ExprType == HB_ET_MACRO )
            {
               /* &var[ 1 ] */
               HB_COMP_EXPR_FREE( pVar );
               pVar = hb_compExprNewNil( HB_COMP_PARAM );
            }
            else
            {
               pVar = hb_compExprAddCodeblockExpr( hb_compExprNewCodeBlock( NULL, 0, 0, HB_COMP_PARAM ), pVar );
            }

            /* pVar will be the first argument now
             */
            pParms->value.asList.pExprList = pVar;
            /* link the rest of parameters
             */
            pVar->pNext = pArg->pNext;
            /* Delete an argument that was the first one
             */
            pArg->value.asList.pIndex = NULL;
            pArg->value.asList.pExprList = NULL;
            HB_COMP_EXPR_CLEAR( pArg );
            /* Create an array with index elements
             */
            pIndex = hb_compExprNewArray( hb_compExprNewList( pIndex, HB_COMP_PARAM ), HB_COMP_PARAM );
            /* The array with index elements have to be the sixth argument
             * of __GetA() call
             */
            uiCount = 1;
            while( ++uiCount < 6 )
            {
               if( pVar->pNext == NULL )
                  pVar->pNext = hb_compExprNewNil( HB_COMP_PARAM );
               pVar = pVar->pNext;
            }
            if( pVar->pNext ) /* Delete 6-th argument if present */
            {
               pIndex->pNext = pVar->pNext->pNext;
               HB_COMP_EXPR_FREE( pVar->pNext );
            }
            pVar->pNext = pIndex;   /* Set a new 6-th argument */

            /* Remove the index expression from a string representation
             */
            pVar = pParms->value.asList.pExprList->pNext;
            if( pVar->ExprType == HB_ET_STRING )
            {
               HB_SIZE i = 0;
               char * szVar = pVar->value.asString.string;

               /* NOTE: Clipper strips a string at the first '[' character too
                */
               while( ++i < pVar->nLength )
               {
                  if( szVar[ i ] == '[' )
                  {
                     if( ! pVar->value.asString.dealloc )
                     {
                        szVar = pVar->value.asString.string = ( char * )
                           hb_xmemdup( pVar->value.asString.string, i + 1 );
                        pVar->value.asString.dealloc = HB_TRUE;
                     }
                     szVar[ i ] = 0;
                     pVar->nLength = i;
                     break;
                  }
               }
            }
            /* clear expressions no longer used */
            if( pBase )
            {
               while( pBase->ExprType == HB_ET_ARRAYAT )
               {
                  pVar = pBase->value.asList.pExprList;
                  pBase->value.asList.pExprList = NULL;
                  HB_COMP_EXPR_CLEAR( pBase );
                  pBase = pVar;
               }
            }
         }
         else if( pArg->ExprType == HB_ET_MACRO )
         {
            /* @ 0,0 GET &var    => __Get( NIL, var,... )
             * @ 0,0 GET var&var => __Get( NIL, "var&var",... )
             */
            pName->value.asSymbol.name = "__GET";
            if( pArg->value.asMacro.pExprList == NULL )
            {
               /* Simple macro expansion (not a parenthesized expressions)
                */
               PHB_EXPR pFirst;

               pFirst = pArg;                /* first argument */
               pNext  = pFirst->pNext;       /* second argument */
               if( pNext )
                  pNext = pNext->pNext;      /* third argument */

               pArg = hb_compExprNewNil( HB_COMP_PARAM );   /* replace 1st with NIL */
               pParms->value.asList.pExprList = pArg;
               pArg->pNext = pFirst->pNext;
               if( pFirst->value.asMacro.cMacroOp == '&' )
               {
                  /* simple &variable - replace the second argument with
                   * a variable name
                   */
                  const char * szName = pFirst->value.asMacro.szMacro;
                  if( pFirst->pNext )
                     HB_COMP_EXPR_FREE( pFirst->pNext );  /* delete a second argument */
                  pArg->pNext = hb_compExprNewVar( szName, HB_COMP_PARAM );
                  pArg->pNext->pNext = pNext;    /* restore third argument */
               }
               else
               {
                  /* text substitution text&variable - replace the second
                   * argument with a string
                   */
                  if( pArg->pNext == NULL )
                  {
                     /* no second argument */
                     const char *szText = pFirst->value.asMacro.szMacro;
                     pArg->pNext = hb_compExprNewString( szText, strlen( szText ), HB_FALSE, HB_COMP_PARAM );
                     pArg->pNext->pNext = pNext;
                  }
               }
               HB_COMP_EXPR_FREE( pFirst );  /* delete first argument */
            }
            else
            {
               /* @ 0,0 GET &(var)
                */
#if defined( HB_MACRO_SUPPORT )
               hb_macroError( EG_SYNTAX, HB_COMP_PARAM );
#else
               hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_GET_COMPLEX_MACRO, NULL, NULL );
#endif
            }
         }
         else
         {
            pName->value.asSymbol.name = "__GET";

            /* store second and a rest of arguments */
            pNext = pArg->pNext;
            pArg->pNext = NULL;
            /* replace first argument with a set/get codeblock */
#if ! defined( HB_MACRO_SUPPORT )
            if( pArg->ExprType == HB_ET_VARIABLE )
            {
               if( hb_compVariableFind( HB_COMP_PARAM, pArg->value.asSymbol.name, NULL, NULL ) )
                  pArg = hb_compExprSetGetBlock( pArg, HB_COMP_PARAM );
               else
               {
                  /* Undeclared variable name - create a set/get codeblock
                   * at runtime
                   */
                  if( HB_COMP_PARAM->iWarnings >= 2 )
                     hb_compGenWarning( HB_COMP_PARAM, hb_comp_szWarnings, 'W', HB_COMP_WARN_AMBIGUOUS_VAR, pArg->value.asSymbol.name, NULL );
                  HB_COMP_EXPR_FREE( pArg );
                  pArg = hb_compExprNewNil( HB_COMP_PARAM );
               }
            }
            else
#endif
            {
               pArg = hb_compExprSetGetBlock( pArg, HB_COMP_PARAM );
            }
            /* restore next arguments */
            pArg->pNext = pNext;
            /* set an updated list of arguments */
            pParms->value.asList.pExprList = pArg;
         }

         pName->value.asSymbol.name =
                              hb_compGetFuncID( pName->value.asSymbol.name,
                                                &pName->value.asSymbol.funcid,
                                                &pName->value.asSymbol.flags );
      }
   }
   else if( pName->ExprType == HB_ET_MACRO )
   {
      /* Signal that macro compiler have to generate a pcode that will
       * return function name as symbol instead of usual value
       */
      pName->value.asMacro.SubType = HB_ET_MACRO_SYMBOL;

      HB_TRACE( HB_TR_DEBUG, ( "hb_compExprNewFunCall(&)" ) );
   }

   pExpr = HB_COMP_EXPR_NEW( HB_ET_FUNCALL );
   pExpr->value.asFunCall.pParms = pParms;
   pExpr->value.asFunCall.pFunName = pName;

   return pExpr;
}
Esempio n. 6
0
int hb_macro_yylex( YYSTYPE * yylval_ptr, HB_MACRO_PTR pMacro )
{
   PHB_MACRO_LEX pLex = ( PHB_MACRO_LEX ) pMacro->pLex;

   while( pLex->nSrc < pLex->nLen )
   {
      unsigned char ch = ( unsigned char ) pLex->pString[ pLex->nSrc++ ];
      switch( ch )
      {
         case ' ':
         case '\t':
            break;

         case '$':
         case ',':
         case '|':
         case '@':
         case '(':
         case '{':
            pLex->quote = HB_TRUE;
            return ch;

         case ')':
         case '}':
         case ']':
            pLex->quote = HB_FALSE;
            return ch;

         case '#':
            pLex->quote = HB_TRUE;
            return NE1;

         case '!':
            pLex->quote = HB_TRUE;
            if( pLex->pString[ pLex->nSrc ] == '=' )
            {
               pLex->nSrc++;
               return NE2;
            }
            return NOT;

         case '<':
            pLex->quote = HB_TRUE;
            if( pLex->pString[ pLex->nSrc ] == '>' )
            {
               pLex->nSrc++;
               return NE2;
            }
            else if( pLex->pString[ pLex->nSrc ] == '=' )
            {
               pLex->nSrc++;
               return LE;
            }
            return '<';

         case '>':
            pLex->quote = HB_TRUE;
            if( pLex->pString[ pLex->nSrc ] == '=' )
            {
               pLex->nSrc++;
               return GE;
            }
            return '>';

         case '=':
            pLex->quote = HB_TRUE;
            if( pLex->pString[ pLex->nSrc ] == '=' )
            {
               pLex->nSrc++;
               return EQ;
            }
            else if( pLex->pString[ pLex->nSrc ] == '>' && HB_SUPPORT_HARBOUR )
            {
               pLex->nSrc++;
               return HASHOP;
            }
            return '=';

         case '+':
            pLex->quote = HB_TRUE;
            if( pLex->pString[ pLex->nSrc ] == '+' )
            {
               pLex->nSrc++;
               return INC;
            }
            else if( pLex->pString[ pLex->nSrc ] == '=' )
            {
               pLex->nSrc++;
               return PLUSEQ;
            }
            return '+';

         case '-':
            pLex->quote = HB_TRUE;
            if( pLex->pString[ pLex->nSrc ] == '-' )
            {
               pLex->nSrc++;
               return DEC;
            }
            else if( pLex->pString[ pLex->nSrc ] == '=' )
            {
               pLex->nSrc++;
               return MINUSEQ;
            }
            else if( pLex->pString[ pLex->nSrc ] == '>' )
            {
               pLex->nSrc++;
               return ALIASOP;
            }
            return '-';

         case '*':
            pLex->quote = HB_TRUE;
            if( pLex->pString[ pLex->nSrc ] == '*' )
            {
               pLex->nSrc++;
               if( pLex->pString[ pLex->nSrc ] == '=' )
               {
                  pLex->nSrc++;
                  return EXPEQ;
               }
               return POWER;
            }
            else if( pLex->pString[ pLex->nSrc ] == '=' )
            {
               pLex->nSrc++;
               return MULTEQ;
            }
            return '*';

         case '/':
            pLex->quote = HB_TRUE;
            if( pLex->pString[ pLex->nSrc ] == '=' )
            {
               pLex->nSrc++;
               return DIVEQ;
            }
            return '/';

         case '%':
            pLex->quote = HB_TRUE;
            if( pLex->pString[ pLex->nSrc ] == '=' )
            {
               pLex->nSrc++;
               return MODEQ;
            }
            return '%';

         case '^':
            pLex->quote = HB_TRUE;
            if( pLex->pString[ pLex->nSrc ] == '=' )
            {
               pLex->nSrc++;
               return EXPEQ;
            }
            return POWER;

         case ':':
            pLex->quote = HB_TRUE;
            if( pLex->pString[ pLex->nSrc ] == '=' )
            {
               pLex->nSrc++;
               return INASSIGN;
            }
            else if( pLex->pString[ pLex->nSrc ] == ':' )
            {
               yylval_ptr->string = "SELF";
               return IDENTIFIER;
            }
            return ':';

         case '.':
            pLex->quote = HB_TRUE;
            if( pLex->nSrc < pLex->nLen &&
                HB_ISDIGIT( pLex->pString[ pLex->nSrc ] ) )
            {
               HB_SIZE ul = pLex->nSrc;
               while( ++ul < pLex->nLen &&
                      HB_ISDIGIT( pLex->pString[ ul ] ) ) {};
               ul -= --pLex->nSrc;
               return hb_lexNumConv( yylval_ptr, pLex, ul );
            }
            if( pLex->nLen - pLex->nSrc >= 4 &&
                pLex->pString[ pLex->nSrc + 3 ] == '.' )
            {
               if( ( pLex->pString[ pLex->nSrc + 0 ] | ( 'a' - 'A' ) ) == 'a' &&
                   ( pLex->pString[ pLex->nSrc + 1 ] | ( 'a' - 'A' ) ) == 'n' &&
                   ( pLex->pString[ pLex->nSrc + 2 ] | ( 'a' - 'A' ) ) == 'd' )
               {
                  pLex->nSrc += 4;
                  return AND;
               }
               if( ( pLex->pString[ pLex->nSrc + 0 ] | ( 'a' - 'A' ) ) == 'n' &&
                   ( pLex->pString[ pLex->nSrc + 1 ] | ( 'a' - 'A' ) ) == 'o' &&
                   ( pLex->pString[ pLex->nSrc + 2 ] | ( 'a' - 'A' ) ) == 't' )
               {
                  pLex->nSrc += 4;
                  return NOT;
               }
            }
            if( pLex->nLen - pLex->nSrc >= 3 &&
                pLex->pString[ pLex->nSrc + 2 ] == '.' )
            {
               if( ( pLex->pString[ pLex->nSrc + 0 ] | ( 'a' - 'A' ) ) == 'o' &&
                   ( pLex->pString[ pLex->nSrc + 1 ] | ( 'a' - 'A' ) ) == 'r' )
               {
                  pLex->nSrc += 3;
                  return OR;
               }
            }
            if( pLex->nLen - pLex->nSrc >= 2 &&
                pLex->pString[ pLex->nSrc + 1 ] == '.' )
            {
               if( ( pLex->pString[ pLex->nSrc ] | ( 'a' - 'A' ) ) == 't' ||
                   ( pLex->pString[ pLex->nSrc ] | ( 'a' - 'A' ) ) == 'y' )
               {
                  pLex->quote = HB_FALSE;
                  pLex->nSrc += 2;
                  return TRUEVALUE;
               }
               if( ( pLex->pString[ pLex->nSrc ] | ( 'a' - 'A' ) ) == 'f' ||
                   ( pLex->pString[ pLex->nSrc ] | ( 'a' - 'A' ) ) == 'n' )
               {
                  pLex->quote = HB_FALSE;
                  pLex->nSrc += 2;
                  return FALSEVALUE;
               }
               if( pLex->pString[ pLex->nSrc ] == '.' )
               {
                  pLex->nSrc += 2;
                  return EPSILON;
               }
            }
            return '.';

         case '[':
            if( pLex->quote )
               return hb_lexStringCopy( yylval_ptr, pMacro, pLex, ']' );
            pLex->quote = HB_TRUE;
            return '[';

         case '`':
         case '\'':
            return hb_lexStringCopy( yylval_ptr, pMacro, pLex, '\'' );

         case '"':
            return hb_lexStringCopy( yylval_ptr, pMacro, pLex, '"' );

         case '&':
            if( pLex->nSrc < pLex->nLen )
            {
               if( HB_ISFIRSTIDCHAR( pLex->pString[ pLex->nSrc ] ) )
               {
                  /* [&<keyword>[.[<nextidchars>]]]+ */
                  int iParts = 0;
                  pLex->quote = HB_FALSE;
                  yylval_ptr->string = pLex->pDst;
                  pLex->nSrc--;
                  do
                  {
                     ++iParts;
                     *pLex->pDst++ = '&';
                     pLex->nSrc++;
                     hb_lexIdentCopy( pLex );
                     if( pLex->pString[ pLex->nSrc ] == '.' )
                     {
                        ++iParts;
                        *pLex->pDst++ = '.';
                        pLex->nSrc++;
                        hb_lexIdentCopy( pLex );
                     }
                  }
                  while( pLex->nLen - pLex->nSrc > 1 &&
                         pLex->pString[ pLex->nSrc ] == '&' &&
                         HB_ISFIRSTIDCHAR( pLex->pString[ pLex->nSrc + 1 ] ) );
                  if( iParts == 2 && *( pLex->pDst - 1 ) == '.' )
                  {
                     pLex->pDst--;
                     iParts = 1;
                  }
                  *pLex->pDst++ = '\0';
                  if( iParts == 1 )
                  {
                     yylval_ptr->string++;
                     if( pLex->pDst - yylval_ptr->string > HB_SYMBOL_NAME_LEN + 1 )
                        ( ( char * ) yylval_ptr->string )[ HB_SYMBOL_NAME_LEN ] = '\0';
                     return MACROVAR;
                  }
                  return MACROTEXT;
               }
               else if( pLex->pString[ pLex->nSrc ] == '\'' ||
                        pLex->pString[ pLex->nSrc ] == '"' ||
                        pLex->pString[ pLex->nSrc ] == '[' )
                  hb_macroError( EG_SYNTAX, pMacro );
            }
            pLex->quote = HB_TRUE;
            return '&';

         default:
            if( HB_ISDIGIT( ch ) )
            {
               HB_SIZE n = pLex->nSrc;

               pLex->quote = HB_FALSE;
               if( ch == '0' && n < pLex->nLen )
               {
                  if( pLex->pString[ n ] == 'd' || pLex->pString[ n ] == 'D' )
                  {
                     while( ++n < pLex->nLen &&
                            HB_ISDIGIT( pLex->pString[ n ] ) ) {};
                     if( n - pLex->nSrc == 9 )
                     {
                        int year, month, day;
                        hb_dateStrGet( pLex->pString + pLex->nSrc + 1,
                                       &year, &month, &day );
                        yylval_ptr->valLong.lNumber =
                                       hb_dateEncode( year, month, day );
                        pLex->nSrc = n;
                        if( yylval_ptr->valLong.lNumber == 0 &&
                            ( year != 0 || month != 0 || day != 0 ) )
                        {
                           hb_macroError( EG_SYNTAX, pMacro );
                        }
                        return NUM_DATE;
                     }
                     else if( n - pLex->nSrc == 2 &&
                              pLex->pString[ pLex->nSrc + 1 ] == '0' )
                     {
                        yylval_ptr->valLong.lNumber = 0;
                        return NUM_DATE;
                     }
                     n = pLex->nSrc;
                  }
                  else if( pLex->pString[ n ] == 'x' ||
                           pLex->pString[ n ] == 'X' )
                  {
                     while( ++n < pLex->nLen &&
                            HB_ISXDIGIT( pLex->pString[ n ] ) ) {};
                     if( n == pLex->nSrc + 1 )
                        --n;
                  }
                  else
                  {
                     while( n < pLex->nLen &&
                            HB_ISDIGIT( pLex->pString[ n ] ) )
                        ++n;
                     if( pLex->nLen - n > 1 && pLex->pString[ n ] == '.' &&
                         HB_ISDIGIT( pLex->pString[ n + 1 ] ) )
                     {
                        while( ++n < pLex->nLen &&
                               HB_ISDIGIT( pLex->pString[ n ] ) ) {};
                     }
                  }
               }
               else
               {
                  while( n < pLex->nLen &&
                         HB_ISDIGIT( pLex->pString[ n ] ) )
                     ++n;
                  if( pLex->nLen - n > 1 && pLex->pString[ n ] == '.' &&
                      HB_ISDIGIT( pLex->pString[ n + 1 ] ) )
                  {
                     while( ++n < pLex->nLen &&
                            HB_ISDIGIT( pLex->pString[ n ] ) ) {};
                  }
               }
               n -= --pLex->nSrc;
               return hb_lexNumConv( yylval_ptr, pLex, n );
            }
            else if( HB_ISFIRSTIDCHAR( ch ) )
            {
               HB_SIZE nLen;
               pLex->quote = HB_FALSE;
               yylval_ptr->string = pLex->pDst;
               *pLex->pDst++ = ch - ( ( ch >= 'a' && ch <= 'z' ) ? 'a' - 'A' : 0 );
               hb_lexIdentCopy( pLex );
               if( pLex->nLen - pLex->nSrc > 1 &&
                   pLex->pString[ pLex->nSrc ] == '&' &&
                   HB_ISFIRSTIDCHAR( pLex->pString[ pLex->nSrc + 1 ] ) )
               {
                  /* [<keyword>][&<keyword>[.[<nextidchars>]]]+ */
                  do
                  {
                     *pLex->pDst++ = '&';
                     pLex->nSrc++;
                     hb_lexIdentCopy( pLex );
                     if( pLex->pString[ pLex->nSrc ] == '.' )
                     {
                        *pLex->pDst++ = '.';
                        pLex->nSrc++;
                        hb_lexIdentCopy( pLex );
                     }
                  }
                  while( pLex->nLen - pLex->nSrc > 1 &&
                         pLex->pString[ pLex->nSrc ] == '&' &&
                         HB_ISFIRSTIDCHAR( pLex->pString[ pLex->nSrc + 1 ] ) );
                  *pLex->pDst++ = '\0';
                  return MACROTEXT;
               }
               nLen = pLex->pDst - yylval_ptr->string;
               *pLex->pDst++ = '\0';
               if( nLen == 1 )
               {
                  if( pLex->nLen > pLex->nSrc &&
                      pLex->pString[ pLex->nSrc ] == '"' )
                  {
                     switch( yylval_ptr->string[ 0 ] )
                     {
                        case 'E':
                           pLex->nSrc++;
                           return hb_lexStringExtCopy( yylval_ptr, pMacro, pLex );
                        case 'T':
                           pLex->nSrc++;
                           return hb_lexTimestampGet( yylval_ptr, pMacro, pLex );
                        case 'D':
                           pLex->nSrc++;
                           return hb_lexDateGet( yylval_ptr, pMacro, pLex );
                     }
                  }
               }
               else if( nLen == 2 )
               {
                  if( yylval_ptr->string[ 0 ] == 'I' &&
                      yylval_ptr->string[ 1 ] == 'F' )
                  {
                     hb_lexSkipBlank( pLex );
                     if( pLex->nSrc < pLex->nLen &&
                         pLex->pString[ pLex->nSrc ] == '(' )
                        return IIF;
                  }
               }
               else if( nLen == 3 )
               {
                  if( yylval_ptr->string[ 0 ] == 'I' &&
                      yylval_ptr->string[ 1 ] == 'I' &&
                      yylval_ptr->string[ 2 ] == 'F' )
                  {
                     hb_lexSkipBlank( pLex );
                     if( pLex->nSrc < pLex->nLen &&
                         pLex->pString[ pLex->nSrc ] == '(' )
                        return IIF;
                  }
                  else if( yylval_ptr->string[ 0 ] == 'N' &&
                           yylval_ptr->string[ 1 ] == 'I' &&
                           yylval_ptr->string[ 2 ] == 'L' )
                     return NIL;
               }
               else /* nLen >= 4 */
               {
                  switch( yylval_ptr->string[ 0 ] )
                  {
                     case '_':
                        if( nLen <= 6 && memcmp( "FIELD", yylval_ptr->string + 1,
                                                 nLen - 1 ) == 0 )
                        {
                           hb_lexSkipBlank( pLex );
                           if( pLex->nSrc + 1 < pLex->nLen &&
                               pLex->pString[ pLex->nSrc ] == '-' &&
                               pLex->pString[ pLex->nSrc + 1 ] == '>' )
                              return FIELD;
                        }
                        break;
                     case 'F':
                        if( nLen <= 5 && memcmp( "IELD", yylval_ptr->string + 1,
                                                 nLen - 1 ) == 0 )
                        {
                           hb_lexSkipBlank( pLex );
                           if( pLex->nSrc + 1 < pLex->nLen &&
                               pLex->pString[ pLex->nSrc ] == '-' &&
                               pLex->pString[ pLex->nSrc + 1 ] == '>' )
                              return FIELD;
                        }
                        break;
                     case 'Q':
                        if( nLen == 5 && memcmp( "SELF", yylval_ptr->string + 1,
                                                 4 ) == 0 )
                        {
                           hb_lexSkipBlank( pLex );
                           if( pLex->nSrc < pLex->nLen &&
                               pLex->pString[ pLex->nSrc ] == '(' )
                           {
                              HB_SIZE n = pLex->nSrc;
                              while( ++n < pLex->nLen )
                              {
                                 if( pLex->pString[ n ] == ')' )
                                 {
                                    pLex->nSrc = n + 1;
                                    return SELF;
                                 }
                                 else if( pLex->pString[ n ] != ' ' &&
                                          pLex->pString[ n ] != '\t' )
                                    break;
                              }
                           }
                        }
                        break;
                  }
                  if( pLex->pDst - yylval_ptr->string > HB_SYMBOL_NAME_LEN + 1 )
                     ( ( char * ) yylval_ptr->string )[ HB_SYMBOL_NAME_LEN ] = '\0';
               }
               return IDENTIFIER;
            }
            return ch;
      }
   }

   return 0;
}