20000519-02:05 GMT-8 Ron Pinkas <Ron@Profit-Master.com>

* include/hbcomp.h
     ! Consoldated COMDECLARED and COMMETHOD into COMDECLARED
     + Added member pClass to COMDECLARED
     + Added member pLast to COMCLASS

   * source/compiler/harbour.y
     + Added support for Methods/Datas of type Object of a declared Class.

   * source/compiler/harbour.c
     ! Fixed bug in hb_compMethodAdd()

   * source/compiler/hbpcode.c
     + Added Strong Type Checking to Objects syntax.

   * include/hberrors.h
     + Added : "HB_COMP_WARN_MESSAGE_NOT_FOUND"

   * source/compiler/hbgenerr.c
     + Added : "3Message \'%s\' not known in Class \'%s\'"

   * tests/testwarn.prg
     + Added code to demonstrate syntax and warnings for OO Strong Type Checking.
This commit is contained in:
Ron Pinkas
2000-05-19 09:25:06 +00:00
parent ce6f538e36
commit 59501e617d
8 changed files with 365 additions and 163 deletions

View File

@@ -1,3 +1,28 @@
20000519-02:05 GMT-8 Ron Pinkas <Ron@Profit-Master.com>
* include/hbcomp.h
! Consoldated COMDECLARED and COMMETHOD into COMDECLARED
+ Added member pClass to COMDECLARED
+ Added member pLast to COMCLASS
* source/compiler/harbour.y
+ Added support for Methods/Datas of type Object of a declared Class.
* source/compiler/harbour.c
! Fixed bug in hb_compMethodAdd()
* source/compiler/hbpcode.c
+ Added Strong Type Checking to Objects syntax.
* include/hberrors.h
+ Added : "HB_COMP_WARN_MESSAGE_NOT_FOUND"
* source/compiler/hbgenerr.c
+ Added : "3Message \'%s\' not known in Class \'%s\'"
* tests/testwarn.prg
+ Added code to demonstrate syntax and warnings for OO Strong Type Checking.
20000516-22:48 GMT+2 Maurilio Longo <maurilio.longo@libero.it>
* source/rtl/memoedit.prg

View File

