see ChangeLog 19990520-01:40

This commit is contained in:
Ryszard Glab
1999-05-20 00:47:57 +00:00
parent 3869a67a82
commit d3d9e6062a
8 changed files with 190 additions and 76 deletions

View File

@@ -1,3 +1,35 @@
19990520-01:40 Ryszard Glab <rglab@imid.med.pl>
* source/compiler/harbour.y
-corrected support for INCLUDE environment variable (the last path
was ignored)
-definition of path delimiter and path list separator was moved to
hbsetup.h file. OS_PATH_DELIMITER and OS_PATH_LIST_SEPARATOR are
now defined.
-changed #define from OBJ_GENERATION to HARBOUR_OBJ_GENERATION
* source/compiler/harbour.l
-EXIT keyword is now properly supported
* source/vm/hvm.c
-changed #define from OBJ_GENERATION to HARBOUR_OBJ_GENERATION
-changed #define from HARBOUR_MAIN to HARBOUR_START_PROCEDURE
* include/hbsetup.h
-changed #define from OBJ_GENERATION to HARBOUR_OBJ_GENERATION
-changed #define from HARBOUR_MAIN to HARBOUR_START_PROCEDURE
-added #define OS_PATH_DELIMITER
-added #define OS_PATH_LIST_SEPARATOR
* include/hberrors.h
-added #define ERR_UNMATCHED_EXIT
* source/rtl/environ.c
-corrected support for Watcom C/C++ compiler
* tests/working/keywords.prg
-added test code for EXIT keyword
19990519-21:22 CET Eddie Runia
* makefile.b16
Patrick patch (command-line too long entered)

View File

@@ -21,5 +21,6 @@
#define ERR_UNMATCHED_ELSEIF 16
#define ERR_SYNTAX 17
#define ERR_UNCLOSED_STRU 18
#define ERR_UNMATCHED_EXIT 19
void GenError( int, char*, char * ); /* generic parsing error management function */

View File

@@ -16,15 +16,19 @@
*
* By default we are using automatic lookup (symbol not defined)
*/
/*#define HARBOUR_MAIN "MAIN"*/
#define HARBOUR_START_PROCEDURE "MAIN"
/* This symbol defines if we want an ability to create and link OBJ files
/* This symbol defines if we want an ability to create and link OBJ files
* generated by Harbour compiler
*
* By default it is disabled (symbol is not defined)
*/
/*#define OBJ_GENERATION*/
/*#define HARBOUR_OBJ_GENERATION*/
/* Operating system specific definitions
*/
#define OS_PATH_DELIMITER '\\'
#define OS_PATH_LIST_SEPARATOR ';'
#endif
#endif

View File

