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

Defines

#define EXTERNAPI   __attribute__((used,noinline,regparm(0),stdcall))
#define C_TYPES   17
#define GET_NEXT_TYPE   prototype = CDR( prototype )
#define GET_NEXT_DATA   protodata = CDR( protodata )

Functions

atom_t EXTERNAPI i1_to_atom (signed char data)
atom_t EXTERNAPI i2_to_atom (signed short data)
atom_t EXTERNAPI i4_to_atom (signed int data)
atom_t EXTERNAPI i8_to_atom (int64_t data)
atom_t EXTERNAPI u1_to_atom (unsigned char data)
atom_t EXTERNAPI u2_to_atom (unsigned short data)
atom_t EXTERNAPI u4_to_atom (unsigned int data)
atom_t EXTERNAPI u8_to_atom (int64_t data)
atom_t EXTERNAPI f4_to_atom (float data)
atom_t EXTERNAPI f8_to_atom (float64_t data)
atom_t EXTERNAPI v0_to_atom (void)
atom_t EXTERNAPI p4_to_atom (void *data)
atom_t EXTERNAPI s2_to_atom (chars_t data)
atom_t EXTERNAPI s1_to_atom (char *data)
signed char EXTERNAPI atom_to_i1 (atom_t data)
signed short EXTERNAPI atom_to_i2 (atom_t data)
signed int EXTERNAPI atom_to_i4 (atom_t data)
int64_t EXTERNAPI atom_to_i8 (atom_t data)
unsigned char EXTERNAPI atom_to_u1 (atom_t data)
unsigned short EXTERNAPI atom_to_u2 (atom_t data)
unsigned int EXTERNAPI atom_to_u4 (atom_t data)
int64_t EXTERNAPI atom_to_u8 (atom_t data)
float EXTERNAPI atom_to_f4 (atom_t data)
float64_t EXTERNAPI atom_to_f8 (atom_t data)
void EXTERNAPI atom_to_v0 (atom_t data)
void *EXTERNAPI atom_to_p4 (atom_t data)
atom_t unique_word (atom_t data)
chars_t EXTERNAPI atom_to_s2 (atom_t data)
char *EXTERNAPI atom_to_s1 (atom_t data)
int type_info (atom_t type)
 gets C-type info
atom_t type_value (int static_link, atom_t parent, atom_t type)
 gets the value of a type variable
int get_c_type (int static_link, atom_t parent, atom_t type)
 gets the C-type of a type
atom_t traverse_pack (int static_link, atom_t parent, atom_t prototype, atom_t protodata, char *ptr, int mode)
 traverses packed data

Variables

typeid_t c_types [C_TYPES]

Define Documentation

#define EXTERNAPI   __attribute__((used,noinline,regparm(0),stdcall))
#define C_TYPES   17
#define GET_NEXT_TYPE   prototype = CDR( prototype )
#define GET_NEXT_DATA   protodata = CDR( protodata )

Function Documentation