@@ -84,23 +84,28 @@ typedef struct
int iFiles; /* number of files currently opened */
} FILES;
/* Declared Method support structure */
typedef struct _COMMETHOD
/* Declared Function/Method support structure */
typedef struct _COMDECLARED
{
char * szName; /* the name of the symbol */
BYTE cType;
BYTE * cParamTypes;
USHORT iParamCount;
struct _COMMETHOD * pNext; /* pointer to the next declared function */
} COMMETHOD, * PCOMMETHOD;
struct _COMCLASS { char * szName; struct _COMDECLARED * pMethod; struct _COMCLASS * pNext; struct _COMDECLARED * pLast; } * pClass;
struct _COMDECLARED * pNext; /* pointer to the next declared function */
} COMDECLARED, * PCOMDECLARED;
/* Declared Class support structure */
/*
typedef struct _COMCLASS
{
char * szName; /* the name of the symbol */
PCOMMETHOD pMethod; /* Pointer to linked list of methods */
struct _COMCLASS * pNext; /* pointer to the next declared function */
char * szName;
PCOMDECLARED pMethod;
struct _COMCLASS * pNext;
} COMCLASS, * PCOMCLASS;
*/
/* Declared Class support structure */
typedef struct _COMCLASS COMCLASS, * PCOMCLASS;
/* locals, static, public variables support */
typedef struct _VAR
@@ -120,29 +125,33 @@ typedef struct _VAR
/* structure to hold a Clipper defined function */
typedef struct __FUNC
{
char * szName; /* name of a defined Clipper function */
char cScope; /* scope of a defined Clipper function */
BYTE bFlags; /* some flags we may need */
USHORT wParamCount; /* number of declared parameters */
USHORT wParamNum; /* current parameter number */
PVAR pLocals; /* pointer to local variables list */
PVAR pStatics; /* pointer to static variables list */
PVAR pFields; /* pointer to fields variables list */
PVAR pMemvars; /* pointer to memvar variables list */
PVAR pPrivates; /* pointer to private variables list */
BYTE * pCode; /* pointer to a memory block where pcode is stored */
ULONG lPCodeSize; /* total memory size for pcode */
ULONG lPCodePos; /* actual pcode offset */
int iStaticsBase; /* base for this function statics */
ULONG * pNOOPs; /* pointer to the NOOP array */
ULONG * pJumps; /* pointer to the Jumps array */
ULONG iNOOPs; /* NOOPs Counter */
ULONG iJumps; /* Jumps Counter */
BYTE * pStack; /* Compile Time Stack */
USHORT iStackSize; /* Compile Time Stack size */
int iStackIndex; /* Compile Time Stack index */
struct __FUNC * pOwner; /* pointer to the function/procedure that owns the codeblock */
struct __FUNC * pNext; /* pointer to the next defined function */
char * szName; /* name of a defined Clipper function */
char cScope; /* scope of a defined Clipper function */
BYTE bFlags; /* some flags we may need */
USHORT wParamCount; /* number of declared parameters */
USHORT wParamNum; /* current parameter number */
PVAR pLocals; /* pointer to local variables list */
PVAR pStatics; /* pointer to static variables list */
PVAR pFields; /* pointer to fields variables list */
PVAR pMemvars; /* pointer to memvar variables list */
PVAR pPrivates; /* pointer to private variables list */
BYTE * pCode; /* pointer to a memory block where pcode is stored */
ULONG lPCodeSize; /* total memory size for pcode */
ULONG lPCodePos; /* actual pcode offset */
int iStaticsBase; /* base for this function statics */
ULONG * pNOOPs; /* pointer to the NOOP array */
ULONG * pJumps; /* pointer to the Jumps array */
ULONG iNOOPs; /* NOOPs Counter */
ULONG iJumps; /* Jumps Counter */
BYTE * pStack; /* Compile Time Stack */
USHORT iStackSize; /* Compile Time Stack size */
int iStackIndex; /* Compile Time Stack index */
PCOMDECLARED pStackFunctions[8]; /* Declared Functions on the Compile Time Stack */
int iStackFunctions; /* Index into DEclared Functions on Compile Time Stack */
PCOMCLASS pStackClasses[8]; /* Declared Classes on the Compile Time Stack */
int iStackClasses; /* Index into Declared Classes on Compile Time Stack */
struct __FUNC * pOwner; /* pointer to the function/procedure that owns the codeblock */
struct __FUNC * pNext; /* pointer to the next defined function */
} _FUNC, * PFUNCTION;
/* structure to control all Clipper defined functions */
@@ -162,16 +171,6 @@ typedef struct _COMSYMBOL
struct _COMSYMBOL * pNext; /* pointer to the next defined symbol */
} COMSYMBOL, * PCOMSYMBOL;
/* Declared Function support structure */
typedef struct _COMDECLARED
{
char * szName; /* the name of the symbol */
BYTE cType;
BYTE * cParamTypes;
USHORT iParamCount;
struct _COMDECLARED * pNext; /* pointer to the next declared function */
} COMDECLARED, * PCOMDECLARED;
/* symbol table support structures */
typedef struct
{
@@ -240,8 +239,8 @@ extern PCOMDECLARED hb_compDeclaredFind( char * );
extern PCOMCLASS hb_compClassAdd( char * );
extern PCOMCLASS hb_compClassFind( char * );
extern PCOMMETHOD hb_compMethodAdd( PCOMCLASS pClass, char * );
extern PCOMMETHOD hb_compMethodFind( PCOMCLASS pClass, char * );
extern PCOMDECLARED hb_compMethodAdd( PCOMCLASS pClass, char * );
extern PCOMDECLARED hb_compMethodFind( PCOMCLASS pClass, char * );
extern void hb_compGenBreak( void ); /* generate code for BREAK statement */
@@ -363,7 +362,7 @@ extern PCOMDECLARED hb_comp_pLastDeclared;
extern PCOMCLASS hb_comp_pFirstClass;
extern PCOMCLASS hb_comp_pLastClass;
extern char * hb_comp_szClass;
extern PCOMMETHOD hb_comp_pLastMethod;
extern PCOMDECLARED hb_comp_pLastMethod;
extern PATHNAMES * hb_comp_pIncludePath;
extern PFUNCTION hb_comp_pInitFunc;
extern PHB_FNAME hb_comp_pFileName;

View File

@@ -114,9 +114,10 @@ extern "C" {
#define HB_COMP_WARN_ARRAY_ASSIGN_TYPE 21
#define HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT 22
#define HB_COMP_WARN_CLASS_NOT_FOUND 23
#define HB_COMP_WARN_MEANINGLESS 24
#define HB_COMP_WARN_UNREACHABLE 25
#define HB_COMP_WARN_DUPL_ANNOUNCE 26
#define HB_COMP_WARN_MESSAGE_NOT_FOUND 24
#define HB_COMP_WARN_MEANINGLESS 25
#define HB_COMP_WARN_UNREACHABLE 26
#define HB_COMP_WARN_DUPL_ANNOUNCE 27
/*
* Errors generated by Harbour preprocessor

View File

@@ -87,7 +87,7 @@ PCOMDECLARED hb_comp_pLastDeclared;
PCOMCLASS hb_comp_pFirstClass;
PCOMCLASS hb_comp_pLastClass;
char * hb_comp_szClass;
PCOMMETHOD hb_comp_pLastMethod;
PCOMDECLARED hb_comp_pLastMethod;
int hb_comp_iLine; /* currently processed line number */
PFUNCTION hb_comp_pInitFunc;
@@ -491,7 +491,7 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
if ( hb_comp_iWarnings < 3 )
return;
//printf( "\nAdding parameter: %s Type: %c\n", szVarName, cValueType );
/*printf( "\nAdding parameter: %s Type: %c\n", szVarName, cValueType );*/
hb_comp_pLastMethod->iParamCount++;
@@ -552,7 +552,7 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
if ( cValueType == '+' )
{
//printf( "\nVariable %s is of Class: %s\n", szVarName, hb_comp_szClass );
/*printf( "\nVariable %s is of Class: %s\n", szVarName, hb_comp_szClass );*/
pVar->pClass = hb_compClassFind( hb_comp_szClass );
if( ! pVar->pClass )
@@ -570,7 +570,7 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
PCOMSYMBOL pSym;
USHORT wPos;
//printf( "\nAdding: %s in Function: %s\n", pVar->szName, pFunc->szName );
/*printf( "\nAdding: %s in Function: %s\n", pVar->szName, pFunc->szName );*/
if( hb_comp_bAutoMemvarAssume || hb_comp_iVarScope == VS_MEMVAR )
{
@@ -606,7 +606,7 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
pSym->cScope |= VS_MEMVAR;
//printf( "\nAdded Symbol: %s Pos: %i\n", pSym->szName, wPos );
/*printf( "\nAdded Symbol: %s Pos: %i\n", pSym->szName, wPos );*/
hb_compGenPCode4( HB_P_PARAMETER, HB_LOBYTE( wPos ), HB_HIBYTE( wPos ), HB_LOBYTE( hb_comp_functions.pLast->wParamNum ), ( BOOL ) 0 );
}
@@ -636,7 +636,7 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
pLastVar->pNext = pVar;
}
//printf( "\nAdded Private: %s Type %c\n", pVar->szName, pVar->cType );
/*printf( "\nAdded Private: %s Type %c\n", pVar->szName, pVar->cType );*/
}
}
@@ -650,7 +650,7 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
pSym->cScope |= VS_MEMVAR;
//printf( "\nAdded Symbol: %s Pos: %i\n", pSym->szName, wPos );
/*printf( "\nAdded Symbol: %s Pos: %i\n", pSym->szName, wPos );*/
}
if ( hb_comp_iWarnings >= 3 )
@@ -678,7 +678,7 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
pLastVar->pNext = pVar;
}
//printf( "\nAdded Private: %s Type %c\n", pVar->szName, pVar->cType );
/*printf( "\nAdded Private: %s Type %c\n", pVar->szName, pVar->cType );*/
}
}
@@ -807,7 +807,7 @@ PCOMCLASS hb_compClassAdd( char * szClassName )
{
PCOMCLASS pClass;
//printf( "\nDeclaring Class: %s\n", szClassName );
/*printf( "\nDeclaring Class: %s\n", szClassName );*/
if ( hb_comp_iWarnings < 3 )
return NULL;
@@ -856,11 +856,11 @@ PCOMCLASS hb_compClassFind( char * szClassName )
return NULL;
}
PCOMMETHOD hb_compMethodAdd( PCOMCLASS pClass, char * szMethodName )
PCOMDECLARED hb_compMethodAdd( PCOMCLASS pClass, char * szMethodName )
{
PCOMMETHOD pMethod;
PCOMDECLARED pMethod;
//printf( "\nDeclaring Method: %s of Class: %s\n", szMethodName, pClass->szName );
/*printf( "\nDeclaring Method: %s of Class: %s Pointer: %li\n", szMethodName, pClass->szName, pClass );*/
if ( hb_comp_iWarnings < 3 )
return NULL;
@@ -868,10 +868,15 @@ PCOMMETHOD hb_compMethodAdd( PCOMCLASS pClass, char * szMethodName )
if ( ( pMethod = hb_compMethodFind( pClass, szMethodName ) ) != NULL )
{
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_DUP_DECLARATION, "Method", szMethodName );
/* Last Declaration override previous declarations */
pMethod->cParamTypes = NULL;
pMethod->iParamCount = 0;
return pMethod;
}
pMethod = ( PCOMMETHOD ) hb_xgrab( sizeof( COMMETHOD ) );
pMethod = ( PCOMDECLARED ) hb_xgrab( sizeof( COMDECLARED ) );
pMethod->szName = szMethodName;
pMethod->cType = ' '; // Not known yet
@@ -882,16 +887,21 @@ PCOMMETHOD hb_compMethodAdd( PCOMCLASS pClass, char * szMethodName )
if ( pClass->pMethod == NULL )
pClass->pMethod = pMethod;
else
pClass->pMethod->pNext = pMethod;
pClass->pLast->pNext = pMethod;
pClass->pLast = pMethod;
hb_comp_pLastMethod = pMethod;
return pMethod;
}
PCOMMETHOD hb_compMethodFind( PCOMCLASS pClass, char * szMethodName )
PCOMDECLARED hb_compMethodFind( PCOMCLASS pClass, char * szMethodName )
{
PCOMMETHOD pMethod = pClass->pMethod;
PCOMDECLARED pMethod = NULL;
if ( pClass )
pMethod = pClass->pMethod;
while( pMethod )
{
@@ -915,7 +925,7 @@ PCOMDECLARED hb_compDeclaredAdd( char * szDeclaredName )
if ( hb_comp_iWarnings < 3 )
return NULL;
//printf( "\nDeclaring Function: %s\n", szDeclaredName, NULL );
/*printf( "\nDeclaring Function: %s\n", szDeclaredName, NULL );*/
if ( ( pDeclared = hb_compDeclaredFind( szDeclaredName ) ) != NULL )
{
@@ -994,29 +1004,31 @@ static PFUNCTION hb_compFunctionNew( char * szName, HB_SYMBOLSCOPE cScope )
PFUNCTION pFunc;
pFunc = ( PFUNCTION ) hb_xgrab( sizeof( _FUNC ) );
pFunc->szName = szName;
pFunc->cScope = cScope;
pFunc->pLocals = NULL;
pFunc->pStatics = NULL;
pFunc->pFields = NULL;
pFunc->pMemvars = NULL;
pFunc->pPrivates = NULL;
pFunc->pCode = NULL;
pFunc->lPCodeSize = 0;
pFunc->lPCodePos = 0;
pFunc->pNext = NULL;
pFunc->wParamCount = 0;
pFunc->wParamNum = 0;
pFunc->iStaticsBase = hb_comp_iStaticCnt;
pFunc->pOwner = NULL;
pFunc->bFlags = 0;
pFunc->iNOOPs = 0;
pFunc->iJumps = 0;
pFunc->pNOOPs = NULL;
pFunc->pJumps = NULL;
pFunc->pStack = NULL;
pFunc->iStackSize = 0;
pFunc->iStackIndex = 0;
pFunc->szName = szName;
pFunc->cScope = cScope;
pFunc->pLocals = NULL;
pFunc->pStatics = NULL;
pFunc->pFields = NULL;
pFunc->pMemvars = NULL;
pFunc->pPrivates = NULL;
pFunc->pCode = NULL;
pFunc->lPCodeSize = 0;
pFunc->lPCodePos = 0;
pFunc->pNext = NULL;
pFunc->wParamCount = 0;
pFunc->wParamNum = 0;
pFunc->iStaticsBase = hb_comp_iStaticCnt;
pFunc->pOwner = NULL;
pFunc->bFlags = 0;
pFunc->iNOOPs = 0;
pFunc->iJumps = 0;
pFunc->pNOOPs = NULL;
pFunc->pJumps = NULL;
pFunc->pStack = NULL;
pFunc->iStackSize = 0;
pFunc->iStackIndex = 0;
pFunc->iStackFunctions = 0;
pFunc->iStackClasses = 0;
return pFunc;
}
@@ -1992,6 +2004,8 @@ void hb_compLinePush( void ) /* generates the pcode with the currently compiled
/* Resting Compile Time Stack */
hb_comp_functions.pLast->iStackIndex = 0;
hb_comp_functions.pLast->iStackFunctions = 0;
hb_comp_functions.pLast->iStackClasses = 0;
}
/* Generates the pcode with the currently compiled source code line
@@ -2775,6 +2789,8 @@ void hb_compFinalizeFunction( void ) /* fixes all last defined function returns
pFunc->iStackSize = 0;
pFunc->iStackIndex = 0;
pFunc->iStackFunctions = 0;
pFunc->iStackClasses = 0;
}
}
}
@@ -2816,7 +2832,7 @@ static void hb_compOptimizeFrames( PFUNCTION pFunc )
while( pVar )
{
//printf( "\nChecking: %s Used: %i\n", pVar->szName, pVar->iUsed );
/*printf( "\nChecking: %s Used: %i\n", pVar->szName, pVar->iUsed );*/
if ( ( ! pVar->iUsed & VU_USED ) && pVar->iUsed & VU_INITIALIZED )
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_VAL_NOT_USED, pVar->szName, NULL );
@@ -3301,6 +3317,8 @@ void hb_compCodeBlockEnd( void )
pCodeblock->iStackSize = 0;
pCodeblock->iStackIndex = 0;
pCodeblock->iStackFunctions = 0;
pCodeblock->iStackClasses = 0;
hb_xfree( ( void * ) pCodeblock );
}

