Lhogho  0.0.027
Defines | Functions | Variables
atoms.c File Reference

Defines

#define void   void __attribute__ ((used,noinline,regparm(0),stdcall))

Functions

void init_atoms ()
 initializes the Atoms module
void finit_atoms ()
 finalizes the Atoms module
atom_t use (atom_t a)
 adds link to atom
void deuse (atom_t a)
 removes link to atom
void dump_atom (atom_t a, int level)
 dumps atom contents
void dump (atom_t a)
 dumps atom contents
void dumpln (atom_t a)
 dumps atom contents
void init_output (outter_t new_outter)
 initializes text output
void init_input (inner_t new_inner, inner_eof_t new_inner_eof)
 initializes text input
void outter (chars_t string, int len)
 prints text
int inner_eof ()
 returns eof status
char_t inner ()

Variables

inner_t std_inner
 hook variable for inputting text
inner_eof_t std_inner_eof
 hook variable for inputting text
outter_t std_outter
 hook variable for outputting text
int outter_size = 0
 counts outted characters
FILE * input_stream = NULL
 current input stream
FILE * output_stream = NULL
 current input stream
struct lconv * locale_info
 locale information

Define Documentation

#define void   void __attribute__ ((used,noinline,regparm(0),stdcall))

Function Documentation

Creates a data pool for all atoms and creates one special atom representing the empty list.

{
  #ifdef DEBUG_ATOM
  printf("<ATOM> Atoms initialized\n");
  #endif //DEBUG_ATOM

  #ifdef ADVANCED
  int i;
  stats_free = 0;
  stats_allocs = 0;
  for( i=MIN_ID; i<MAX_ID; i++ )
  {
    stats[i].max      = 0;
    stats[i].allocs   = 0;
    stats[i].deallocs = 0;
  }
  #endif //ADVANCED

  #ifdef SAFEMODE
  assert( sizeof(atomrec_t)==16 );
  #endif

  //setlocale( LC_ALL, "" );
  locale_info = localeconv();

  init_pool( &data_pool, ATOM_SIZE );
  init_pool( &data_pool_ex, ATOM_SIZE_EX );

  empty_list = (atom_t)take_from_pool( &data_pool );
  REF(empty_list) = 1;
  ID(empty_list) = LIST_ID;
  CAR(empty_list) = empty_list;
  CDR(empty_list) = empty_list;
  FLAGS(empty_list) = 0;
}

Returns the empty list back to the data pool.

{
  return_to_pool( &data_pool, empty_list );

  #ifdef DEBUG_MEMORY_LEAKS
  dump_pool();
  #endif

  #ifdef DEBUG_ATOM
  printf("<ATOM> Atoms finalized\n");
  #endif //DEBUG_ATOM
}
atom_t use ( atom_t  a)
Parameters:
aatom to use

Adds a link to an atom by increasing atom's reference count.

{
  if( IS_UNBOUND(a) || IS_EMPTY(a) || IS_STOPPED(a) )
  return a;

  //if( a==0x49f3b8)
  //{
  //printf("USE.BUG[%08x] ref %d->%d\n", (int)a, REF(a), REF(a)+1 );
  //}


  #ifdef DEBUG_RUNTIME_ATOMS
  if( running_compiled_code )
  {
    outter( TEXT("<RUNTIME> use  "), -1 );
    dump_atom_address( a );
    dump_atom( a, 1 );
    outter( TEXT("\n"), -1 );
  }
  #endif
  #ifdef DEBUG_COMPILETIME_ATOMS
  if( compiling_code )
  {
    outter( TEXT("<COMPILETIME> use  "), -1 );
    dump_atom_address( a );
    dump_atom( a, 1 );
    outter( TEXT("\n"), -1 );
  }
  #endif

  //if( IS_ERROR(a) )
  //  {
  //    printf("TO BE USEIT hex(a)=%x id=%d REF=%d a=",(int)a,ID(a),REF(a)); dumpln(a);
  //  }

  #ifdef SAFEMODE
  assert( a );
  assert( ID(a)<MAX_ID );
  assert( REF(a)>=0 ); // 2009 was >0
  #endif //SAFEMODE

  //if( IS_INTEGER(a) || IS_FLOAT(a))
  //{
  //printf("deuse[addr=%x ref=%d]\n",a,REF(a));
  //printf("use atom="); dumpln(a);
  //}

  REF(a)++;

  #ifdef DEBUG_ATOM
  printf("<ATOM>  [%08x] ref+1\n",(int)a);
  #endif //DEBUG_ATOM
  return a;
}
void deuse ( atom_t  a)
Parameters:
aatom to unlink

