diff --git a/harbour/ChangeLog b/harbour/ChangeLog index b463c45b9d..e655a61832 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,49 @@ +19990516-07:04 Ryszard Glab + + * source/compiler/harbour.l, source/compiler/harbour.y + -cleaned rules for NEXT, BREAK, WHILE, BEGIN, DO to be 100% + Clipper compatible (mainly keyword[] use); + -corrected support for END keyword; + -added include files: hbsetup.h and hberrors.h; + -code for OBJ generation is now linked optionally -it is linked if + the symbol OBJ_GENERATION is defined in hbsetup.h file; + -corrected the generation of EXTERNAL symbols + + * source/vm/hvm.c + -code with support for symbols defined in OBJ files is now linked + optionally -it is linked if the symbol OBJ_GENERATION is defined + in hbsetup.h file + -added support for optional definition of the starting procedure + (in case when automatic lookup for it doesn't work (Watcom C/C++)) + + * include/hbsetup.h + -new file with Harbour configuration options (see this file for + available options) + + * include/hberrors.h + -new file with error constants definition shared by + harbour.y and harbour.l + + * include/extend.h + -added declaration of FindDynSym() function used in hvm.c + + * source/rtl/environ.c + -added correct #include for Watcom C/C++ to use REGS union + (although I am not sure if OS function should be placed here) + + * source/rtl/itemapi.c + -corrected wrog declaration of symEval variable + (it is SYMBOL structure instead of PSYMBOL pointer) + + * tests/working/keywords.prg + -added test code for END keyword + + * makewat.env, makefile.wat + -added/corrected makefiles for Watcom C/C++ compiler + + * makedos.env, makefile.dos + -added/corrected makefiles for pure DOS DJGPP compiler + 19990516-06:30 CET Eddie Runia * tests/working/bld32exe.bat Correct version added diff --git a/harbour/include/extend.h b/harbour/include/extend.h index 8bd39b316a..5b9a81a0b4 100644 --- a/harbour/include/extend.h +++ b/harbour/include/extend.h @@ -163,6 +163,7 @@ char * _GetClassName( PITEM pObject ); /* retrieves an object class name */ /* dynamic symbol table management */ PDYNSYM GetDynSym( char * szName ); /* finds and creates a dynamic symbol if not found */ PDYNSYM NewDynSym( PSYMBOL pSymbol ); /* creates a new dynamic symbol based on a local one */ +PDYNSYM FindDynSym( char * szName ); /* finds a dynamic symbol */ /* error API */ PITEM _errNew( void ); diff --git a/harbour/include/hberrors.h b/harbour/include/hberrors.h new file mode 100644 index 0000000000..a3c6035bfd --- /dev/null +++ b/harbour/include/hberrors.h @@ -0,0 +1,22 @@ +/* + * $Id$ + * + * Errors generated by Harbour compiler +*/ +#define ERR_OUTSIDE 1 +#define ERR_FUNC_DUPL 2 +#define ERR_VAR_DUPL 3 +#define ERR_FOLLOWS_EXEC 4 +#define ERR_OUTER_VAR 5 +#define ERR_NUMERIC_FORMAT 6 +#define ERR_STRING_TERMINATOR 7 +#define ERR_FUNC_RESERVED 8 +#define ERR_ILLEGAL_INIT 9 +#define ERR_CANT_OPEN_INCLUDE 10 +#define ERR_ENDIF 11 +#define ERR_ENDDO 12 +#define ERR_ENDCASE 13 +#define ERR_NEXTFOR 14 +#define ERR_SYNTAX 15 + +void GenError( int, char*, char * ); /* generic parsing error management function */ diff --git a/harbour/include/hbsetup.h b/harbour/include/hbsetup.h new file mode 100644 index 0000000000..32cbc8a8cb --- /dev/null +++ b/harbour/include/hbsetup.h @@ -0,0 +1,25 @@ +/* + * $Id$ + * + * Harbour compiler and runtime configuration file +*/ + +#ifndef hbsetuph +#define hbsetuph + +/* The name of starting procedure + * Note: You have to define it in case when Harbour cannot find the proper + * starting procedure (due to incorrect order of static data initialization) + * Now compilers that require it: + * Watcom C/C++ 10.0 +*/ +#define HARBOUR_MAIN "MAIN" + +/* The ability to create and link OBJ files created by Harbour compiler + * By default it is disabled +*/ +/*#define OBJ_GENERATION*/ + + + +#endif \ No newline at end of file diff --git a/harbour/makedos.env b/harbour/makedos.env index 37d153e82a..c43dd86332 100644 --- a/harbour/makedos.env +++ b/harbour/makedos.env @@ -1,11 +1,20 @@ +# $Id$ # Makefile definitions for DOS DJGPP +# This file is included by makefile.dos located in subdirectories +# Usage: +# make -f makefile.dos +# for test application use it: +# make -r -f makefile.dos +# where is the name of compiled file without extension # # HARBOURDIR: should be set to directory where the Harbour project is installed # -# -HARBOURDIR=h:/harbour/harbour +HARBOURDIR=o:/h HARBOURLIB=$(HARBOURDIR)/libs/libharb.a # compiler macros for DOS DJGPP CC=gcc CFLAGS=-Wall -g -DDEBUG -I$(HARBOURDIR)/include -x c + +%.c : %.prg + ../../bin/harbour -n $< diff --git a/harbour/makewat.env b/harbour/makewat.env index a57cc642f6..d487056f4f 100644 --- a/harbour/makewat.env +++ b/harbour/makewat.env @@ -1,11 +1,14 @@ +# $Id$ # Makefile definitions for WATCOM C/C++ 10.x +# This file is included by makefile.wat located in subdirectories +# Usage: +# wmake /f makefile.wat # # HARBOURDIR: set to where the Harbour project is installed # -# # Harbour project directories -HARBOURDIR = h:\harbour\harbour +HARBOURDIR = o:\h HARBOURLIB = $(HARBOURDIR)\libs\harbour.lib # Watcom directories @@ -30,6 +33,10 @@ WLSTACK = op stack=16384 WLDEBUG = debug all WLLIBS = $(HARBOURLIB) +.EXTENSIONS: .prg + .c.obj: # $< # .AUTODEPEND *$(WPP) $(WCOPTIONS) $(WCINCLUDE) $(WCDEBUG) $(WCDEFINE) $(WCEXTRA) $< +.prg.c: # <$ # .AUTODEPEND + *$(HARBOURDIR)\BIN\HARBOUR -N $^* diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index c939cabc39..794ab6b9a6 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -13,6 +13,8 @@ #include #include #include "y_tab.h" +#include "hbsetup.h" /* main configuration file */ +#include "hberrors.h" void yyerror( char * ); static void yyunput( int, char * ); @@ -26,10 +28,6 @@ int yywrap( void ); extern FILE * yyin; /* currently yacc parsed file */ int yy_lex_input( char *, int ); #define YY_INPUT( buf, result, max_size ) result = yy_lex_input( buf, max_size ); -void GenError( int, char*, char * ); /* generic parsing error management function */ - -#define ERR_NUMERIC_FORMAT 6 -#define ERR_STRING_TERMINATOR 7 typedef struct { @@ -84,7 +82,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} %x COMMENT3 DEFINE DEFINE_PARAMS DEFINE_EXPR %x IFDEF IFNDEF STRING1 STRING2 -%x NEXT_ BREAK_ CASE_ DO_ WHILE_ WITH_ +%x NEXT_ BREAK_ CASE_ DO_ WHILE_ WITH_ END_ %% @@ -155,7 +153,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} "begin"{Separator}+"sequ"("ence"|"enc"|"en"|"e")? return BEGINSEQ; %{ -/* ** */ +/* ************************************************************************ */ %} "break" BEGIN BREAK_; {Separator}*\n { /* at the end of line */ @@ -173,7 +171,13 @@ Separator {SpaceTab}|{Comment}|{LineCont} return IDENTIFIER; } } -{Separator}*[^_a-zA-Z] { /* there is no identifier after "break" */ +{Separator}*[\[] { /* array */ + yy_lex_count_lf(); + BEGIN 0; + /* Clipper does not like break[] at all */ + GenError( ERR_SYNTAX, yytext, NULL ); + } +{Separator}*[^_a-zA-Z\[] { /* there is no identifier after "break" */ yy_lex_count_lf(); BEGIN 0; yylval.string = strdup( "BREAK" ); @@ -190,10 +194,10 @@ Separator {SpaceTab}|{Comment}|{LineCont} } . { BEGIN 0; unput( yytext[ yyleng-1 ] ); } %{ -/* ** */ +/* ************************************************************************ */ %} "case" { BEGIN CASE_; } -{Separator}*[\:\=\|\$\%\*\,\/\[\]\)\}] { /* there is an operator after "case" */ +{Separator}*[\:\=\|\$\%\*\,\/\]\)\}\^] { /* there is an operator after "case" */ yy_lex_count_lf(); BEGIN 0; yylval.string = strdup( "CASE" ); @@ -201,6 +205,12 @@ Separator {SpaceTab}|{Comment}|{LineCont} unput( yytext[ yyleng-1 ] ); return IDENTIFIER; } +{Separator}*[\[] { /* array */ + yy_lex_count_lf(); + BEGIN 0; + /* Clipper does not like case[] at all */ + GenError( ERR_SYNTAX, yytext, NULL ); + } {Separator}*("+="|"-="|"->") { /* operators */ yy_lex_count_lf(); BEGIN 0; @@ -228,7 +238,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} } } %{ -/* ** */ +/* ************************************************************************ */ %} "do" BEGIN DO_; {Separator}+"case" { /* DO CASE statement */ @@ -273,15 +283,68 @@ Separator {SpaceTab}|{Comment}|{LineCont} return IDENTIFIER; } %{ -/* ** */ +/* ************************************************************************ */ +%} +"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; +"end" { BEGIN END_; } +{Separator}*[\[\(] { /* array, function call */ + yy_lex_count_lf(); + BEGIN 0; + if( _iState == LOOKUP ) + { /* Clipper does not like end[] & end() at the begining of line */ + GenError( ERR_ENDIF, NULL, NULL ); + } + yylval.string = strdup( "END" ); + _iState =IDENTIFIER; + unput( yytext[ yyleng-1 ] ); + return IDENTIFIER; + } +{Separator}*("->"|"++"|"--") { /* operators */ + yy_lex_count_lf(); + BEGIN 0; + if( _iState == LOOKUP ) + { /* Clipper does not like end-> & end++ at the begining of line */ + GenError( ERR_ENDIF, NULL, NULL ); + } + yylval.string = strdup( "END" ); + _iState =IDENTIFIER; + unput( yytext[ yyleng-1 ] ); + unput( yytext[ yyleng-2 ] ); + return IDENTIFIER; + } +{Separator}*[\+\-\:\=\|\$\%\*\,\/\[\]\)\}\^] { /* there is an operator after "end" */ + yy_lex_count_lf(); + BEGIN 0; + yylval.string = strdup( "END" ); + _iState =IDENTIFIER; + unput( yytext[ yyleng-1 ] ); + return IDENTIFIER; + } +{Separator}*(\n|.) { /* not operator */ + yy_lex_count_lf(); + BEGIN 0; + if( yytext[ yyleng-1 ] == '\n' ) + --iLine; + unput( yytext[ yyleng-1 ] ); + if( _iState == LOOKUP ) + { /* it is first item in the line */ + _iState =END; + return END; + } + else + { /* there is another item in line already */ + yylval.string = strdup( "END" ); + return IDENTIFIER; + } + } +%{ +/* ************************************************************************ */ %} -"else" return ELSE; -"elseif" _iState =ELSEIF; return ELSEIF; -"end"/[^(] return END; "endif" return ENDIF; "endcase" return ENDCASE; "enddo" return ENDDO; -"end"{Separator}+"sequ"("ence"|"enc"|"en"|"e")? return END; "exit"/[\n\;] return EXITLOOP; "exit" return EXIT; "extern"|"external" _iState =EXTERN; return EXTERN; @@ -296,6 +359,9 @@ Separator {SpaceTab}|{Comment}|{LineCont} "local" _iState =LOCAL; return LOCAL; "loop" return LOOP; "memvar" _iState =MEMVAR; return MEMVAR; +%{ +/* ************************************************************************ */ +%} "next" BEGIN NEXT_; {Separator}*[\n\;] { /* at the end of line */ BEGIN 0; @@ -308,14 +374,39 @@ Separator {SpaceTab}|{Comment}|{LineCont} else { /* there is another item in line already */ unput( yytext[ yyleng-1 ] ); - yylval.string = strdup( "nExT" ); + yylval.string = strdup( "NEXT" ); return IDENTIFIER; } } +{Separator}*[\[\(] { /* array, function call */ + yy_lex_count_lf(); + BEGIN 0; + if( _iState == LOOKUP ) + { /* Clipper does not like NEXT[] & NEXT() at the begining of line */ + GenError( ERR_NEXTFOR, NULL, NULL ); + } + yylval.string = strdup( "NEXT" ); + _iState =IDENTIFIER; + unput( yytext[ yyleng-1 ] ); + return IDENTIFIER; + } +{Separator}*("->"|"++"|"--") { /* operators */ + yy_lex_count_lf(); + BEGIN 0; + if( _iState == LOOKUP ) + { /* Clipper does not like next-> & next++ at the begining of line */ + GenError( ERR_NEXTFOR, NULL, NULL ); + } + yylval.string = strdup( "NEXT" ); + _iState =IDENTIFIER; + unput( yytext[ yyleng-1 ] ); + unput( yytext[ yyleng-2 ] ); + return IDENTIFIER; + } {Separator}*[^_a-zA-Z] { /* there is no identifier after "next" */ yy_lex_count_lf(); BEGIN 0; - yylval.string = strdup( ((yytext[ yyleng-1 ] =='(')?"NEXT":"nExT") ); + yylval.string = strdup( "NEXT" ); unput( yytext[ yyleng-1 ] ); return IDENTIFIER; } @@ -326,7 +417,9 @@ Separator {SpaceTab}|{Comment}|{LineCont} _iState =NEXT; return NEXT; } -. { BEGIN 0; unput( yytext[ yyleng-1 ] ); } +%{ +/* ************************************************************************ */ +%} "nil" return NIL; "otherwise" return OTHERWISE; "parameters" _iState =PARAMETERS; return PARAMETERS; @@ -341,7 +434,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} "to" return TO; "using" return USING; %{ -/* ** */ +/* ************************************************************************ */ %} "while" BEGIN WHILE_; {Separator}*\n { /* end of line */ @@ -356,7 +449,13 @@ Separator {SpaceTab}|{Comment}|{LineCont} yylval.string = strdup( "WHILE" ); return IDENTIFIER; } -{Separator}*[\:\=\|\$\%\*\,\/\[\]\)\}] { /* there is an operator after "case" */ +{Separator}*[\[] { /* array */ + yy_lex_count_lf(); + BEGIN 0; + /* Clipper does not like while[] at all */ + GenError( ERR_SYNTAX, yytext, NULL ); + } +{Separator}*[\:\=\|\$\%\*\,\/\]\)\}\^] { /* there is an operator after "case" */ yy_lex_count_lf(); BEGIN 0; yylval.string = strdup( "WHILE" ); @@ -388,7 +487,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} } } %{ -/* ** */ +/* ************************************************************************ */ %} "with" BEGIN WITH_; {Separator}*\n { /* at the end of line */ @@ -415,6 +514,11 @@ Separator {SpaceTab}|{Comment}|{LineCont} return WITH; } } +{Separator}*[\[] { /* array */ + yy_lex_count_lf(); + /* Clipper does not like with[] at all */ + GenError( ERR_SYNTAX, yytext, NULL ); + } {Separator}*. { yy_lex_count_lf(); BEGIN 0; @@ -431,7 +535,7 @@ Separator {SpaceTab}|{Comment}|{LineCont} } } %{ -/* ** */ +/* ************************************************************************ */ %} "#" _iState =NE1; return NE1; "=" _iState =OPERATOR; return yytext[ 0 ]; diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 44243dc6ed..62859ff03d 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -14,9 +14,11 @@ #include #include #include /* required for allocating and freeing memory */ +#include "hbsetup.h" /* main configuration file */ #include "pcode.h" /* pcode values */ #include "types.h" /* our defined types */ #include "compiler.h" +#include "hberrors.h" #ifdef __BORLANDC__ #define HAVE_STRUPR @@ -139,7 +141,6 @@ PFUNCTION FunctionNew( char *, char ); /* creates and initialises the _FUNC str void FunDef( char * szFunName, char cScope, int iType ); /* starts a new Clipper language function definition */ void GenArray( WORD wElements ); /* instructs the virtual machine to build an array and load elemnst from the stack */ void * GenElseIf( void * pFirstElseIf, WORD wOffset ); /* generates a support structure for elseifs pcode fixups */ -void GenError( int, char*, char * ); /* generic parsing error management function */ void GenExterns( void ); /* generates the symbols for the EXTERN names */ void GenReturn( WORD wOffset ); /* generates a return offset to later on fill it with the proper exiting pcode address */ PFUNCTION GetFuncall( char * szFunName ); /* locates a previously defined called function */ @@ -192,7 +193,9 @@ void GenCCode( char *, char * ); /* generates the C language output */ 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 */ +#ifdef OBJ_GENERATION void GenObj32( char *, char * ); /* generates OBJ 32 bits */ +#endif void PrintUsage( char * ); @@ -215,17 +218,6 @@ int iVarScope = 0; /* holds the scope for next variables to be defined #define VS_FIELD 3 #define VS_MEMVAR 4 -#define ERR_OUTSIDE 1 -#define ERR_FUNC_DUPL 2 -#define ERR_VAR_DUPL 3 -#define ERR_FOLLOWS_EXEC 4 -#define ERR_OUTER_VAR 5 -#define ERR_NUMERIC_FORMAT 6 -#define ERR_STRING_TERMINATOR 7 -#define ERR_FUNC_RESERVED 8 -#define ERR_ILLEGAL_INIT 9 -#define ERR_CANT_OPEN_INCLUDE 10 - /* Table with parse errors */ char * _szErrors[] = { "Statement not allowed outside of procedure or function", "Redefinition of procedure or function: \'%s\'", @@ -236,7 +228,12 @@ char * _szErrors[] = { "Statement not allowed outside of procedure or function", "Unterminated string: \'%s\'", "Redefinition of predefined function %s: \'%s\'", "Illegal initializer: \'%s\'", - "Can't open #include file: \'%s\'" + "Can\'t open #include file: \'%s\'", + "ENDIF does not match IF", + "ENDDO does not match WHILE", + "ENDCASE does not match DO CASE", + "NEXT does not match FOR", + "Syntax error: \'%s\'" }; /* Table with reserved functions names @@ -344,7 +341,9 @@ 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 */ +#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; @@ -990,7 +989,7 @@ int harbour_main( int argc, char * argv[] ) free( szDefText ); } break; - +#ifdef OBJ_GENERATION case 'f': case 'F': { @@ -1000,7 +999,7 @@ int harbour_main( int argc, char * argv[] ) free( szUpper ); } break; - +#endif case 'g': case 'G': switch( argv[ iArg ][ 2 ] ) @@ -1113,10 +1112,15 @@ int harbour_main( int argc, char * argv[] ) FunDef( strupr( strdup( pFileName->name ) ), FS_PUBLIC, FUN_PROCEDURE ); yyparse(); FixReturns(); /* fix all previous function returns offsets */ + GenExterns(); /* generates EXTERN symbols names */ fclose( yyin ); files.pLast =NULL; +#ifdef OBJ_GENERATION if( ! _iSyntaxCheckOnly && ! _iObj32 ) +#else + if( ! _iSyntaxCheckOnly ) +#endif { if( _pInitFunc ) { @@ -1162,12 +1166,14 @@ int harbour_main( int argc, char * argv[] ) break; } } +#ifdef OBJ_GENERATION if( _iObj32 ) { pFileName->extension = ".obj"; MakeFilename( szFileName, pFileName ); GenObj32( szFileName, pFileName->name ); } +#endif } else { @@ -1190,8 +1196,10 @@ void PrintUsage( char * szSelf ) printf( "Syntax: %s [options]\n" "\nOptions: \n" "\t/d[=]\t#define \n" +#ifdef OBJ_GENERATION "\t/f\t\tgenerated object file\n" "\t\t\t /fobj32 --> Windows/Dos 32 bits OBJ\n" +#endif "\t/g\t\tgenerated output language\n" "\t\t\t /gc (C default) --> \n" "\t\t\t /gj (Java) --> \n" @@ -1623,8 +1631,6 @@ void FunDef( char * szFunName, char cScope, int iType ) /* there is not a symbol on the symbol table for this function name */ pSym = AddSymbol( szFunName ); - GenExterns(); /* generates EXTERN symbols names */ - if( cScope == FS_PUBLIC ) pSym->cScope = FS_PUBLIC; else @@ -2324,25 +2330,24 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag void GenExterns( void ) /* generates the symbols for the EXTERN names */ { - PEXTERN pLast = pExterns, pDelete; + PEXTERN pDelete; - if( pExterns ) - { - while( pLast ) - { - PushSymbol( pLast->szName, 1 ); - pLast = pLast->pNext; - } - pLast = pExterns; - pDelete = pExterns; - while( pLast ) - { - pLast = pLast->pNext; - OurFree( pDelete ); - pDelete = pLast; - } - pExterns = 0; - } + while( pExterns ) + { + if( GetSymbolPos( pExterns->szName ) ) + { + if( ! GetFuncall( pExterns->szName ) ) + AddFunCall( pExterns->szName ); + } + else + { + AddSymbol( pExterns->szName ); + AddFunCall( pExterns->szName ); + } + pDelete = pExterns; + pExterns = pExterns->pNext; + OurFree( pDelete ); + } } void GenReturn( WORD wOffset ) /* generates a return offset to later on fill it with the proper exiting pcode address */ diff --git a/harbour/source/compiler/makefile.dos b/harbour/source/compiler/makefile.dos new file mode 100644 index 0000000000..b24ea61fd8 --- /dev/null +++ b/harbour/source/compiler/makefile.dos @@ -0,0 +1,25 @@ +# $ID$ +# Makefile for DOS DJGPP +# +# NOTE: use it with -r option +# +include ..\..\makedos.env + +TARGET=$(HARBOURDIR)/bin/harbour.exe + +all: $(TARGET) + +$(TARGET): y_tab.c harbour.c lexyy.c + $(CC) $(CFLAGS) y_tab.c harbour.c lexyy.c -o $(TARGET) + +y_tab.c : harbour.y + bison -d -v harbour.y -o y_tab.c + +lexyy.c : harbour.l + flex -i -8 -olexyy.c harbour.l + +clean: + -del *.o + -del y_tab.* + -del lexyy.c + -del *.out diff --git a/harbour/source/compiler/makefile.wat b/harbour/source/compiler/makefile.wat new file mode 100644 index 0000000000..d2609a7591 --- /dev/null +++ b/harbour/source/compiler/makefile.wat @@ -0,0 +1,43 @@ +# $Id$ +# Makefile for Watcom C/C++ 10.x +# +!include ..\..\makewat.env + +TARGET=$(HARBOURDIR)\bin\harbour.exe + +all : $(TARGET) + +$(TARGET) : y_tab.obj lexyy.obj harbour.obj + %create link.tmp + %append link.tmp $(WLDEBUG) + %append link.tmp FI y_tab + %append link.tmp FI lexyy + %append link.tmp FI harbour + %append link.tmp NAME $(TARGET) + %append link.tmp $(WLOPTIONS) + %append link.tmp $(WLSTACK) + wlink @link.tmp + +y_tab.obj : y_tab.c + *$(WC) $(WCOPTIONS) $(WCINCLUDE) $(WCDEBUG) $(WCDEFINE) $(WCEXTRA) $< + +lexyy.obj : lexyy.c + *$(WC) $(WCOPTIONS) $(WCINCLUDE) $(WCDEBUG) $(WCDEFINE) $(WCEXTRA) $< + +harbour.obj : harbour.c + *$(WC) $(WCOPTIONS) $(WCINCLUDE) $(WCDEBUG) $(WCDEFINE) $(WCEXTRA) $< + +y_tab.c : harbour.y + bison -d -v -o y_tab.c harbour.y + +lexyy.c : harbour.l + flex -i -8 -olexyy.c harbour.l + +clean : .SYMBOLIC + del *.out + del *.obj + del y_tab.* + del lexyy.* + del *.h + del *.err + del *.tmp diff --git a/harbour/source/makefile.dos b/harbour/source/makefile.dos new file mode 100644 index 0000000000..c3eaddd0a4 --- /dev/null +++ b/harbour/source/makefile.dos @@ -0,0 +1,20 @@ +# $Id$ +# Makefile for DOS DJGPP +# +.PHONY: compiler vm rtl + +all: compiler vm rtl + +compiler: + make --directory=./compiler -r -f makefile.dos + +vm: + make --directory=./vm -f makefile.dos + +rtl: + make --directory=./rtl -f makefile.dos + +clean: + make --directory=./compiler -f makefile.dos clean + make --directory=./vm -f makefile.dos clean + make --directory=./rtl -f makefile.dos clean diff --git a/harbour/source/makefile.wat b/harbour/source/makefile.wat new file mode 100644 index 0000000000..d241713cad --- /dev/null +++ b/harbour/source/makefile.wat @@ -0,0 +1,33 @@ +# $Id$ +# Makefile for Watcom C/C++ +# +all : compiler vm rtl tools + +compiler : .SYMBOLIC + cd compiler + wmake $(__MAKEOPTS__) /f makefile.wat all + cd .. + +vm : .SYMBOLIC + cd vm + wmake $(__MAKEOPTS__) /f makefile.wat all + cd .. + +rtl : .SYMBOLIC + cd rtl + wmake $(__MAKEOPTS__) /f makefile.wat all + cd .. + +tools: .SYMBOLIC + cd tools + wmake $(__MAKEOPTS__) /f makefile.wat all + cd .. + +clean : .SYMBOLIC + cd compiler + wmake /f makefile.wat clean + cd ../vm + wmake /f makefile.wat clean + cd ../rtl + wmake /f makefile.wat clean + cd .. diff --git a/harbour/source/rtl/environ.c b/harbour/source/rtl/environ.c index 3b4f1b326c..fca88c55f9 100644 --- a/harbour/source/rtl/environ.c +++ b/harbour/source/rtl/environ.c @@ -4,6 +4,10 @@ #include +#ifdef __WATCOMC__ + #include +#endif + HARBOUR OS() { #ifdef __GNUC__ diff --git a/harbour/source/rtl/itemapi.c b/harbour/source/rtl/itemapi.c index 12fb235f5e..d669de0914 100644 --- a/harbour/source/rtl/itemapi.c +++ b/harbour/source/rtl/itemapi.c @@ -12,7 +12,7 @@ #define hb_param _param extern STACK stack; -extern PSYMBOL symEval; +extern SYMBOL symEval; /* TODO: Someone make a dates.h so this isn't necessary! */ //long greg2julian( long lDay, long lMonth, long lYear ); @@ -86,7 +86,7 @@ PITEM hb_evalLaunch( PEVALINFO pEvalInfo ) } else if( IS_BLOCK( pEvalInfo->pItems[ 0 ] ) ) { - PushSymbol( symEval ); + PushSymbol( &symEval ); Push( pEvalInfo->pItems[ 0 ] ); while( w < 10 && pEvalInfo->pItems[ w ] ) Push( pEvalInfo->pItems[ w++ ] ); diff --git a/harbour/source/rtl/makefile.dos b/harbour/source/rtl/makefile.dos new file mode 100644 index 0000000000..bdb3708de0 --- /dev/null +++ b/harbour/source/rtl/makefile.dos @@ -0,0 +1,19 @@ +# $Id$ +# Make file for DOS DJGPP +# +include ../../makedos.env + +SRCPRG:= $(wildcard *.prg) +CPRG=$(SRCPRG:.prg=.c) +OBJPRG=$(CPRG:.c=.o) + +SRCC:= $(wildcard *.c) +OBJC=$(SRCC:.c=.o) + +all: $(HARBOURLIB) + +$(HARBOURLIB): ${OBJPRG} $(OBJC) + ar r $(HARBOURLIB) ${OBJC} ${OBJPRG} + +clean: + -del *.o diff --git a/harbour/source/rtl/makefile.wat b/harbour/source/rtl/makefile.wat new file mode 100644 index 0000000000..9c43519083 --- /dev/null +++ b/harbour/source/rtl/makefile.wat @@ -0,0 +1,24 @@ +# $Id$ +# Makefile for Watcom C/C++ 10.x +# +!include ..\..\makewat.env + +TARGET=$(HARBOURLIB) + +PRGSYS=tclass.prg errorsys.prg error.prg asort.prg objfunc.prg +OBJSYS=tclass.obj errorsys.obj error.obj asort.obj objfunc.obj +OBJECTS=arrays.obj console.obj dates.obj extend.obj strings.obj classes.obj & + strcmp.obj files.obj set.obj math.obj environ.obj itemapi.obj & + transfrm.obj errorapi.obj codebloc.obj $(OBJSYS) + +all: $(TARGET) + +$(TARGET): $(OBJECTS) + %create lib.tmp + @for %i in ( $(OBJECTS) ) do @%append lib.tmp +-%i + wlib $^@ @lib.tmp + +clean: .SYMBOLIC + del *.obj + del *.tmp + del *.err diff --git a/harbour/source/tools/makefile.dos b/harbour/source/tools/makefile.dos new file mode 100644 index 0000000000..e465f81e67 --- /dev/null +++ b/harbour/source/tools/makefile.dos @@ -0,0 +1,20 @@ +# $Id$ +# Make file for DOS DJGPP +# +include ../../makedos.env + +SRCC:= $(wildcard *.c) +OBJC=$(SRCC:.c=.o) + +all: $(HARBOURLIB) + +$(HARBOURLIB): ${OBJC} ${OBJPRG} + ar r $(HARBOURLIB) ${OBJC} + +prg: + ../../bin/harbour -n error.prg + ../../bin/harbour -n errorsys.prg + ../../bin/harbour -n tclass.prg + +clean: + -del *.o diff --git a/harbour/source/tools/makefile.wat b/harbour/source/tools/makefile.wat new file mode 100644 index 0000000000..f1f6e1f8bd --- /dev/null +++ b/harbour/source/tools/makefile.wat @@ -0,0 +1,20 @@ +# $Id$ +# Makefile for Watcom C/C++ 10.x +# +!include ..\..\makewat.env + +TARGET=$(HARBOURLIB) + +OBJECTS=datesx.obj stringsx.obj mathx.obj + +all: $(TARGET) + +$(TARGET): $(OBJECTS) $(HARBSYS) + %create lib.tmp + @for %i in ( $(OBJECTS) ) do @%append lib.tmp +-%i + wlib $^@ @lib.tmp + +clean: .SYMBOLIC + del *.obj + del *.tmp + del *.err diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index bcd4f80d83..d80fa9ca58 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -17,6 +17,7 @@ #include #include +#include "hbsetup.h" /* main configuration file */ #include #include #include @@ -94,7 +95,6 @@ typedef struct _SYMBOLS } SYMBOLS, * PSYMBOLS; /* structure to keep track of all modules symbol tables */ void ProcessSymbols( PSYMBOL pSymbols, WORD wSymbols ); /* statics symbols initialization */ -void ProcessObjSymbols ( void ); /* process Harbour generated OBJ symbols */ void DoInitFunctions( int argc, char * argv[] ); /* executes all defined PRGs INIT functions */ void DoExitFunctions( void ); /* executes all defined PRGs EXIT functions */ void LogSymbols( void ); /* displays all dynamic symbols */ @@ -129,13 +129,15 @@ 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 +void ProcessObjSymbols ( void ); /* process Harbour generated OBJ symbols */ + typedef struct { WORD wSymbols; /* module local symbol table symbols amount */ PSYMBOL pSymbols; /* module local symbol table address */ } OBJSYMBOLS, * POBJSYMBOLS; /* structure used from Harbour generated OBJs */ -#ifndef NO_OBJ extern POBJSYMBOLS HB_FIRSTSYMBOL, HB_LASTSYMBOL; #endif @@ -176,11 +178,24 @@ BYTE bErrorLevel = 0; /* application exit errorlevel */ StackInit(); NewDynSym( &symEval ); /* initialize dynamic symbol for evaluating codeblocks */ InitializeSets(); /* initialize Sets */ -#ifndef NO_OBJ +#ifdef OBJ_GENERATION ProcessObjSymbols(); /* initialize Harbour generated OBJs symbols */ #endif DoInitFunctions( argc, argv ); /* process defined INIT functions */ +#ifdef HARBOUR_MAIN + { + PDYNSYM pDynSym =FindDynSym( HARBOUR_MAIN ); + if( pDynSym ) + pSymStart =pDynSym->pSymbol; + else + { + printf( "Can\'t locate the starting procedure: \'%s\'", HARBOUR_MAIN ); + exit(1); + } + } +#endif + PushSymbol( pSymStart ); /* pushes first FS_PUBLIC defined symbol to the stack */ PushNil(); /* places NIL at self */ @@ -1798,9 +1813,9 @@ void ProcessSymbols( PSYMBOL pModuleSymbols, WORD wModuleSymbols ) /* module sym { PSYMBOLS pNewSymbols, pLastSymbols; WORD w; +#ifdef OBJ_GENERATION static int iObjChecked = 0; -#ifndef NO_OBJ if( ! iObjChecked ) { iObjChecked = 1; @@ -1834,9 +1849,9 @@ void ProcessSymbols( PSYMBOL pModuleSymbols, WORD wModuleSymbols ) /* module sym } } +#ifdef OBJ_GENERATION void ProcessObjSymbols( void ) { -#ifndef NO_OBJ POBJSYMBOLS pObjSymbols = ( POBJSYMBOLS ) &HB_FIRSTSYMBOL; static int iDone = 0; @@ -1850,8 +1865,8 @@ void ProcessObjSymbols( void ) pObjSymbols++; } } -#endif } +#endif void ReleaseLocalSymbols( void ) { diff --git a/harbour/source/vm/makefile.dos b/harbour/source/vm/makefile.dos new file mode 100644 index 0000000000..bdfb23feba --- /dev/null +++ b/harbour/source/vm/makefile.dos @@ -0,0 +1,14 @@ +# $Id$ +# Makefile for DJGPP DOS version +# +include ..\..\makedos.env + +OBJECTS=hvm.o dynsym.o + +all: $(HARBOURLIB) + +$(HARBOURLIB): ${OBJECTS} + ar r $(HARBOURLIB) ${OBJECTS} + +clean: + -del *.o \ No newline at end of file diff --git a/harbour/source/vm/makefile.wat b/harbour/source/vm/makefile.wat new file mode 100644 index 0000000000..9e8c935a27 --- /dev/null +++ b/harbour/source/vm/makefile.wat @@ -0,0 +1,20 @@ +# $Id$ +# Makefile for Watcom C/C++ 10.x +# +!include ..\..\makewat.env + +TARGET=$(HARBOURLIB) + +OBJECTS=hvm.obj dynsym.obj + +all : $(TARGET) + +$(TARGET) : $(OBJECTS) + %create lib.tmp + @for %i in ( $(OBJECTS) ) do @%append lib.tmp +-%i + wlib $^@ @lib.tmp + +clean : .SYMBOLIC + -del *.obj + -del *.tmp + -del *.err diff --git a/harbour/tests/working/keywords.prg b/harbour/tests/working/keywords.prg index 4c07fdd0d4..d3fa68cf7e 100644 --- a/harbour/tests/working/keywords.prg +++ b/harbour/tests/working/keywords.prg @@ -3,6 +3,7 @@ */ //DO NOT RUN THIS PROGRAM - ITS PURPOSE IS THE SYNTAX CHECK ONLY! +EXTERNAL __case, __begin STATIC nExt, bEgin, bReak, cAse, do, wHile, wIth Function Main() @@ -19,9 +20,9 @@ Function Main() // // NEXT(nExt) //in Clipper: NEXT does not match FOR - BEGIN( bEgin +';' + ;; //////Clipper doesn't like more then one ';' - ";" ; /* ;;;;;Clipper doesn't like this comment after ';' ;;;;;;; */ - ) +// BEGIN( bEgin +';' + ;; //////Clipper doesn't like more then one ';' +// ";" ; /* ;;;;;Clipper doesn't like this comment after ';' ;;;;;;; */ +// ) BREAK_(bReak) // CASE(case) //it is not possible to call case() in this context case :=CASE( CASE ) //this is valid @@ -30,6 +31,14 @@ Function Main() DO_( nExt+bEgin/bReak-do*wHile%cAse $ wIth ) // WHILE( while ) //it is not possible to call while() in this context + ELSE_() //ELSE is reserved word for *real* + ELSEIF_() //ELSEIF is reserved word for *real* + ENDIF_() //see above + ENDCASE_() //see above + ENDDO_() //see above + + END_() //END? surprise :) it works in some cases! + RETURN nil /*================================================================ @@ -55,15 +64,19 @@ Local nExt, nExt7, nExtNEXT nExt := 10 //next - nExt++ /*in Clipper: NEXT does not match FOR*/ +// nExt++ /*in Clipper: NEXT does not match FOR*/ + nExt :=nExt++ --nExt /*next*/ nExt7 :=7 nExtNEXT := nExt //next - nExt[ 1 ] :=nExt //in Clipper: NEXT does not match FOR - nExt[ nExt ] := NEXT( nExt[nExt+nExt] * nExt *(nExt+nExt*5) ) +// nExt[ 1 ] :=nExt //in Clipper: NEXT does not match FOR +// nExt[ nExt ] := next[ next ] + nExt :=next[ next ] - next->next :=next->next + next->next +// next->next :=next->next + next->next //NEXT does not match FOR + next :=next->next + ( next )->( next() ) IF( nExt > nExt+4 ) nExt =nExt +nExt * 5 @@ -82,8 +95,8 @@ FUNCTION BEGIN( BEGIN_BEGIN ) LOCAL bEgin LOCAL xbEgin LOCAL bEginBEGIN -LOCAL bEgin0, /* BEGIN OF BEGIN */ ; /* in Clipper: Incomplete statement */ - bEgin1 +//LOCAL bEgin0, /* BEGIN OF BEGIN */ ; /* in Clipper: Incomplete statement */ +// bEgin1 LOCAL xbEginBEGIN := 100 BEGIN SEQUENCE @@ -96,10 +109,11 @@ BEGIN SEQUENCE --xbEginBEGIN bEgin++ --bEgin + ( begin )->( begin () ) NEXT bEgin - begin->begin :=begin->begin +; /************************/ - begin->begin +// begin->begin :=begin->begin +; /************************/ +// begin->begin bEgin :=BEGIN( xbegin +bEgin +bEginBEGIN -bEgin0 * xbEginBEGIN ) +; bEgin[ bEgin ] @@ -123,7 +137,7 @@ LOCAL bReak:=0 IF( bReak = 0 ) Break /*break*/ ( nil ) BREAK /* break to beggining */ - Break() //in Clipper: syntax error: ')' + Break(0) //in Clipper: syntax error: ')' ENDIF Break /*** break ***/ ; @@ -145,21 +159,24 @@ LOCAL bReak:=0 ; //it ; //often? ;/////////////////////////////////////////////////// - () //in Clipper: incomplete statement or unbalanced delimiters + (0) //in Clipper: incomplete statement or unbalanced delimiters begin sequence FOR bReak:=1 To 10 QOut( bReak * bReak ) + break->break :=1 + ( break )->( break(0) ) NEXT bReak break->break :=break->break +break->break BREAK +// break :=break[ 2 ] //not allowed in Clipper bReak :=IIF( bReak=1, BREAK(0), BREAK(bReak) ) recover USING bReak - BREAK( Break( break() ) ) + BREAK( Break( break(0) ) ) end BREAK -RETURN bReak[ bReak ] //in Clipper: syntax error ' BREAK ' +RETURN bReak( bReak ) /*==================================================================== * Test for CASE/DO CASE @@ -173,11 +190,13 @@ LOCAL case case ) NEXT case - case[ case ] :=case //in Clipper: Case is not immediatelly within DO CASE - case[ 2 ] :=2 //in Clipper: the same as above - Harbour compiles both +// case[ case ] :=case //in Clipper: Case is not immediatelly within DO CASE +// case[ 2 ] :=2 //in Clipper: the same as above - Harbour compiles both +// case :=case[ 2 ] case =case + case - case case :={|case| case( case )} case :={|| case } +// case :={|case| case[ 4 ]} DO /* case */ CASE CASE 1 @@ -204,6 +223,7 @@ case ) CASE( CASE ) //new CASE or function call? :) CASE case->case case->case :=case->case +1 + ( case )->( case() ) OTHERWISE case *=case ENDCASE @@ -257,17 +277,18 @@ LOCAL with do++ do +=do do->do :=do->do +1 + ( do )->( do() ) do[ 1 ] :=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 @@ -277,17 +298,26 @@ LOCAL with while->while :=while() +while->while enddo - while[ 1 ] :=while - while[ while ] :=while[ while ] + while[ 1 ] :=while + while[ 2 ] +=2 +// while( while ) +// while( while[1] ) +// while[ while ] :=while[ 1 ] //in Clipper: syntax error ' 1 ' while :={|while| while} + while while++ < 10 + ( while )->( while() ) enddo +// while while[1] //in Clipper: syntax error ' 1 ' +// enddo + DO /* **** */; ; ; while + DO while WITH do :=with + while ENDDO @@ -308,9 +338,11 @@ LOCAL with ++with with +=with with->with :=with() +with->with +1 + ( with )->( with() ) with :={|with| with} - with[ with ] :=with[ with ][ with ] - with[ with ][ with ] =with[ with ][ with ] +// with :=with[ 1 ] //Syntax error ' 1 ' +// with[ with ] :=1 //Syntax error ' WITH ' +// with[ with ][ with ] =with[ with ][ with ] DO with WITH with DO with WITH with() @@ -327,3 +359,57 @@ RETURN while FUNCTION With( with ) RETURN with + +/*==================================================================== +* Test for END +*/ +FUNCTION END_( ) +LOCAL end, while + +// end() //in Clipper: ENDIF does not match IF + end :=end() + + ++end +// end++ //in Clipper ENDIF does not match IF + end :=end++ + +// end->end +=1 //in Clipper; ENDIF does not match IF + end :=end->end + + DO end WITH end + DO end WITH end++ + +// end->( end() ) //in Clipper: ENDIF does not match IF + ( end )->( end() ) + + DO WHILE !end + --while + END + + DO WHILE end + ++while + END + + IF end + END + + DO CASE + CASE end + END + +// end[ 1 ] :=1 //in Clipper: ENDIF does not match IF +// end[ end ] :=2 + end :=end[ end ] + end =end[ end ] + end +=end + end ^=end + end %=end + +BEGIN SEQU + end :={| end | end } +END + +RETURN end + +FUNCTION end( end ) +RETURN end * end diff --git a/harbour/tests/working/makefile.dos b/harbour/tests/working/makefile.dos new file mode 100644 index 0000000000..2e06236305 --- /dev/null +++ b/harbour/tests/working/makefile.dos @@ -0,0 +1,21 @@ +# $Id$ +# Makefile for DOS DJGPP +# Usage: +# make -r -f makefile.dos +# where is the name of compiled file without extension +# +include ..\..\makedos.env + +TARGET=$(MAKECMDGOALS) + +$(TARGET): $(TARGET).exe + +$(TARGET).exe: $(TARGET).o + $(CC) $? -L$(HARBOURDIR)/libs -lharb -o $@ + +$(TARGET).c: $(TARGET).prg + $(HARBOURDIR)/bin/harbour $(TARGET).prg -n + +$(TARGET).o: $(TARGET).c + $(CC) $(CFLAGS) -c -o $@ $? + diff --git a/harbour/tests/working/makefile.wat b/harbour/tests/working/makefile.wat index 6060699e16..00182e3cc9 100644 --- a/harbour/tests/working/makefile.wat +++ b/harbour/tests/working/makefile.wat @@ -1,3 +1,4 @@ +# $Id$ # Makefile for WATCOM C/C++ 10.x # !ifdef FILE