View File

@@ -1153,14 +1153,36 @@ ClassInfo : DecMethod
;
DecMethod : IdentName '(' { hb_comp_pLastMethod = hb_compMethodAdd( hb_comp_pLastClass, $1 ); } DecList ')' AsType { if ( hb_comp_pLastMethod )
hb_comp_pLastMethod->cType = hb_comp_cVarType;
{
hb_comp_pLastMethod->cType = hb_comp_cVarType;
if ( hb_comp_cVarType == '+' )
{
hb_comp_pLastMethod->pClass = hb_compClassFind( hb_comp_szClass );
if( ! hb_comp_pLastMethod->pClass )
{
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_CLASS_NOT_FOUND, hb_comp_szClass, hb_comp_pLastMethod->szName );
hb_comp_pLastMethod->cType = 'O';
}
}
}
hb_comp_pLastMethod = NULL;
hb_comp_cVarType = ' ';
}
;
DecData : IdentName { hb_comp_pLastMethod = hb_compMethodAdd( hb_comp_pLastClass, $1 ); } AsType { if ( hb_comp_pLastMethod )
hb_comp_pLastMethod->cType = hb_comp_cVarType;
{
hb_comp_pLastMethod->cType = hb_comp_cVarType;
if ( hb_comp_cVarType == '+' )
{
hb_comp_pLastMethod->pClass = hb_compClassFind( hb_comp_szClass );
if( ! hb_comp_pLastMethod->pClass )
{
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_CLASS_NOT_FOUND, hb_comp_szClass, hb_comp_pLastMethod->szName );
hb_comp_pLastMethod->cType = 'O';
}
}
}
hb_comp_pLastMethod = NULL;
hb_comp_cVarType = ' ';
}

