221 lines · 5.6 KB · C++
RawDownload
/*----------------------------------------------------------------------------  ChucK Concurrent, On-the-fly Audio Programming Language    Compiler and Virtual Machine   Copyright (c) 2004 Ge Wang and Perry R. Cook.  All rights reserved.    http://chuck.stanford.edu/    http://chuck.cs.princeton.edu/   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  U.S.A.-----------------------------------------------------------------------------*/ //-----------------------------------------------------------------------------// file: chuck_table.cpp// desc: chuck table implementation for parsers//// No algorithm should use these functions directly, because// programming with void* is too error-prone.  Instead,// each module should make "wrapper" functions that take// well-typed arguments and call the TAB_ functions.//// copyright (c) 1997 Andrew W. Appel.//// original author: Andrew Appel (appel@cs.princeton.edu)// modified: Ge Wang (gewang@cs.princeton.edu)// date: Autumn 2002//-----------------------------------------------------------------------------#include "chuck_table.h"#include "chuck_utils.h"#include <stdio.h>#include <string.h> #define TABSIZE 65437  typedef struct binder_ *binder;struct binder_ {void *key; void *value; binder next; void *prevtop;};struct TAB_table_ {  unsigned long size;  binder * table;  void * top;  TAB_eq_func eq_func;  TAB_hash_func hash_func;};  static binder Binder(void *key, void *value, binder next, void *prevtop){    binder b = (binder)checked_malloc(sizeof(struct binder_));    b->key = key; b->value=value; b->next=next; b->prevtop = prevtop;    return b;}  TAB_table TAB_empty(void){    return TAB_empty2(TABSIZE);}  TAB_table TAB_empty2( unsigned long s ){    TAB_table t = (TAB_table)checked_malloc(sizeof(struct TAB_table_));    unsigned long i;    t->table = (binder *)checked_malloc(sizeof(binder)*s);    t->size = s;    t->top = NULL;    t->eq_func = NULL;    t->hash_func = NULL;    for( i = 0; i < s; i++ )        t->table[i] = NULL;    return t;}  TAB_table TAB_empty3( TAB_eq_func eq, TAB_hash_func hash, unsigned long s ){    TAB_table t = TAB_empty2(s);    t->eq_func = eq;    t->hash_func = hash;    return t;}  void TAB_delete( TAB_table t ){    unsigned long i;    binder p = NULL, n = NULL;    for(i = 0; i < t->size; i++ )    {        p = t->table[i];        while( p )        {            n = p->next;            free(p);            p = n;        }    }     // free the table    free( t->table );    free( t );}   /* The cast from pointer to integer in the expression *   ((unsigned)key) % TABSIZE * may lead to a warning message.  However, the code is safe, * and will still operate correctly.  This line is just hashing * a pointer value into an integer value, and no matter how the * conversion is done, as long as it is done consistently, a * reasonable and repeatable index into the table will result. */ void TAB_enter(TAB_table t, void *key, void *value){    t_CKINT index;    t_CKUINT hval = (t_CKUINT)key;    assert(t && key);    if( t->hash_func )        hval = (t_CKUINT)t->hash_func(key);    index = hval % t->size;    t->table[index] = Binder(key, value, t->table[index], t->top);    t->top = key;} void *TAB_look(TAB_table t, void *key){    t_CKINT index;    t_CKUINT hval = (t_CKUINT)key;    binder b;    assert(t && key);    if( t->hash_func )        hval = (t_CKUINT)t->hash_func(key);    index= hval % t->size;    if( !t->eq_func )    {        for(b=t->table[index]; b; b=b->next)            if (b->key==key) return b->value;    }    else    {        for(b=t->table[index]; b; b=b->next)            if (t->eq_func(b->key, key)) return b->value;    }     return NULL;} void *TAB_pop(TAB_table t){    void *k; binder b; long index;    t_CKUINT hval;    assert (t);    k = t->top;    assert (k);    hval = (t_CKUINT)k;    if(t->hash_func) hval = (t_CKUINT)t->hash_func(k);    index = hval % t->size;    b = t->table[index];    assert(b);    t->table[index] = b->next;    t->top=b->prevtop;    return b->key;} void *TAB_topv(TAB_table t){    void *k; binder b; t_CKINT index;    t_CKUINT hval;    assert(t);    k = t->top;    assert(k);    hval = (t_CKUINT)k;    if(t->hash_func) hval = (t_CKUINT)t->hash_func(k);    index = hval % t->size;    b = t->table[index];    assert(b);    return b->value;} void TAB_dump(TAB_table t, void (*show)(void *key, void *value)){    void *k = t->top;    t_CKINT index = ((t_CKUINT)k) % t->size;    binder b = t->table[index];    if (b==NULL) return;    t->table[index]=b->next;    t->top=b->prevtop;    show(b->key,b->value);    TAB_dump(t,show);    assert(t->top == b->prevtop && t->table[index]==b->next);    t->top=k;    t->table[index]=b;} long str_eq( void * lhs, void * rhs ){    return !strcmp( (char *)lhs, (char *)rhs );} long str_hash( void * str ){    unsigned long h=0; char *s;    for(s=(char *)str; *s; s++)        h = h*65599 + *s;    return h;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t