atom_t EXTERNAPI i1_to_atom ( signed char  data)
{ RETURN(new_integer( data )); }
atom_t EXTERNAPI i2_to_atom ( signed short  data)
{ RETURN(new_integer( data )); }
atom_t EXTERNAPI i4_to_atom ( signed int  data)
{ RETURN(new_integer( data )); }
atom_t EXTERNAPI i8_to_atom ( int64_t  data)
{ RETURN(new_integer( data )); }
atom_t EXTERNAPI u1_to_atom ( unsigned char  data)
{ RETURN(new_integer( data )); }
atom_t EXTERNAPI u2_to_atom ( unsigned short  data)
{ RETURN(new_integer( data )); }
atom_t EXTERNAPI u4_to_atom ( unsigned int  data)
{ RETURN(new_integer( data )); }
atom_t EXTERNAPI u8_to_atom ( int64_t  data)
{ RETURN(new_integer( data )); }
atom_t EXTERNAPI f4_to_atom ( float  data)
{ RETURN(new_float( data )); }
{ RETURN(new_float( data )); }
{ RETURN(new_integer( (int)data )); }
{
  int len = STRLEN( data );
  chars_t w = ALLOC((len+1)*CHAR_SIZE);
  memcpy( w, data, (len+1)*CHAR_SIZE);
  RETURN(new_word( w, len ));
}
atom_t EXTERNAPI s1_to_atom ( char *  data)
{
  RETURN(new_word(ASCII_to_UTF16 (data), -1));
}
signed char EXTERNAPI atom_to_i1 ( atom_t  data)
{ int64_t i; atom_to_int( data, &i ); return i; }
signed short EXTERNAPI atom_to_i2 ( atom_t  data)
{ int64_t i; atom_to_int( data, &i ); return i; }
signed int EXTERNAPI atom_to_i4 ( atom_t  data)
{ int64_t i; atom_to_int( data, &i ); return i; }
int64_t EXTERNAPI atom_to_i8 ( atom_t  data)
{ int64_t i; atom_to_int( data, &i ); return i; }
unsigned char EXTERNAPI atom_to_u1 ( atom_t  data)
{ int64_t i; atom_to_int( data, &i ); return i; }
unsigned short EXTERNAPI atom_to_u2 ( atom_t  data)
{ int64_t i; atom_to_int( data, &i ); return i; }
unsigned int EXTERNAPI atom_to_u4 ( atom_t  data)
{ int64_t i; atom_to_int( data, &i ); return i; }
int64_t EXTERNAPI atom_to_u8 ( atom_t  data)
{ int64_t i; atom_to_int( data, &i ); return i; }
float EXTERNAPI atom_to_f4 ( atom_t  data)
{ float64_t i; atom_to_float( data, &i ); return i; }
{ float64_t i; atom_to_float( data, &i ); return i; }
{ return; }
                                                   {
  if( IS_MEM(data) )
  {
    return MEMORY(data);
  };
  int64_t i;
  atom_to_int( data, &i );
  return (void*)((int)i);
}
{
  if( IS_SUBWORD(data) ) data = new_word( STRING(data), LENGTH(data) );
  if( !IS_WORD(data)   ) data = atom_to_word( data );
  if( !IS_WORD(data)   ) data = new_word( TEXT(""), -1 );
  return USE(data);
}
{
  data = unique_word( data );
  delayed_free = new_list( data, delayed_free );
  return STRING(data);
}
char* EXTERNAPI atom_to_s1 ( atom_t  data)
{
  data = unique_word( data );
  
  char* c = UTF16_to_ASCII( STRING(data) );
  DEUSE( data );
  
  data = new_mem( 0 );
  DEALLOC( MEMORY(data) );
  MEMORY(data)   = c;

  delayed_free = new_list( data, delayed_free );

  return c;
}
int type_info ( atom_t  type)
Parameters:
typeword containing type name
Returns:
C-type of the data

Examines the value of type which must be a 2-character word. Returns an index of the type which can be used with array c c_types[] to get more details.

{
  if( IS_LIST(type) ) return C_TYPE_STRUCT;
    
#ifdef SAFE_MODE
  assert( IS_ANY_WORD(type) );
#endif
  
  // check whether the word is: i1 i2 i4 i8 u1 u2 u4 u8 f4 f8 v0 p4 a4 s1 s2
  if( LENGTH(type)==2 )
  {
    char_t ch1 = TOUPPER(*(STRING(type)));
    char_t ch2 = *(STRING(type)+1);
    int i;
    for( i=2; i<C_TYPES; i++ ) // skip 0-th and 1-st elements
    {
      //printf("compare index=%d %C %C\n",i,*c_types[i].name,*(c_types[i].name+1));
      if( ch1==*c_types[i].name && ch2==*(c_types[i].name+1) )
      {
        //printf("type_info("); dump(type); printf(")=%d\n",i);
        return i;
      }
    }
  }
  
  //printf("type_info("); dump(type); printf(")=0\n");
  return C_TYPE_UNKNOWN;
}
atom_t type_value ( int  static_link,
atom_t  parent,
atom_t  type 
)
Parameters:
static_linkstatic link from the current frame
parentcurrent parent
typeword containing type name
Returns:
value or unbound

