Logo Search packages:      
Sourcecode: fenix version File versions  Download package

identifier.c

/*
 *  Fenix - Videogame compiler/interpreter
 *  Current release       : FENIX - PROJECT 1.0 - R 0.84
 *  Last stable release   :
 *  Project documentation : http://fenix.divsite.net
 *
 *
 *  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.
 *
 *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 *  Copyright © 1999 José Luis Cebrián Pagüe
 *  Copyright © 2002 Fenix Team
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef TARGET_BEOS
#include <posix/assert.h>
#else
#include <assert.h>
#endif
#include "token.h"
#include "identifiers.h"
#include "compiler.h"

/* ---------------------------------------------------------------------- */
/* Gestor de identificadores                                              */
/* ---------------------------------------------------------------------- */

static identifier * identifier_hash[64] ;
static int          identifier_code = 1 ;
int                 identifier_count = 0 ;

int identifier_hash_value (const char * string)
{
      int t = 0 ;
      const char * ptr = string ;

/*    while (*ptr) t = (t << 1) | *ptr++ ; */
      while (*ptr) t = (t << 3) | ( (*ptr++) & 0x07 ) ; /* Mejor dispersion en el hashing */

      return (t & 63) ;
}

identifier * identifier_first()
{
      int n ;

      for (n = 0 ; n < 64 ; n++)
      {
            if (identifier_hash[n])
                  return identifier_hash[n] ;
      }
      return 0 ;
}

identifier * identifier_next (identifier * id)
{
      int n ;

      if (id->next) return id->next ;

      n = identifier_hash_value (id->name) ;
      for (n++ ; n < 64 ; n++)
      {
            if (identifier_hash[n])
                  return identifier_hash[n] ;
      }
      return 0 ;
}

void identifier_init ()
{
      int i ;

      for (i = 0 ; i < 64 ; i++) identifier_hash[i] = 0 ;

      identifier_count = 0 ;
      identifier_code = 1 ;
}

void identifier_dump ()
{
      int i, ii ;
      identifier * ptr ;

      printf ("---- %d identifiers ----\n", identifier_count) ;
      for (i = 0 ; i < 64 ; i++)
      {
            ptr = identifier_hash[i] ;
            ii = 0;
            while (ptr)
            {
                  ii++;
                  printf ("%4d: %-32s [%04d] [%3d]\n", ptr->code, ptr->name, i, ii) ;
                  ptr = ptr->next ;
            }
      }
}

int identifier_add_as (const char * string, int code)
{
      int hash = identifier_hash_value(string) ;
      identifier * w = (identifier *)malloc(sizeof(identifier)) ;

      if (!w)
      {
            fprintf (stdout, "identifier_add: sin memoria\n") ;
            exit(1);
      }

      w->name = strdup(string) ;
      if (!w->name)
      {
            fprintf (stdout, "identifier_add: sin memoria\n") ;
            exit(1);
      }
      w->line = line_count ; // Save First appearance
      w->f = current_file ;  // Save File info
      w->code = code ;
      w->next = identifier_hash[hash] ;
      identifier_hash[hash] = w ;
      identifier_count++ ;

      return 1 ;
}

int identifier_add (const char * string)
{
      int code = identifier_code++ ;
      if (!identifier_add_as (string, code)) return 0 ;
      return code ;
}

int identifier_search (const char * string)
{
      int hash = identifier_hash_value (string) ;
      identifier * ptr = identifier_hash[hash] ;

      while (ptr)
      {
            assert (ptr->name) ;
            if (ptr->name[0] == *string)
            {
                  if (strcmp (string, ptr->name) == 0)
                        break ;
            }
            ptr = ptr->next ;
      }
      return ptr ? ptr->code : 0 ;
}

// Return line for the identifier
int identifier_line (int code)
{
int i ;
      identifier * ptr ;

      for (i = 0 ; i < 64 ; i++)
      {
            ptr = identifier_hash[i] ;
            while (ptr)
            {
                  if (ptr->code == code) {
                        return ptr->line ;
                  }
                  ptr = ptr->next ;
            }
      }
      return 0 ;
}

// Return file for the identifier
int identifier_file (int code)
{
int i ;
      identifier * ptr ;

      for (i = 0 ; i < 64 ; i++)
      {
            ptr = identifier_hash[i] ;
            while (ptr)
            {
                  if (ptr->code == code) {
                        return ptr->f ;
                  }
                  ptr = ptr->next ;
            }
      }
      return 0 ;
}

const char * identifier_name (int code)
{
      int i ;
      identifier * ptr ;

      for (i = 0 ; i < 64 ; i++)
      {
            ptr = identifier_hash[i] ;
            while (ptr)
            {
                  if (ptr->code == code) {
                        return ptr->name ;
                  }
                  ptr = ptr->next ;
            }
      }
      return 0 ;
}

int identifier_search_or_add (const char * string)
{
      int result ;

      result = identifier_search (string) ;
      return result ? result : identifier_add (string) ;
}

int identifier_next_code ()
{
      return identifier_code ;
}

int identifier_is_basic_type (int id)
{
      return (
            id == identifier_int ||
            id == identifier_short ||
            id == identifier_char ||
            id == identifier_dword ||
            id == identifier_word ||
            id == identifier_byte ||
            id == identifier_signed ||
            id == identifier_unsigned ||
            id == identifier_float ||
            id == identifier_string
            );
}

int identifier_is_type (int id)
{
      return identifier_is_basic_type(id) || segment_by_name(id) != NULL;
}


Generated by  Doxygen 1.6.0   Back to index