See ChangeLog: 19990518-01:45 <rglab@imid.med.pl>

This commit is contained in:
Ryszard Glab
1999-05-18 00:55:30 +00:00
parent 893c8b6a15
commit 1c40a309b6
5 changed files with 164 additions and 42 deletions

View File

@@ -1,3 +1,19 @@
19990518-01:45 Ryszard Glab <rglab@imid.med.pl>
* source/compiler/harbour.l, source/compiler/harbour.y
-added support for '-i' option (#include file search path)
however it doesn't use SET INCLUDE environment variable yet
-added error messages if unmatched ENDDO, ENDCASE, ENDIF, NEXT
is found
* include/extend.h
-added forward declaration of CODEBLOCK structure and added
the proper type for pCodeblock member of ITEM structure
* source/vm/hvm.c
-corrected pCodeblock type casting
-added C++ style declaration of HB_FIRSTSYMBOL and HB_LASTSYMBOL
19990517-16:05 CET Eddie Runia
* source/rtl/classes.c, source/rtl/tclass.prg, include/extend.h
Initializers for DATA items added

View File

@@ -46,6 +46,8 @@ void VirtualMachine( PBYTE pCode, PSYMBOL pSymbols ); /* invokes the virtual ma
#define IT_NUMERIC ( IT_INTEGER | IT_LONG | IT_DOUBLE )
#define IT_ANY 0xFFFF
struct _CODEBLOCK; /* forward declaration */
typedef struct /* items hold at the virtual machine stack */
{
WORD wType; /* type of the item */
@@ -59,7 +61,7 @@ typedef struct /* items hold at the virtual machine stack */
int iLogical; /* logical values */
long lDate; /* date values */
PSYMBOL pSymbol; /* functions call symbol */
BYTE * pCodeblock;/* pointer to a codeblock structure */
struct _CODEBLOCK * pCodeblock;/* pointer to a codeblock structure */
WORD wItem; /* variable by reference, stack offset */
void * pBaseArray; /* array base */
} value;
@@ -97,7 +99,7 @@ typedef struct
} DYNSYM, * PDYNSYM; /* dynamic symbol structure */
/* internal structure for codeblocks */
typedef struct
typedef struct _CODEBLOCK
{
BYTE * pCode; /* codeblock pcode */
PITEM pItems; /* table with referenced local variables */

View File

@@ -15,6 +15,7 @@
#include "y_tab.h"
#include "hbsetup.h" /* main configuration file */
#include "hberrors.h"
#include "types.h"
void yyerror( char * );
static void yyunput( int, char * );
@@ -43,8 +44,14 @@ void DefineKey( char * szKey ); /* add a new key to a #define expression */
void AddDefine( char * szDefine, char * szValue ); /* add a new define from the command line */
PDEFINE FindDef( char * szText ); /* finds a #define */
/* variables defined in harbour.y */
extern int _iQuiet;
extern int _iRestrictSymbolLength;
extern WORD _wSeqCounter;
extern WORD _wForCounter;
extern WORD _wIfCounter;
extern WORD _wWhileCounter;
extern WORD _wCaseCounter;
PDEFINE pDefs = 0; /* support for #defines */
int iLine = 1;
@@ -285,9 +292,23 @@ Separator {SpaceTab}|{Comment}|{LineCont}
%{
/* ************************************************************************ */
%}
"else" _iState =ELSE; return ELSE; /* ELSE can be used in one contex only */
"elseif" _iState =ELSEIF; return ELSEIF; /* ELSEIF can be used in one context only */
"end"{Separator}+"sequ"("ence"|"enc"|"en"|"e")? return END;
"else" { /* ELSE can be used in one context only */
if( _wIfCounter == 0 )
GenError( ERR_UNMATCHED_ELSE, NULL, NULL );
_iState =ELSE;
return ELSE;
}
"elseif" { /* ELSEIF can be used in one context only */
if( _wIfCounter == 0 )
GenError( ERR_UNMATCHED_ELSEIF, NULL, NULL );
_iState =ELSEIF;
return ELSEIF;
}
"end"{Separator}+"sequ"("ence"|"enc"|"en"|"e")? {
if( _wSeqCounter == 0 )
GenError( ERR_ENDIF, NULL, NULL );
return END;
}
"end" { BEGIN END_; }
<END_>{Separator}*[\[\(] { /* array, function call */
yy_lex_count_lf();
@@ -342,9 +363,21 @@ Separator {SpaceTab}|{Comment}|{LineCont}
%{
/* ************************************************************************ */
%}
"endif" return ENDIF;
"endcase" return ENDCASE;
"enddo" return ENDDO;
"endif"|"endi" { /* ENDIF can be used in one context only */
if( _wIfCounter == 0 )
GenError( ERR_ENDIF, NULL, NULL );
return ENDIF;
}
"endc"("ase"|"as"|"a")? { /* ENDCASE can be used in one context only */
if( _wWhileCounter == 0 )
GenError( ERR_ENDCASE, NULL, NULL );
return ENDCASE;
}
"enddo"|"endd" { /* ENDDO can be used in one context only */
if( _wWhileCounter == 0 )
GenError( ERR_ENDDO, NULL, NULL );
return ENDDO;
}
"exit"/[\n\;] return EXITLOOP;
"exit" return EXIT;
"extern"|"external" _iState =EXTERN; return EXTERN;
@@ -368,6 +401,8 @@ Separator {SpaceTab}|{Comment}|{LineCont}
if( _iState == LOOKUP )
{ /* it is first item in the line */
++iLine;
if( _wForCounter == 0 )
GenError( ERR_NEXTFOR, NULL, NULL );
_iState =NEXT;
return NEXT;
}
@@ -413,6 +448,8 @@ Separator {SpaceTab}|{Comment}|{LineCont}
<NEXT_>{Separator}*. { /* an identifier follows NEXT statement */
yy_lex_count_lf();
BEGIN 0;
if( _wForCounter == 0 )
GenError( ERR_NEXTFOR, NULL, NULL );
unput( yytext[ yyleng-1 ] );
_iState =NEXT;
return NEXT;
@@ -560,8 +597,8 @@ Separator {SpaceTab}|{Comment}|{LineCont}
"^=" _iState =EXPEQ; return EXPEQ;
"%=" _iState =MODEQ; return MODEQ;
"**"|"^" _iState =POWER; return POWER;
"."[t|y]"." return TRUE;
"."[f|n]"." return FALSE;
"."[t|y]"." return TRUEVALUE;
"."[f|n]"." return FALSEVALUE;
".and." return AND;
".or." return OR;
"!"|".not." return NOT;

View File

@@ -55,7 +55,12 @@ typedef struct
int iFiles; /* number of files currently opened */
} FILES; /* structure to control several opened PRGs and CHs */
int Include( char * szFileName ); /* end #include support */
typedef struct _PATHNAMES { /* the list of pathnames to search with #include */
char *szPath;
struct _PATHNAMES *pNext;
} PATHNAMES;
int Include( char * szFileName, PATHNAMES *pSearchPath ); /* end #include support */
/*
* flags for bFlags member
@@ -233,7 +238,10 @@ char * _szErrors[] = { "Statement not allowed outside of procedure or function",
"ENDDO does not match WHILE",
"ENDCASE does not match DO CASE",
"NEXT does not match FOR",
"Syntax error: \'%s\'"
"ELSE does not match IF",
"ELSEIF does not match IF",
"Syntax error: \'%s\'",
"Unclosed control structures"
};
/* Table with reserved functions names
@@ -330,6 +338,7 @@ int EXTERNAL_LINKAGE sz_compare4( const void *pLookup, const void *pReserved )
#define RESERVED_FUNC(szName) \
bsearch( (szName), _szReservedFun, RESERVED_FUNCTIONS, sizeof(char*), sz_compare4 )
FILES files;
FUNCTIONS functions, funcalls;
PFUNCTION _pInitFunc;
@@ -341,12 +350,18 @@ int _iSyntaxCheckOnly = 0; /* syntax check only */
int _iLanguage = LANG_C; /* default Harbour generated output language */
int _iRestrictSymbolLength = 0; /* generate 10 chars max symbols length */
int _iShortCuts = 1; /* .and. & .or. expressions shortcuts */
WORD _wSeqCounter = 0;
WORD _wForCounter = 0;
WORD _wIfCounter = 0;
WORD _wWhileCounter = 0;
WORD _wCaseCounter = 0;
#ifdef OBJ_GENERATION
int _iObj32 = 0; /* generate OBJ 32 bits */
#endif
WORD _wStatics = 0; /* number of defined statics variables on the PRG */
PRETURN pReturns = 0; /* list of multiple returns from a function */
PEXTERN pExterns = 0;
PATHNAMES *_pIncludePath = NULL;
%}
@@ -360,7 +375,7 @@ PEXTERN pExterns = 0;
};
%token FUNCTION PROCEDURE IDENTIFIER RETURN NIL DOUBLE INASSIGN INTEGER INTLONG
%token LOCAL STATIC IF ELSE ELSEIF END ENDIF LITERAL TRUE FALSE
%token LOCAL STATIC IF ELSE ELSEIF END ENDIF LITERAL TRUEVALUE FALSEVALUE
%token INCLUDE EXTERN INIT EXIT AND OR NOT PUBLIC EQ NE1 NE2
%token INC DEC ALIAS DOCASE CASE OTHERWISE ENDCASE ENDDO MEMVAR
%token WHILE EXIT LOOP END FOR NEXT TO STEP LE GE FIELD IN PARAMETERS
@@ -424,7 +439,7 @@ Source : Crlf
| Source MEMVAR IdentList
;
Include : NE1 INCLUDE LITERAL { if( ! Include( $3 ) )
Include : NE1 INCLUDE LITERAL { if( ! Include( $3, _pIncludePath ) )
GenError( ERR_CANT_OPEN_INCLUDE, $3, NULL );
} Crlf
;
@@ -689,8 +704,8 @@ Operators : Expression '=' Expression { GenPCode1( _EQUAL ); } /* compare
| VarAssign
;
Logical : TRUE { $$ = 1; }
| FALSE { $$ = 0; }
Logical : TRUEVALUE { $$ = 1; }
| FALSEVALUE { $$ = 0; }
;
Array : '{' ElemList '}' { GenArray( $2 ); }
@@ -774,7 +789,7 @@ IfEndif : IfBegin EndIf { JumpHere( $1 ); }
| IfBegin IfElseIf IfElse EndIf { JumpHere( $1 ); FixElseIfs( $2 ); }
;
IfBegin : IF Expression Crlf { $$ = JumpFalse( 0 ); } IfStats
IfBegin : IF Expression Crlf { $$ = JumpFalse( 0 ); ++_wIfCounter; } IfStats
{ $$ = Jump( 0 ); JumpHere( $<iNumber>4 ); }
;
@@ -788,8 +803,8 @@ IfElseIf : ELSEIF Expression Crlf { $<iNumber>$ = JumpFalse( 0 ); }
IfStats { $$ = GenElseIf( $1, Jump( 0 ) ); JumpHere( $<iNumber>5 ); }
;
EndIf : ENDIF
| END
EndIf : ENDIF { --_wIfCounter; }
| END { --_wIfCounter; }
;
IfStats : /* no statements */
@@ -813,11 +828,11 @@ DoCase : DoCaseBegin
EndCase { FixElseIfs( $2 ); }
;
EndCase : ENDCASE
| END
EndCase : ENDCASE { --_wCaseCounter; }
| END { --_wCaseCounter; }
;
DoCaseBegin : DOCASE Crlf
DoCaseBegin : DOCASE Crlf { ++_wCaseCounter; }
;
Cases : CASE Expression Crlf { $<iNumber>$ = JumpFalse( 0 ); Line(); } CaseStmts { $$ = GenElseIf( 0, Jump( 0 ) ); JumpHere( $<iNumber>4 ); Line(); }
@@ -833,14 +848,14 @@ CaseStmts : /* no statements */
DoWhile : WhileBegin Expression Crlf { $<lNumber>$ = JumpFalse( 0 ); }
{ Jump( $1 - functions.pLast->lPCodePos ); }
EndWhile { JumpHere( $<lNumber>4 ); }
EndWhile { JumpHere( $<lNumber>4 ); --_wWhileCounter; }
| WhileBegin Expression Crlf { $<lNumber>$ = JumpFalse( 0 ); Line(); }
WhileStatements { Jump( $1 - functions.pLast->lPCodePos ); }
EndWhile { JumpHere( $<lNumber>4 ); }
EndWhile { JumpHere( $<lNumber>4 ); --_wWhileCounter; }
;
WhileBegin : WHILE { $$ = functions.pLast->lPCodePos; }
WhileBegin : WHILE { $$ = functions.pLast->lPCodePos; ++_wWhileCounter; }
;
WhileStatements : Statement
@@ -851,7 +866,7 @@ EndWhile : END
| ENDDO
;
ForNext : FOR IDENTIFIER ForAssign Expression { PopId( $2 ); $<iNumber>$ = functions.pLast->lPCodePos; }
ForNext : FOR IDENTIFIER ForAssign Expression { PopId( $2 ); $<iNumber>$ = functions.pLast->lPCodePos; ++_wForCounter;}
TO Expression { PushId( $2 ); }
StepExpr Crlf { GenPCode1( _FORTEST ); $<iNumber>$ = JumpTrue( 0 ); PushId( $2 ) }
ForStatements { GenPCode1( _PLUS ); PopId( $2 ); Jump( $<iNumber>5 - functions.pLast->lPCodePos ); JumpHere( $<iNumber>11 ); }
@@ -865,23 +880,23 @@ StepExpr : /* default step expression */ { PushInteger( 1 ); }
| STEP Expression
;
ForStatements : ForStat NEXT
| ForStat NEXT IDENTIFIER
| NEXT
| NEXT IDENTIFIER
ForStatements : ForStat NEXT { --_wForCounter; }
| ForStat NEXT IDENTIFIER { --_wForCounter; }
| NEXT { --_wForCounter; }
| NEXT IDENTIFIER { --_wForCounter; }
;
ForStat : Statements { Line(); }
;
BeginSeq : BEGINSEQ Crlf
BeginSeq : BEGINSEQ Crlf { ++_wSeqCounter; }
RecoverSeq
END
END { --_wSeqCounter; }
| BEGINSEQ Crlf
| BEGINSEQ Crlf { ++_wSeqCounter; }
Statements
RecoverSeq
END
END { --_wSeqCounter; }
;
RecoverSeq : /* no recover */
@@ -955,7 +970,7 @@ int harbour_main( int argc, char * argv[] )
{
int iStatus = 0, iArg = 1;
char szFileName[ _POSIX_PATH_MAX ]; /* filename to parse */
char *szPath ="";
char *szOutPath ="";
FILENAME *pFileName =NULL;
if( argc > 1 )
@@ -1030,6 +1045,27 @@ int harbour_main( int argc, char * argv[] )
}
break;
case 'i':
case 'I':
{
PATHNAMES *pPath = _pIncludePath;
if( pPath )
{
while( pPath->pNext )
pPath =pPath->pNext;
pPath->pNext =(PATHNAMES *)OurMalloc( sizeof(PATHNAMES) );
pPath =pPath->pNext;
}
else
{
_pIncludePath = pPath =(PATHNAMES *)OurMalloc( sizeof(PATHNAMES) );
}
pPath->pNext = NULL;
pPath->szPath = argv[ iArg ]+2;
}
break;
case 'l':
case 'L':
_iLineNumbers = 0;
@@ -1042,7 +1078,7 @@ int harbour_main( int argc, char * argv[] )
case 'o':
case 'O':
szPath = argv[ iArg ]+2;
szOutPath = argv[ iArg ]+2;
break;
case 'q':
@@ -1107,7 +1143,7 @@ int harbour_main( int argc, char * argv[] )
atexit( close_on_exit );
if( Include( szFileName ) )
if( Include( szFileName, NULL ) )
{
FunDef( strupr( strdup( pFileName->name ) ), FS_PUBLIC, FUN_PROCEDURE );
yyparse();
@@ -1120,7 +1156,7 @@ int harbour_main( int argc, char * argv[] )
if( ! _iSyntaxCheckOnly && ! _iObj32 )
#else
if( ! _iSyntaxCheckOnly )
#endif
#endif
{
if( _pInitFunc )
{
@@ -1138,7 +1174,7 @@ int harbour_main( int argc, char * argv[] )
}
/* we create a the output file */
pFileName->path = szPath;
pFileName->path = szOutPath;
switch( _iLanguage )
{
case LANG_C:
@@ -1205,6 +1241,7 @@ void PrintUsage( char * szSelf )
"\t\t\t /gj (Java) --> <file.java>\n"
"\t\t\t /gp (Pascal) --> <file.pas>\n"
"\t\t\t /gr (Resources) --> <file.rc>\n"
"\t/i<path>\tadd #include file search path\n"
"\t/l\t\tsuppress line number information\n"
"\t/n\t\tno implicit starting procedure\n"
"\t/o<path>\tobject file drive and/or path\n"
@@ -1495,12 +1532,35 @@ PCOMSYMBOL AddSymbol( char * szSymbolName )
return pSym;
}
int Include( char * szFileName )
int Include( char * szFileName, PATHNAMES *pSearch )
{
PFILE pFile;
if( ! ( yyin = fopen( szFileName, "r" ) ) )
if( ! ( yyin = fopen( szFileName, "r" ) ) )
{
if( pSearch )
{
FILENAME *pFileName =SplitFilename( szFileName );
char szFName[ _POSIX_PATH_MAX ]; /* filename to parse */
pFileName->name =szFileName;
pFileName->extension =NULL;
while( pSearch && !yyin )
{
pFileName->path =pSearch->szPath;
MakeFilename( szFName, pFileName );
if( ! ( yyin = fopen( szFName, "r" ) ) )
{
pSearch = pSearch->pNext;
if( ! pSearch )
return 0;
}
}
OurFree( pFileName );
}
else
return 0;
}
if( ! _iQuiet )
printf( "\nparsing file %s\n", szFileName );
@@ -2934,6 +2994,9 @@ void FixReturns( void ) /* fixes all last defined function returns jumps offsets
}
pReturns = 0;
}
if( (_wSeqCounter + _wWhileCounter + _wIfCounter + _wCaseCounter + _wForCounter) > 0 )
GenError( ERR_UNCLOSED_STRU, NULL, NULL );
}
void Function( BYTE bParams )

View File

@@ -138,8 +138,12 @@ typedef struct
PSYMBOL pSymbols; /* module local symbol table address */
} OBJSYMBOLS, * POBJSYMBOLS; /* structure used from Harbour generated OBJs */
#ifdef __cplusplus
extern "C" POBJSYMBOLS HB_FIRSTSYMBOL, HB_LASTSYMBOL;
#else
extern POBJSYMBOLS HB_FIRSTSYMBOL, HB_LASTSYMBOL;
#endif
#endif
STACK stack;
int iHBDEBUG = 0; /* if 1 traces the virtual machine activity */
@@ -1610,7 +1614,7 @@ void PushBlock( BYTE * pCode, WORD wSize, WORD wParam, PSYMBOL pSymbols )
{
ItemRelease( stack.pPos );
stack.pPos->wType = IT_BLOCK;
stack.pPos->value.pCodeblock = (BYTE *)CodeblockNew( pCode, wSize, pSymbols,
stack.pPos->value.pCodeblock = CodeblockNew( pCode, wSize, pSymbols,
stack.iStatics, stack.pBase - stack.pItems );
/* store the stack base of function where the codeblock was defined */
stack.pPos->wBase = stack.pBase - stack.pItems;