Assumes that type is a name of a type variable and returns its value. If it is not a variable or has no value then return unbound atom.

{
  atom_t var = find_runtime_var( type, static_link );

  // not found or not a var then exit
  if( !var || !IS_VARIABLE( var ) ) return unbound;

  // get the value and try again to calculate type size
  if( IS_RUNTIME( var ) )
    return VALUE( var );
  else
    return rt_var_value( static_link, parent, var );
}
int get_c_type ( int  static_link,
atom_t  parent,
atom_t  type 
)
Parameters:
static_linkstatic link from the current frame
parentcurrent parent
typeword containing type name
Returns:
index of C-type

This function finds the C-type index of a type. This index can be used with c_types[] array to get additional information about the C-type.

This function does not recurse into struct types.

{
  int c_type;
  
try_again:
  c_type = type_info( type );
  if( c_type==C_TYPE_UNKNOWN )
  {
    type = type_value( static_link, parent, type );
    if( IS_UNBOUND(type) ) return C_TYPE_UNKNOWN;
    goto try_again;
  }
  return c_type;
}
atom_t traverse_pack ( int  static_link,
atom_t  parent,
atom_t  prototype,
atom_t  protodata,
char *  ptr,
int  mode 
)
Parameters:
static_linkstatic link from the current frame
parentcurrent parent
prototypelist describing the c-type in the pack
protodatalist containing the Logo data
ptrpointer to memory with C data
modemode of traversal
Returns:
traversal result (depends on the mode)

This function traverses a structure defined by c-type prototype and performs an action determined by mode.

If mode is MEM_STRUCT_SIZE then only the size of the packed data is calculated. Parameters protodata and ptr are not used. The returned value is an integer atom containing the size.

If mode is MEM_STRUCT_PACK then Logo data from protodata is packed into the memory pointed to by ptr using the structure described in prototype. The result is unbound atom.

If mode is MEM_STRUCT_UNPACK then packed data from ptr is unpacked into a list of Logo data using the structure described in prototype . The result of traverse_pack is the list of Logo data.

