OpenCores
URL https://opencores.org/ocsvn/copyblaze/copyblaze/trunk

Subversion Repositories copyblaze

[/] [copyblaze/] [trunk/] [copyblaze/] [sw/] [tools/] [asm/] [pBlazASM/] [pBlazASM/] [pbSymbols.c] - Rev 2

Compare with Previous | Blame | View Log

/*
 *  Copyright © 2003..2010 : Henk van Kampen <henk@mediatronix.com>
 *
 *	This file is part of pBlazASM.
 *
 *  pBlazASM 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 3 of the License, or
 *  (at your option) any later version.
 *
 *  pBlazASM 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 pBlazASM.  If not, see <http://www.gnu.org/licenses/>.
 */
 
/*! \file
 * Implements a closed hash table, with linear probing, with an increment of 1
 */
 
#include <malloc.h>
#include <stdio.h>
#include <ctype.h>
#include <stdint.h>
#include <string.h>
 
#include "pbTypes.h"
#include "pbSymbols.h"
#include "pbOpcodes.h"
#include "pbDirectives.h"
 
// our symbol table
#define SIZE 4096UL
static symbol_t symbols[ SIZE ] ;
 
//! \fn static uint32_t hash( const char * text )
//  \brief hash function, free after Donald Knuth
//  \param text string to hash
static uint32_t hash( const char * text ) {
	uint64_t r = 0 ;
	int i ;
 
	if ( text != NULL ) {
		for ( i = 0 ; i < strlen( text ) ; i += 1 )
			r ^= 0x9E3779B1 * text[ i ] ;
		return r & ( SIZE - 1 ) ;
	} else
		return 0xFFFFFFFF ;
}
 
// add all known words, our keywords
 
static void add_keyword( const symbol_t * sym ) {
	add_symbol( sym->type, sym->subtype, sym->text, sym->value ) ;
}
 
void init_symbol( void ) {
	int h ;
 
	// clear table
	for ( h = 0 ; h < SIZE ; h += 1 ) {
		symbols[ h ].type = tNONE ;
		symbols[ h ].text = NULL ;
		symbols[ h ].value = 0 ;
	}
	// add keywords
	for ( h = 0 ; h < sizeof( opcodes ) / sizeof(symbol_t) ; h += 1 )
		add_keyword( &opcodes[ h ] ) ;
	for ( h = 0 ; h < sizeof( conditions ) / sizeof(symbol_t) ; h += 1 )
		add_keyword( &conditions[ h ] ) ;
	for ( h = 0 ; h < sizeof( indexes ) / sizeof(symbol_t) ; h += 1 )
		add_keyword( &indexes[ h ] ) ;
	for ( h = 0 ; h < sizeof( directives ) / sizeof(symbol_t) ; h += 1 )
		add_keyword( &directives[ h ] ) ;
	for ( h = 0 ; h < sizeof( registers ) / sizeof(symbol_t) ; h += 1 )
		add_keyword( &registers[ h ] ) ;
}
 
// find a symbol, returns the found symbol, or NULL
symbol_t * find_symbol( const char * text, bool bUpper ) {
	int h, p ;
	char buf[ 256 ], *s ;
 
	if (!text)
		return NULL ;
 
	// uppercase only?
	strcpy( buf, text ) ;
	for ( s = buf ; bUpper && *s != '\0' ; s++ )
		*s = toupper( *s ) ;
 
	// compute 1st entry
	p = hash( buf ) ;
	if ( p == 0xFFFFFFFF )
		return NULL ;
	// if empty spot, not found
	if ( symbols[ p ].text == NULL )
		return NULL ;
	// if text is equal, found
	if ( strcmp( symbols[ p ].text, buf ) == 0 )
		return &symbols[ p ] ;
	// else maybe next entry
	for ( h = ( p + 1 ) & ( SIZE - 1 ) ; h != p ; h = ( h + 1 ) & ( SIZE - 1 ) ) {
		if ( symbols[ h ].text == NULL )
			return NULL ;
		if ( strcmp( symbols[ h ].text, buf ) == 0 )
			return &symbols[ h ] ;
	}
	return NULL ; // unlikely
}
 
// add a symbol, rehashing is by linear probing
// returns false if we want to add an already known symbol
bool add_symbol( const type_e type, const subtype_e subtype, const char * text, const uint32_t value ) {
	int p = hash( text ) ;
	int h = p ;
 
	if ( p == 0xFFFFFFFF )
		return false ;
	do {
		if ( symbols[ h ].text == NULL ) { // if empty spot, put it here
			symbols[ h ].type = type ;
			symbols[ h ].subtype = subtype ;
			symbols[ h ].text = strdup( text ) ;
			symbols[ h ].value = value ;
			return true ;
		} else if ( strcmp( symbols[ h ].text, text ) == 0 ) { // if text is equal, already there?
			if ( symbols[ h ].type == type && symbols[ h ].subtype == subtype && symbols[ h ].value == value )
				return false ; // really same?
		}
		h = ( h + 1 ) & ( SIZE - 1 ) ; // wrap
	} while ( h != p ) ; // full ?
	return false ;
}
 
// debug
void dump_map( void ) {
	int h = 0 ;
	int count = 0 ;
 
	for ( h = 0 ; h < SIZE ; h += 1 )
		if ( symbols[ h ].type != tNONE && symbols[ h ].text != NULL )
			printf(
					"%d-%d: %s, %d, %d, %d\n", h, count += 1, symbols[ h ].text, symbols[ h ].value, symbols[ h ].type,
					symbols[ h ].subtype ) ;
}
 
// free any allocated storage
void free_symbol( void ) {
	int h ;
 
	for ( h = 0 ; h < SIZE ; h += 1 ) {
		symbols[ h ].type = tNONE ;
		if ( symbols[ h ].text != NULL )
			free( symbols[ h ].text ) ;
		symbols[ h ].text = NULL ;
		symbols[ h ].value = 0 ;
	}
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.