Decrements the reference count for the atom and if it reaches 0 then frees the atom using one of the functions delete_numeric, delete_list, delete_word, delete_subword, delete_error, delete_var.

{
  __asm__ volatile ( ASM_STORE_RESULT:::ASM_CLOBBER_REGISTERS );

  typedef void(*deleter_t)(atom_t);

  static deleter_t deleters[MAX_ID] = {
    delete_numeric,  // INTEGER_ID
    delete_numeric,  // FLOAT_ID
    delete_list,  // LIST_ID
    delete_word,  // WORD_ID
    delete_subword,  // SUBWORD_ID
    delete_error, // ERROR_ID
    delete_var,      // VAR_ID
    delete_mem,      // MEM_ID
  }; // array of deleter functions for each atom type

  //if( a==0x49f3b8)
  //{
  //printf("DEUSE.BUG[%08x] ref %d->%d\n", (int)a, REF(a), REF(a)-1 );
  //}

  //if( IS_INTEGER(a) || IS_FLOAT(a))
  //  {
  //    //printf("deuse[addr=%x ref=%d]\n",(int)a,REF(a));
  //    printf("deuse atom="); dumpln(a);
  //  }


  if( !IS_EMPTY(a) && !IS_UNBOUND(a) && !IS_STOPPED(a))
  {
    //printf("deuse "); dumpln(a);
    #ifdef DEBUG_RUNTIME_ATOMS
    if( running_compiled_code )
    {
      outter( TEXT("<RUNTIME> deuse"), -1 );
      dump_atom_address( a );
      dump_atom( a, 1 );
      outter( TEXT("\n"), -1 );
    }
    #endif
    #ifdef DEBUG_COMPILETIME_ATOMS
    if( compiling_code )
    {
      outter( TEXT("<COMPILETIME> deuse"), -1 );
      dump_atom_address( a );
      dump_atom( a, 1 );
      outter( TEXT("\n"), -1 );
    }
    #endif

    //if( IS_ERROR(a) )
    //{
    //printf("TO BE DEUSE hex(a)=%x id=%d REF=%d a=",(int)a,ID(a),REF(a)); dumpln(a);
    //}

    #ifdef SAFEMODE
    assert( a );
    //if(ID(a)>=MAX_ID) {printf("ASSERT[%x]\n",a);}
    assert( (ID(a)<MAX_ID) );
    assert( REF(a)>0 );
    #endif // SAFEMODE
    //printf("GOODY hex(a)=%x id=%d REF=%d\n\n",(int)a,ID(a),REF(a));

    if( !--REF(a) )
    {
      #ifdef DEBUG_ATOM
      printf("<ATOM>  [%08x] ref-1\n",(int)a);
      #endif //DEBUG_ATOM

      #ifdef ADVANCED
      stats[ID(a)].deallocs++;
      stats_free++;
      #endif //ADVANCED

      deleter_t deleter = deleters[ID(a)];
      deleter(a);
    }
  }
  __asm__ volatile ( ASM_RESTORE_RESULT:::ASM_CLOBBER_REGISTERS );
}
void dump_atom ( atom_t  a,
int  level 
)
Parameters:
aatom to dump
levellevel of nesting