{
  int ofs = 0;
  atom_t new_type;
  
  atom_t traverse( atom_t prototype, atom_t protodata )
  {
    atom_t result = unbound;
    atom_t result_end;
    
    // check prototype list
    if (IS_ERROR( prototype )) return prototype;
    if (!IS_LIST( prototype )) return new_error( ERROR_NOT_A_LIST, prototype );

    // check data list
    if (IS_ERROR( protodata )) return protodata;
    if (!IS_LIST( protodata )) return new_error( ERROR_NOT_A_LIST, protodata );

    if( mode==MEM_STRUCT_UNPACK )
    {
      result = empty_list;
      result_end = empty_list;
    }
    
    int count = 1;
    
#define GET_NEXT_TYPE   prototype = CDR( prototype )
#define GET_NEXT_DATA   protodata = CDR( protodata )

    // scan all elements of the prototype
    for (; IS_NOT_EMPTY( prototype ); )
    {
      atom_t type = CAR( prototype );
      atom_t data = CAR( protodata );

try_again:

      // list prototypes are processed recursively
      if( IS_LIST(type) )
      {
        atom_t res = traverse( type, data );
        if( IS_ERROR(res) ) return res;
        if( mode==MEM_STRUCT_UNPACK ) append( res, &result, &result_end );
        goto to_continue;
      }

      // other non-word prototypes are not accepted
      if( IS_INTEGER(type) || IS_FLOAT(type) ) goto its_a_number;
      if( !IS_ANY_WORD(type) ) return new_error(ERROR_NOT_A_TYPE_NAME,type);

      int type_id = type_info( type );
      int type_size = c_types[type_id].size;
      switch( c_types[type_id].class )
      {
        case C_TYPE_POINTER:
          {
            int64_t i = 0;
            if( mode==MEM_STRUCT_PACK )
            {
              if( !IS_EMPTY( data ) )
              {
                if( IS_MEM(data) )
                  i = (int)MEMORY(data);
                else
                  GET_INT( data, i );
              }
              *(int*)(ptr+ofs) = (int)i;
            }
            if( mode==MEM_STRUCT_UNPACK )
            {
              i = *(int*)(ptr+ofs);
              append( new_integer(i), &result, &result_end );
            }
            ofs += type_size/8;
            goto to_continue;
          }
        case C_TYPE_ATOM:
          {
            atom_t i = 0;
            if( mode==MEM_STRUCT_PACK )
            {
              break;
            }
            if( mode==MEM_STRUCT_UNPACK )
            {
              i = *(atom_t*)(ptr+ofs);
              append( USE(i), &result, &result_end );
            }
            ofs += type_size/8;
            goto to_continue;
          }
        case C_TYPE_FLOAT:
          {
            float64_t i = 0;
            if( mode==MEM_STRUCT_PACK )
            {
              if( !IS_EMPTY( data ) ) GET_FLOAT( data, i );
              switch( type_size ) 
              {                   
                case 32: *(float32_t*)(ptr+ofs) = i; break;
                case 64: *(float64_t*)(ptr+ofs) = i; break;
                default: goto subtype_test;
              }
            }
            if( mode==MEM_STRUCT_UNPACK )
            {
              switch( type_size )
              {                   
                case 32: i = *(float32_t*)(ptr+ofs); break;
                case 64: i = *(float64_t*)(ptr+ofs); break;
                default: goto subtype_test;
              }
              append( new_float(i), &result, &result_end );
            }
            ofs += type_size/8;
            goto to_continue;
          }

        case C_TYPE_SIGNED:
          {
              int64_t i = 0;
              if( mode==MEM_STRUCT_PACK )
              {
                if( !IS_EMPTY( data ) ) GET_INT( data, i );
                switch( type_size ) 
                {                   
                  case  8: *(int8_t*) (ptr+ofs) = i; break;
                  case 16: *(int16_t*)(ptr+ofs) = i; break;
                  case 32: *(int32_t*)(ptr+ofs) = i; break;
                  case 64: *(int64_t*)(ptr+ofs) = i; break;
                  default: goto subtype_test;
                }
              }
              if( mode==MEM_STRUCT_UNPACK )
              {
                switch( type_size ) 
                {                   
                  case  8: i = *(int8_t*) (ptr+ofs); break;
                  case 16: i = *(int16_t*)(ptr+ofs); break;
                  case 32: i = *(int32_t*)(ptr+ofs); break;
                  case 64: i = *(int64_t*)(ptr+ofs); break;
                  default: goto subtype_test;
                }
                append( new_integer(i), &result, &result_end );
              }
              ofs += type_size/8;
              goto to_continue;
            }
        case C_TYPE_UNSIGNED:
            {
              int64_t i = 0;
              if( mode==MEM_STRUCT_PACK )
              {
                if( !IS_EMPTY( data ) ) GET_INT( data, i );\
                switch( type_size ) 
                {                   
                  case  8: *(uint8_t*) (ptr+ofs) = i; break;
                  case 16: *(uint16_t*)(ptr+ofs) = i; break;
                  case 32: *(uint32_t*)(ptr+ofs) = i; break;
                  case 64: *(uint64_t*)(ptr+ofs) = i; break;
                  default: goto subtype_test;
                }
              }
              if( mode==MEM_STRUCT_UNPACK )
              {
                switch( type_size ) 
                {                   
                  case  8: i = *(uint8_t*) (ptr+ofs); break;
                  case 16: i = *(uint16_t*)(ptr+ofs); break;
                  case 32: i = *(uint32_t*)(ptr+ofs); break;
                  case 64: i = *(uint64_t*)(ptr+ofs); break;
                  default: goto subtype_test;
                }
                append( new_integer(i), &result, &result_end );
              }
              ofs += type_size/8;
              goto to_continue;
            }
      }

   subtype_test:
      new_type = type_value( static_link, parent, type );
      if( IS_UNBOUND(new_type) )
      {
   its_a_number:
        if( atom_to_integer( type, &count ) )
        {
          GET_NEXT_TYPE;
          continue;
        }
        return USE(new_error( ERROR_NOT_A_TYPE_NAME, type ));
      }
      type = new_type;
      
      goto try_again;
      
   to_continue:
      count--;
      if( !count )
      {
        count = 1;
        GET_NEXT_TYPE;
      }
      GET_NEXT_DATA;
    } //for

    return result ;
  }

  atom_t res = traverse( prototype, protodata );
  if( IS_ERROR(res) ) return res;
  
  // if there is no target pointer, then just return the size  
  if( mode==MEM_STRUCT_SIZE ) return new_integer( ofs );

  return res;
}