View File

@@ -113,7 +113,8 @@ char * hb_comp_szWarnings[] =
"3Value of Variable \'%s\' never used",
"3Incompatible type in assignment to declared array element expected: \'%s\'",
"4Suspicious type in assignment to declared array element expected: \'%s\'",
"3Class \'%s\' not known in declaration of variable \'%s\'",
"3Class \'%s\' not known in declaration of \'%s\'",
"3Message \'%s\' not known in Class \'%s\'",
"0Meaningless use of expression: \'%s\'",
"2Unreachable code",
"1Redundant \'ANNOUNCE %s\' statement ignored"

View File

@@ -171,11 +171,6 @@ static BYTE s_pcode_len[] = {
1 /* HB_P_ONE, */
};
static BYTE * hb_comp_cParamTypes = NULL;
static int hb_comp_iParamCount = -1;
static PCOMCLASS hb_comp_pStackClass[8];
static int hb_comp_iClasses;
static PVAR hb_compPrivateFind( char * szPrivateName )
{
PFUNCTION pFunc = hb_comp_functions.pLast;
@@ -303,9 +298,15 @@ void hb_compStrongType( int iSize )
if ( pFunc->iStackIndex < ( wVar + 2 ) )
break;
if ( hb_comp_iParamCount > -1 )
if ( pFunc->iStackFunctions > 0 && pFunc->pStackFunctions[ --pFunc->iStackFunctions ] )
{
int iParamCount = hb_comp_iParamCount, iOptionals = 0;
int hb_comp_iParamCount, iParamCount, iOptionals = 0;
BYTE * hb_comp_cParamTypes;
hb_comp_cParamTypes = pFunc->pStackFunctions[ pFunc->iStackFunctions ]->cParamTypes;
hb_comp_iParamCount = pFunc->pStackFunctions[ pFunc->iStackFunctions ]->iParamCount;
iParamCount = hb_comp_iParamCount;
/* First, find how many optionals. */
while ( --iParamCount >= 0 )
@@ -316,7 +317,7 @@ void hb_compStrongType( int iSize )
break;
}
//printf( "\nOptionals: %i\n", iOptionals );
/*printf( "\nOptionals: %i\n", iOptionals );*/
/* Now, check the types. */
if( wVar >= ( hb_comp_iParamCount - iOptionals ) && wVar <= hb_comp_iParamCount )
@@ -362,7 +363,7 @@ void hb_compStrongType( int iSize )
}
}
/* Removing all the optional parameters. Rteurn type already pushed just prior to parameters */
/* Removing all the parameters. Rteurn type already pushed just prior to parameters */
pFunc->iStackIndex -= wVar;
/* Removing the NIL */
@@ -372,13 +373,9 @@ void hb_compStrongType( int iSize )
/* No return value. */
pFunc->iStackIndex--;
else
/* Declared result already on stack. */
; /* Declared result already on stack. */
//printf( "\nType of Function: \'%c\'\n", pFunc->pStack[ pFunc->iStackIndex - 1 ] );
/* Resetting */
hb_comp_cParamTypes = NULL;
hb_comp_iParamCount = -1;
/*printf( "\nType of Function: \'%c\'\n", pFunc->pStack[ pFunc->iStackIndex - 1 ] );*/
break;
@@ -394,36 +391,139 @@ void hb_compStrongType( int iSize )
sprintf( ( char * ) szType1, "%c", cSubType1 );
if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] == 'O' )
;
{
/* The Object is not declared. */
}
else if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] == '+' )
;
{
pSym = hb_compSymbolGetPos( pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256 );
if ( pSym && pSym->szName && pFunc->iStackClasses > 0 && pFunc->iStackFunctions < 8 )
{
pFunc->pStackFunctions[ pFunc->iStackFunctions++ ] = hb_compMethodFind( pFunc->pStackClasses[ pFunc->iStackClasses - 1 ], pSym->szName );
/*printf( "\nMethod: %s of Class: %s Parameters: %i\n", pSym->szName, pFunc->pStackClasses[ pFunc->iStackClasses - 1 ]->szName, pFunc->pStackFunctions[ pFunc->iStackFunctions - 1 ]->iParamCount );*/
if ( pFunc->pStackFunctions[ pFunc->iStackFunctions - 1 ] == NULL )
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_MESSAGE_NOT_FOUND, pSym->szName, pFunc->pStackClasses[ pFunc->iStackClasses - 1 ]->szName );
}
else
{
/* The method is not declared. */
pFunc->pStackFunctions[ pFunc->iStackFunctions++ ] = NULL;
}
}
else if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] == ' ' )
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_OPERAND_SUSPECT, "O", NULL );
else
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_OPERAND_TYPE, ( char * ) szType1, "O" );
/* TODO: Allow declaration of Methods */
/* Result will be pushed by HB_P_SEND*/
/* Unknown result of method */
pFunc->pStack[ pFunc->iStackIndex - 1 ] = ' ';
break;
/* Handles by HB_P_MESSAGE. */
case HB_P_SENDSHORT :
wVar = ( SHORT ) pFunc->pCode[ ulPos + 1 ];
/* Fall Through - don't add break !!! */
case HB_P_SEND :
/* Remove the 'C' resulted from the Method Name just pushed. */
pFunc->iStackIndex--;
wVar = * ( ( SHORT * ) &( pFunc->pCode )[ ulPos + 1 ] );
/* Fall Through - don't add break !!! */
case HB_P_SENDSHORT :
if ( wVar == 0 )
wVar = * ( ( SHORT * ) &( pFunc->pCode )[ ulPos + 1 ] );
wVar = ( SHORT ) pFunc->pCode[ ulPos + 1 ];
if ( pFunc->pStack[ pFunc->iStackIndex - ( wVar + 1 ) ] == '+' )
/*printf( "\nParams: %i Stack: %i\n", wVar, pFunc->iStackIndex );*/
if ( pFunc->iStackIndex < ( wVar + 1 ) )
break;
if ( pFunc->pStack[ pFunc->iStackIndex - ( wVar + 1 ) ] == '+' )
{
if ( pFunc->iStackFunctions > 0 && pFunc->pStackFunctions[ --pFunc->iStackFunctions ] )
{
int hb_comp_iParamCount, iParamCount, iOptionals = 0;
BYTE * hb_comp_cParamTypes;
hb_comp_cParamTypes = pFunc->pStackFunctions[ pFunc->iStackFunctions ]->cParamTypes;
hb_comp_iParamCount = pFunc->pStackFunctions[ pFunc->iStackFunctions ]->iParamCount;
iParamCount = hb_comp_iParamCount;
/*printf( "\nExec Method: %s of Class: %s Parameters: %i\n", pFunc->pStackFunctions[ pFunc->iStackFunctions ]->szName, pFunc->pStackClasses[ pFunc->iStackClasses - 1 ]->szName, pFunc->pStackFunctions[ pFunc->iStackFunctions ]->iParamCount );*/
/* First, find how many optionals. */
while ( --iParamCount >= 0 )
{
if ( hb_comp_cParamTypes[ iParamCount ] == ( ' ' + VT_OFFSET_OPTIONAL ) || hb_comp_cParamTypes[ iParamCount ] >= ( 'A' + VT_OFFSET_OPTIONAL ) )
iOptionals++;
else
break;
}
/*printf( "\nOptionals: %i\n", iOptionals );*/
/* Now, check the types. */
if( wVar >= ( hb_comp_iParamCount - iOptionals ) && wVar <= hb_comp_iParamCount )
{
BYTE iOffset = 0, iParamBase = pFunc->iStackIndex - wVar, cFormalType;
while ( iOffset < wVar )
{
cFormalType = hb_comp_cParamTypes[ iOffset ];
if ( cFormalType == ( ' ' + VT_OFFSET_OPTIONAL ) || cFormalType >= ( 'A' + VT_OFFSET_OPTIONAL ) )
cFormalType -= VT_OFFSET_OPTIONAL;
if ( cFormalType == ' ' + VT_OFFSET_BYREF )
cFormalType = '@';
if ( cFormalType == ' ' )
; /* Declared is Variant, accept anything. */
else if ( pFunc->pStack[ iParamBase + iOffset ] == '-' )
; /* Parameter is NIL, always accepted. */
else if ( cFormalType == '@' && pFunc->pStack[ iParamBase + iOffset ] >= ( 'A' + VT_OFFSET_BYREF ) )
; /* Prameter is ANY REFERENCE, and Parameter is SOME REFERENCE. */
else if ( cFormalType != pFunc->pStack[ iParamBase + iOffset ] )
{
if ( cFormalType > ( 'A' + VT_OFFSET_BYREF ) )
sprintf( ( char * ) szType2, "@%c", cFormalType - VT_OFFSET_BYREF );
else
sprintf( ( char * ) szType2, "%c", cFormalType );
sprintf( ( char * ) szType1, "%i", iOffset + 1 );
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_PARAM_TYPE, ( char * ) szType1, ( char * ) szType2 );
}
iOffset++;
}
}
else
{
sprintf( ( char * ) szType1, "%i", wVar );
sprintf( ( char * ) szType2, "%i", hb_comp_iParamCount - iOptionals );
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_PARAM_COUNT, ( char * ) szType1, ( char * ) szType2 );
}
}
}
/* Removing all the parameters.*/
pFunc->iStackIndex -= wVar;
if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] == '+' && pFunc->pStackFunctions[ pFunc->iStackFunctions ] )
{
pFunc->pStack[ pFunc->iStackIndex - 1 ] = pFunc->pStackFunctions[ pFunc->iStackFunctions ]->cType;
/*printf( "\nDeclared Method!!! Stack: %i Type: %c\n", pFunc->iStackIndex, pFunc->pStack[ pFunc->iStackIndex - 1 ] );*/
if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] == '+' && pFunc->iStackClasses < 8 )
{
/*printf( "\nNested CLASS!!! Stack: %i Type: %c Class Pointer: %i\n", pFunc->iStackIndex, pFunc->pStack[ pFunc->iStackIndex - 1 ], pFunc->pStackFunctions[ pFunc->iStackFunctions ]->pClass );*/
pFunc->pStackClasses[ pFunc->iStackClasses++ ] = pFunc->pStackFunctions[ pFunc->iStackFunctions ]->pClass;
}
}
else
pFunc->pStack[ pFunc->iStackIndex - 1 ] = ' ';
break;
case HB_P_DEC :
@@ -562,7 +662,7 @@ void hb_compStrongType( int iSize )
/* TODO Error Message after finalizing all possible pcodes. */
break;
//printf( "\nTop: %c Bottom: %c Typ-SubType: %c Bottom->SubType: %c\n", pFunc->pStack[ pFunc->iStackIndex], pFunc->pStack[ pFunc->iStackIndex - 1 ], pFunc->pStack[ pFunc->iStackIndex] - 100, pFunc->pStack[ pFunc->iStackIndex - 1 ] - 100 );
/*printf( "\nTop: %c Bottom: %c Typ-SubType: %c Bottom->SubType: %c\n", pFunc->pStack[ pFunc->iStackIndex], pFunc->pStack[ pFunc->iStackIndex - 1 ], pFunc->pStack[ pFunc->iStackIndex] - 100, pFunc->pStack[ pFunc->iStackIndex - 1 ] - 100 );*/
if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] >= ( 'A' + VT_OFFSET_VARIANT ) )
cSubType1 = ( pFunc->pStack[ pFunc->iStackIndex - 1 ] -= VT_OFFSET_VARIANT );
@@ -970,27 +1070,26 @@ void hb_compStrongType( int iSize )
else
pSym = hb_compSymbolGetPos( pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256 );
//printf( "\nSymbol: %s\n", pSym->szName );
/*printf( "\nSymbol: %s\n", pSym->szName );*/
if ( pSym && pSym->szName )
{
pDeclared = hb_compDeclaredFind( pSym->szName );
if ( pDeclared )
{
pFunc->pStack[ pFunc->iStackIndex++ ] = pDeclared->cType;
/* Storing, will be checked by FUNCTION* */
hb_comp_cParamTypes = pDeclared->cParamTypes;
hb_comp_iParamCount = pDeclared->iParamCount;
}
else
pFunc->pStack[ pFunc->iStackIndex++ ] = ' ';
/* Storing, will be checked by HB_P_FUNCTION, OK to store NULL */
/* TODO don't use hard coded size */
if ( pFunc->iStackFunctions < 8 )
pFunc->pStackFunctions[ pFunc->iStackFunctions++ ] = pDeclared;
/* QUESTION: Add other "safe" functions, or remove adaptive type checking support for memvars? */
if ( strcmp( pSym->szName, "QOUT" ) )
{
//printf( "\nRestting privates affected by: %s\n", pSym->szName );
/*printf( "\nRestting privates affected by: %s\n", pSym->szName );*/
/* All Private Variants Subtype will be unknown after function call. */
pVar = pFunc->pMemvars;
@@ -1003,6 +1102,13 @@ void hb_compStrongType( int iSize )
}
}
}
else
{
/* Storing, will be checked by FUNCTION, OK to store NULL */
/* TODO don't use hard coded size */
if ( pFunc->iStackFunctions < 8 )
pFunc->pStackFunctions[ pFunc->iStackFunctions++ ] = NULL;
}
}
break;
@@ -1037,10 +1143,10 @@ void hb_compStrongType( int iSize )
/* Mark as used */
pVar->iUsed |= VU_USED;
if ( pVar->cType == '+' )
if ( pVar->cType == '+' && pFunc->iStackClasses < 8 )
{
/* Object of declared class */
hb_comp_pStackClass[ hb_comp_iClasses++ ] = pVar->pClass;
pFunc->pStackClasses[ pFunc->iStackClasses++ ] = pVar->pClass;
pFunc->pStack[ pFunc->iStackIndex++ ] = '+';
}
else if ( pFunc->pCode[ ulPos ] == HB_P_PUSHLOCALREF )
@@ -1069,7 +1175,7 @@ void hb_compStrongType( int iSize )
if ( pVar )
{
//printf( "\nStatic: %s Function: %s Found in: %s\n", pVar->szName, pFunc->szName, pTmp->szName );
/*printf( "\nStatic: %s Function: %s Found in: %s\n", pVar->szName, pFunc->szName, pTmp->szName );*/
/* Only if "private" static, since global static may be intialized elsewhere. */
/* May have been initialized in previous execution of the function.
@@ -1081,10 +1187,10 @@ void hb_compStrongType( int iSize )
/* Mark as used */
pVar->iUsed |= VU_USED;
if ( pVar->cType == '+' )
if ( pVar->cType == '+' && pFunc->iStackClasses < 8 )
{
/* Object of declared class */
hb_comp_pStackClass[ hb_comp_iClasses++ ] = pVar->pClass;
pFunc->pStackClasses[ pFunc->iStackClasses++ ] = pVar->pClass;
pFunc->pStack[ pFunc->iStackIndex++ ] = '+';
}
if ( pFunc->pCode[ ulPos ] == HB_P_PUSHSTATICREF )
@@ -1161,7 +1267,7 @@ void hb_compStrongType( int iSize )
if ( pVar )
{
//printf( "\nPused: %s Type: %c SubType: %c\n", pVar->szName, pVar->cType, pVar->cType - 100 );
/*printf( "\nPushed: %s Type: %c SubType: %c\n", pVar->szName, pVar->cType, pVar->cType - 100 );*/
if ( ! ( pVar->iUsed & VU_INITIALIZED ) )
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_NOT_INITIALIZED, pVar->szName, NULL );
@@ -1169,10 +1275,10 @@ void hb_compStrongType( int iSize )
/* Mark as used */
pVar->iUsed |= VU_USED;
if ( pVar->cType == '+' )
if ( pVar->cType == '+' && pFunc->iStackClasses < 8 )
{
/* Object of declared class */
hb_comp_pStackClass[ hb_comp_iClasses++ ] = pVar->pClass;
pFunc->pStackClasses[ pFunc->iStackClasses++ ] = pVar->pClass;
pFunc->pStack[ pFunc->iStackIndex++ ] = '+';
}
else if ( pFunc->pCode[ ulPos ] == HB_P_PUSHMEMVARREF )
@@ -1204,7 +1310,7 @@ void hb_compStrongType( int iSize )
/* Push type array of NILs (empty array). */
pFunc->pStack[ pFunc->iStackIndex++ ] = '-' + 100;
//printf( "\nPushed array at: %i\n", pFunc->iStackIndex - 1 );
/*printf( "\nPushed array at: %i\n", pFunc->iStackIndex - 1 );*/
break;
case HB_P_ARRAYGEN :
@@ -1370,10 +1476,10 @@ void hb_compStrongType( int iSize )
case HB_P_POPVARIABLE :
pFunc->iStackIndex--;
if ( pFunc->pStack[ pFunc->iStackIndex ] == '+' )
if ( pFunc->pStack[ pFunc->iStackIndex ] == '+' && pFunc->iStackClasses > 0 )
{
/* Object of declared class */
hb_comp_pStackClass[ --hb_comp_iClasses ] = NULL;
pFunc->pStackClasses[ --pFunc->iStackClasses ] = NULL;
}
break;
@@ -1382,10 +1488,10 @@ void hb_compStrongType( int iSize )
/* TODO: check what is aliasedvar? */
pFunc->iStackIndex--;
if ( pFunc->pStack[ pFunc->iStackIndex ] == '+' )
if ( pFunc->pStack[ pFunc->iStackIndex ] == '+' && pFunc->iStackClasses > 0 )
{
/* Object of declared class */
hb_comp_pStackClass[ --hb_comp_iClasses ] = NULL;
pFunc->pStackClasses[ --pFunc->iStackClasses ] = NULL;
}
break;
@@ -1407,7 +1513,7 @@ void hb_compStrongType( int iSize )
pSym = hb_compSymbolGetPos( wVar );
}
//printf( "\nField: %s Pos: %i", pSym->szName, wVar );
/*printf( "\nField: %s Pos: %i", pSym->szName, wVar );*/
/* For fall through as well */
if ( pSym && pSym->szName && pFunc->pFields )
@@ -1432,10 +1538,10 @@ void hb_compStrongType( int iSize )
/* TODO Error Message after finalizing all possible pcodes. */
break;
if ( pFunc->pStack[ pFunc->iStackIndex ] == '+' )
if ( pFunc->pStack[ pFunc->iStackIndex ] == '+' && pFunc->iStackClasses > 0 )
{
/* Object of declared class */
hb_comp_pStackClass[ --hb_comp_iClasses ] = NULL;
pFunc->pStackClasses[ --pFunc->iStackClasses ] = NULL;
pFunc->pStack[ pFunc->iStackIndex ] = 'O';
}
@@ -1478,7 +1584,7 @@ void hb_compStrongType( int iSize )
{
pVar->iUsed |= VU_INITIALIZED;
//printf( "\nSymbol: %s Variable: %s Type: %c #%i Function: %s\n", pSym->szName, pVar->szName, pVar->cType, wVar, pFunc->szName );
/*printf( "\nSymbol: %s Variable: %s Type: %c #%i Function: %s\n", pSym->szName, pVar->szName, pVar->cType, wVar, pFunc->szName );*/
/* Allow any type into a Variant, and record the subtype */
if ( pVar->cType == ' ' || pVar->cType >= ( 'A' + VT_OFFSET_VARIANT ) )
@@ -1490,20 +1596,25 @@ void hb_compStrongType( int iSize )
else
pVar->cType = pFunc->pStack[ pFunc->iStackIndex ] + VT_OFFSET_VARIANT;
//printf( "\nSymbol: %s Variable: %s Assigned Type: \'%c\' SubType: %c #%i Stack: %i\n", pSym->szName, pVar->szName, pVar->cType, pVar->cType - 100, wVar, pFunc->iStackIndex );
/*printf( "\nSymbol: %s Variable: %s Assigned Type: \'%c\' SubType: %c #%i Stack: %i\n", pSym->szName, pVar->szName, pVar->cType, pVar->cType - 100, wVar, pFunc->iStackIndex );*/
}
else
{
char szType[2];
sprintf( ( char * ) szType, "%c", pVar->cType );
if ( islower( pVar->cType ) )
sprintf( ( char * ) szType, "ARRAY OF %c", toupper( pVar->cType ) );
else
sprintf( ( char * ) szType, "%c", pVar->cType );
//printf( "Variable: %s Type: \'%c\' SubType: %c Comparing: %c Recorded: %s\n", pSym->szName, pVar->cType, pVar->cType - 100, pFunc->pStack[ pFunc->iStackIndex ], ( char * ) szType );
/*printf( "Variable: %s Type: \'%c\' SubType: %c Comparing: %c Recorded: %s\n", pSym->szName, pVar->cType, pVar->cType - 100, pFunc->pStack[ pFunc->iStackIndex ], ( char * ) szType );*/
if ( pFunc->pStack[ pFunc->iStackIndex ] >= ( 'A' + VT_OFFSET_VARIANT ) )
pFunc->pStack[ pFunc->iStackIndex ] -= VT_OFFSET_VARIANT;
if ( pFunc->pStack[ pFunc->iStackIndex ] == '-' )
; /* NIL allowed into all types */
else if ( islower( pFunc->pStack[ pFunc->iStackIndex ] ) && pVar->cType == 'a' )
; /* Array Of may accept any Array */
else if ( pFunc->pStack[ pFunc->iStackIndex ] == ' ' )
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_SUSPECT, pVar->szName, ( char * ) szType );
else if ( isupper( pVar->cType ) && pVar->cType != pFunc->pStack[ pFunc->iStackIndex ] )
@@ -1531,13 +1642,18 @@ void hb_compStrongType( int iSize )
else
{
char szType[2];
sprintf( ( char * ) szType, "%c", pSym->cType );
if ( islower( pSym->cType ) )
sprintf( ( char * ) szType, "ARRAY OF %c", toupper( pSym->cType ) );
else
sprintf( ( char * ) szType, "%c", pSym->cType );
if ( pFunc->pStack[ pFunc->iStackIndex ] >= ( 'A' + VT_OFFSET_VARIANT ) )
pFunc->pStack[ pFunc->iStackIndex ] -= VT_OFFSET_VARIANT;
if ( pFunc->pStack[ pFunc->iStackIndex ] == '-' )
; /* NIL allowed into all types */
else if ( islower( pFunc->pStack[ pFunc->iStackIndex ] ) && pSym->cType == 'a' )
; /* Array Of may accept any Array */
else if ( pFunc->pStack[ pFunc->iStackIndex ] == ' ' )
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_SUSPECT, pSym->szName, ( char * ) szType );
else if ( isupper( pSym->cType ) && pSym->cType != pFunc->pStack[ pFunc->iStackIndex ] )
@@ -1562,10 +1678,10 @@ void hb_compStrongType( int iSize )
/* TODO Error Message after finalizing all possible pcodes. */
break;
if ( pFunc->pStack[ pFunc->iStackIndex ] == '+' )
if ( pFunc->pStack[ pFunc->iStackIndex ] == '+' && pFunc->iStackClasses > 0 )
{
/* Object of declared class */
hb_comp_pStackClass[ --hb_comp_iClasses ] = NULL;
pFunc->pStackClasses[ --pFunc->iStackClasses ] = NULL;
pFunc->pStack[ pFunc->iStackIndex ] = 'O';
}
@@ -1606,13 +1722,18 @@ void hb_compStrongType( int iSize )
else
{
char szType[2];
sprintf( ( char * ) szType, "%c", pVar->cType );
if ( islower( pVar->cType ) )
sprintf( ( char * ) szType, "ARRAY OF %c", toupper( pVar->cType ) );
else
sprintf( ( char * ) szType, "%c", pVar->cType );
if ( pFunc->pStack[ pFunc->iStackIndex ] >= ( 'A' + VT_OFFSET_VARIANT ) )
pFunc->pStack[ pFunc->iStackIndex ] -= VT_OFFSET_VARIANT;
if ( pFunc->pStack[ pFunc->iStackIndex ] == '-' )
; /* NIL allowed into all types */
else if ( islower( pFunc->pStack[ pFunc->iStackIndex ] ) && pVar->cType == 'a' )
; /* Array Of may accept any Array */
else if ( pFunc->pStack[ pFunc->iStackIndex ] == ' ' )
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_SUSPECT, pVar->szName, ( char * ) szType );
else if ( isupper( pVar->cType ) && pVar->cType != pFunc->pStack[ pFunc->iStackIndex ] )
@@ -1631,10 +1752,10 @@ void hb_compStrongType( int iSize )
/* TODO Error Message after finalizing all possible pcodes. */
break;
if ( pFunc->pStack[ pFunc->iStackIndex ] == '+' )
if ( pFunc->pStack[ pFunc->iStackIndex ] == '+' && pFunc->iStackClasses > 0 )
{
/* Object of declared class */
hb_comp_pStackClass[ --hb_comp_iClasses ] = NULL;
pFunc->pStackClasses[ --pFunc->iStackClasses ] = NULL;
pFunc->pStack[ pFunc->iStackIndex ] = 'O';
}
@@ -1667,13 +1788,18 @@ void hb_compStrongType( int iSize )
else
{
char szType[2];
sprintf( ( char * ) szType, "%c", pVar->cType );
if ( islower( pVar->cType ) )
sprintf( ( char * ) szType, "ARRAY OF %c", toupper( pVar->cType ) );
else
sprintf( ( char * ) szType, "%c", pVar->cType );
if ( pFunc->pStack[ pFunc->iStackIndex ] >= ( 'A' + VT_OFFSET_VARIANT ) )
pFunc->pStack[ pFunc->iStackIndex ] -= VT_OFFSET_VARIANT;
if ( pFunc->pStack[ pFunc->iStackIndex ] == '-' )
; /* NIL allowed into all types */
else if ( islower( pFunc->pStack[ pFunc->iStackIndex ] ) && pVar->cType == 'a' )
; /* Array Of may accept any Array */
else if ( pFunc->pStack[ pFunc->iStackIndex ] == ' ' )
hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_SUSPECT, pVar->szName, ( char * ) szType );
else if ( isupper( pVar->cType ) && pVar->cType != pFunc->pStack[ pFunc->iStackIndex ] )