Dumps atom's contents using a call-back outter function. Texts are automatically indented according to the level. Typically this function is used to print an atom when the call-back function forwards contents to standard output. The call-back function is set by init_output().

< array of deleter functions for each atom type

{
  typedef void(*dumper_t)(atom_t,int);

  static dumper_t dumpers[MAX_ID] = {
    dump_integer, // INTEGER_ID
    dump_float,      // FLOAT_ID
    dump_list,    // LIST_ID
    dump_word,    // WORD_ID
    dump_word,    // SUBWORD_ID
    dump_error,      // ERROR_ID
    dump_var,     // VAR_ID
    dump_mem,     // MEM_ID
  }; 


  #ifdef SAFEMODE
  assert( a );
  //assert( outter );
  if( IS_NOT_EMPTY(a) ) assert( ID(a)<MAX_ID );
  #endif //SAFEMODE

  #ifdef DEBUG_REF_COUNT
  if( IS_EMPTY(a) )
  {
    outter( TEXT("##"), 2 );
  }
  else
  {
    int n;
    char_t buf[64];
    n = SPRINTF( buf, DUMP_BUF_SIZE, TEXT(" %d#"), REF(a) );
    outter( buf, n );
  }
  #endif

  dumper_t dumper = dumpers[ID(a)];
  dumper(a,level);
}
void dump ( atom_t  a)
Parameters:
aatom to dump

Dumps atom's contents throught the current text output function (e.g. use_stdout).

{
  dump_atom( a, 0 );
}
void dumpln ( atom_t  a)
Parameters:
aatom to dump

Dumps atom's contents throught the current text output function (e.g. use_stdout) and moves cursor to the next line.

{
  dump_atom( a, 0 );
  outter( TEXT("\n"), 1 );
}
void init_output ( outter_t  new_outter)
Parameters:
new_outternew outter function to use by dump and dumpln

Initializes the text output system by setting the std_outter function to output text throught it.

{
  std_outter = new_outter;
}
void init_input ( inner_t  new_inner,
inner_eof_t  new_inner_eof 
)
Parameters:
new_innernew inner function
new_inner_eofnew inner_eof function

Initializes the text input system by setting the std_inner and :std_inner_eof functions to input text throught it.

{
  std_inner = new_inner;
  std_inner_eof = new_inner_eof;
}
void outter ( chars_t  string,
int  len 
)
Parameters:
stringtext to print
lenlength of text

This function prints text to either the hooked output or to a file.

{
  if( output_stream==NULL )
  {
    std_outter( string, len );
  }
  else
  {
    if( len==-1 ) len = STRLEN( string );
    for( ; len>0; len--, string++ )
    {
      int crlf = (DEBAR(*string)==0x0D) && (DEBAR(*(string+1))==0x0A);
      if( !crlf ) 
      {
        char_t wc[2];
        wc[0] = DEBAR(*string);
        wc[1] = 0;

        char* buf =(char*) UTF16_to_UTF8(wc);
        DEALLOC( buf );
        fprintf( output_stream, "%S", wc );
      }
    }
  }
}

Return EOF status of a hooked or file stream.

{
  if( input_stream==NULL )
  {
    return std_inner_eof();
  }
  else
  {
    return feof(input_stream)?1:0;
  }
}
{
  if( input_stream==NULL )
  {
    return std_inner();
  }
  else
  {
    char_t ch;
    //ch = GETCHAR( input_stream );
    //while( ch=='\r' ) ch = GETCHAR( input_stream ); // remove ^M from input, keep ^J

    ch = (char_t)getc( input_stream );
    while( ch=='\r' ) ch = (char_t)getc( input_stream ); // remove ^M from input, keep ^J
    return ch;
  }
}

Variable Documentation

int outter_size = 0
FILE* input_stream = NULL
FILE* output_stream = NULL
struct lconv* locale_info

[ HOME | INDEX | ATOMS | VARS | REFERENCE ]
Lhogho Developer's Documentation
Tue Feb 7 2012