Variable Documentation

Initial value:
{
  { TEXT(""),     0, C_TYPE_UNKNOWN,  0, 0, TEXT(""), TEXT("") }, 
  { TEXT(""),     0, C_TYPE_STRUCT,   0, 0, TEXT(""), TEXT("") }, 
  { TEXT("I1"),   8, C_TYPE_SIGNED,   (fn)i1_to_atom, (fn)atom_to_i1, TEXT("i1_to_atom"), TEXT("atom_to_i1") },
  { TEXT("I2"),  16, C_TYPE_SIGNED,   (fn)i2_to_atom, (fn)atom_to_i2, TEXT("i2_to_atom"), TEXT("atom_to_i2") },
  { TEXT("I4"),  32, C_TYPE_SIGNED,   (fn)i4_to_atom, (fn)atom_to_i4, TEXT("i4_to_atom"), TEXT("atom_to_i4") },
  { TEXT("I8"),  64, C_TYPE_SIGNED,   (fn)i8_to_atom, (fn)atom_to_i8, TEXT("i8_to_atom"), TEXT("atom_to_i8") },
  { TEXT("U1"),   8, C_TYPE_UNSIGNED, (fn)u1_to_atom, (fn)atom_to_u1, TEXT("u1_to_atom"), TEXT("atom_to_u1") },
  { TEXT("U2"),  16, C_TYPE_UNSIGNED, (fn)u2_to_atom, (fn)atom_to_u2, TEXT("u2_to_atom"), TEXT("atom_to_u2") },
  { TEXT("U4"),  32, C_TYPE_UNSIGNED, (fn)u4_to_atom, (fn)atom_to_u4, TEXT("u4_to_atom"), TEXT("atom_to_u4") },
  { TEXT("U8"),  64, C_TYPE_UNSIGNED, (fn)u8_to_atom, (fn)atom_to_u8, TEXT("u8_to_atom"), TEXT("atom_to_u8") },
  { TEXT("F4"),  32, C_TYPE_FLOAT,    (fn)f4_to_atom, (fn)atom_to_f4, TEXT("f4_to_atom"), TEXT("atom_to_f4") },
  { TEXT("F8"),  64, C_TYPE_FLOAT,    (fn)f8_to_atom, (fn)atom_to_f8, TEXT("f8_to_atom"), TEXT("atom_to_f8") },
  { TEXT("V0"),   0, C_TYPE_VOID,     (fn)v0_to_atom, (fn)atom_to_v0, TEXT("v0_to_atom"), TEXT("atom_to_v0") },
  { TEXT("P4"),  32, C_TYPE_POINTER,  (fn)p4_to_atom, (fn)atom_to_p4, TEXT("p4_to_atom"), TEXT("atom_to_p4") },
  { TEXT("A4"),  32, C_TYPE_ATOM,     (fn)NULL,       (fn)NULL,       TEXT(""),           TEXT("")           },
  { TEXT("S1"),  32, C_TYPE_STRING,   (fn)s1_to_atom, (fn)atom_to_s1, TEXT("s1_to_atom"), TEXT("atom_to_s1") },

  { TEXT("S2"),  32, C_TYPE_STRING,   (fn)s2_to_atom, (fn)atom_to_s2, TEXT("s2_to_atom"), TEXT("atom_to_s2") },

}

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