View File

@@ -53,24 +53,24 @@
DECLARE nMyFunc( cVar AS STRING, @nVar AS NUMERIC ) AS NUMERIC
DECLARE cOtherFunc( @cVar as char, optional nVar as num, optional other as variant ) AS CHAR
DECLARE cOtherFunc( ) AS CHAR
DECLARE cOtherFunc( @cVar as char, optional nVar as num, optional other as variant ) AS CHAR
DECLARE seconds() AS NUM
DECLARE int( n AS NUMERIC ) AS NUMERIC
DECLARE TEST() AS NUMERIC
DECLARE MyClass ;
nMyFunc( nVal As Num ) As Num
DECLARE MyClass ;
nMyFunc( nVal As Num ) As Num ;
nMyFunc( nVal As Num ) As Num ;
cMyData ;
FinalMethod
DECLARE MyClass ;
nMyFunc( nVal As Num ) As Num
oNext() As Object FROM CLASS MyClass
FIELD a AS CHAR
FIELD b AS CHAR
@@ -84,7 +84,7 @@ PROCEDURE THEMAIN( optional )
STATIC lStatic := 0, oMyObj As Object From CLASS WrongClass
LOCAL cVar AS CHAR := [declare function]
oMyObj:MyMethod( 2, 3, 4 )
LOCAL a As Char, b AS Object FROM CLASS MyClass
FIELD b AS NUM
USE TEMP
@@ -94,6 +94,16 @@ PROCEDURE THEMAIN( optional )
PRIVATE TEST AS CHAR
oMyObj:MyMethod( 2, 3, 4 )
a := b:nMyFunc(2,3)
a := b:nMyFunc(2)
a := b:oNext:cMyData
a := b:oNext:cMyData2
DO Optional WITH Var1
DO Optional WITH 1
DO Optional WITH "something"