@@ -97,7 +97,7 @@ Separator {SpaceTab}|{Comment}|{LineCont}
%x COMMENT3 DEFINE DEFINE_PARAMS DEFINE_EXPR
%x IFDEF IFNDEF STRING1 STRING2 STRING3
%x NEXT_ BREAK_ CASE_ DO_ WHILE_ WITH_ END_
%x NEXT_ BREAK_ CASE_ DO_ WHILE_ WITH_ END_ EXIT_
%s INDEX
%%
@@ -305,7 +305,7 @@ Separator {SpaceTab}|{Comment}|{LineCont}
else
{ /* there is another item in line already */
yylval.string = strdup( "DO" );
_iState =IDENTIFIER;
_iState =IDENTIFIER;
return IDENTIFIER;
}
}
@@ -339,6 +339,9 @@ Separator {SpaceTab}|{Comment}|{LineCont}
GenError( ERR_ENDIF, NULL, NULL );
return END;
}
%{
/* ************************************************************************ */
%}
"end" { BEGIN END_; }
<END_>{Separator}*[\[\(] { /* array, function call */
yy_lex_count_lf();
@@ -395,7 +398,7 @@ Separator {SpaceTab}|{Comment}|{LineCont}
%}
"endif"|"endi" { /* ENDIF can be used in one context only */
if( _wIfCounter == 0 )
GenError( ERR_ENDIF, NULL, NULL );
GenError( ERR_ENDIF, NULL, NULL );
return ENDIF;
}
"endc"("ase"|"as"|"a")? { /* ENDCASE can be used in one context only */
@@ -408,8 +411,56 @@ Separator {SpaceTab}|{Comment}|{LineCont}
GenError( ERR_ENDDO, NULL, NULL );
return ENDDO;
}
"exit"/[\n\;] return EXITLOOP;
"exit" return EXIT;
%{
/* ************************************************************************ */
%}
"exit" { BEGIN EXIT_; }
<EXIT_>{Separator}*[\n] { /* EXIT last item in the line */
yy_lex_count_lf();
--iLine;
unput( yytext[ yyleng-1 ] );
BEGIN 0;
if( _iState == LOOKUP )
{ /* it is first item in the line */
if( _wForCounter == 0 && _wWhileCounter == 0 )
GenError( ERR_UNMATCHED_EXIT, NULL, NULL );
_iState =EXITLOOP;
return EXITLOOP;
}
else
{ /* there is another item in line already */
yylval.string = strdup( "EXIT" );
_iState =IDENTIFIER;
return IDENTIFIER;
}
}
<EXIT_>{Separator}+[_a-zA-Z] { /* an identifier after the EXIT */
yy_lex_count_lf();
unput( yytext[ yyleng-1 ] );
BEGIN 0;
if( _iState == LOOKUP )
{ /* it is first item in the line */
_iState =EXIT;
return EXIT;
}
else
{ /* there is another item in line already */
yylval.string = strdup( "EXIT" );
_iState =IDENTIFIER;
return IDENTIFIER;
}
}
<EXIT_>{Separator}*. { /* any character (not identifier) after EXIT */
yy_lex_count_lf();
unput( yytext[ yyleng-1 ] );
yylval.string = strdup( "EXIT" );
BEGIN 0;
_iState =IDENTIFIER;
return IDENTIFIER;
}
%{
/* ************************************************************************ */
%}
"extern"|"external" _iState =EXTERN; return EXTERN;
"field"/[^(] _iState =FIELD; return FIELD;
"for" _iState = FOR; return FOR;
@@ -633,7 +684,7 @@ Separator {SpaceTab}|{Comment}|{LineCont}
".or." return OR;
"!"|".not." return NOT;
"::" unput( ':' ); unput( 'f' ); unput( 'l' ); unput( 'e' ); unput( 'S' );
[,\;\{\}\|\#\&\:\<\>\[\]\(\)\@] return yytext[ 0 ];
[,\;\{\}\|\#\&\:\<\>\[\]\(\)\@] _iState =OPERATOR; return yytext[ 0 ];
{InvalidNumber} GenError( ERR_NUMERIC_FORMAT, NULL, NULL );

View File

@@ -30,8 +30,7 @@
#endif
/* TODO: #define this for various platforms */
#define PATH_DELIMITER "/\\"
#define IS_PATH_SEP( c ) (strchr(PATH_DELIMITER, (c))!=NULL)
#define IS_PATH_SEP( c ) ( (c) == OS_PATH_DELIMITER )
#define OPT_DELIMITER "/-"
#define IS_OPT_SEP( c ) (strchr(OPT_DELIMITER, (c))!=NULL)
@@ -200,7 +199,7 @@ void GenJava( char *, char * ); /* generates the Java language output */
void GenPascal( char *, char * ); /* generates the Pascal language output */
void GenRC( char *, char * ); /* generates the RC language output */
void GenPortObj( char *, char * ); /* generates the portable objects */
#ifdef OBJ_GENERATION
#ifdef HARBOUR_OBJ_GENERATION
void GenObj32( char *, char * ); /* generates OBJ 32 bits */
#endif
@@ -244,7 +243,8 @@ char * _szErrors[] = { "Statement not allowed outside of procedure or function",
"ELSE does not match IF",
"ELSEIF does not match IF",
"Syntax error: \'%s\'",
"Unclosed control structures"
"Unclosed control structures",
"EXIT statement with no loop in sight"
};
/* Table with reserved functions names
@@ -359,7 +359,7 @@ WORD _wForCounter = 0;
WORD _wIfCounter = 0;
WORD _wWhileCounter = 0;
WORD _wCaseCounter = 0;
#ifdef OBJ_GENERATION
#ifdef HARBOUR_OBJ_GENERATION
int _iObj32 = 0; /* generate OBJ 32 bits */
#endif
WORD _wStatics = 0; /* number of defined statics variables on the PRG */
@@ -837,7 +837,7 @@ EndCase : ENDCASE { --_wCaseCounter; }
| END { --_wCaseCounter; }
;
DoCaseBegin : DOCASE Crlf { ++_wCaseCounter; }
DoCaseBegin : DOCASE { ++_wCaseCounter; } Crlf
;
Cases : CASE Expression Crlf { $<iNumber>$ = JumpFalse( 0 ); Line(); } CaseStmts { $$ = GenElseIf( 0, Jump( 0 ) ); JumpHere( $<iNumber>4 ); Line(); }
@@ -871,9 +871,9 @@ EndWhile : END
| ENDDO
;
ForNext : FOR IDENTIFIER ForAssign Expression { PopId( $2 ); $<iNumber>$ = functions.pLast->lPCodePos; ++_wForCounter;}
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 ) }
StepExpr Crlf { GenPCode1( _FORTEST ); $<iNumber>$ = JumpTrue( 0 ); PushId( $2 ); }
ForStatements { GenPCode1( _PLUS ); PopId( $2 ); Jump( $<iNumber>5 - functions.pLast->lPCodePos ); JumpHere( $<iNumber>11 ); }
;
@@ -1009,7 +1009,7 @@ int harbour_main( int argc, char * argv[] )
free( szDefText );
}
break;
#ifdef OBJ_GENERATION
#ifdef HARBOUR_OBJ_GENERATION
case 'f':
case 'F':
{
@@ -1152,12 +1152,13 @@ int harbour_main( int argc, char * argv[] )
char * pDelim;
pPath = szInclude = strdup( szInclude );
while( (pDelim = strchr( pPath, ';' )) != NULL )
while( (pDelim = strchr( pPath, OS_PATH_LIST_SEPARATOR )) != NULL )
{
*pDelim ='\0';
AddSearchPath( pPath, &_pIncludePath );
pPath =pDelim + 1;
}
AddSearchPath( pPath, &_pIncludePath );
}
FunDef( strupr( strdup( pFileName->name ) ), FS_PUBLIC, FUN_PROCEDURE );
@@ -1167,7 +1168,7 @@ int harbour_main( int argc, char * argv[] )
fclose( yyin );
files.pLast =NULL;
#ifdef OBJ_GENERATION
#ifdef HARBOUR_OBJ_GENERATION
if( ! _iSyntaxCheckOnly && ! _iObj32 )
#else
if( ! _iSyntaxCheckOnly )
@@ -1223,7 +1224,7 @@ int harbour_main( int argc, char * argv[] )
break;
}
}
#ifdef OBJ_GENERATION
#ifdef HARBOUR_OBJ_GENERATION
if( _iObj32 )
{
pFileName->extension = ".obj";
@@ -1253,7 +1254,7 @@ void PrintUsage( char * szSelf )
printf( "Syntax: %s <file.prg> [options]\n"
"\nOptions: \n"
"\t/d<id>[=<val>]\t#define <id>\n"
#ifdef OBJ_GENERATION
#ifdef HARBOUR_OBJ_GENERATION
"\t/f\t\tgenerated object file\n"
"\t\t\t /fobj32 --> Windows/Dos 32 bits OBJ\n"
#endif
@@ -1294,7 +1295,7 @@ FILENAME *SplitFilename( char *szFilename )
if( iSlashPos == 0 )
{
/* root path -> \filename */
pName->_buffer[ 0 ] =PATH_DELIMITER[ 0 ];
pName->_buffer[ 0 ] =OS_PATH_DELIMITER;
pName->_buffer[ 1 ] ='\x0';
pName->path =pName->_buffer;
iPos =2; /* first free position after the slash */
@@ -1368,7 +1369,7 @@ char *MakeFilename( char *szFileName, FILENAME *pFileName )
*/
if( !( IS_PATH_SEP(pFileName->name[ 0 ]) || IS_PATH_SEP(pFileName->path[ iLen-1 ]) ) )
{
szFileName[ iLen++ ] =PATH_DELIMITER[ 0 ];
szFileName[ iLen++ ] =OS_PATH_DELIMITER;
szFileName[ iLen ] ='\x0';
}
}
@@ -3365,11 +3366,10 @@ void GenPortObj( char *szFileName, char *szName )
{
PFUNCTION pFunc = functions.pFirst;
PCOMSYMBOL pSym = symbols.pFirst;
WORD w, wLen, wSym, wVar;
WORD w, wLen, wVar;
LONG lPCodePos;
LONG lPad;
LONG lSymbols;
char chr;
FILE * yyc; /* file handle for C output */
szName = szName;
@@ -3379,6 +3379,8 @@ void GenPortObj( char *szFileName, char *szName )
return;
}
szName = szName;
if( ! _iQuiet )
printf( "\ngenerating portable object file...\n" );

View File

@@ -14,6 +14,17 @@
#ifdef __WATCOMC__
#include <i86.h>
#if defined(__386__) && !defined(__WINDOWS_386__)
#define INT_86 int386
#else
#define INT_86 int86
#endif
#else
#if defined(__EMX__)
#define INT_86 _int86
#else
#define INT_86 int86
#endif
#endif
HARBOUR OS()
@@ -101,22 +112,7 @@ HARBOUR OS()
/* detect OS/2 */
regs.h.ah = 0x30;
#if defined(__WATCOMC__) && defined(__386__)
int386(0x21, &regs, &regs);
#else
#if defined(__EMX__)
_int86(0x21, &regs, &regs);
#else
int86(0x21, &regs, &regs);
#endif /* __EMX__ */
#endif /* WATCOMC */
INT_86( 0x21, &regs, &regs );
if(regs.h.al >= 10)
{
@@ -139,28 +135,13 @@ HARBOUR OS()
hb_osminor = _osminor;
regs.w.ax = 0x160A;
#if defined(__WATCOMC__) && defined(__386__)
INT_86( 0x2F, &regs, &regs );
int386(0x2F, &regs, &regs);
#else
#if defined(__EMX__)
_int86(0x2F, &regs, &regs);
#else
int86(0x2F, &regs, &regs);
#endif /* EMX */
#endif /* WATCOMC */
if(regs.x.ax == 0)
if( regs.w.ax == 0)
{
hb_os = "Windows";
hb_osmajor = regs.x.bx / 256;
hb_osminor = regs.x.bx % 256;
hb_osmajor = regs.w.bx / 256;
hb_osminor = regs.w.bx % 256;
hb_osletter = 0;
}
else

View File

@@ -1,6 +1,6 @@
/* $Id$
*
* The Harbour virtual machine
* The Harbour virtual machine
*/
/* Please note the following comments we may use everywhere
@@ -134,7 +134,7 @@ extern ULONG ulMemoryMaxBlocks; /* maximum number of used memory blocks */
extern ULONG ulMemoryConsumed; /* memory size consumed */
extern ULONG ulMemoryMaxConsumed; /* memory max size consumed */
#ifdef OBJ_GENERATION
#ifdef HARBOUR_OBJ_GENERATION
void ProcessObjSymbols ( void ); /* process Harbour generated OBJ symbols */
typedef struct
@@ -187,7 +187,7 @@ BYTE bErrorLevel = 0; /* application exit errorlevel */
StackInit();
NewDynSym( &symEval ); /* initialize dynamic symbol for evaluating codeblocks */
InitializeSets(); /* initialize Sets */
#ifdef OBJ_GENERATION
#ifdef HARBOUR_OBJ_GENERATION
ProcessObjSymbols(); /* initialize Harbour generated OBJs symbols */
#endif
@@ -196,14 +196,14 @@ BYTE bErrorLevel = 0; /* application exit errorlevel */
DoInitFunctions( argc, argv ); /* process defined INIT functions */
#ifdef HARBOUR_MAIN
#ifdef HARBOUR_START_PROCEDURE
{
PDYNSYM pDynSym =FindDynSym( HARBOUR_MAIN );
PDYNSYM pDynSym =FindDynSym( HARBOUR_START_PROCEDURE );
if( pDynSym )
pSymStart =pDynSym->pSymbol;
else
{
printf( "Can\'t locate the starting procedure: \'%s\'", HARBOUR_MAIN );
printf( "Can\'t locate the starting procedure: \'%s\'", HARBOUR_START_PROCEDURE );
exit(1);
}
}
@@ -1826,7 +1826,7 @@ void ProcessSymbols( PSYMBOL pModuleSymbols, WORD wModuleSymbols ) /* module sym
{
PSYMBOLS pNewSymbols, pLastSymbols;
WORD w;
#ifdef OBJ_GENERATION
#ifdef HARBOUR_OBJ_GENERATION
static int iObjChecked = 0;
if( ! iObjChecked )
@@ -1862,7 +1862,7 @@ void ProcessSymbols( PSYMBOL pModuleSymbols, WORD wModuleSymbols ) /* module sym
}
}
#ifdef OBJ_GENERATION
#ifdef HARBOUR_OBJ_GENERATION
void ProcessObjSymbols( void )
{
POBJSYMBOLS pObjSymbols = ( POBJSYMBOLS ) &HB_FIRSTSYMBOL;

View File

@@ -4,7 +4,7 @@
//DO NOT RUN THIS PROGRAM - ITS PURPOSE IS THE SYNTAX CHECK ONLY!
EXTERNAL __case, __begin
STATIC nExt, bEgin, bReak, cAse, do, wHile, wIth
STATIC nExt, bEgin, bReak, cAse, do, wHile, wIth, eXit
Function Main()
@@ -39,6 +39,8 @@ Function Main()
END_() //END? surprise :) it works in some cases!
EXIT( eXit )
RETURN nil
/*================================================================
@@ -279,16 +281,16 @@ LOCAL with
do->do :=do->do +1
( do )->( do() )
do[ 1 ] :=do
do[ do ] :=do[ do ][ do ]
//////// do[ do ] :=do[ do ][ do ]
DO do WITH do
DO do WITH do()
DO do
DO do
DO while;
while
while :=while()
ENDDO
ENDDO
while while
// while++ //incomplete statement or unbalanced delimiter
@@ -298,8 +300,8 @@ LOCAL with
while->while :=while() +while->while
enddo
while[ 1 ] :=while
while[ 2 ] +=2
// while[ 1 ] :=while
// while[ 2 ] +=2
// while( while )
// while( while[1] )
// while[ while ] :=while[ 1 ] //in Clipper: syntax error ' 1 '
@@ -413,3 +415,44 @@ RETURN end
FUNCTION end( end )
RETURN end * end
/*====================================================================
* Test for EXIT
*/
EXIT FUNCTION EXIT( exit )
//LOCAL exit
exit++
++exit
exit[ 1 ] :=1
exit :=exit[ 1 ]
exit->exit :=exit->exit +1
( exit )->exit :=exit
DO exit WITH exit
exit()
exit( exit )
// EXIT //EXIT statement with no loop in sight
FOR exit:=1 TO 10
exit++
DO exit
EXIT
NEXT
WHILE !exit
exit +=1
EXIT
ENDDO
DO CASE
CASE exit
// EXIT //EXIT statement with no loop in sight
CASE !exit
exit()
ENDCASE
RETURN exit