diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 4604b74b56..3bc243d88c 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,8 +1,26 @@ +20000507-21:20 GMT-8 Ron Pinkas + + * source/compiler/harbour.l + + Added token "optional" + + * source/compiler/harbour.y + + Added token "optional", DecParam, DecParamList, OptParams. + + Added support for optional parameters syntax in declared functions. + + * source/compiler/harbour.c + + Added logic in hb_compVariableAdd() to deal with optional parameters of declared functions. + + * source/compiler/hbpcode.c + + Added logic in hb_compStrongType() to deal with optional parameters of declared functions. + + * tests/testwarn.prg + + Added code to demonstrate usage and warnings of optional parameters in declared functions. + 20000507-23:30 CET Patrick Mast * source/compiler/cmdcheck.c + Added -? and -h option for the compiler. - these options shouw the Harbour usage page. + these options show the Harbour usage page. 20000507-13:35 GMT-8 Ron Pinkas diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index b9a301e1c3..43e282ddc1 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -474,7 +474,11 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType ) pDeclared->cParamTypes = ( BYTE * ) hb_xgrab( 1 ); /* Store declared type of this parameter into the parameters type list. */ - pDeclared->cParamTypes[ pDeclared->iParamCount - 1 ] = hb_comp_cVarType; + if ( cValueType == '-' ) + /* Optional parameter */ + pDeclared->cParamTypes[ pDeclared->iParamCount - 1 ] = hb_comp_cVarType + 100; + else + pDeclared->cParamTypes[ pDeclared->iParamCount - 1 ] = hb_comp_cVarType; return; } diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index 58448614e2..e0d49e1485 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -1327,7 +1327,8 @@ Separator {SpaceTab} "as var array" { return AS_VARIANT; } "as variant array" { return AS_VARIANT; } -"declare function" { return DECLARE_FUN; } +"declare function" { return DECLARE_FUN; } +"optional" { return OPTIONAL;} %{ /* ************************************************************************ */ diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 9ac2ad961e..7968f98014 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -161,7 +161,7 @@ char * hb_comp_szAnnounce = NULL; /* ANNOUNCEd procedure */ %token PLUSEQ MINUSEQ MULTEQ DIVEQ POWER EXPEQ MODEQ EXITLOOP %token PRIVATE BEGINSEQ BREAK RECOVER RECOVERUSING DO WITH SELF LINE %token MACROVAR MACROTEXT -%token AS_NUMERIC AS_CHARACTER AS_LOGICAL AS_DATE AS_ARRAY AS_BLOCK AS_OBJECT AS_VARIANT DECLARE_FUN +%token AS_NUMERIC AS_CHARACTER AS_LOGICAL AS_DATE AS_ARRAY AS_BLOCK AS_OBJECT AS_VARIANT DECLARE_FUN OPTIONAL %token AS_NUMERIC_ARRAY AS_CHARACTER_ARRAY AS_LOGICAL_ARRAY AS_DATE_ARRAY AS_ARRAY_ARRAY AS_BLOCK_ARRAY AS_OBJECT_ARRAY AS_VARIANT_ARRAY /*the lowest precedence*/ @@ -195,7 +195,7 @@ char * hb_comp_szAnnounce = NULL; /* ANNOUNCEd procedure */ %type NUM_INTEGER %type NUM_LONG %type FunScope AsType AsArray -%type Params ParamList +%type Params ParamList DecParams DecParamList OptParams %type IfBegin VarList ExtVarList %type FieldList %type WhileBegin @@ -261,10 +261,10 @@ Line : LINE NUM_INTEGER LITERAL Crlf Function : FunScope FUNCTION IdentName { hb_comp_cVarType = ' '; hb_compFunctionAdd( $3, ( HB_SYMBOLSCOPE ) $1, 0 ); } Params Crlf {} | FunScope PROCEDURE IdentName { hb_comp_cVarType = ' '; hb_compFunctionAdd( $3, ( HB_SYMBOLSCOPE ) $1, FUN_PROCEDURE ); } Params Crlf {} - | FunScope DECLARE_FUN IdentName { hb_compDeclaredAdd( $3 ); hb_comp_szDeclaredFun = $3 ; } Params AsType Crlf { if( hb_comp_pLastDeclared ) + | FunScope DECLARE_FUN IdentName { hb_compDeclaredAdd( $3 ); hb_comp_szDeclaredFun = $3 ; } DecParams AsType Crlf { if( hb_comp_pLastDeclared ) hb_comp_pLastDeclared->cType = hb_comp_cVarType; - hb_comp_szDeclaredFun = NULL; - hb_comp_cVarType = ' '; } + hb_comp_szDeclaredFun = NULL; + hb_comp_cVarType = ' '; } ; FunScope : { $$ = HB_FS_PUBLIC; } @@ -273,6 +273,20 @@ FunScope : { $$ = HB_FS_PUBLIC; } | EXIT { $$ = HB_FS_EXIT; } ; +DecParams : { $$ = 0; } + | '(' ')' { $$ = 0; } + | '(' { hb_comp_iVarScope = VS_PARAMETER; } DecParamList ')' { $$ = $3; } + ; + +DecParamList : IdentName AsType { hb_compVariableAdd( $1, ' ' ); $$ = 1; } + | DecParamList ',' IdentName AsType { hb_compVariableAdd( $3, $4 ); $$++; } + | DecParamList OptParams + ; + +OptParams : ',' OPTIONAL IdentName AsType { hb_compVariableAdd( $3, '-' ); $$ = 3; } + | OptParams ',' OPTIONAL IdentName AsType { hb_compVariableAdd( $4, '-' ); $$++; } + ; + Params : { $$ = 0; } | '(' ')' { $$ = 0; } | '(' { hb_comp_iVarScope = VS_PARAMETER; } ParamList ')' { $$ = $3; } diff --git a/harbour/source/compiler/hbpcode.c b/harbour/source/compiler/hbpcode.c index 7238e6929c..e8a9c64d7e 100644 --- a/harbour/source/compiler/hbpcode.c +++ b/harbour/source/compiler/hbpcode.c @@ -298,35 +298,49 @@ void hb_compStrongType( int iSize ) if ( wVar == 0 ) wVar = pFunc->pCode[ ulPos + 1 ]; - if ( pFunc->iStackIndex < wVar + 2 ) + if ( pFunc->iStackIndex < ( wVar + 2 ) ) break; if ( hb_comp_iParamCount > -1 ) { - if( hb_comp_iParamCount == wVar ) + int iParamCount = hb_comp_iParamCount, iOptionals = 0; + + while ( --iParamCount >= 0 ) { - BYTE iOffset = 0; + if ( hb_comp_cParamTypes[ iParamCount ] > 122 ) + iOptionals++; + else + break; + } - while ( hb_comp_iParamCount-- > 0 ) - { - iOffset++; + //printf( "\nOptionals: %i\n", iOptionals ); - if ( pFunc->pStack[ pFunc->iStackIndex - iOffset ] > 122 ) - /* cSubType1 = */( pFunc->pStack[ pFunc->iStackIndex - iOffset ] -= 100 ); + if( wVar >= ( hb_comp_iParamCount - iOptionals ) && wVar <= hb_comp_iParamCount ) + { + BYTE iOffset = 0, iParamBase = pFunc->iStackIndex - wVar; - if ( pFunc->iStackIndex - iOffset && hb_comp_cParamTypes[ hb_comp_iParamCount ] != pFunc->pStack[ pFunc->iStackIndex - iOffset ] ) - { - sprintf( szType1, "%i", hb_comp_iParamCount + 1 ); - sprintf( szType2, "%c", hb_comp_cParamTypes[ hb_comp_iParamCount ] ); - hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_PARAM_TYPE, szType1, szType2 ); - } - } + while ( iOffset < wVar ) + { + if ( pFunc->pStack[ iParamBase + iOffset ] > 122 ) + /* cSubType1 = */( pFunc->pStack[ iParamBase + iOffset ] -= 100 ); + + if ( hb_comp_cParamTypes[ iOffset ] > 122 ) + hb_comp_cParamTypes[ iOffset ] -= 100; + + if ( hb_comp_cParamTypes[ iOffset ] != ' ' && hb_comp_cParamTypes[ iOffset ] != pFunc->pStack[ iParamBase + iOffset ] ) + { + sprintf( szType1, "%i", iOffset + 1 ); + sprintf( szType2, "%c", hb_comp_cParamTypes[ iOffset ] ); + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_PARAM_TYPE, szType1, szType2 ); + } + iOffset++; + } } else { - sprintf( szType1, "%i", wVar ); - sprintf( szType2, "%i", hb_comp_iParamCount ); - hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_PARAM_COUNT, szType1, szType2 ); + sprintf( szType1, "%i", wVar ); + sprintf( szType2, "%i", hb_comp_iParamCount ); + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_PARAM_COUNT, szType1, szType2 ); } } diff --git a/harbour/tests/testwarn.prg b/harbour/tests/testwarn.prg index 810d2f10e5..19fe3f1e45 100644 --- a/harbour/tests/testwarn.prg +++ b/harbour/tests/testwarn.prg @@ -51,7 +51,7 @@ DECLARE FUNCTION nMyFunc( cVar AS STRING, nVar AS NUMERIC ) AS NUMERIC -DECLARE FUNCTION cOtherFunc( ) AS CHAR +DECLARE FUNCTION cOtherFunc( cVar as char, optional nVar as num, optional other as variant ) AS CHAR DECLARE FUNCTION cOtherFunc( ) AS CHAR @@ -71,6 +71,7 @@ STATIC lGlobal AS LOGICAL PROCEDURE THEMAIN() STATIC lStatic := 0 + LOCAL cVar AS CHAR := 'Hello' FIELD b AS NUM USE TEMP @@ -80,6 +81,10 @@ PROCEDURE THEMAIN() PRIVATE TEST AS CHAR + x := cOtherFunc( 'A' ) + x := cOtherFunc( 1 ) + x := cOtherFunc( 'A', 'A', 'A' ) + M->TEST := "TEST" //OK - no warnings here a := 'A' @@ -123,6 +128,7 @@ PROC MAIN1() PRIVATE OTHER, TEST AS CHAR Var1 := M->TEST + Var2 := Test() ? Var1 + 2