diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 3c83efb3af..eb9c405ca0 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,22 @@ +19990911-13:03 GMT+1 Victor Szel + * source/compiler/harbour.y + source/compiler/genc.c + source/compiler/genhrb.c + source/compiler/genjava.c + source/compiler/genpas.c + source/compiler/genrc.c + source/compiler/Makefile + include/compiler.h + makefile.b32 + makefile.b40 + makefile.vc + harbour.b31 + + Separated the generation code from the main HARBOUR.Y file. + (The Borland and MSVC make files have been modified, but I could not test + them) + * source/rtl/arrays.c + + One comment added about hb_itemGetDS( NULL, szDate ); + 19990911-12:45 GMT+2 Ryszard Glab *source/compiler/harbour.y @@ -16,7 +35,6 @@ *source/vm/hvm.c * functions called from virtual machine return SUCCESS or FAILURE - 19990911-11:30 GMT+1 Victor Szel * contrib/odbc/odbc.c include/classes.ch @@ -59,7 +77,7 @@ source/vm/dynsym.c source/vm/hvm.c * Partial copyright headers formatted, joined where possible, etc. - * Copyright header changed to the standard doc/hdr_tpl.txt for + * Copyright header changed to the standard doc/hdr_tpl.txt for Antonio Linares. 19990911-01:42 EDT Paul Tucker diff --git a/harbour/harbour.b31 b/harbour/harbour.b31 index 72e673c522..2c61ce237d 100644 --- a/harbour/harbour.b31 +++ b/harbour/harbour.b31 @@ -31,16 +31,31 @@ PROJECT: harbour.exe tlib .\libs\b16\harbour.lib -+$@,, harbour.exe : harboury.obj harbourl.obj lex_t1.obj lex_t2.obj lex_t3.obj harbour.obj genobj32.obj \ + genc.obj \ + genhrb.obj \ + genrc.obj \ + genjava.obj \ + genpas.obj \ hbpp.obj hbppint.obj table.obj echo -ebin\harbour.exe obj\harboury.obj > b31.bc echo obj\harbourl.obj obj\lex_t1.obj >> b31.bc echo obj\lex_t2.obj obj\lex_t3.obj >> b31.bc echo obj\harbour.obj obj\genobj32.obj >> b31.bc + echo obj\genc.obj >> b31.bc + echo obj\genhrb.obj >> b31.bc + echo obj\genrc.obj >> b31.bc + echo obj\genjava.obj >> b31.bc + echo obj\genpas.obj >> b31.bc echo obj\hbpp.obj obj\hbppint.obj obj\table.obj >> b31.bc bcc $(c_opt) -Isource\compiler @b31.bc fixflex.obj : source\compiler\fixflex.c genobj32.obj : source\compiler\genobj32.c +genc.obj : source\compiler\genc.c +genhrb.obj : source\compiler\genhrb.c +genrc.obj : source\compiler\genrc.c +genjava.obj : source\compiler\genjava.c +genpas.obj : source\compiler\genpas.c harbour.obj : source\compiler\harbour.c harbourl.obj : source\compiler\harbourl.c harbour.l harboury.obj : source\compiler\harboury.c harbour.y diff --git a/harbour/include/compiler.h b/harbour/include/compiler.h index 9cd3a1bd82..0258f7f82b 100644 --- a/harbour/include/compiler.h +++ b/harbour/include/compiler.h @@ -36,6 +36,8 @@ #ifndef HB_COMPILER_H_ #define HB_COMPILER_H_ +#include "hbpp.h" + /* compiler related declarations */ /* locals, static, public variables support */ @@ -107,4 +109,55 @@ extern void * hb_xgrab( ULONG lSize ); /* allocates memory, exists on failur extern void * hb_xrealloc( void * pMem, ULONG lSize ); /* reallocates memory */ extern void hb_xfree( void * pMem ); /* frees memory */ +#ifdef __cplusplus +typedef struct yy_buffer_state *YY_BUFFER_STATE; +YY_BUFFER_STATE yy_create_buffer( FILE *, int ); /* yacc functions to manage multiple files */ +void yy_switch_to_buffer( YY_BUFFER_STATE ); /* yacc functions to manage multiple files */ +void yy_delete_buffer( YY_BUFFER_STATE ); /* yacc functions to manage multiple files */ +#else +void * yy_create_buffer( FILE *, int ); /* yacc functions to manage multiple files */ +void yy_switch_to_buffer( void * ); /* yacc functions to manage multiple files */ +void yy_delete_buffer( void * ); /* yacc functions to manage multiple files */ +#endif + +char * yy_strdup( char * p ); /* this will exit if there is not enough memory */ +char * yy_strupr( char * p ); + +#if 0 +static void __yy_memcpy( char * from, char * to, int count ); /* Bison prototype */ +#endif + +extern WORD FixSymbolPos( WORD ); /* converts symbol's compile-time position into generation-time position */ +extern PFUNCTION GetFuncall( char * szFunName ); /* locates a previously defined called function */ +extern PVAR GetVar( PVAR pVars, WORD wOrder ); /* returns a variable if defined or zero */ +extern PCOMSYMBOL GetSymbol( char *, WORD * ); /* returns a symbol pointer from the symbol table */ +extern PCOMSYMBOL GetSymbolOrd( WORD ); /* returns a symbol based on its index on the symbol table */ +extern PFUNCTION KillFunction( PFUNCTION ); /* releases all memory allocated by function and returns the next one */ +extern PCOMSYMBOL KillSymbol( PCOMSYMBOL ); /* releases all memory allocated by symbol and returns the next one */ + +extern FUNCTIONS functions, funcalls; +extern PFUNCTION _pInitFunc; +extern SYMBOLS symbols; +extern PHB_FNAME _pFileName; +extern BOOL _bQuiet; +extern BOOL _bStartProc; +extern char _szPrefix[ 20 ]; /* holds the prefix added to the generated symbol init function name (in C output currently) */ + +#define VS_LOCAL 1 +#define VS_STATIC 2 +#define VS_FIELD 4 +#define VS_PARAMETER 8 +#define VS_PRIVATE 64 +#define VS_PUBLIC 128 +#define VS_MEMVAR ( VS_PUBLIC | VS_PRIVATE ) + +/* + * flags for bFlags member +*/ +#define FUN_STATEMENTS 1 /* Function have at least one executable statement */ +#define FUN_USES_STATICS 2 /* Function uses static variables */ +#define FUN_PROCEDURE 4 /* This is a procedure that shouldn't return value */ +#define FUN_ILLEGAL_INIT 8 /* Attempt to initialize static variable with a function call */ +#define FUN_USES_LOCAL_PARAMS 16 /* parameters are declared using () */ + #endif /* HB_COMPILER_H_ */ diff --git a/harbour/makefile.b32 b/harbour/makefile.b32 index 9760b5cf14..6778ab6b53 100644 --- a/harbour/makefile.b32 +++ b/harbour/makefile.b32 @@ -118,13 +118,18 @@ xsavescr.c : xsavescr.prg harbour.exe bcc32 -c -O2 -I.\include -o$@ -DHARBOUR_USE_GTAPI $< tlib .\libs\b32\harbour.lib -+$@,, -harbour.exe : harboury.c harbourl.c genobj32.obj harbour.obj compiler.h hbppint.c hbpp.c table.c +harbour.exe : harboury.c harbourl.c genc.obj genhrb.obj genjava.obj genrc.obj genpas.obj genobj32.obj harbour.obj compiler.h hbppint.c hbpp.c table.c echo -O2 > bld.32 echo -ebin\harbour.exe >> bld.32 echo -Iinclude;source\compiler;source\hbpp >> bld.32 echo source\compiler\harboury.c >> bld.32 echo source\compiler\harbourl.c >> bld.32 echo source\compiler\genobj32.obj >> bld.32 + echo source\compiler\genc.obj >> bld.32 + echo source\compiler\genhrb.obj >> bld.32 + echo source\compiler\genjava.obj >> bld.32 + echo source\compiler\genrc.obj >> bld.32 + echo source\compiler\genpas.obj >> bld.32 echo source\compiler\harbour.obj >> bld.32 echo source\hbpp\hbppint.c >> bld.32 echo source\hbpp\hbpp.c >> bld.32 @@ -142,6 +147,26 @@ genobj32.obj : genobj32.c bcc32 -c -O2 -I.\include -osource\compiler\genobj32.obj \ source\compiler\genobj32.c +genc.obj : genc.c + bcc32 -c -O2 -I.\include -osource\compiler\genc.obj \ + source\compiler\genc.c + +genhrb.obj : genhrb.c + bcc32 -c -O2 -I.\include -osource\compiler\genhrb.obj \ + source\compiler\genhrb.c + +genrc.obj : genrc.c + bcc32 -c -O2 -I.\include -osource\compiler\genrc.obj \ + source\compiler\genrc.c + +genjava.obj : genjava.c + bcc32 -c -O2 -I.\include -osource\compiler\genjava.obj \ + source\compiler\genjava.c + +genpas.obj : genpas.c + bcc32 -c -O2 -I.\include -osource\compiler\genpas.obj \ + source\compiler\genpas.c + harbour.obj : harbour.c bcc32 -c -O2 -I.\include -osource\compiler\harbour.obj \ source\compiler\harbour.c diff --git a/harbour/makefile.b40 b/harbour/makefile.b40 index 5dd7c4cbb8..0b591c3379 100644 --- a/harbour/makefile.b40 +++ b/harbour/makefile.b40 @@ -85,12 +85,17 @@ alert.c : alert.prg harbour.exe bcc32 -c -I.\include -o$@ -DHARBOUR_USE_GTAPI $< tlib .\libs\b32\harbour.lib -+$@,, -harbour.exe : harboury.c harbourl.c genobj32.obj harbour.obj compiler.h hbppint.c hbpp.c table.c +harbour.exe : harboury.c harbourl.c genc.obj genhrb.obj genjava.obj genrc.obj genpas.obj genobj32.obj harbour.obj compiler.h hbppint.c hbpp.c table.c echo -ebin\harbour.exe >> bld.32 echo -Iinclude;source\compiler;source\hbpp >> bld.32 echo source\compiler\harboury.c >> bld.32 echo source\compiler\harbourl.c >> bld.32 echo source\compiler\genobj32.obj >> bld.32 + echo source\compiler\genc.obj >> bld.32 + echo source\compiler\genhrb.obj >> bld.32 + echo source\compiler\genjava.obj >> bld.32 + echo source\compiler\genrc.obj >> bld.32 + echo source\compiler\genpas.obj >> bld.32 echo source\compiler\harbour.obj >> bld.32 echo source\hbpp\hbppint.c >> bld.32 echo source\hbpp\hbpp.c >> bld.32 @@ -113,6 +118,26 @@ genobj32.obj : genobj32.c bcc32 -c -I.\include -osource\compiler\genobj32.obj \ source\compiler\genobj32.c +genc.obj : genc.c + bcc32 -c -I.\include -osource\compiler\genc.obj \ + source\compiler\genc.c + +genhrb.obj : genhrb.c + bcc32 -c -I.\include -osource\compiler\genhrb.obj \ + source\compiler\genhrb.c + +genrc.obj : genrc.c + bcc32 -c -I.\include -osource\compiler\genrc.obj \ + source\compiler\genrc.c + +genjava.obj : genjava.c + bcc32 -c -I.\include -osource\compiler\genjava.obj \ + source\compiler\genjava.c + +genpas.obj : genpas.c + bcc32 -c -I.\include -osource\compiler\genpas.obj \ + source\compiler\genpas.c + harbour.obj : harbour.c bcc32 -c -I.\include -osource\compiler\harbour.obj \ source\compiler\harbour.c diff --git a/harbour/makefile.vc b/harbour/makefile.vc index c8bb20b0e4..e69bc148df 100644 --- a/harbour/makefile.vc +++ b/harbour/makefile.vc @@ -179,7 +179,7 @@ HBPP_LIB_OBJS = \ DEBUG_LIB_OBJS = \ $(OBJ_DIR)\debugger.obj \ - $(OBJ_DIR)\tbrwtext.obj + $(OBJ_DIR)\tbrwtext.obj # # Our default target @@ -197,6 +197,11 @@ $(HARBOUR_EXE) : \ $(COMPILER_DIR)\harboury.c \ $(COMPILER_DIR)\harbourl.c \ $(COMPILER_DIR)\genobj32.c \ + $(COMPILER_DIR)\genc.c \ + $(COMPILER_DIR)\genhrb.c \ + $(COMPILER_DIR)\genrc.c \ + $(COMPILER_DIR)\genjava.c \ + $(COMPILER_DIR)\genpas.c \ $(COMPILER_DIR)\harbour.c \ $(HBPP_DIR)\hbpp.c \ $(HBPP_DIR)\hbppint.c \ diff --git a/harbour/source/compiler/Makefile b/harbour/source/compiler/Makefile index cce4fd349e..7da80aa53f 100644 --- a/harbour/source/compiler/Makefile +++ b/harbour/source/compiler/Makefile @@ -22,7 +22,12 @@ LEX_HEADERS=\ hbdefs.h C_SOURCES=\ - genobj32.c \ + genc.c \ + genhrb.c \ + genjava.c \ + genobj32.c \ + genpas.c \ + genrc.c \ C_MAIN=harbour.c diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c new file mode 100644 index 0000000000..b9b51b3d69 --- /dev/null +++ b/harbour/source/compiler/genc.c @@ -0,0 +1,939 @@ +/* + * $Id$ + */ + +/* + Harbour Project source code + + Harbour C Generation. + + Copyright 1999 Antonio Linares + www - http://www.harbour-project.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version, with one exception: + + The exception is that if you link the Harbour Runtime Library (HRL) + and/or the Harbour Virtual Machine (HVM) with other files to produce + an executable, this does not by itself cause the resulting executable + to be covered by the GNU General Public License. Your use of that + executable is in no way restricted on account of linking the HRL + and/or HVM code into it. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit + their web site at http://www.gnu.org/). +*/ + +#include "extend.h" +#include "compiler.h" +#include "pcode.h" + +void GenCCode( char * szFileName, char * szName ) /* generates the C language output */ +{ + PFUNCTION pFunc = functions.pFirst, pFTemp; + PCOMSYMBOL pSym = symbols.pFirst; + WORD w, wLen, wSym, wVar; + WORD iNestedCodeblock = 0; + ULONG lPCodePos; + char chr; + BOOL bEndProcRequired; + + + FILE * yyc; /* file handle for C output */ + + HB_SYMBOL_UNUSED( szName ); + + yyc = fopen( szFileName, "wb" ); + if( ! yyc ) + { + printf( "Error opening file %s\n", szFileName ); + return; + } + + if( ! _bQuiet ) + printf( "\nGenerating C language output...\n" ); + + fprintf( yyc, "/* Harbour compiler generated code */\n\n" ); + fprintf( yyc, "#include \"hb_vmpub.h\"\n" ); + fprintf( yyc, "#include \"init.h\"\n\n\n" ); + + if( ! _bStartProc ) + pFunc = pFunc->pNext; /* No implicit starting procedure */ + + /* write functions prototypes for PRG defined functions */ + while( pFunc ) + { + if( pFunc->cScope & FS_STATIC || pFunc->cScope & FS_INIT || pFunc->cScope & FS_EXIT ) + fprintf( yyc, "static " ); + + if( pFunc == _pInitFunc ) + fprintf( yyc, "HARBOUR hb_INITSTATICS( void );\n" ); /* NOTE: hb_ intentionally in lower case */ + else + fprintf( yyc, "HARBOUR HB_%s( void );\n", pFunc->szName ); + pFunc = pFunc->pNext; + } + /* write functions prototypes for called functions outside this PRG */ + pFunc = funcalls.pFirst; + while( pFunc ) + { + pFTemp = GetFunction( pFunc->szName ); + if( ! pFTemp || pFTemp == functions.pFirst ) + fprintf( yyc, "HARBOUR HB_%s( void );\n", pFunc->szName ); + pFunc = pFunc->pNext; + } + + /* writes the symbol table */ + /* Generate the wrapper that will initialize local symbol table + */ + yy_strupr( _pFileName->szName ); + fprintf( yyc, "\n\nHB_INIT_SYMBOLS_BEGIN( hb_vm_SymbolInit_%s%s )\n", _szPrefix, _pFileName->szName ); + + if( ! _bStartProc ) + pSym = pSym->pNext; /* starting procedure is always the first symbol */ + + wSym = 0; /* symbols counter */ + while( pSym ) + { + if( pSym->szName[ 0 ] == '(' ) + { + /* Since the normal function cannot be INIT and EXIT at the same time + * we are using these two bits to mark the special function used to + * initialize static variables + */ + fprintf( yyc, "{ \"(_INITSTATICS)\", FS_INIT | FS_EXIT, hb_INITSTATICS, 0}" ); /* NOTE: hb_ intentionally in lower case */ + } + else + { + fprintf( yyc, "{ \"%s\", ", pSym->szName ); + + if( pSym->cScope & FS_STATIC ) + fprintf( yyc, "FS_STATIC" ); + + else if( pSym->cScope & FS_INIT ) + fprintf( yyc, "FS_INIT" ); + + else if( pSym->cScope & FS_EXIT ) + fprintf( yyc, "FS_EXIT" ); + + else + fprintf( yyc, "FS_PUBLIC" ); + + if( pSym->cScope & VS_MEMVAR ) + fprintf( yyc, " | FS_MEMVAR" ); + + if( ( pSym->cScope != FS_MESSAGE ) && ( pSym->cScope & FS_MESSAGE ) ) /* only for non public symbols */ + fprintf( yyc, " | FS_MESSAGE" ); + + /* specify the function address if it is a defined function or an + external called function */ + if( GetFunction( pSym->szName ) ) /* is it a function defined in this module */ + fprintf( yyc, ", HB_%s, 0 }", pSym->szName ); + else if( GetFuncall( pSym->szName ) ) /* is it a function called from this module */ + fprintf( yyc, ", HB_%s, 0 }", pSym->szName ); + else + fprintf( yyc, ", 0, 0 }" ); /* memvar */ + } + ++wSym; + + if( pSym != symbols.pLast ) + fprintf( yyc, ",\n" ); + + pSym = pSym->pNext; + } + fprintf( yyc, "\nHB_INIT_SYMBOLS_END( hb_vm_SymbolInit_%s%s )\n", _szPrefix, _pFileName->szName ); + fprintf( yyc, "#if ! defined(__GNUC__)\n #pragma startup hb_vm_SymbolInit_%s%s\n#endif\n\n\n", _szPrefix, _pFileName->szName ); + + /* Generate functions data + */ + pFunc = functions.pFirst; + if( ! _bStartProc ) + pFunc = pFunc->pNext; /* No implicit starting procedure */ + while( pFunc ) + { + if( pFunc->cScope != FS_PUBLIC ) + fprintf( yyc, "static " ); + + if( pFunc == _pInitFunc ) /* Is it (_INITSTATICS) */ + fprintf( yyc, "HARBOUR hb_INITSTATICS( void )\n{\n static BYTE pcode[] = { \n" ); /* NOTE: hb_ intentionally in lower case */ + else + fprintf( yyc, "HARBOUR HB_%s( void )\n{\n static BYTE pcode[] = { \n", pFunc->szName ); + + bEndProcRequired = TRUE; + lPCodePos = 0; + while( lPCodePos < pFunc->lPCodePos ) + { + switch( pFunc->pCode[ lPCodePos ] ) + { + case HB_P_AND: + fprintf( yyc, "\t\tHB_P_AND,\n" ); + lPCodePos++; + break; + + case HB_P_ARRAYAT: + fprintf( yyc, "\t\tHB_P_ARRAYAT,\n" ); + lPCodePos++; + break; + + case HB_P_ARRAYPUT: + fprintf( yyc, "\t\tHB_P_ARRAYPUT,\n" ); + lPCodePos++; + break; + + case HB_P_DEC: + fprintf( yyc, "\t\tHB_P_DEC,\n" ); + lPCodePos++; + break; + + case HB_P_DIMARRAY: + w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + fprintf( yyc, "\t\tHB_P_DIMARRAY, %i, %i,\t/* %i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], w ); + lPCodePos += 3; + break; + + case HB_P_DIVIDE: + fprintf( yyc, "\t\tHB_P_DIVIDE,\n" ); + lPCodePos++; + break; + + case HB_P_DO: + fprintf( yyc, "\t\tHB_P_DO, %i, %i,\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ] ); + lPCodePos += 3; + break; + + case HB_P_DUPLICATE: + fprintf( yyc, "\t\tHB_P_DUPLICATE,\n" ); + lPCodePos++; + break; + + case HB_P_DUPLTWO: + fprintf( yyc, "\t\tHB_P_DUPLTWO,\n" ); + lPCodePos++; + break; + + case HB_P_EQUAL: + fprintf( yyc, "\t\tHB_P_EQUAL,\n" ); + lPCodePos++; + break; + + case HB_P_EXACTLYEQUAL: + fprintf( yyc, "\t\tHB_P_EXACTLYEQUAL,\n" ); + lPCodePos++; + break; + + case HB_P_ENDBLOCK: + --iNestedCodeblock; + fprintf( yyc, "\t\tHB_P_ENDBLOCK,\n" ); + lPCodePos++; + break; + + case HB_P_ENDPROC: + lPCodePos++; + if( lPCodePos == pFunc->lPCodePos ) + { + bEndProcRequired = FALSE; + fprintf( yyc, "\t\tHB_P_ENDPROC\n" ); + } + else + fprintf( yyc, "\t\tHB_P_ENDPROC,\n" ); + break; + + case HB_P_FALSE: + fprintf( yyc, "\t\tHB_P_FALSE,\n" ); + lPCodePos++; + break; + + case HB_P_FORTEST: /* ER For tests. Step > 0 LESS */ + /* Step < 0 GREATER */ + fprintf( yyc, "\t\tHB_P_FORTEST,\n" ); + lPCodePos++; + break; + + case HB_P_FRAME: + { + PVAR pLocal = pFunc->pLocals; + BYTE bLocals = 0; + + while( pLocal ) + { + pLocal = pLocal->pNext; + bLocals++; + } + + if( bLocals || pFunc->wParamCount ) + fprintf( yyc, "\t\tHB_P_FRAME, %i, %i,\t/* locals, params */\n", + bLocals - pFunc->wParamCount, + pFunc->wParamCount ); + lPCodePos += 3; + } + break; + + case HB_P_FUNCPTR: + fprintf( yyc, "\t\tHB_P_FUNCPTR,\n" ); + lPCodePos++; + break; + + case HB_P_FUNCTION: + fprintf( yyc, "\t\tHB_P_FUNCTION, %i, %i,\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ] ); + lPCodePos += 3; + break; + + case HB_P_GENARRAY: + w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + fprintf( yyc, "\t\tHB_P_GENARRAY, %i, %i,\t/* %i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], w ); + lPCodePos += 3; + break; + + case HB_P_GREATER: + fprintf( yyc, "\t\tHB_P_GREATER,\n" ); + lPCodePos++; + break; + + case HB_P_GREATEREQUAL: + fprintf( yyc, "\t\tHB_P_GREATEREQUAL,\n" ); + lPCodePos++; + break; + + case HB_P_INC: + fprintf( yyc, "\t\tHB_P_INC,\n" ); + lPCodePos++; + break; + + case HB_P_INSTRING: + fprintf( yyc, "\t\tHB_P_INSTRING,\n" ); + lPCodePos++; + break; + + case HB_P_JUMP: + /* if( 1 ) ( lPCodePos + 3 ) < pFunc->lPCodePos ) */ + { + w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + fprintf( yyc, "\t\tHB_P_JUMP, %i, %i,\t/* %i (abs: %05li) */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], w, lPCodePos + ( w ? w: 3 ) ); + } + lPCodePos += 3; + break; + + case HB_P_JUMPFALSE: + w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + fprintf( yyc, "\t\tHB_P_JUMPFALSE, %i, %i,\t/* %i (abs: %05li) */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], w, lPCodePos + ( w ? w: 3 ) ); + lPCodePos += 3; + break; + + case HB_P_JUMPTRUE: + w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + fprintf( yyc, "\t\tHB_P_JUMPTRUE, %i, %i,\t/* %i (abs: %05li) */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], w, lPCodePos + ( w ? w: 3 ) ); + lPCodePos += 3; + break; + + case HB_P_LESS: + fprintf( yyc, "\t\tHB_P_LESS,\n" ); + lPCodePos++; + break; + + case HB_P_LESSEQUAL: + fprintf( yyc, "\t\tHB_P_LESSEQUAL,\n" ); + lPCodePos++; + break; + + case HB_P_LINE: + fprintf( yyc, "/* %05li */", lPCodePos ); + w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + fprintf( yyc, " HB_P_LINE, %i, %i,\t\t/* %i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], w ); + lPCodePos += 3; + break; + + case HB_P_LOCALNAME: + fprintf( yyc, "\t\tHB_P_LOCALNAME, %i, %i,\t/* %s */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + ( char * ) pFunc->pCode + lPCodePos + 3 ); + lPCodePos += 3; + while( pFunc->pCode[ lPCodePos ] ) + { + chr = pFunc->pCode[ lPCodePos++ ]; + if( chr == '\'' || chr == '\\') + fprintf( yyc, " \'\\%c\',", chr ); + else + fprintf( yyc, " \'%c\',", chr ); + } + fprintf( yyc, " 0,\n" ); + lPCodePos++; + break; + + case HB_P_MESSAGE: + { + WORD wFixPos; + + wSym = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + wFixPos = FixSymbolPos( wSym ); + fprintf( yyc, "\t\tHB_P_MESSAGE, %i, %i,\t/* %s */\n", + LOBYTE( wFixPos ), + HIBYTE( wFixPos ), + GetSymbolOrd( wSym )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_MINUS: + fprintf( yyc, "\t\tHB_P_MINUS,\n" ); + lPCodePos++; + break; + + case HB_P_MODULENAME: + fprintf( yyc, "\t\tHB_P_MODULENAME,\t/* %s */\n", + ( char * ) pFunc->pCode + lPCodePos++ + 1 ); + while( pFunc->pCode[ lPCodePos ] ) + { + chr = pFunc->pCode[ lPCodePos++ ]; + if( chr == '\'' || chr == '\\') + fprintf( yyc, " \'\\%c\',", chr ); + else + fprintf( yyc, " \'%c\',", chr ); + } + fprintf( yyc, " 0,\n" ); + lPCodePos++; + break; + + case HB_P_MODULUS: + fprintf( yyc, "\t\tHB_P_MODULUS,\n" ); + lPCodePos++; + break; + + case HB_P_MULT: + fprintf( yyc, "\t\tHB_P_MULT,\n" ); + lPCodePos++; + break; + + case HB_P_NEGATE: + fprintf( yyc, "\t\tHB_P_NEGATE,\n" ); + lPCodePos++; + break; + + case HB_P_NOT: + fprintf( yyc, "\t\tHB_P_NOT,\n" ); + lPCodePos++; + break; + + case HB_P_NOTEQUAL: + fprintf( yyc, "\t\tHB_P_NOTEQUAL,\n" ); + lPCodePos++; + break; + + case HB_P_OR: + fprintf( yyc, "\t\tHB_P_OR,\n" ); + lPCodePos++; + break; + + case HB_P_PARAMETER: + { + WORD wFixPos; + + wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + wFixPos = FixSymbolPos( wVar ); + fprintf( yyc, "\t\tHB_P_PARAMETER, %i, %i, %i,\t/* %s */\n", + LOBYTE( wFixPos ), + HIBYTE( wFixPos ), + pFunc->pCode[ lPCodePos + 3 ], + GetSymbolOrd( wVar )->szName ); + lPCodePos += 4; + } + break; + + case HB_P_PLUS: + fprintf( yyc, "\t\tHB_P_PLUS,\n" ); + lPCodePos++; + break; + + case HB_P_POP: + fprintf( yyc, "\t\tHB_P_POP,\n" ); + lPCodePos++; + break; + + case HB_P_POPALIAS: + fprintf( yyc, "\t\tHB_P_POPALIAS,\n" ); + lPCodePos++; + break; + + case HB_P_POPALIASEDFIELD: + { + WORD wFixPos; + + wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + wFixPos = FixSymbolPos( wVar ); + fprintf( yyc, "\t\tHB_P_POPALIASEDFIELD, %i, %i,\t/* %s */\n", + LOBYTE( wFixPos ), + HIBYTE( wFixPos ), + GetSymbolOrd( wVar )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_POPFIELD: + { + WORD wFixPos; + + wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + wFixPos = FixSymbolPos( wVar ); + fprintf( yyc, "\t\tHB_P_POPFIELD, %i, %i,\t/* %s */\n", + LOBYTE( wFixPos ), + HIBYTE( wFixPos ), + GetSymbolOrd( wVar )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_POPLOCAL: + { + SHORT wVar = * ( ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ] ); + /* Variable with negative order are local variables + * referenced in a codeblock -handle it with care + */ + if( iNestedCodeblock ) + { + /* we are accesing variables within a codeblock */ + /* the names of codeblock variable are lost */ + if( wVar < 0 ) + fprintf( yyc, "\t\tHB_P_POPLOCAL, %i, %i,\t/* localvar%i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + -wVar ); + else + fprintf( yyc, "\t\tHB_P_POPLOCAL, %i, %i,\t/* codeblockvar%i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + wVar ); + } + else + fprintf( yyc, "\t\tHB_P_POPLOCAL, %i, %i,\t/* %s */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + GetVar( pFunc->pLocals, wVar )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_POPMEMVAR: + { + WORD wFixPos; + + wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + wFixPos = FixSymbolPos( wVar ); + fprintf( yyc, "\t\tHB_P_POPMEMVAR, %i, %i,\t/* %s */\n", + LOBYTE( wFixPos ), + HIBYTE( wFixPos ), + GetSymbolOrd( wVar )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_POPSTATIC: + { + PVAR pVar; + PFUNCTION pTmp = functions.pFirst; + + wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + while( pTmp->pNext && pTmp->pNext->iStaticsBase < wVar ) + pTmp = pTmp->pNext; + pVar = GetVar( pTmp->pStatics, wVar - pTmp->iStaticsBase ); + fprintf( yyc, "\t\tHB_P_POPSTATIC, %i, %i,\t/* %s */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + pVar->szName ); + lPCodePos += 3; + } + break; + + case HB_P_POWER: + fprintf( yyc, "\t\tHB_P_POWER,\n" ); + lPCodePos++; + break; + + case HB_P_PUSHALIAS: + fprintf( yyc, "\t\tHB_P_PUSHALIAS,\n" ); + lPCodePos++; + break; + + case HB_P_PUSHALIASEDFIELD: + { + WORD wFixPos; + + wVar = pFunc->pCode[ lPCodePos + 1 ] + + pFunc->pCode[ lPCodePos + 2 ] * 256; + wFixPos = FixSymbolPos( wVar ); + fprintf( yyc, "\t\tHB_P_PUSHALIASEDFIELD, %i, %i,\t/* %s */\n", + LOBYTE( wFixPos ), + HIBYTE( wFixPos ), + GetSymbolOrd( wVar )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_PUSHBLOCK: + ++iNestedCodeblock; + fprintf( yyc, "\t\tHB_P_PUSHBLOCK, %i, %i,\t/* %i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + pFunc->pCode[ lPCodePos + 1 ] + + pFunc->pCode[ lPCodePos + 2 ] * 256 ); + w = * ( ( WORD * ) &( pFunc->pCode [ lPCodePos + 3 ] ) ); + fprintf( yyc, "\t\t%i, %i,\t/* number of local parameters (%i) */\n", + pFunc->pCode[ lPCodePos + 3 ], + pFunc->pCode[ lPCodePos + 4 ], w ); + wVar = * ( ( WORD * ) &( pFunc->pCode [ lPCodePos + 5 ] ) ); + fprintf( yyc, "\t\t%i, %i,\t/* number of local variables (%i) */\n", + pFunc->pCode[ lPCodePos + 5 ], + pFunc->pCode[ lPCodePos + 6 ], wVar ); + lPCodePos += 7; /* codeblock size + number of parameters + number of local variables */ + /* create the table of referenced local variables */ + while( wVar-- ) + { + w = * ( ( WORD * ) &( pFunc->pCode [ lPCodePos ] ) ); + fprintf( yyc, "\t\t%i, %i,\t/* %s */\n", + pFunc->pCode[ lPCodePos ], + pFunc->pCode[ lPCodePos + 1 ], + GetVar( pFunc->pLocals, w )->szName ); + lPCodePos +=2; + } + break; + + case HB_P_PUSHDOUBLE: + { + int i; + ++lPCodePos; + fprintf( yyc, "\t\tHB_P_PUSHDOUBLE, " ); + for( i = 0; i < sizeof( double ) + sizeof( BYTE ); ++i ) + fprintf( yyc, "%i,", ( ( BYTE * ) pFunc->pCode )[ lPCodePos + i ] ); + fprintf( yyc, "\t/* %.*f, %d */\n", + *( ( BYTE * ) &( pFunc->pCode[ lPCodePos + sizeof( double ) ] ) ), + *( ( double * ) &( pFunc->pCode[ lPCodePos ] ) ), + *( ( BYTE * ) &( pFunc->pCode[ lPCodePos + sizeof( double ) ] ) ) ); + lPCodePos += sizeof( double ) + sizeof( BYTE ); + } + break; + + case HB_P_PUSHFIELD: + { + WORD wFixPos; + + wVar = pFunc->pCode[ lPCodePos + 1 ] + + pFunc->pCode[ lPCodePos + 2 ] * 256; + wFixPos = FixSymbolPos( wVar ); + fprintf( yyc, "\t\tHB_P_PUSHFIELD, %i, %i,\t/* %s */\n", + LOBYTE( wFixPos ), + HIBYTE( wFixPos ), + GetSymbolOrd( wVar )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_PUSHINT: + fprintf( yyc, "\t\tHB_P_PUSHINT, %i, %i,\t/* %i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + pFunc->pCode[ lPCodePos + 1 ] + + pFunc->pCode[ lPCodePos + 2 ] * 256 ); + lPCodePos += 3; + break; + + case HB_P_PUSHLOCAL: + { + SHORT wVar = * ( ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ] ); + /* Variable with negative order are local variables + * referenced in a codeblock -handle it with care + */ + if( iNestedCodeblock ) + { + /* we are accesing variables within a codeblock */ + /* the names of codeblock variable are lost */ + if( wVar < 0 ) + fprintf( yyc, "\t\tHB_P_PUSHLOCAL, %i, %i,\t/* localvar%i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + -wVar ); + else + fprintf( yyc, "\t\tHB_P_PUSHLOCAL, %i, %i,\t/* codeblockvar%i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + wVar ); + } + else + fprintf( yyc, "\t\tHB_P_PUSHLOCAL, %i, %i,\t/* %s */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + GetVar( pFunc->pLocals, wVar )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_PUSHLOCALREF: + { + SHORT wVar = * ( ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ] ); + /* Variable with negative order are local variables + * referenced in a codeblock -handle it with care + */ + if( iNestedCodeblock ) + { + /* we are accesing variables within a codeblock */ + /* the names of codeblock variable are lost */ + if( wVar < 0 ) + fprintf( yyc, "\t\tHB_P_PUSHLOCALREF, %i, %i,\t/* localvar%i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + -wVar ); + else + fprintf( yyc, "\t\tHB_P_PUSHLOCALREF, %i, %i,\t/* codeblockvar%i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + wVar ); + } + else + fprintf( yyc, "\t\tHB_P_PUSHLOCALREF, %i, %i,\t/* %s */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + GetVar( pFunc->pLocals, wVar )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_PUSHLONG: + fprintf( yyc, "\t\tHB_P_PUSHLONG, %i, %i, %i, %i,\t/* %li */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + pFunc->pCode[ lPCodePos + 3 ], + pFunc->pCode[ lPCodePos + 4 ], + *( ( long * ) &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); + lPCodePos += ( 1 + sizeof( long ) ); + break; + + case HB_P_PUSHMEMVAR: + { + WORD wFixPos; + + wVar = pFunc->pCode[ lPCodePos + 1 ] + + pFunc->pCode[ lPCodePos + 2 ] * 256; + wFixPos = FixSymbolPos( wVar ); + fprintf( yyc, "\t\tHB_P_PUSHMEMVAR, %i, %i,\t/* %s */\n", + LOBYTE( wFixPos ), + HIBYTE( wFixPos ), + GetSymbolOrd( wVar )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_PUSHMEMVARREF: + { + WORD wFixPos; + + wVar = pFunc->pCode[ lPCodePos + 1 ] + + pFunc->pCode[ lPCodePos + 2 ] * 256; + wFixPos = FixSymbolPos( wVar ); + fprintf( yyc, "\t\tHB_P_PUSHMEMVARREF, %i, %i,\t/* %s */\n", + LOBYTE( wFixPos ), + HIBYTE( wFixPos ), + GetSymbolOrd( wVar )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_PUSHNIL: + fprintf( yyc, "\t\tHB_P_PUSHNIL,\n" ); + lPCodePos++; + break; + + case HB_P_PUSHSELF: + fprintf( yyc, "\t\tHB_P_PUSHSELF,\n" ); + lPCodePos++; + break; + + case HB_P_PUSHSTATIC: + { + PVAR pVar; + PFUNCTION pTmp = functions.pFirst; + + wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + while( pTmp->pNext && pTmp->pNext->iStaticsBase < wVar ) + pTmp = pTmp->pNext; + pVar = GetVar( pTmp->pStatics, wVar - pTmp->iStaticsBase ); + fprintf( yyc, "\t\tHB_P_PUSHSTATIC, %i, %i,\t/* %s */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + pVar->szName ); + lPCodePos += 3; + } + break; + + case HB_P_PUSHSTATICREF: + { + PVAR pVar; + PFUNCTION pTmp = functions.pFirst; + + wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + while( pTmp->pNext && pTmp->pNext->iStaticsBase < wVar ) + pTmp = pTmp->pNext; + pVar = GetVar( pTmp->pStatics, wVar - pTmp->iStaticsBase ); + fprintf( yyc, "\t\tHB_P_PUSHSTATICREF, %i, %i,\t/* %s */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], + pVar->szName ); + lPCodePos += 3; + } + break; + + case HB_P_PUSHSTR: + wLen = pFunc->pCode[ lPCodePos + 1 ] + + pFunc->pCode[ lPCodePos + 2 ] * 256; + fprintf( yyc, "\t\tHB_P_PUSHSTR, %i, %i,\t/* %i */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], wLen ); + lPCodePos +=3; + while( wLen-- ) + { + chr = pFunc->pCode[ lPCodePos++ ]; + if( chr == '\'' || chr == '\\') + fprintf( yyc, " \'\\%c\',", chr ); + else + fprintf( yyc, " \'%c\',", chr ); + } + fprintf( yyc, "\n" ); + break; + + case HB_P_PUSHSYM: + { + WORD wFixPos; + + wSym = pFunc->pCode[ lPCodePos + 1 ] + + pFunc->pCode[ lPCodePos + 2 ] * 256; + wFixPos = FixSymbolPos( wSym ); + fprintf( yyc, "\t\tHB_P_PUSHSYM, %i, %i,\t/* %s */\n", + LOBYTE( wFixPos ), + HIBYTE( wFixPos ), + GetSymbolOrd( wSym )->szName ); + lPCodePos += 3; + } + break; + + case HB_P_RETVALUE: + fprintf( yyc, "\t\tHB_P_RETVALUE,\n" ); + lPCodePos++; + break; + + case HB_P_SEQBEGIN: + w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + fprintf( yyc, "\t\tHB_P_SEQBEGIN, %i, %i,\t/* %i (abs: %05li) */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], w, lPCodePos + ( w ? w: 3 ) ); + lPCodePos += 3; + break; + + case HB_P_SEQEND: + fprintf( yyc, "/* %05li */", lPCodePos ); + w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; + fprintf( yyc, " HB_P_SEQEND, %i, %i,\t/* %i (abs: %05li) */\n", + pFunc->pCode[ lPCodePos + 1 ], + pFunc->pCode[ lPCodePos + 2 ], w, lPCodePos + ( w ? w: 3 ) ); + lPCodePos += 3; + break; + + case HB_P_SEQRECOVER: + fprintf( yyc, "\t\tHB_P_SEQRECOVER,\n" ); + lPCodePos++; + break; + + case HB_P_SFRAME: + /* we only generate it if there are statics used in this function */ + if( pFunc->bFlags & FUN_USES_STATICS ) + { + GetSymbol( _pInitFunc->szName, &w ); + w = FixSymbolPos( w ); + fprintf( yyc, "\t\tHB_P_SFRAME, %i, %i,\t/* symbol (_INITSTATICS) */\n", + LOBYTE( w ), HIBYTE( w ) ); + } + lPCodePos += 3; + break; + + case HB_P_STATICS: + { + GetSymbol( _pInitFunc->szName, &w ); + w = FixSymbolPos( w ); + fprintf( yyc, "\t\tHB_P_STATICS, %i, %i,\t/* symbol (_INITSTATICS) */\n", + LOBYTE( w ), HIBYTE( w ) ); + lPCodePos += 3; + } + break; + + case HB_P_SWAPALIAS: + fprintf( yyc, "\t\tHB_P_SWAPALIAS,\n" ); + lPCodePos++; + break; + + case HB_P_TRUE: + fprintf( yyc, "\t\tHB_P_TRUE,\n" ); + lPCodePos++; + break; + + case HB_P_ZERO: + fprintf( yyc, "\t\tHB_P_ZERO,\n" ); + lPCodePos++; + break; + + default: + printf( "Incorrect pcode value: %u\n", pFunc->pCode[ lPCodePos ] ); + lPCodePos = pFunc->lPCodePos; + break; + } + } + + fprintf( yyc, "/* %05li */", lPCodePos ); + if( bEndProcRequired ) + fprintf( yyc, " HB_P_ENDPROC };\n\n" ); + else + fprintf( yyc, " };\n\n" ); + fprintf( yyc, " hb_vmExecute( pcode, symbols );\n}\n\n" ); + pFunc = pFunc->pNext; + } + + fclose( yyc ); + + pFunc = functions.pFirst; + while( pFunc ) + pFunc = KillFunction( pFunc ); + + pFunc = funcalls.pFirst; + while( pFunc ) + { + funcalls.pFirst = pFunc->pNext; + hb_xfree( ( void * ) pFunc ); /* NOTE: szName will be released by KillSymbol() */ + pFunc = funcalls.pFirst; + } + + pSym = symbols.pFirst; + while( pSym ) + pSym = KillSymbol( pSym ); + + if( ! _bQuiet ) + printf( "%s -> done!\n", szFileName ); +} diff --git a/harbour/source/compiler/genhrb.c b/harbour/source/compiler/genhrb.c new file mode 100644 index 0000000000..2e862b804e --- /dev/null +++ b/harbour/source/compiler/genhrb.c @@ -0,0 +1,383 @@ +/* + * $Id$ + */ + +/* + Harbour Project source code + + Harbour HRB (Portable Object) Generation. + + Copyright 1999 Eddie Runia + www - http://www.harbour-project.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version, with one exception: + + The exception is that if you link the Harbour Runtime Library (HRL) + and/or the Harbour Virtual Machine (HVM) with other files to produce + an executable, this does not by itself cause the resulting executable + to be covered by the GNU General Public License. Your use of that + executable is in no way restricted on account of linking the HRL + and/or HVM code into it. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit + their web site at http://www.gnu.org/). +*/ + +#include "extend.h" +#include "compiler.h" +#include "pcode.h" + +#define SYM_NOLINK 0 /* Symbol does not have to be linked */ +#define SYM_FUNC 1 /* Defined function */ +#define SYM_EXTERN 2 /* Previously defined function */ + +void GenPortObj( char * szFileName, char * szName ) +{ + PFUNCTION pFunc /*= functions.pFirst */; + PCOMSYMBOL pSym = symbols.pFirst; + WORD w, wLen, wVar; + LONG lPCodePos; + LONG lPad; + LONG lSymbols; + BOOL bEndProcReq; + ULONG ulCodeLength; + FILE * yyc; /* file handle for C output */ + + HB_SYMBOL_UNUSED( szName ); + + yyc = fopen( szFileName, "wb" ); + if( ! yyc ) + { + printf( "Error opening file %s\n", szFileName ); + return; + } + + if( ! _bQuiet ) + printf( "\nGenerating portable object...\n" ); + + /* writes the symbol table */ + + if( ! _bStartProc ) + pSym = pSym->pNext; /* starting procedure is always the first symbol */ + + lSymbols = 0; /* Count number of symbols */ + while( pSym ) + { + lSymbols++; + pSym = pSym->pNext; + } + fputc( ( BYTE ) ( ( lSymbols ) & 255 ), yyc ); /* Write number symbols */ + fputc( ( BYTE ) ( ( lSymbols >> 8 ) & 255 ), yyc ); + fputc( ( BYTE ) ( ( lSymbols >> 16 ) & 255 ), yyc ); + fputc( ( BYTE ) ( ( lSymbols >> 24 ) & 255 ), yyc ); + + pSym = symbols.pFirst; + if( ! _bStartProc ) + pSym = pSym->pNext; /* starting procedure is always the first symbol */ + + while( pSym ) + { + fputs( pSym->szName, yyc ); + fputc( 0, yyc ); + if( pSym->cScope != FS_MESSAGE ) + fputc( pSym->cScope, yyc ); + else + fputc( 0, yyc ); + + /* specify the function address if it is a defined function or a + external called function */ + if( GetFunction( pSym->szName ) ) /* is it a defined function ? */ + { + fputc( SYM_FUNC, yyc ); + } + else + { + if( GetFuncall( pSym->szName ) ) + { + fputc( SYM_EXTERN, yyc ); + } + else + { + fputc( SYM_NOLINK, yyc ); + } + } + pSym = pSym->pNext; + } + + pFunc = functions.pFirst; + if( ! _bStartProc ) + pFunc = pFunc->pNext; + + lSymbols = 0; /* Count number of symbols */ + while( pFunc ) + { + lSymbols++; + pFunc = pFunc->pNext; + } + fputc( ( BYTE ) ( ( lSymbols ) & 255 ), yyc ); /* Write number symbols */ + fputc( ( BYTE ) ( ( lSymbols >> 8 ) & 255 ), yyc ); + fputc( ( BYTE ) ( ( lSymbols >> 16 ) & 255 ), yyc ); + fputc( ( BYTE ) ( ( lSymbols >> 24 ) & 255 ), yyc ); + + /* Generate functions data + */ + pFunc = functions.pFirst; + if( ! _bStartProc ) + pFunc = pFunc->pNext; /* No implicit starting procedure */ + + while( pFunc ) + { + fputs( pFunc->szName, yyc ); + fputc( 0, yyc ); + /* We will have to add HB_P_ENDPROC in cases when RETURN statement + * was not used in a function/procedure - this is why we have to reserve + * one additional byte + */ + ulCodeLength = pFunc->lPCodePos + 1; + fputc( ( BYTE ) ( ( ulCodeLength ) & 255 ), yyc ); /* Write size */ + fputc( ( BYTE ) ( ( ulCodeLength >> 8 ) & 255 ), yyc ); + fputc( ( BYTE ) ( ( ulCodeLength >> 16 ) & 255 ), yyc ); + fputc( ( BYTE ) ( ( ulCodeLength >> 24 ) & 255 ), yyc ); + +/* printf( "Creating output for %s\n", pFunc->szName ); */ + + lPCodePos = 0; + lPad = 0; /* Number of bytes optimized */ + bEndProcReq = TRUE; + while( lPCodePos < pFunc->lPCodePos ) + { + switch( pFunc->pCode[ lPCodePos ] ) + { + case HB_P_AND: + case HB_P_ARRAYAT: + case HB_P_ARRAYPUT: + case HB_P_DEC: + case HB_P_DIVIDE: + case HB_P_DUPLICATE: + case HB_P_DUPLTWO: + case HB_P_ENDBLOCK: + case HB_P_EQUAL: + case HB_P_EXACTLYEQUAL: + case HB_P_FALSE: + case HB_P_FORTEST: + case HB_P_FUNCPTR: + case HB_P_GREATER: + case HB_P_GREATEREQUAL: + case HB_P_INC: + case HB_P_INSTRING: + case HB_P_LESS: + case HB_P_LESSEQUAL: + case HB_P_MINUS: + case HB_P_MODULUS: + case HB_P_MULT: + case HB_P_NEGATE: + case HB_P_NOT: + case HB_P_NOTEQUAL: + case HB_P_OR: + case HB_P_PLUS: + case HB_P_POP: + case HB_P_POPALIAS: + case HB_P_POWER: + case HB_P_PUSHALIAS: + case HB_P_PUSHNIL: + case HB_P_PUSHSELF: + case HB_P_RETVALUE: + case HB_P_SWAPALIAS: + case HB_P_SEQRECOVER: + case HB_P_TRUE: + case HB_P_ZERO: + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + break; + + case HB_P_DIMARRAY: + case HB_P_DO: + case HB_P_FUNCTION: + case HB_P_GENARRAY: + case HB_P_JUMP: + case HB_P_JUMPFALSE: + case HB_P_JUMPTRUE: + case HB_P_LINE: + case HB_P_POPLOCAL: + case HB_P_POPSTATIC: + case HB_P_PUSHINT: + case HB_P_PUSHLOCAL: + case HB_P_PUSHLOCALREF: + case HB_P_PUSHSTATIC: + case HB_P_PUSHSTATICREF: + case HB_P_SEQBEGIN: + case HB_P_SEQEND: + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + break; + + case HB_P_ENDPROC: + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + if( lPCodePos == pFunc->lPCodePos ) + bEndProcReq = FALSE; + break; + + case HB_P_FRAME: + /* update the number of local variables */ + { + PVAR pLocal = pFunc->pLocals; + BYTE bLocals = 0; + + while( pLocal ) + { + pLocal = pLocal->pNext; + bLocals++; + } + + if( bLocals || pFunc->wParamCount ) + { + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( ( BYTE )( bLocals - pFunc->wParamCount ), yyc ); + fputc( ( BYTE )( pFunc->wParamCount ), yyc ); + lPCodePos += 2; + } + else + { + lPad += 3; + lPCodePos += 3; + } + } + break; + + case HB_P_PUSHSYM: + case HB_P_MESSAGE: + case HB_P_POPMEMVAR: + case HB_P_PUSHMEMVAR: + case HB_P_PUSHMEMVARREF: + case HB_P_POPFIELD: + case HB_P_PUSHFIELD: + case HB_P_POPALIASEDFIELD: + case HB_P_PUSHALIASEDFIELD: + fputc( pFunc->pCode[ lPCodePos ], yyc ); + wVar = FixSymbolPos( pFunc->pCode[ lPCodePos + 1 ] + 256 * pFunc->pCode[ lPCodePos + 2 ] ); + fputc( LOBYTE( wVar ), yyc ); + fputc( HIBYTE( wVar ), yyc ); + lPCodePos += 3; + break; + + case HB_P_PARAMETER: + fputc( pFunc->pCode[ lPCodePos ], yyc ); + wVar = FixSymbolPos( pFunc->pCode[ lPCodePos + 1 ] + 256 * pFunc->pCode[ lPCodePos + 2 ] ); + fputc( LOBYTE( wVar ), yyc ); + fputc( HIBYTE( wVar ), yyc ); + fputc( pFunc->pCode[ lPCodePos + 3 ], yyc ); + lPCodePos +=4; + break; + + case HB_P_PUSHBLOCK: + wVar = * ( ( WORD * ) &( pFunc->pCode [ lPCodePos + 5 ] ) ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + /* create the table of referenced local variables */ + while( wVar-- ) + { + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + } + break; + + case HB_P_PUSHDOUBLE: + { + int i; + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + for( i = 0; i < sizeof( double ); ++i ) + fputc( ( ( BYTE * ) pFunc->pCode )[ lPCodePos + i ], yyc ); + fputc( pFunc->pCode[ lPCodePos + sizeof( double ) ], yyc ); + lPCodePos += sizeof( double ) + 1; + } + break; + + case HB_P_PUSHLONG: + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + break; + + case HB_P_PUSHSTR: + wLen = pFunc->pCode[ lPCodePos + 1 ] + + pFunc->pCode[ lPCodePos + 2 ] * 256; + fputc( pFunc->pCode[ lPCodePos ], yyc ); + fputc( pFunc->pCode[ lPCodePos + 1 ], yyc ); + fputc( pFunc->pCode[ lPCodePos + 2 ], yyc ); + lPCodePos += 3; + while( wLen-- ) + fputc( pFunc->pCode[ lPCodePos++ ], yyc ); + break; + + case HB_P_SFRAME: + /* we only generate it if there are statics used in this function */ + if( pFunc->bFlags & FUN_USES_STATICS ) + { + GetSymbol( _pInitFunc->szName, &w ); + w = FixSymbolPos( w ); + fputc( pFunc->pCode[ lPCodePos ], yyc ); + fputc( LOBYTE( w ), yyc ); + fputc( HIBYTE( w ), yyc ); + } + else + lPad += 3; + lPCodePos += 3; + break; + + case HB_P_STATICS: + GetSymbol( _pInitFunc->szName, &w ); + w = FixSymbolPos( w ); + fputc( pFunc->pCode[ lPCodePos ], yyc ); + fputc( LOBYTE( w ), yyc ); + fputc( HIBYTE( w ), yyc ); + lPCodePos += 3; + break; + + default: + printf( "Incorrect pcode value: %u\n", pFunc->pCode[ lPCodePos ] ); + lPCodePos = pFunc->lPCodePos; + break; + } + } + + if( bEndProcReq ) + fputc( HB_P_ENDPROC, yyc ); + else + { + /* HB_P_ENDPROC was the last opcode: we have to fill the byte + * reserved earlier + */ + lPad++; + } + for( ; lPad; lPad-- ) + { + /* write additional bytes to agree with stored earlier + * function/procedure size + */ + fputc( 0, yyc ); + } + pFunc = pFunc->pNext; + } + + fclose( yyc ); + + if( ! _bQuiet ) + printf( "%s -> done!\n", szFileName ); +} diff --git a/harbour/source/compiler/genjava.c b/harbour/source/compiler/genjava.c new file mode 100644 index 0000000000..cd6f568025 --- /dev/null +++ b/harbour/source/compiler/genjava.c @@ -0,0 +1,44 @@ +/* + * $Id$ + */ + +/* + Harbour Project source code + + Harbour RC Generation. + + Copyright 1999 Antonio Linares + www - http://www.harbour-project.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version, with one exception: + + The exception is that if you link the Harbour Runtime Library (HRL) + and/or the Harbour Virtual Machine (HVM) with other files to produce + an executable, this does not by itself cause the resulting executable + to be covered by the GNU General Public License. Your use of that + executable is in no way restricted on account of linking the HRL + and/or HVM code into it. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit + their web site at http://www.gnu.org/). +*/ + +#include "extend.h" +#include "compiler.h" +#include "pcode.h" + +void GenJava( char * szFileName, char * szName ) +{ + printf( "\nGenerating Java language output...\n" ); + printf( "%s -> not implemented yet! %s\n", szFileName, szName ); +} diff --git a/harbour/source/compiler/genobj32.c b/harbour/source/compiler/genobj32.c index 313b0e0d7c..6fdc797af9 100644 --- a/harbour/source/compiler/genobj32.c +++ b/harbour/source/compiler/genobj32.c @@ -59,11 +59,6 @@ static void GenerateCodeSegment( FILE * hObjFile ); static void GenerateDataSegment( FILE * hObjFile ); static void GenerateSymbolsSegment( FILE * hObjFile ); -extern FUNCTIONS functions, funcalls; -extern SYMBOLS symbols; -extern BOOL _bQuiet; -extern BOOL _bStartProc; - static BYTE prgFunction[] = { 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x83, 0xC4, 0x08, 0xC3 }; diff --git a/harbour/source/compiler/genpas.c b/harbour/source/compiler/genpas.c new file mode 100644 index 0000000000..9fd23a8d15 --- /dev/null +++ b/harbour/source/compiler/genpas.c @@ -0,0 +1,44 @@ +/* + * $Id$ + */ + +/* + Harbour Project source code + + Harbour Pascal Generation. + + Copyright 1999 Antonio Linares + www - http://www.harbour-project.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version, with one exception: + + The exception is that if you link the Harbour Runtime Library (HRL) + and/or the Harbour Virtual Machine (HVM) with other files to produce + an executable, this does not by itself cause the resulting executable + to be covered by the GNU General Public License. Your use of that + executable is in no way restricted on account of linking the HRL + and/or HVM code into it. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit + their web site at http://www.gnu.org/). +*/ + +#include "extend.h" +#include "compiler.h" +#include "pcode.h" + +void GenPascal( char * szFileName, char * szName ) +{ + printf( "\nGenerating Pascal language output...\n" ); + printf( "%s -> not implemented yet! %s\n", szFileName, szName ); +} diff --git a/harbour/source/compiler/genrc.c b/harbour/source/compiler/genrc.c new file mode 100644 index 0000000000..0516b335a6 --- /dev/null +++ b/harbour/source/compiler/genrc.c @@ -0,0 +1,44 @@ +/* + * $Id$ + */ + +/* + Harbour Project source code + + Harbour RC Generation. + + Copyright 1999 Antonio Linares + www - http://www.harbour-project.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version, with one exception: + + The exception is that if you link the Harbour Runtime Library (HRL) + and/or the Harbour Virtual Machine (HVM) with other files to produce + an executable, this does not by itself cause the resulting executable + to be covered by the GNU General Public License. Your use of that + executable is in no way restricted on account of linking the HRL + and/or HVM code into it. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit + their web site at http://www.gnu.org/). +*/ + +#include "extend.h" +#include "compiler.h" +#include "pcode.h" + +void GenRC( char * szFileName, char * szName ) +{ + printf( "\nGenerating resources output...\n" ); + printf( "%s -> not implemented yet! %s\n", szFileName, szName ); +} diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 809a43c2b5..21d4be9495 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -85,15 +85,6 @@ typedef struct int Include( char * szFileName, PATHNAMES * pSearchPath ); /* end #include support */ -/* - * flags for bFlags member -*/ -#define FUN_STATEMENTS 1 /* Function have at least one executable statement */ -#define FUN_USES_STATICS 2 /* Function uses static variables */ -#define FUN_PROCEDURE 4 /* This is a procedure that shouldn't return value */ -#define FUN_ILLEGAL_INIT 8 /* Attempt to initialize static variable with a function call */ -#define FUN_USES_LOCAL_PARAMS 16 /* parameters are declared using () */ - /* pcode chunks bytes size */ #define PCODE_CHUNK 100 @@ -179,24 +170,6 @@ int yywrap( void ); /* manages the EOF of current processed file */ /* Following line added for preprocessor */ void Hbpp_init ( void ); -#ifdef __cplusplus -typedef struct yy_buffer_state *YY_BUFFER_STATE; -YY_BUFFER_STATE yy_create_buffer( FILE *, int ); /* yacc functions to manage multiple files */ -void yy_switch_to_buffer( YY_BUFFER_STATE ); /* yacc functions to manage multiple files */ -void yy_delete_buffer( YY_BUFFER_STATE ); /* yacc functions to manage multiple files */ -#else -void * yy_create_buffer( FILE *, int ); /* yacc functions to manage multiple files */ -void yy_switch_to_buffer( void * ); /* yacc functions to manage multiple files */ -void yy_delete_buffer( void * ); /* yacc functions to manage multiple files */ -#endif - -char * yy_strdup( char * p ); /* this will exit if there is not enough memory */ -char *yy_strupr( char * p ); - -#if 0 -static void __yy_memcpy( char * from, char * to, int count ); /* Bison prototype */ -#endif - /* production related functions */ PFUNCTION AddFunCall( char * szFuntionName ); void AddExtern( char * szExternName ); /* defines a new extern name */ @@ -212,7 +185,6 @@ void DupPCode( ULONG ulStart ); /* duplicates the current generated pcode from a void FieldPCode( BYTE , char * ); /* generates the pcode for database field */ void FixElseIfs( void * pIfElseIfs ); /* implements the ElseIfs pcode fixups */ void FixReturns( void ); /* fixes all last defined function returns jumps offsets */ -WORD FixSymbolPos( WORD ); /* converts symbol's compile-time position into generation-time position */ void Function( BYTE bParams ); /* generates the pcode to execute a Clipper function pushing its result */ PFUNCTION FunctionNew( char *, char ); /* creates and initialises the _FUNC structure */ void FunDef( char * szFunName, SYMBOLSCOPE cScope, int iType ); /* starts a new Clipper language function definition */ @@ -221,21 +193,15 @@ void GenBreak( void ); /* generate code for BREAK statement */ void * GenElseIf( void * pFirstElseIf, ULONG ulOffset ); /* generates a support structure for elseifs pcode fixups */ void GenExterns( void ); /* generates the symbols for the EXTERN names */ void GenIfInline( void ); /* generates pcodes for IIF( expr1, expr2, expr3 ) */ -PFUNCTION GetFuncall( char * szFunName ); /* locates a previously defined called function */ int GetFieldVarPos( char *, PFUNCTION * ); /* return if passed name is a field variable */ -PVAR GetVar( PVAR pVars, WORD wOrder ); /* returns a variable if defined or zero */ WORD GetVarPos( PVAR pVars, char * szVarName ); /* returns the order + 1 of a variable if defined or zero */ int GetLocalVarPos( char * szVarName ); /* returns the order + 1 of a local variable */ -PCOMSYMBOL GetSymbol( char *, WORD * ); /* returns a symbol pointer from the symbol table */ -PCOMSYMBOL GetSymbolOrd( WORD ); /* returns a symbol based on its index on the symbol table */ void Inc( void ); /* generates the pcode to increment the latest value on the virtual machine stack */ ULONG Jump( LONG lOffset ); /* generates the pcode to jump to a specific offset */ ULONG JumpFalse( LONG lOffset ); /* generates the pcode to jump if false */ void JumpHere( ULONG ulOffset ); /* returns the pcode pos where to set a jump offset */ void JumpThere( ULONG ulFrom, ULONG ulTo ); /* sets a jump offset */ ULONG JumpTrue( LONG lOffset ); /* generates the pcode to jump if true */ -PFUNCTION KillFunction( PFUNCTION ); /* releases all memory allocated by function and returns the next one */ -PCOMSYMBOL KillSymbol( PCOMSYMBOL ); /* releases all memory allocated by symbol and returns the next one */ void Line( void ); /* generates the pcode with the currently compiled source code line */ void LineDebug( void ); /* generates the pcode with the currently compiled source code line */ void LineBody( void ); /* generates the pcode with the currently compiled source code line */ @@ -276,13 +242,13 @@ void StaticDefEnd( int ); void StaticAssign( void ); /* checks if static variable is initialized with function call */ /* output related functions */ -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 */ -void GenPortObj( char *, char * ); /* generates the portable objects */ +extern void GenCCode( char *, char * ); /* generates the C language output */ +extern void GenJava( char *, char * ); /* generates the Java language output */ +extern void GenPascal( char *, char * ); /* generates the Pascal language output */ +extern void GenRC( char *, char * ); /* generates the RC language output */ +extern void GenPortObj( char *, char * ); /* generates the portable objects */ #ifdef HARBOUR_OBJ_GENERATION -void GenObj32( char *, char * ); /* generates OBJ 32 bits */ +extern void GenObj32( char *, char * ); /* generates OBJ 32 bits */ #endif /* argument checking */ @@ -301,13 +267,6 @@ typedef enum LANG_PORT_OBJ /* Portable objects */ } LANGUAGES; /* supported Harbour output languages */ -#define VS_LOCAL 1 -#define VS_STATIC 2 -#define VS_FIELD 4 -#define VS_PARAMETER 8 -#define VS_PRIVATE 64 -#define VS_PUBLIC 128 -#define VS_MEMVAR ( VS_PUBLIC | VS_PRIVATE ) int iVarScope = VS_LOCAL; /* holds the scope for next variables to be defined */ /* different values for iVarScope */ @@ -2546,925 +2505,6 @@ void FunDef( char * szFunName, SYMBOLSCOPE cScope, int iType ) } } -void GenJava( char * szFileName, char * szName ) -{ - printf( "\nGenerating Java language output...\n" ); - printf( "%s -> not implemented yet! %s\n", szFileName, szName ); -} - -void GenPascal( char * szFileName, char * szName ) -{ - printf( "\nGenerating Pascal language output...\n" ); - printf( "%s -> not implemented yet! %s\n", szFileName, szName ); -} - -void GenRC( char * szFileName, char * szName ) -{ - printf( "\nGenerating resources output...\n" ); - printf( "%s -> not implemented yet! %s\n", szFileName, szName ); -} - -void GenCCode( char * szFileName, char * szName ) /* generates the C language output */ -{ - PFUNCTION pFunc = functions.pFirst, pFTemp; - PCOMSYMBOL pSym = symbols.pFirst; - WORD w, wLen, wSym, wVar; - WORD iNestedCodeblock = 0; - ULONG lPCodePos; - char chr; - BOOL bEndProcRequired; - - - FILE * yyc; /* file handle for C output */ - - HB_SYMBOL_UNUSED( szName ); - - yyc = fopen( szFileName, "wb" ); - if( ! yyc ) - { - printf( "Error opening file %s\n", szFileName ); - return; - } - - if( ! _bQuiet ) - printf( "\nGenerating C language output...\n" ); - - fprintf( yyc, "/* Harbour compiler generated code */\n\n" ); - fprintf( yyc, "#include \"hb_vmpub.h\"\n" ); - fprintf( yyc, "#include \"init.h\"\n\n\n" ); - - if( ! _bStartProc ) - pFunc = pFunc->pNext; /* No implicit starting procedure */ - - /* write functions prototypes for PRG defined functions */ - while( pFunc ) - { - if( pFunc->cScope & FS_STATIC || pFunc->cScope & FS_INIT || pFunc->cScope & FS_EXIT ) - fprintf( yyc, "static " ); - - if( pFunc == _pInitFunc ) - fprintf( yyc, "HARBOUR hb_INITSTATICS( void );\n" ); /* NOTE: hb_ intentionally in lower case */ - else - fprintf( yyc, "HARBOUR HB_%s( void );\n", pFunc->szName ); - pFunc = pFunc->pNext; - } - /* write functions prototypes for called functions outside this PRG */ - pFunc = funcalls.pFirst; - while( pFunc ) - { - pFTemp = GetFunction( pFunc->szName ); - if( ! pFTemp || pFTemp == functions.pFirst ) - fprintf( yyc, "HARBOUR HB_%s( void );\n", pFunc->szName ); - pFunc = pFunc->pNext; - } - - /* writes the symbol table */ - /* Generate the wrapper that will initialize local symbol table - */ - yy_strupr( _pFileName->szName ); - fprintf( yyc, "\n\nHB_INIT_SYMBOLS_BEGIN( hb_vm_SymbolInit_%s%s )\n", _szPrefix, _pFileName->szName ); - - if( ! _bStartProc ) - pSym = pSym->pNext; /* starting procedure is always the first symbol */ - - wSym = 0; /* symbols counter */ - while( pSym ) - { - if( pSym->szName[ 0 ] == '(' ) - { - /* Since the normal function cannot be INIT and EXIT at the same time - * we are using these two bits to mark the special function used to - * initialize static variables - */ - fprintf( yyc, "{ \"(_INITSTATICS)\", FS_INIT | FS_EXIT, hb_INITSTATICS, 0}" ); /* NOTE: hb_ intentionally in lower case */ - } - else - { - fprintf( yyc, "{ \"%s\", ", pSym->szName ); - - if( pSym->cScope & FS_STATIC ) - fprintf( yyc, "FS_STATIC" ); - - else if( pSym->cScope & FS_INIT ) - fprintf( yyc, "FS_INIT" ); - - else if( pSym->cScope & FS_EXIT ) - fprintf( yyc, "FS_EXIT" ); - - else - fprintf( yyc, "FS_PUBLIC" ); - - if( pSym->cScope & VS_MEMVAR ) - fprintf( yyc, " | FS_MEMVAR" ); - - if( ( pSym->cScope != FS_MESSAGE ) && ( pSym->cScope & FS_MESSAGE ) ) /* only for non public symbols */ - fprintf( yyc, " | FS_MESSAGE" ); - - /* specify the function address if it is a defined function or an - external called function */ - if( GetFunction( pSym->szName ) ) /* is it a function defined in this module */ - fprintf( yyc, ", HB_%s, 0 }", pSym->szName ); - else if( GetFuncall( pSym->szName ) ) /* is it a function called from this module */ - fprintf( yyc, ", HB_%s, 0 }", pSym->szName ); - else - fprintf( yyc, ", 0, 0 }" ); /* memvar */ - } - ++wSym; - - if( pSym != symbols.pLast ) - fprintf( yyc, ",\n" ); - - pSym = pSym->pNext; - } - fprintf( yyc, "\nHB_INIT_SYMBOLS_END( hb_vm_SymbolInit_%s%s )\n", _szPrefix, _pFileName->szName ); - fprintf( yyc, "#if ! defined(__GNUC__)\n #pragma startup hb_vm_SymbolInit_%s%s\n#endif\n\n\n", _szPrefix, _pFileName->szName ); - - /* Generate functions data - */ - pFunc = functions.pFirst; - if( ! _bStartProc ) - pFunc = pFunc->pNext; /* No implicit starting procedure */ - while( pFunc ) - { - if( pFunc->cScope != FS_PUBLIC ) - fprintf( yyc, "static " ); - - if( pFunc == _pInitFunc ) /* Is it (_INITSTATICS) */ - fprintf( yyc, "HARBOUR hb_INITSTATICS( void )\n{\n static BYTE pcode[] = { \n" ); /* NOTE: hb_ intentionally in lower case */ - else - fprintf( yyc, "HARBOUR HB_%s( void )\n{\n static BYTE pcode[] = { \n", pFunc->szName ); - - bEndProcRequired = TRUE; - lPCodePos = 0; - while( lPCodePos < pFunc->lPCodePos ) - { - switch( pFunc->pCode[ lPCodePos ] ) - { - case HB_P_AND: - fprintf( yyc, "\t\tHB_P_AND,\n" ); - lPCodePos++; - break; - - case HB_P_ARRAYAT: - fprintf( yyc, "\t\tHB_P_ARRAYAT,\n" ); - lPCodePos++; - break; - - case HB_P_ARRAYPUT: - fprintf( yyc, "\t\tHB_P_ARRAYPUT,\n" ); - lPCodePos++; - break; - - case HB_P_DEC: - fprintf( yyc, "\t\tHB_P_DEC,\n" ); - lPCodePos++; - break; - - case HB_P_DIMARRAY: - w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, "\t\tHB_P_DIMARRAY, %i, %i,\t/* %i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], w ); - lPCodePos += 3; - break; - - case HB_P_DIVIDE: - fprintf( yyc, "\t\tHB_P_DIVIDE,\n" ); - lPCodePos++; - break; - - case HB_P_DO: - fprintf( yyc, "\t\tHB_P_DO, %i, %i,\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ] ); - lPCodePos += 3; - break; - - case HB_P_DUPLICATE: - fprintf( yyc, "\t\tHB_P_DUPLICATE,\n" ); - lPCodePos++; - break; - - case HB_P_DUPLTWO: - fprintf( yyc, "\t\tHB_P_DUPLTWO,\n" ); - lPCodePos++; - break; - - case HB_P_EQUAL: - fprintf( yyc, "\t\tHB_P_EQUAL,\n" ); - lPCodePos++; - break; - - case HB_P_EXACTLYEQUAL: - fprintf( yyc, "\t\tHB_P_EXACTLYEQUAL,\n" ); - lPCodePos++; - break; - - case HB_P_ENDBLOCK: - --iNestedCodeblock; - fprintf( yyc, "\t\tHB_P_ENDBLOCK,\n" ); - lPCodePos++; - break; - - case HB_P_ENDPROC: - lPCodePos++; - if( lPCodePos == pFunc->lPCodePos ) - { - bEndProcRequired = FALSE; - fprintf( yyc, "\t\tHB_P_ENDPROC\n" ); - } - else - fprintf( yyc, "\t\tHB_P_ENDPROC,\n" ); - break; - - case HB_P_FALSE: - fprintf( yyc, "\t\tHB_P_FALSE,\n" ); - lPCodePos++; - break; - - case HB_P_FORTEST: /* ER For tests. Step > 0 LESS */ - /* Step < 0 GREATER */ - fprintf( yyc, "\t\tHB_P_FORTEST,\n" ); - lPCodePos++; - break; - - case HB_P_FRAME: - { - PVAR pLocal = pFunc->pLocals; - BYTE bLocals = 0; - - while( pLocal ) - { - pLocal = pLocal->pNext; - bLocals++; - } - - if( bLocals || pFunc->wParamCount ) - fprintf( yyc, "\t\tHB_P_FRAME, %i, %i,\t/* locals, params */\n", - bLocals - pFunc->wParamCount, - pFunc->wParamCount ); - lPCodePos += 3; - } - break; - - case HB_P_FUNCPTR: - fprintf( yyc, "\t\tHB_P_FUNCPTR,\n" ); - lPCodePos++; - break; - - case HB_P_FUNCTION: - fprintf( yyc, "\t\tHB_P_FUNCTION, %i, %i,\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ] ); - lPCodePos += 3; - break; - - case HB_P_GENARRAY: - w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, "\t\tHB_P_GENARRAY, %i, %i,\t/* %i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], w ); - lPCodePos += 3; - break; - - case HB_P_GREATER: - fprintf( yyc, "\t\tHB_P_GREATER,\n" ); - lPCodePos++; - break; - - case HB_P_GREATEREQUAL: - fprintf( yyc, "\t\tHB_P_GREATEREQUAL,\n" ); - lPCodePos++; - break; - - case HB_P_INC: - fprintf( yyc, "\t\tHB_P_INC,\n" ); - lPCodePos++; - break; - - case HB_P_INSTRING: - fprintf( yyc, "\t\tHB_P_INSTRING,\n" ); - lPCodePos++; - break; - - case HB_P_JUMP: - /* if( 1 ) ( lPCodePos + 3 ) < pFunc->lPCodePos ) */ - { - w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, "\t\tHB_P_JUMP, %i, %i,\t/* %i (abs: %05li) */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], w, lPCodePos + ( w ? w: 3 ) ); - } - lPCodePos += 3; - break; - - case HB_P_JUMPFALSE: - w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, "\t\tHB_P_JUMPFALSE, %i, %i,\t/* %i (abs: %05li) */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], w, lPCodePos + ( w ? w: 3 ) ); - lPCodePos += 3; - break; - - case HB_P_JUMPTRUE: - w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, "\t\tHB_P_JUMPTRUE, %i, %i,\t/* %i (abs: %05li) */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], w, lPCodePos + ( w ? w: 3 ) ); - lPCodePos += 3; - break; - - case HB_P_LESS: - fprintf( yyc, "\t\tHB_P_LESS,\n" ); - lPCodePos++; - break; - - case HB_P_LESSEQUAL: - fprintf( yyc, "\t\tHB_P_LESSEQUAL,\n" ); - lPCodePos++; - break; - - case HB_P_LINE: - fprintf( yyc, "/* %05li */", lPCodePos ); - w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, " HB_P_LINE, %i, %i,\t\t/* %i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], w ); - lPCodePos += 3; - break; - - case HB_P_LOCALNAME: - fprintf( yyc, "\t\tHB_P_LOCALNAME, %i, %i,\t/* %s */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - ( char * ) pFunc->pCode + lPCodePos + 3 ); - lPCodePos += 3; - while( pFunc->pCode[ lPCodePos ] ) - { - chr = pFunc->pCode[ lPCodePos++ ]; - if( chr == '\'' || chr == '\\') - fprintf( yyc, " \'\\%c\',", chr ); - else - fprintf( yyc, " \'%c\',", chr ); - } - fprintf( yyc, " 0,\n" ); - lPCodePos++; - break; - - case HB_P_MESSAGE: - { - WORD wFixPos; - - wSym = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - wFixPos = FixSymbolPos( wSym ); - fprintf( yyc, "\t\tHB_P_MESSAGE, %i, %i,\t/* %s */\n", - LOBYTE( wFixPos ), - HIBYTE( wFixPos ), - GetSymbolOrd( wSym )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_MINUS: - fprintf( yyc, "\t\tHB_P_MINUS,\n" ); - lPCodePos++; - break; - - case HB_P_MODULENAME: - fprintf( yyc, "\t\tHB_P_MODULENAME,\t/* %s */\n", - ( char * ) pFunc->pCode + lPCodePos++ + 1 ); - while( pFunc->pCode[ lPCodePos ] ) - { - chr = pFunc->pCode[ lPCodePos++ ]; - if( chr == '\'' || chr == '\\') - fprintf( yyc, " \'\\%c\',", chr ); - else - fprintf( yyc, " \'%c\',", chr ); - } - fprintf( yyc, " 0,\n" ); - lPCodePos++; - break; - - case HB_P_MODULUS: - fprintf( yyc, "\t\tHB_P_MODULUS,\n" ); - lPCodePos++; - break; - - case HB_P_MULT: - fprintf( yyc, "\t\tHB_P_MULT,\n" ); - lPCodePos++; - break; - - case HB_P_NEGATE: - fprintf( yyc, "\t\tHB_P_NEGATE,\n" ); - lPCodePos++; - break; - - case HB_P_NOT: - fprintf( yyc, "\t\tHB_P_NOT,\n" ); - lPCodePos++; - break; - - case HB_P_NOTEQUAL: - fprintf( yyc, "\t\tHB_P_NOTEQUAL,\n" ); - lPCodePos++; - break; - - case HB_P_OR: - fprintf( yyc, "\t\tHB_P_OR,\n" ); - lPCodePos++; - break; - - case HB_P_PARAMETER: - { - WORD wFixPos; - - wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - wFixPos = FixSymbolPos( wVar ); - fprintf( yyc, "\t\tHB_P_PARAMETER, %i, %i, %i,\t/* %s */\n", - LOBYTE( wFixPos ), - HIBYTE( wFixPos ), - pFunc->pCode[ lPCodePos + 3 ], - GetSymbolOrd( wVar )->szName ); - lPCodePos += 4; - } - break; - - case HB_P_PLUS: - fprintf( yyc, "\t\tHB_P_PLUS,\n" ); - lPCodePos++; - break; - - case HB_P_POP: - fprintf( yyc, "\t\tHB_P_POP,\n" ); - lPCodePos++; - break; - - case HB_P_POPALIAS: - fprintf( yyc, "\t\tHB_P_POPALIAS,\n" ); - lPCodePos++; - break; - - case HB_P_POPALIASEDFIELD: - { - WORD wFixPos; - - wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - wFixPos = FixSymbolPos( wVar ); - fprintf( yyc, "\t\tHB_P_POPALIASEDFIELD, %i, %i,\t/* %s */\n", - LOBYTE( wFixPos ), - HIBYTE( wFixPos ), - GetSymbolOrd( wVar )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_POPFIELD: - { - WORD wFixPos; - - wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - wFixPos = FixSymbolPos( wVar ); - fprintf( yyc, "\t\tHB_P_POPFIELD, %i, %i,\t/* %s */\n", - LOBYTE( wFixPos ), - HIBYTE( wFixPos ), - GetSymbolOrd( wVar )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_POPLOCAL: - { - SHORT wVar = * ( ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ] ); - /* Variable with negative order are local variables - * referenced in a codeblock -handle it with care - */ - if( iNestedCodeblock ) - { - /* we are accesing variables within a codeblock */ - /* the names of codeblock variable are lost */ - if( wVar < 0 ) - fprintf( yyc, "\t\tHB_P_POPLOCAL, %i, %i,\t/* localvar%i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - -wVar ); - else - fprintf( yyc, "\t\tHB_P_POPLOCAL, %i, %i,\t/* codeblockvar%i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - wVar ); - } - else - fprintf( yyc, "\t\tHB_P_POPLOCAL, %i, %i,\t/* %s */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - GetVar( pFunc->pLocals, wVar )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_POPMEMVAR: - { - WORD wFixPos; - - wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - wFixPos = FixSymbolPos( wVar ); - fprintf( yyc, "\t\tHB_P_POPMEMVAR, %i, %i,\t/* %s */\n", - LOBYTE( wFixPos ), - HIBYTE( wFixPos ), - GetSymbolOrd( wVar )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_POPSTATIC: - { - PVAR pVar; - PFUNCTION pTmp = functions.pFirst; - - wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - while( pTmp->pNext && pTmp->pNext->iStaticsBase < wVar ) - pTmp = pTmp->pNext; - pVar = GetVar( pTmp->pStatics, wVar - pTmp->iStaticsBase ); - fprintf( yyc, "\t\tHB_P_POPSTATIC, %i, %i,\t/* %s */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - pVar->szName ); - lPCodePos += 3; - } - break; - - case HB_P_POWER: - fprintf( yyc, "\t\tHB_P_POWER,\n" ); - lPCodePos++; - break; - - case HB_P_PUSHALIAS: - fprintf( yyc, "\t\tHB_P_PUSHALIAS,\n" ); - lPCodePos++; - break; - - case HB_P_PUSHALIASEDFIELD: - { - WORD wFixPos; - - wVar = pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256; - wFixPos = FixSymbolPos( wVar ); - fprintf( yyc, "\t\tHB_P_PUSHALIASEDFIELD, %i, %i,\t/* %s */\n", - LOBYTE( wFixPos ), - HIBYTE( wFixPos ), - GetSymbolOrd( wVar )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_PUSHBLOCK: - ++iNestedCodeblock; - fprintf( yyc, "\t\tHB_P_PUSHBLOCK, %i, %i,\t/* %i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256 ); - w = * ( ( WORD * ) &( pFunc->pCode [ lPCodePos + 3 ] ) ); - fprintf( yyc, "\t\t%i, %i,\t/* number of local parameters (%i) */\n", - pFunc->pCode[ lPCodePos + 3 ], - pFunc->pCode[ lPCodePos + 4 ], w ); - wVar = * ( ( WORD * ) &( pFunc->pCode [ lPCodePos + 5 ] ) ); - fprintf( yyc, "\t\t%i, %i,\t/* number of local variables (%i) */\n", - pFunc->pCode[ lPCodePos + 5 ], - pFunc->pCode[ lPCodePos + 6 ], wVar ); - lPCodePos += 7; /* codeblock size + number of parameters + number of local variables */ - /* create the table of referenced local variables */ - while( wVar-- ) - { - w = * ( ( WORD * ) &( pFunc->pCode [ lPCodePos ] ) ); - fprintf( yyc, "\t\t%i, %i,\t/* %s */\n", - pFunc->pCode[ lPCodePos ], - pFunc->pCode[ lPCodePos + 1 ], - GetVar( pFunc->pLocals, w )->szName ); - lPCodePos +=2; - } - break; - - case HB_P_PUSHDOUBLE: - { - int i; - ++lPCodePos; - fprintf( yyc, "\t\tHB_P_PUSHDOUBLE, " ); - for( i = 0; i < sizeof( double ) + sizeof( BYTE ); ++i ) - fprintf( yyc, "%i,", ( ( BYTE * ) pFunc->pCode )[ lPCodePos + i ] ); - fprintf( yyc, "\t/* %.*f, %d */\n", - *( ( BYTE * ) &( pFunc->pCode[ lPCodePos + sizeof( double ) ] ) ), - *( ( double * ) &( pFunc->pCode[ lPCodePos ] ) ), - *( ( BYTE * ) &( pFunc->pCode[ lPCodePos + sizeof( double ) ] ) ) ); - lPCodePos += sizeof( double ) + sizeof( BYTE ); - } - break; - - case HB_P_PUSHFIELD: - { - WORD wFixPos; - - wVar = pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256; - wFixPos = FixSymbolPos( wVar ); - fprintf( yyc, "\t\tHB_P_PUSHFIELD, %i, %i,\t/* %s */\n", - LOBYTE( wFixPos ), - HIBYTE( wFixPos ), - GetSymbolOrd( wVar )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_PUSHINT: - fprintf( yyc, "\t\tHB_P_PUSHINT, %i, %i,\t/* %i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256 ); - lPCodePos += 3; - break; - - case HB_P_PUSHLOCAL: - { - SHORT wVar = * ( ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ] ); - /* Variable with negative order are local variables - * referenced in a codeblock -handle it with care - */ - if( iNestedCodeblock ) - { - /* we are accesing variables within a codeblock */ - /* the names of codeblock variable are lost */ - if( wVar < 0 ) - fprintf( yyc, "\t\tHB_P_PUSHLOCAL, %i, %i,\t/* localvar%i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - -wVar ); - else - fprintf( yyc, "\t\tHB_P_PUSHLOCAL, %i, %i,\t/* codeblockvar%i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - wVar ); - } - else - fprintf( yyc, "\t\tHB_P_PUSHLOCAL, %i, %i,\t/* %s */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - GetVar( pFunc->pLocals, wVar )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_PUSHLOCALREF: - { - SHORT wVar = * ( ( SHORT * ) &( pFunc->pCode )[ lPCodePos + 1 ] ); - /* Variable with negative order are local variables - * referenced in a codeblock -handle it with care - */ - if( iNestedCodeblock ) - { - /* we are accesing variables within a codeblock */ - /* the names of codeblock variable are lost */ - if( wVar < 0 ) - fprintf( yyc, "\t\tHB_P_PUSHLOCALREF, %i, %i,\t/* localvar%i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - -wVar ); - else - fprintf( yyc, "\t\tHB_P_PUSHLOCALREF, %i, %i,\t/* codeblockvar%i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - wVar ); - } - else - fprintf( yyc, "\t\tHB_P_PUSHLOCALREF, %i, %i,\t/* %s */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - GetVar( pFunc->pLocals, wVar )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_PUSHLONG: - fprintf( yyc, "\t\tHB_P_PUSHLONG, %i, %i, %i, %i,\t/* %li */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - pFunc->pCode[ lPCodePos + 3 ], - pFunc->pCode[ lPCodePos + 4 ], - *( ( long * ) &( pFunc->pCode[ lPCodePos + 1 ] ) ) ); - lPCodePos += ( 1 + sizeof( long ) ); - break; - - case HB_P_PUSHMEMVAR: - { - WORD wFixPos; - - wVar = pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256; - wFixPos = FixSymbolPos( wVar ); - fprintf( yyc, "\t\tHB_P_PUSHMEMVAR, %i, %i,\t/* %s */\n", - LOBYTE( wFixPos ), - HIBYTE( wFixPos ), - GetSymbolOrd( wVar )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_PUSHMEMVARREF: - { - WORD wFixPos; - - wVar = pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256; - wFixPos = FixSymbolPos( wVar ); - fprintf( yyc, "\t\tHB_P_PUSHMEMVARREF, %i, %i,\t/* %s */\n", - LOBYTE( wFixPos ), - HIBYTE( wFixPos ), - GetSymbolOrd( wVar )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_PUSHNIL: - fprintf( yyc, "\t\tHB_P_PUSHNIL,\n" ); - lPCodePos++; - break; - - case HB_P_PUSHSELF: - fprintf( yyc, "\t\tHB_P_PUSHSELF,\n" ); - lPCodePos++; - break; - - case HB_P_PUSHSTATIC: - { - PVAR pVar; - PFUNCTION pTmp = functions.pFirst; - - wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - while( pTmp->pNext && pTmp->pNext->iStaticsBase < wVar ) - pTmp = pTmp->pNext; - pVar = GetVar( pTmp->pStatics, wVar - pTmp->iStaticsBase ); - fprintf( yyc, "\t\tHB_P_PUSHSTATIC, %i, %i,\t/* %s */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - pVar->szName ); - lPCodePos += 3; - } - break; - - case HB_P_PUSHSTATICREF: - { - PVAR pVar; - PFUNCTION pTmp = functions.pFirst; - - wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - while( pTmp->pNext && pTmp->pNext->iStaticsBase < wVar ) - pTmp = pTmp->pNext; - pVar = GetVar( pTmp->pStatics, wVar - pTmp->iStaticsBase ); - fprintf( yyc, "\t\tHB_P_PUSHSTATICREF, %i, %i,\t/* %s */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], - pVar->szName ); - lPCodePos += 3; - } - break; - - case HB_P_PUSHSTR: - wLen = pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, "\t\tHB_P_PUSHSTR, %i, %i,\t/* %i */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], wLen ); - lPCodePos +=3; - while( wLen-- ) - { - chr = pFunc->pCode[ lPCodePos++ ]; - if( chr == '\'' || chr == '\\') - fprintf( yyc, " \'\\%c\',", chr ); - else - fprintf( yyc, " \'%c\',", chr ); - } - fprintf( yyc, "\n" ); - break; - - case HB_P_PUSHSYM: - { - WORD wFixPos; - - wSym = pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256; - wFixPos = FixSymbolPos( wSym ); - fprintf( yyc, "\t\tHB_P_PUSHSYM, %i, %i,\t/* %s */\n", - LOBYTE( wFixPos ), - HIBYTE( wFixPos ), - GetSymbolOrd( wSym )->szName ); - lPCodePos += 3; - } - break; - - case HB_P_RETVALUE: - fprintf( yyc, "\t\tHB_P_RETVALUE,\n" ); - lPCodePos++; - break; - - case HB_P_SEQBEGIN: - w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, "\t\tHB_P_SEQBEGIN, %i, %i,\t/* %i (abs: %05li) */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], w, lPCodePos + ( w ? w: 3 ) ); - lPCodePos += 3; - break; - - case HB_P_SEQEND: - fprintf( yyc, "/* %05li */", lPCodePos ); - w = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256; - fprintf( yyc, " HB_P_SEQEND, %i, %i,\t/* %i (abs: %05li) */\n", - pFunc->pCode[ lPCodePos + 1 ], - pFunc->pCode[ lPCodePos + 2 ], w, lPCodePos + ( w ? w: 3 ) ); - lPCodePos += 3; - break; - - case HB_P_SEQRECOVER: - fprintf( yyc, "\t\tHB_P_SEQRECOVER,\n" ); - lPCodePos++; - break; - - case HB_P_SFRAME: - /* we only generate it if there are statics used in this function */ - if( pFunc->bFlags & FUN_USES_STATICS ) - { - GetSymbol( _pInitFunc->szName, &w ); - w = FixSymbolPos( w ); - fprintf( yyc, "\t\tHB_P_SFRAME, %i, %i,\t/* symbol (_INITSTATICS) */\n", - LOBYTE( w ), HIBYTE( w ) ); - } - lPCodePos += 3; - break; - - case HB_P_STATICS: - { - GetSymbol( _pInitFunc->szName, &w ); - w = FixSymbolPos( w ); - fprintf( yyc, "\t\tHB_P_STATICS, %i, %i,\t/* symbol (_INITSTATICS) */\n", - LOBYTE( w ), HIBYTE( w ) ); - lPCodePos += 3; - } - break; - - case HB_P_SWAPALIAS: - fprintf( yyc, "\t\tHB_P_SWAPALIAS,\n" ); - lPCodePos++; - break; - - case HB_P_TRUE: - fprintf( yyc, "\t\tHB_P_TRUE,\n" ); - lPCodePos++; - break; - - case HB_P_ZERO: - fprintf( yyc, "\t\tHB_P_ZERO,\n" ); - lPCodePos++; - break; - - default: - printf( "Incorrect pcode value: %u\n", pFunc->pCode[ lPCodePos ] ); - lPCodePos = pFunc->lPCodePos; - break; - } - } - - fprintf( yyc, "/* %05li */", lPCodePos ); - if( bEndProcRequired ) - fprintf( yyc, " HB_P_ENDPROC };\n\n" ); - else - fprintf( yyc, " };\n\n" ); - fprintf( yyc, " hb_vmExecute( pcode, symbols );\n}\n\n" ); - pFunc = pFunc->pNext; - } - - fclose( yyc ); - - pFunc = functions.pFirst; - while( pFunc ) - pFunc = KillFunction( pFunc ); - - pFunc = funcalls.pFirst; - while( pFunc ) - { - funcalls.pFirst = pFunc->pNext; - hb_xfree( ( void * ) pFunc ); /*NOTE: szName will be released by KillSymbol() */ - pFunc = funcalls.pFirst; - } - - pSym = symbols.pFirst; - while( pSym ) - pSym = KillSymbol( pSym ); - - if( ! _bQuiet ) - printf( "%s -> done!\n", szFileName ); -} - PFUNCTION KillFunction( PFUNCTION pFunc ) { PFUNCTION pNext = pFunc->pNext; @@ -5956,352 +4996,6 @@ static char * reserved_name( char * szName ) return (char *) _szReservedFun[ wNum - 1 ]; } - -#define SYM_NOLINK 0 /* Symbol does not have to be linked */ -#define SYM_FUNC 1 /* Defined function */ -#define SYM_EXTERN 2 /* Previously defined function */ - -void GenPortObj( char * szFileName, char * szName ) -{ - PFUNCTION pFunc /*= functions.pFirst */; - PCOMSYMBOL pSym = symbols.pFirst; - WORD w, wLen, wVar; - LONG lPCodePos; - LONG lPad; - LONG lSymbols; - BOOL bEndProcReq; - ULONG ulCodeLength; - FILE * yyc; /* file handle for C output */ - - HB_SYMBOL_UNUSED( szName ); - - yyc = fopen( szFileName, "wb" ); - if( ! yyc ) - { - printf( "Error opening file %s\n", szFileName ); - return; - } - - if( ! _bQuiet ) - printf( "\nGenerating portable object...\n" ); - - /* writes the symbol table */ - - if( ! _bStartProc ) - pSym = pSym->pNext; /* starting procedure is always the first symbol */ - - lSymbols = 0; /* Count number of symbols */ - while( pSym ) - { - lSymbols++; - pSym = pSym->pNext; - } - fputc( ( BYTE ) ( ( lSymbols ) & 255 ), yyc ); /* Write number symbols */ - fputc( ( BYTE ) ( ( lSymbols >> 8 ) & 255 ), yyc ); - fputc( ( BYTE ) ( ( lSymbols >> 16 ) & 255 ), yyc ); - fputc( ( BYTE ) ( ( lSymbols >> 24 ) & 255 ), yyc ); - - pSym = symbols.pFirst; - if( ! _bStartProc ) - pSym = pSym->pNext; /* starting procedure is always the first symbol */ - - while( pSym ) - { - fputs( pSym->szName, yyc ); - fputc( 0, yyc ); - if( pSym->cScope != FS_MESSAGE ) - fputc( pSym->cScope, yyc ); - else - fputc( 0, yyc ); - - /* specify the function address if it is a defined function or a - external called function */ - if( GetFunction( pSym->szName ) ) /* is it a defined function ? */ - { - fputc( SYM_FUNC, yyc ); - } - else - { - if( GetFuncall( pSym->szName ) ) - { - fputc( SYM_EXTERN, yyc ); - } - else - { - fputc( SYM_NOLINK, yyc ); - } - } - pSym = pSym->pNext; - } - - pFunc = functions.pFirst; - if( ! _bStartProc ) - pFunc = pFunc->pNext; - - lSymbols = 0; /* Count number of symbols */ - while( pFunc ) - { - lSymbols++; - pFunc = pFunc->pNext; - } - fputc( ( BYTE ) ( ( lSymbols ) & 255 ), yyc ); /* Write number symbols */ - fputc( ( BYTE ) ( ( lSymbols >> 8 ) & 255 ), yyc ); - fputc( ( BYTE ) ( ( lSymbols >> 16 ) & 255 ), yyc ); - fputc( ( BYTE ) ( ( lSymbols >> 24 ) & 255 ), yyc ); - - /* Generate functions data - */ - pFunc = functions.pFirst; - if( ! _bStartProc ) - pFunc = pFunc->pNext; /* No implicit starting procedure */ - - while( pFunc ) - { - fputs( pFunc->szName, yyc ); - fputc( 0, yyc ); - /* We will have to add HB_P_ENDPROC in cases when RETURN statement - * was not used in a function/procedure - this is why we have to reserve - * one additional byte - */ - ulCodeLength = pFunc->lPCodePos + 1; - fputc( ( BYTE ) ( ( ulCodeLength ) & 255 ), yyc ); /* Write size */ - fputc( ( BYTE ) ( ( ulCodeLength >> 8 ) & 255 ), yyc ); - fputc( ( BYTE ) ( ( ulCodeLength >> 16 ) & 255 ), yyc ); - fputc( ( BYTE ) ( ( ulCodeLength >> 24 ) & 255 ), yyc ); - -/* printf( "Creating output for %s\n", pFunc->szName ); */ - - lPCodePos = 0; - lPad = 0; /* Number of bytes optimized */ - bEndProcReq = TRUE; - while( lPCodePos < pFunc->lPCodePos ) - { - switch( pFunc->pCode[ lPCodePos ] ) - { - case HB_P_AND: - case HB_P_ARRAYAT: - case HB_P_ARRAYPUT: - case HB_P_DEC: - case HB_P_DIVIDE: - case HB_P_DUPLICATE: - case HB_P_DUPLTWO: - case HB_P_ENDBLOCK: - case HB_P_EQUAL: - case HB_P_EXACTLYEQUAL: - case HB_P_FALSE: - case HB_P_FORTEST: - case HB_P_FUNCPTR: - case HB_P_GREATER: - case HB_P_GREATEREQUAL: - case HB_P_INC: - case HB_P_INSTRING: - case HB_P_LESS: - case HB_P_LESSEQUAL: - case HB_P_MINUS: - case HB_P_MODULUS: - case HB_P_MULT: - case HB_P_NEGATE: - case HB_P_NOT: - case HB_P_NOTEQUAL: - case HB_P_OR: - case HB_P_PLUS: - case HB_P_POP: - case HB_P_POPALIAS: - case HB_P_POWER: - case HB_P_PUSHALIAS: - case HB_P_PUSHNIL: - case HB_P_PUSHSELF: - case HB_P_RETVALUE: - case HB_P_SWAPALIAS: - case HB_P_SEQRECOVER: - case HB_P_TRUE: - case HB_P_ZERO: - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - break; - - case HB_P_DIMARRAY: - case HB_P_DO: - case HB_P_FUNCTION: - case HB_P_GENARRAY: - case HB_P_JUMP: - case HB_P_JUMPFALSE: - case HB_P_JUMPTRUE: - case HB_P_LINE: - case HB_P_POPLOCAL: - case HB_P_POPSTATIC: - case HB_P_PUSHINT: - case HB_P_PUSHLOCAL: - case HB_P_PUSHLOCALREF: - case HB_P_PUSHSTATIC: - case HB_P_PUSHSTATICREF: - case HB_P_SEQBEGIN: - case HB_P_SEQEND: - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - break; - - case HB_P_ENDPROC: - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - if( lPCodePos == pFunc->lPCodePos ) - bEndProcReq = FALSE; - break; - - case HB_P_FRAME: - /* update the number of local variables */ - { - PVAR pLocal = pFunc->pLocals; - BYTE bLocals = 0; - - while( pLocal ) - { - pLocal = pLocal->pNext; - bLocals++; - } - - if( bLocals || pFunc->wParamCount ) - { - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( ( BYTE )( bLocals - pFunc->wParamCount ), yyc ); - fputc( ( BYTE )( pFunc->wParamCount ), yyc ); - lPCodePos += 2; - } - else - { - lPad += 3; - lPCodePos += 3; - } - } - break; - - case HB_P_PUSHSYM: - case HB_P_MESSAGE: - case HB_P_POPMEMVAR: - case HB_P_PUSHMEMVAR: - case HB_P_PUSHMEMVARREF: - case HB_P_POPFIELD: - case HB_P_PUSHFIELD: - case HB_P_POPALIASEDFIELD: - case HB_P_PUSHALIASEDFIELD: - fputc( pFunc->pCode[ lPCodePos ], yyc ); - wVar = FixSymbolPos( pFunc->pCode[ lPCodePos + 1 ] + 256 * pFunc->pCode[ lPCodePos + 2 ] ); - fputc( LOBYTE( wVar ), yyc ); - fputc( HIBYTE( wVar ), yyc ); - lPCodePos += 3; - break; - - case HB_P_PARAMETER: - fputc( pFunc->pCode[ lPCodePos ], yyc ); - wVar = FixSymbolPos( pFunc->pCode[ lPCodePos + 1 ] + 256 * pFunc->pCode[ lPCodePos + 2 ] ); - fputc( LOBYTE( wVar ), yyc ); - fputc( HIBYTE( wVar ), yyc ); - fputc( pFunc->pCode[ lPCodePos + 3 ], yyc ); - lPCodePos +=4; - break; - - case HB_P_PUSHBLOCK: - wVar = * ( ( WORD * ) &( pFunc->pCode [ lPCodePos + 5 ] ) ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - /* create the table of referenced local variables */ - while( wVar-- ) - { - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - } - break; - - case HB_P_PUSHDOUBLE: - { - int i; - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - for( i = 0; i < sizeof( double ); ++i ) - fputc( ( ( BYTE * ) pFunc->pCode )[ lPCodePos + i ], yyc ); - fputc( pFunc->pCode[ lPCodePos + sizeof( double ) ], yyc ); - lPCodePos += sizeof( double ) + 1; - } - break; - - case HB_P_PUSHLONG: - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - break; - - case HB_P_PUSHSTR: - wLen = pFunc->pCode[ lPCodePos + 1 ] + - pFunc->pCode[ lPCodePos + 2 ] * 256; - fputc( pFunc->pCode[ lPCodePos ], yyc ); - fputc( pFunc->pCode[ lPCodePos + 1 ], yyc ); - fputc( pFunc->pCode[ lPCodePos + 2 ], yyc ); - lPCodePos += 3; - while( wLen-- ) - fputc( pFunc->pCode[ lPCodePos++ ], yyc ); - break; - - case HB_P_SFRAME: - /* we only generate it if there are statics used in this function */ - if( pFunc->bFlags & FUN_USES_STATICS ) - { - GetSymbol( _pInitFunc->szName, &w ); - w = FixSymbolPos( w ); - fputc( pFunc->pCode[ lPCodePos ], yyc ); - fputc( LOBYTE( w ), yyc ); - fputc( HIBYTE( w ), yyc ); - } - else - lPad += 3; - lPCodePos += 3; - break; - - case HB_P_STATICS: - GetSymbol( _pInitFunc->szName, &w ); - w = FixSymbolPos( w ); - fputc( pFunc->pCode[ lPCodePos ], yyc ); - fputc( LOBYTE( w ), yyc ); - fputc( HIBYTE( w ), yyc ); - lPCodePos += 3; - break; - - default: - printf( "Incorrect pcode value: %u\n", pFunc->pCode[ lPCodePos ] ); - lPCodePos = pFunc->lPCodePos; - break; - } - } - - if( bEndProcReq ) - fputc( HB_P_ENDPROC, yyc ); - else - { - /* HB_P_ENDPROC was the last opcode: we have to fill the byte - * reserved earlier - */ - lPad++; - } - for( ; lPad; lPad-- ) - { - /* write additional bytes to agree with stored earlier - * function/procedure size - */ - fputc( 0, yyc ); - } - pFunc = pFunc->pNext; - } - - fclose( yyc ); - - if( ! _bQuiet ) - printf( "%s -> done!\n", szFileName ); -} - /* NOTE: iMinParam = -1, means no checking */ /* iMaxParam = -1, means no upper limit */ diff --git a/harbour/source/rtl/arrays.c b/harbour/source/rtl/arrays.c index 0a4edbc6c3..42f264da33 100644 --- a/harbour/source/rtl/arrays.c +++ b/harbour/source/rtl/arrays.c @@ -272,6 +272,8 @@ char * hb_arrayGetDS( PHB_ITEM pArray, ULONG ulIndex, char * szDate ) if( IS_ARRAY( pArray ) && ulIndex > 0 && ulIndex <= pArray->item.asArray.value->ulLen ) hb_itemGetDS( pArray->item.asArray.value->pItems + ulIndex - 1, szDate ); else + /* NOTE: Intentionally calling it with a bad parameter in order to get + the default value from hb_itemGetDS(). */ hb_itemGetDS( NULL, szDate ); return szDate;