diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 840b9fb4c1..8634778c35 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,18 @@ +2001-07-26 02:50 UTC-0800 Ron Pinkas + * include/hbexpra.c + + Added logic to optimize 2nd parameter of __DBLIST(). + Scan it if array, and optiimize elements that are codeblocks containg macros to the core value of such macro. + + * source/rdd/dblist.prg + + Added logic to scan abEval for Strings, parse and convert them to codeblocks. + + Added HB_aTokens() + + /* This should complete support for: + + cFields := "Field1,Field2,..." + LIST &cFields*/ ... + */ + 2001-07-24 20:45 GMT -3 Luiz Rafael Culik +doc/es/math.txt *Math docs translated to spanish. Thanks for Ricardo Ramírez R. @@ -18,7 +33,7 @@ * contrib/libct/pos.1 * fixed error and warning about mixture of pointers to signed and unsigned char - + 2001-07-23 20:50 UTC-0800 Ron Pinkas * source/vm/macro.c ! Corrected a compiler warning. diff --git a/harbour/include/hbexpra.c b/harbour/include/hbexpra.c index dd57dcaf45..ab6ee88870 100644 --- a/harbour/include/hbexpra.c +++ b/harbour/include/hbexpra.c @@ -329,7 +329,92 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms ) HB_EXPR_PCODE1( hb_compExprDelete, pName ); } } + else if( ( strcmp( "__DBLIST", pName->value.asSymbol ) == 0 ) && iCount >= 10 ) + { + HB_EXPR_PTR pArray = pParms->value.asList.pExprList->pNext; + if( pArray->ExprType == HB_ET_ARRAY ) + { + HB_EXPR_PTR pElem = pArray->value.asList.pExprList; + HB_EXPR_PTR pPrev = NULL, pNext; + + while( pElem ) + { + /* The {|| &cMacro } block is now &( "{||" + cMacro + "}" ) due to early macro expansion in compiler. */ + if( pElem->ExprType == HB_ET_MACRO ) + { + HB_EXPR_PTR pMacro = pElem->value.asMacro.pExprList; + + if( pMacro && + pMacro->ExprType == HB_EO_PLUS && + pMacro->value.asOperator.pLeft->ExprType == HB_EO_PLUS && + pMacro->value.asOperator.pLeft->value.asOperator.pRight->ExprType == HB_ET_VARIABLE + ) + { + /* Saving the next array element so the list can be relinked after we substitute the macro block. */ + pNext = pElem->pNext; + + /* Instead we only want the macro variable, {|| &cMacro } -> &( "{||" + cMacro + "}" ) -> cMacro */ + hb_compExprClear( pElem ); + pElem = pMacro->value.asOperator.pLeft->value.asOperator.pRight; + if( pPrev ) + { + /* Previous element should point to the new element. */ + pPrev->pNext = pElem; + } + else + { + /* Top of array should point to the new first element. */ + pArray->value.asList.pExprList = pElem; + } + pElem->pNext = pNext; + } + } + /* Search for {|| &(cMacro) }. */ + else if( pElem->ExprType == HB_ET_CODEBLOCK ) + { + HB_EXPR_PTR pBlock = pElem->value.asList.pExprList; + + /* Search for macros {|| &cMacro }. */ + if( pBlock->ExprType == HB_ET_MACRO ) + { + /* Saving the next array element so the list can be relinked after we substitute the macro block. */ + pNext = pElem->pNext; + + /* Instead we only want the core expression. */ + hb_compExprClear( pElem ); + if( pBlock->value.asMacro.pExprList ) /* &( exp ) -> exp */ + { + pElem = pBlock->value.asMacro.pExprList; + } + else if( pBlock->value.asMacro.cMacroOp ) /* simple macro in Flex build {|| &cMacro}, because harbour.y does not support early macros yet*/ + { + pElem = hb_compExprNewVar( pBlock->value.asMacro.szMacro ); + } + else /* {|| &cMacro.suffix } -> cMacro + "suffix" */ + { + pElem = hb_compExprNewString( pBlock->value.asMacro.szMacro ); + } + + if( pPrev ) + { + /* Previous element should point to the new element. */ + pPrev->pNext = pElem; + } + else + { + /* Top of array should point to the new first element. */ + pArray->value.asList.pExprList = pElem; + } + pElem->pNext = pNext; + } + } + + pPrev = pElem; + pElem = pElem->pNext; + } + } + } #ifndef SIMPLEX else if( ( strcmp( "_GET_", pName->value.asSymbol ) == 0 ) && iCount ) diff --git a/harbour/source/rdd/dblist.prg b/harbour/source/rdd/dblist.prg index dc35516d0d..410b56b8b4 100644 --- a/harbour/source/rdd/dblist.prg +++ b/harbour/source/rdd/dblist.prg @@ -48,12 +48,19 @@ * whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. * - */ + * The following parts are Copyright of the individual authors. + * www - http://www.harbour-project.org + * + * Copyright 2000 RonPinkas + * HB_aTokens() + * +*/ /* NOTE: lAll is basically a dummy parameter, nothing really depends on it. [vszakats] */ FUNCTION __dbList( lOff, abEval, lAll, bFor, bWhile, nNext, nRecord, lRest, lToPrint, cToFileName ) + LOCAL lOldPrinter LOCAL lOldExtra LOCAL cOldExtraFile @@ -65,8 +72,35 @@ FUNCTION __dbList( lOff, abEval, lAll, bFor, bWhile, nNext, nRecord, lRest, lToP LOCAL bOutBlock - /* Choose the output style */ + LOCAL nLen := Len( abEval ), nIndex, asMacros, nMacros, nMacroIndex + // Scan for strings instead of blocks - These are macros that need to be compiled into blocks. + FOR nIndex := 1 TO nLen + IF ValType( abEval[ nIndex ] ) == 'C' + ? abEval[ nIndex ] + // Macro may be a comma seperated list. + asMacros := HB_aTokens( abEval[ nIndex ], ',' ) + nMacros := Len( asMacros ) + + // Array has to be sized to allow dor the extra blocks + nLen += ( nMacros - 1 ) + aSize( abEval, nLen ) + + // We will use the place holder of the string for the first new block. + abEval[ nIndex ] := &( "{||" + asMacros[ 1 ] + "}" ) + + // We will now push all subsequent blocks 1 at a time and insert the new block inplace. + FOR nMacroIndex := 2 TO nMacros + aIns( abEval, nIndex + nMacroIndex - 1 ) + abEval[ nIndex + nMacroIndex - 1 ] := &( "{||" + asMacros[ nMacroIndex ] + "}" ) + NEXT + + // The loop counter should skip the new elements. + nIndex += ( nMacros - 1 ) + ENDIF + NEXT + + /* Choose the output style */ IF lOff bOutBlock := {|| QOut( iif( Deleted(), "*", " " ) ),; aEval( abEval, {| bEval | QQOut( Eval( bEval ), "" ) } ) } @@ -124,5 +158,60 @@ FUNCTION __dbList( lOff, abEval, lAll, bFor, bWhile, nNext, nRecord, lRest, lToP Break( oError ) ENDIF - RETURN NIL +RETURN NIL +FUNCTION HB_aTokens( cLine, cDelimiter ) + + LOCAL aTokens := {} + + #ifdef __HARBOUR__ + + IF cDelimiter == NIL + cDelimiter := ' ' + ENDIF + + HB_INLINE( aTokens, cLine, Asc( cDelimiter ) ) + { + PHB_ITEM pArray = hb_param( 1, HB_IT_ARRAY ); + PHB_ITEM pLine = hb_param( 2, HB_IT_STRING ); + char cDelimiter = (char) hb_parni(3); + size_t i, iOffset = 0, iIndex = 1; + + for( i = 0; i < pLine->item.asString.length; i++ ) + { + if( pLine->item.asString.value[i] == cDelimiter ) + { + hb_arraySize( pArray, iIndex ); + hb_storclen( pLine->item.asString.value + iOffset, i - iOffset, 1, iIndex ); + iOffset = i + 1; + iIndex++; + } + } + if( iOffset < pLine->item.asString.length - 1 ) + { + hb_arraySize( pArray, iIndex ); + hb_storclen( pLine->item.asString.value + iOffset, pLine->item.asString.length - iOffset, 1, iIndex ); + } + } + + #else + + LOCAL nLen := Len( cLine ), i, nOffset := 1 + + IF cDelimiter == NIL + cDelimiter := ' ' + ENDIF + + FOR i := 1 to nLen + IF SubStr( cLine, i, 1 ) == cDelimiter + aAdd( aTokens, SubStr( cLine, nOffset, i - nOffset ) ) + nOffset := i + 1 + ENDIF + NEXT + IF nOffset < nLen - 1 + aAdd( aTokens, SubStr( cLine, nOffset ) ) + ENDIF + + #endif + +RETURN aTokens