Lhogho
0.0.027
|
Data Structures | |
struct | node |
core atom structure More... | |
struct | node_ex |
Typedefs | |
typedef struct node | atomrec_t |
core structure of an atom | |
typedef atomrec_t * | atom_t |
global atom type | |
typedef struct node_ex | atomrec_ex_t |
core structure of an atom | |
typedef atomrec_ex_t * | atom_ex_t |
global atom type | |
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 | __attribute__ ((used, noinline, regparm(0), stdcall)) deuse(atom_t a) |
void | outter (chars_t string, int len) |
prints text | |
char_t | inner () |
int | inner_eof () |
returns eof status | |
void | dump (atom_t a) |
dumps atom contents | |
void | dumpln (atom_t a) |
dumps atom contents | |
void | dump_atom (atom_t a, int level) |
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 | |
Variables | |
int | stats_free |
statistics for free atoms (of any type) | |
FILE * | input_stream |
current input stream | |
FILE * | output_stream |
current input stream | |
int | outter_size |
counts outted characters | |
struct lconv * | locale_info |
locale information | |
Atom IDs | |
These constants represent atom ID. | |
#define | MIN_ID INTEGER_ID |
#define | INTEGER_ID 0 |
#define | FLOAT_ID 1 |
#define | LIST_ID 2 |
#define | WORD_ID 3 |
#define | SUBWORD_ID 4 |
#define | ERROR_ID 5 |
#define | VAR_ID 6 |
#define | MEM_ID 7 |
#define | MAX_ID (MEM_ID+1) |
Common atoms | |
#define | OFFSET_ID 4 |
#define | OFFSET_INT 8 |
#define | OFFSET_REPCOUNT 8 |
#define | OFFSET_REPLIMIT 12 |
#define | REF(x) ((x)->unode.u[0]) |
#define | ID(x) ((x)->unode.b[OFFSET_ID]) |
#define | FLAGS(x) ((x)->unode.s[3]) |
#define | GET_FLAGS(a, bitmask) (FLAGS(a) & (bitmask)) |
#define | SET_FLAGS(a, bitmask) FLAGS(a) |= (bitmask) |
#define | CLR_FLAGS(a, bitmask) FLAGS(a) &= ~(bitmask) |
#define | DEUSE(x) deuse(x) |
#define | USE(x) use(x) |
Sizes | |
#define | ATOM_SIZE sizeof(atomrec_t) |
atom size (in bytes) | |
#define | ATOM_SIZE_EX (ATOM_SIZE+1*sizeof(int_t)) |
size of extended atom | |
#define | CHAR_SIZE sizeof(char_t) |
char size (in bytes) | |
#define | UNKNOWN -1 |
#define MIN_ID INTEGER_ID |
#define INTEGER_ID 0 |
#define FLOAT_ID 1 |
#define LIST_ID 2 |
#define WORD_ID 3 |
#define SUBWORD_ID 4 |
#define ERROR_ID 5 |
#define VAR_ID 6 |
#define MEM_ID 7 |
#define OFFSET_ID 4 |
#define OFFSET_INT 8 |
#define OFFSET_REPCOUNT 8 |
#define OFFSET_REPLIMIT 12 |
#define REF | ( | x | ) | ((x)->unode.u[0]) |
#define FLAGS | ( | x | ) | ((x)->unode.s[3]) |
#define ATOM_SIZE_EX (ATOM_SIZE+1*sizeof(int_t)) |
#define UNKNOWN -1 |
typedef struct node_ex atomrec_ex_t |
typedef atomrec_ex_t* atom_ex_t |
void init_atoms | ( | ) |
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; }
void finit_atoms | ( | ) |
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 }
a | atom 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; }
atom_t __attribute__ | ( | (used, noinline, regparm(0), stdcall) | ) |
string | text to print |
len | length 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 ); } } } }
{ 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; } }
int inner_eof | ( | ) |
Return EOF status of a hooked or file stream.
{ if( input_stream==NULL ) { return std_inner_eof(); } else { return feof(input_stream)?1:0; } }
a | atom to dump |
Dumps atom's contents throught the current text output function (e.g. use_stdout).
{ dump_atom( a, 0 ); }
a | atom to dump |
Dumps atom's contents throught the current text output function (e.g. use_stdout) and moves cursor to the next line.
a | atom to dump |
level | level 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 init_output | ( | outter_t | new_outter | ) |
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 | ||
) |
new_inner | new inner function |
new_inner_eof | new 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; }
int stats_free |
FILE* input_stream |
FILE* output_stream |
int outter_size |
struct lconv* locale_info |