EnglishРусский  

   ..

   alias.c

   alias.h

   bcodes.c

   bcodes.h

   body.c

   compile.c

   compile.h

   define.c

   define.h

   desc.c

   expr.c

   extern.c

   for.c

   foreach.c

   func.c

   func.h

   global.c

   global.h

   goto.c

   if.c

   ifdef.c

   ifdef.h

   import.c

   import.h

   include.c

   include.h

   jump.c

   lexem.c

   lexem.h

   macro.c

   macro.h

   operlist.txt

   out.c

   out.h

   subfunc.c

   switch.c

   type.c

   type.h

   vars.c

   while.c

   with.c

Реклама

Инсталлятор CreateInstall
Бесплатные и коммерческие инсталляторы

source\src\compiler\compile.c
  1 /******************************************************************************
  2 *
  3 * Copyright (C) 2006, The Gentee Group. All rights reserved. 
  4 * This file is part of the Gentee open source project - http://www.gentee.com. 
  5 * 
  6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT"). 
  7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS 
  8 * ACCEPTANCE OF THE AGREEMENT.
  9 *
 10 * ID: compile 18.10.06 0.0.A.
 11 *
 12 * Author: Alexey Krivonogov ( gentee )
 13 *
 14 ******************************************************************************/
 15 
 16 #include "compile.h"
 17 #include "../lex/lex.h"
 18 #include "../lex/lexgentee.h"
 19 #include "../genteeapi/gentee.h"
 20 #include "../common/file.h"
 21 #include "../common/hash.h"
 22 #include "../bytecode/ge.h"
 23 #include "lexem.h"
 24 #include "operlist.h"
 25 #include "define.h"
 26 #include "macro.h"
 27 #include "compinit.h"
 28 #include "include.h"
 29 #include "import.h"
 30 #include "global.h"
 31 
 32 #include <setjmp.h> 
 33 jmp_buf stack_state;
 34 
 35 //----------------------------------------------------------------------------
 36 
 37 extern const uint lexgentee[];
 38 
 39 /*-----------------------------------------------------------------------------
 40 *
 41 * ID: compile_process 23.10.06 0.0.A.
 42 * 
 43 * Summary: The main gentee compile function
 44 *
 45 -----------------------------------------------------------------------------*/
 46 
 47 uint STDCALL compile_process( pstr filename )
 48 {
 49    pcompilefile   prev;
 50    compilefile    cmpfile;
 51    arr            lexout;
 52    arr            lexems;
 53    pstr      stemp;
 54    pstr      dir;
 55    pubyte    input;
 56    plexem    plex;
 57    pvmobj    pvmo;
 58    uint      i;
 59 
 60 //   plexem    pil;
 61 //   ubyte  idname[ 32 ];  // delete
 62 //   pcompile  pcmp = _gentee.compile;
 63 
 64    prev = _compile->cur;
 65 
 66    mem_zero( &cmpfile, sizeof( compilefile ));
 67    cmpfile.src = str_new( str_ptr( filename ));
 68    cmpfile.filename = str_new( 0 );
 69 
 70    dir = str_new( 0 );
 71    stemp = str_new( 0 );
 72 
 73    if ( _compile->flag & CMPL_SRC )
 74       _compile->flag &= ~CMPL_SRC;
 75    else
 76    {
 77       os_filefullname( filename, cmpfile.filename );
 78       if ( hash_find( &_compile->files, str_ptr( cmpfile.filename )))
 79          goto end;
 80 
 81       os_dirgetcur( dir );
 82       file2buf( filename, cmpfile.src, prev ? prev->pos : 0  );
 83       os_filefullname( filename, cmpfile.filename );
 84       if ( hash_find( &_compile->files, str_ptr( cmpfile.filename )))
 85          goto end;
 86 
 87       hash_create( &_compile->files, str_ptr( cmpfile.filename ));
 88       // Set a new directory
 89       str_getdirfile( filename, stemp, 0 );
 90       os_dirsetcur( stemp );
 91    }
 92 
 93    _compile->cur = &cmpfile;
 94    _compile->cur->idfirst = _vm.count;
 95 
 96 //   print("First=%i\n", _compile->cur->idfirst );
 97    if ( *( puint )str_ptr( cmpfile.src ) == GE_STRING )
 98    {
 99       msg( MLoad | MSG_STR, cmpfile.filename );
100       // Загружаем байт-код из откомпилированного файла
101       ge_load( cmpfile.src );
102 //  ???   Обнуление смещения vm->curoff проиcходит в конце gentee_load
103       goto end;
104    }
105    msg( MLoad | MSG_STR, cmpfile.filename );
106    _compile->flag &= ~CMPL_LINE;
107 
108    // Adding zero character
109    buf_appendch( cmpfile.src, 0 );
110 
111    input = str_ptr( cmpfile.src );
112    // Ignoring all first strings beginning with #
113    while ( input[ cmpfile.off ] == '#' )
114    {
115       while ( input[ cmpfile.off ] && input[ cmpfile.off ] != 0xA )
116          cmpfile.off++;
117       if ( input[ cmpfile.off ] == 0xA )
118          cmpfile.off++;
119    }
120    input += cmpfile.off;
121    // The first pass
122    arr_init( &lexout, sizeof( lexitem ));
123 
124    gentee_lexptr( input, &_compile->ilex, &lexout );
125 
126    _compile->cur->lexems = &lexems;
127    // The second pass and generating an array of lexems
128    lexem_load( &lexems, &lexout );
129 
130 /*   for ( i = 0; i < arr_count( &lexems ); i++ )
131    {
132       pil = ( plexem )arr_ptr( &lexems, i );
133       printf("Type = %i pos = %i ", pil->type, pil->pos );
134       switch ( pil->type )
135       {
136          case LEXEM_BINARY:
137             printf( "binary= %s", str_ptr( lexem_getstr(  pil )));
138             break;
139          case LEXEM_FILENAME:
140             printf( "filename= %s", str_ptr( lexem_getstr( pil )));
141             break;
142          case LEXEM_STRING:
143             printf( "string= %s len = %i", str_ptr( lexem_getstr(  pil )), 
144                      str_len( lexem_getstr(  pil )));
145             break;
146          case LEXEM_MACRO:
147             printf( "macro= %s", hash_name( &_compile->names, pil->macroid ));
148             break;
149          case LEXEM_NAME:
150             printf( "name= %s", hash_name( &_compile->names, pil->nameid ));
151             break;
152          case LEXEM_KEYWORD:
153             printf( "keyword = %i", pil->key );
154             break;
155          case LEXEM_OPER:
156             printf( "oper= %s id=%i", &pil->oper.name, pil->oper.operid );
157             break;
158          case LEXEM_NUMBER:
159             printf( "number = " );
160             switch ( pil->num.type )
161             {
162                case TUint:
163                   printf( "+%lu", pil->num.vint );
164                   break;
165                case TInt:
166                   printf( "%i", pil->num.vint );
167                   break;
168                case TUlong:
169                   printf( "+%sL", _ui64toa( pil->num.vlong, &idname, 10 ));
170                   break;
171                case TLong:
172                   printf( "%sL", _i64toa( pil->num.vlong, &idname, 10 ));
173                   break;
174                case TFloat:
175                   printf( "F%e", pil->num.vfloat  );
176                   break;
177                case TDouble:
178                   printf( "D%e", pil->num.vdouble  );
179                   break;
180                }
181             break;
182       }
183       printf("\n" );
184    }
185 */
186    plex = 0;
187 //   print("Before "); memstat();
188    while ( plex = lexem_next( plex, LEXNEXT_NULL | LEXNEXT_IGNLINE ))
189    {
190       if ( plex->type == LEXEM_KEYWORD )
191       {
192          switch ( plex->key ) {
193             case KEY_DEFINE:
194                plex = define( plex );
195                break;
196             case KEY_GLOBAL:
197                plex = global( plex );
198                break;
199 //            case KEY_IFDEF:  // check in lexem_next
200 //               break;
201             case KEY_IMPORT:
202                plex = import( plex );
203                break;
204             case KEY_INCLUDE:
205                plex = include( plex );
206                break;
207             case KEY_TYPE:
208                plex = type( plex );
209                break;
210 				case KEY_OPERATOR:
211 				case KEY_METHOD:
212             case KEY_FUNC:
213 				case KEY_TEXT:
214 				case KEY_PROPERTY:
215                plex = m_func( plex, 0 );
216                break;
217             case KEY_PRIVATE:
218                _compile->cur->priv = 1;
219                break;
220             case KEY_PUBLIC:
221                _compile->cur->priv = 0;
222                break;
223             case KEY_EXTERN:
224                plex = m_extern( plex );
225                break;
226             default:
227                msg( MUnkcmd | MSG_LEXNAMEERR, plex );
228                break;
229          }
230       }
231       else
232          msg( MUnkcmd | MSG_LEXNAMEERR, plex );
233    }
234    // Proceed private public protected
235    for ( i = _compile->cur->idfirst; i < _vm.count; i++ )
236    {
237       pvmo = ( pvmobj )PCMD( i );
238       if ( pvmo->flag & GHRT_INCLUDED )
239          continue;
240       if ( pvmo->type == OVM_TYPE && pvmo->flag & GHTY_PROTECTED )
241          type_protect( ( povmtype )pvmo );
242       if ( pvmo->flag & GHRT_PRIVATE )   
243          vm_clearname( i );
244       // Надо добавить для глобальных переменных !!! ???
245 
246       pvmo->flag |= GHRT_INCLUDED;
247    }
248    
249    lexem_delete( &lexems );
250    arr_delete( &lexout );
251 end:
252 
253    if ( str_len( dir ))
254       os_dirsetcur( dir );
255    str_destroy( cmpfile.src );
256    str_destroy( cmpfile.filename );
257    str_destroy( dir );
258    str_destroy( stemp );
259    _compile->cur = prev;
260 
261    return 1;
262 }
263 
264 /*-----------------------------------------------------------------------------
265 *
266 * ID: gentee_compile 23.10.06 0.0.A.
267 * 
268 * Summary: The public compile function
269 *
270 -----------------------------------------------------------------------------*/
271 //uint  STDCALL gentee_compile( pcompileinfo compinit )
272 uint  STDCALL thread_compile( pcompileinfo compinit )
273 {
274    compile   icompile;
275    pstr      data;//, src;
276    uint      i;
277    pubyte    ptr;
278    buf       stack;
279  //  pstr      src;
280 
281    if ( setjmp( stack_state ) == -1 ) 
282       return FALSE;
283 
284 //   if ( !getenv("GNUMSIGN") )
285       msg( MStart );
286 //   else
287 //      _time = os_time();
288 
289    initcompile();
290 //   memstat();
291    _vm.loadmode = 1;
292    mem_zero( &icompile, sizeof( compile ));
293    _compile = &icompile;
294 
295    icompile.curdir = str_new( 0 );
296    os_dirgetcur( icompile.curdir );
297    
298    if ( compinit->flag & CMPL_OPTIMIZE )
299       _compile->popti = &compinit->opti;
300 
301    icompile.flag = compinit->flag;
302    data = str_new( compinit->input );
303    buf_init( &stack );
304    buf_reserve( &stack, (( STACK_OPERS + STACK_OPS ) << 1 ) + STACK_PARS );//0xFFFF << 1 );
305 
306    arrdata_strload( arrdata_init( &icompile.libdirs ), compinit->libdirs );
307    hash_init( &icompile.files, sizeof( uint ));
308    hash_init( &icompile.names, sizeof( uint ));
309    hash_init( &icompile.resource, sizeof( uint ));
310    hash_init( &icompile.opers, sizeof( uint ));
311    hash_init( &icompile.macros, sizeof( macro ));
312    hash_init( &icompile.namedef, sizeof( macro ));
313 
314    arrdata_init( &icompile.string );
315    arrdata_init( &icompile.binary );
316    icompile.files.ignore = 1;
317    lex_init( &icompile.ilex, ( puint )&lexgentee );
318    icompile.stkopers = buf_ptr( &stack );
319    icompile.stkops = ( pubyte )icompile.stkopers + STACK_OPERS;//0xFFFF;
320    icompile.stkpars = ( pubyte )icompile.stkops + STACK_OPS;//0xFFFF;
321    icompile.stkmopers = ( pubyte )icompile.stkpars + STACK_PARS;//0xFFFF;
322    icompile.stkmops = ( pubyte )icompile.stkmopers + STACK_OPERS;//0xFFFF;
323    ptr = ( pubyte )&operlexlist;
324    // Loading hash of operators
325    for ( i = 0; i < OPERCOUNT; i++ )
326    {
327       if ( *ptr )
328       {
329          hash_setuint( &icompile.opers, ptr, i );
330          ptr += mem_len( ptr );
331       }
332       ptr++;
333    }
334    macro_init();
335 
336 /*#ifndef LINUX
337    src = str_new( 0 );
338    if ( icompile.flag & CMPL_SRC )
339       str_copy( src, data );
340    else
341       file2buf( data, src, 0  );
342 
343    //   print( "CMD LINE=%s\n",str_ptr( cmpfile.src ) );
344 //   getch();
345    if ( *( pushort )str_ptr( src ) == 0x2123 && 
346         _compile->flag & CMPL_LINE && !getenv("GNUMSIGN"))
347    {
348       ubyte   cmdline[512];
349       pubyte  cur;
350       pubyte  input = str_ptr( src ) + 2;
351       PROCESS_INFORMATION  stpi;
352       STARTUPINFO          start;
353       
354       ZeroMemory( &stpi, sizeof( PROCESS_INFORMATION ));
355       ZeroMemory( &start, sizeof( STARTUPINFO ));
356       start.cb = sizeof( STARTUPINFO );
357 
358       cur = ( pubyte )&cmdline;
359       while ( *input >= ' ' )
360       {
361          if ( *input == '%' && *( input + 1 ) == '1' )
362          {
363             mem_copyuntilzero( cur, str_ptr( data ));
364             cur += mem_len( cur );
365             input += 2;
366          }
367          else
368             *cur++ = *input++;
369       }
370       *cur = 0;
371       _putenv("GNUMSIGN=1");
372 //      print( "CMD LINE=%s\n",cmdline );
373       CreateProcess( 0, cmdline, 0, 0, TRUE,
374                      CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS, 
375                      0, 0, &start, &stpi );
376       ExitProcess( 0 );
377    }
378    str_destroy( src );
379 #endif*/
380 
381    if ( *compinit->defargs || *compinit->include )
382    {
383       pstr  stemp = str_new( "" );
384       pstr  include = str_new( "" );
385       pstr  dargs = str_new( "" );
386       pubyte  cur, src;
387       
388       str_reserve( stemp, 1024 );
389       str_reserve( include, 1024 );
390       str_reserve( dargs, 1024 );
391       
392       if ( *compinit->include )
393       {
394          cur = str_ptr( include );
395          src = compinit->include;
396          while ( *src )
397          {
398             sprintf( cur, "$\"%s\"\r\n", src );
399             cur += mem_len( cur );
400             src += mem_len( src ) + 1;
401          }
402          *cur = 0;
403          str_setlen( include, cur - str_ptr( include ));
404       }
405       if ( *compinit->defargs )
406       {
407          cur = str_ptr( dargs );
408          src = compinit->defargs;
409          while ( *src )
410          {
411             sprintf( cur, "%s\r\n", src );
412             cur += mem_len( cur );
413             src += mem_len( src ) + 1;
414          }
415          *cur = 0;
416          str_setlen( dargs, cur - str_ptr( dargs ));
417       }
418       str_printf( stemp, "define {\r\n\
419 %s\r\n\
420 }\r\n\
421 include {\r\n\
422   %s\r\n\
423 }\r\n\
424 include : $\"%s\"", str_ptr( dargs ), str_ptr( include ), str_ptr( data ));
425 //      printf( str_ptr( stemp ));
426       _compile->flag |= CMPL_SRC;
427       str_copy( data, stemp );
428       str_destroy( stemp );
429       str_destroy( include );
430       str_destroy( dargs );
431    }
432    compile_process( data );
433 
434    hash_delete( &icompile.files );
435    hash_delete( &icompile.names );
436    hash_delete( &icompile.resource );
437    hash_delete( &icompile.opers );
438    hash_delete( &icompile.macros );
439    hash_delete( &icompile.namedef );
440    arrdata_delete( &icompile.libdirs );
441    arrdata_delete( &icompile.string );
442    arrdata_delete( &icompile.binary );
443 
444    lex_delete( &icompile.ilex );
445    msg( MEnd );
446 
447    if ( compinit->flag & CMPL_GE )
448    {
449       buf_clear( &stack );
450       ge_save( &stack );
451       if ( compinit->output[0] )
452          str_copyzero( data, compinit->output );
453       else
454       {
455          str_copyzero( data, compinit->input );
456          str_ptr( data )[ str_len( data )] = 'e';
457          buf_appendch( (pbuf)data, 0 );
458       }
459       buf2file( data, &stack );
460    }
461    str_destroy( icompile.curdir );
462    _compile = NULL;
463    buf_delete( &stack );
464    str_destroy( data );
465 //  memstat();
466 
467    if ( !( icompile.flag & CMPL_NORUN ))
468       compinit->result = vm_execute( 1 );
469    return TRUE;
470 }
471 
472 /*-----------------------------------------------------------------------------
473 ** Id: gentee_compile F
474 * 
475 * Summary: Program compilation. This function allows to compile and run 
476            programs in Gentee.
477 *
478 * Params: compinit - The pointer to $[compileinfo] structure with the /
479                      specified compiling options.
480 *
481 * Return: #lng/retf#
482 *  
483 -----------------------------------------------------------------------------*/
484 
485 uint  STDCALL gentee_compile( pcompileinfo compinit )
486 {
487    uint ret = 0;
488    uint i;
489 
490    compinit->result = 0;
491    compinit->hthread = 0;
492    if ( !( compinit->flag & CMPL_NOCLEAR ))
493       for ( i = KERNEL_COUNT; i < arr_count( &_vm.objtbl ); i++ )
494       {
495          ((pvmobj)PCMD( i ))->flag |= GHRT_SKIP;
496          vm_clearname( i );
497       }
498 
499    if ( compinit->flag & CMPL_THREAD )
500    {
501       compinit->hthread = os_thread( &thread_compile, compinit );
502       if ( compinit->flag & CMPL_NOWAIT )
503          return 1;
504       os_wait( compinit->hthread, INFINITE );
505       os_exitcode( compinit->hthread, &ret );
506    }
507    else
508       ret = thread_compile( compinit );
509 
510    return ret;
511 }
512 
513 //----------------------------------------------------------------------------
514 
Редактировать