X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/blobdiff_plain/dd3c57bc8cac59e0d657ee665ce462988d27d714..18c831dcd0ae4d660c70ccac69d27ed2a97851be:/struct/atom.h diff --git a/struct/atom.h b/struct/atom.h new file mode 100644 index 0000000..430f23b --- /dev/null +++ b/struct/atom.h @@ -0,0 +1,183 @@ +/* -*-c-*- + * + * Atom management + * + * (c) 2000 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of the mLib utilities library. + * + * mLib is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * mLib 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 Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with mLib; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef MLIB_ATOM_H +#define MLIB_ATOM_H + +#ifdef __cplusplus + extern "C" { +#endif + +/*----- Header files ------------------------------------------------------*/ + +#ifndef MLIB_SYM_H +# include "sym.h" +#endif + +/*----- Data structures ---------------------------------------------------*/ + +typedef struct atom_table { + sym_table t; /* Symbol table of interned atoms */ + hash_base *g; /* List of uninterned atoms */ + unsigned long gseq; /* Sequence number for @gensym@ */ +} atom_table; + +typedef struct atom { + sym_base b; /* Base structure for symbol table */ + unsigned f; /* Various useful flags */ +} atom; + +#define ATOMF_GENSYM 1u /* Atom is uninterned */ + +typedef struct { sym_iter i; } atom_iter; + +/*----- Global magic ------------------------------------------------------*/ + +#define ATOM_GLOBAL 0 + +/*----- Functions provided ------------------------------------------------*/ + +/* --- @atom_createtable@ --- * + * + * Arguments: @atom_table *t@ = pointer to an atom table + * + * Returns: --- + * + * Use: Initializes an atom table. + */ + +extern void atom_createtable(atom_table */*t*/); + +/* --- @atom_destroytable@ --- * + * + * Arguments: @atom_table *t@ = pointer to an atom table + * + * Returns: --- + * + * Use: Destroys all of the atoms in an atom table. All of the atoms + * (including uninterned atoms) are freed. Any references to + * atoms from the table become invalid, and any association + * tables dependent on the atom table are unusable, except that + * they may be destroyed safely. + */ + +extern void atom_destroytable(atom_table */*t*/); + +/* --- @atom_intern@ --- * + * + * Arguments: @atom_table *t@ = pointer to an atom table + * @const char *p@ = pointer to the string to intern + * @size_t n@ = size of the string (for @atom_nintern) + * + * Returns: A pointer to the atom block for the given symbol string. + * + * Use: Interns an atom, returning the atom block. The string can be + * extracted from the atom by means of the @ATOM_NAME@ macro. + */ + +#define INTERN(p) atom_intern(ATOM_GLOBAL, (p)) + +extern atom *atom_intern(atom_table */*t*/, const char */*p*/); +extern atom *atom_nintern(atom_table */*t*/, + const char */*p*/, size_t /*n*/); + +/* --- @atom_gensym@ --- * + * + * Arguments: @atom_table *t@ = pointer to a symbol table + * + * Returns: A pointer to a new atom block, not previously interned. + * + * Use: Creates a new, uninterned atom. This atom will never be + * returned by either @atom_intern@ or any other call to + * @atom_gensym@, while the symbol table exists. + */ + +#define GENSYM atom_gensym(ATOM_GLOBAL) + +extern atom *atom_gensym(atom_table */*t*/); + +/* --- @atom_name@ --- * + * + * Arguments: @atom *a@ = pointer to an atom + * + * Returns: The atom's textual name. + * + * Use: Given an atom, returns the name with which it was interned + * (or a made-up name if it was created using @gensym@. + */ + +#define ATOM_NAME(a) SYM_NAME(a) + +extern const char *atom_name(const atom */*a*/); + +/* --- @atom_len@ --- * + * + * Arguments: @atom *a@ = pointer to an atom + * + * Returns: The atom string's length. + * + * Use: Given an atom, return the length of its textual + * representation. + */ + +#define ATOM_LEN(a) SYM_LEN(a) + +extern size_t atom_len(const atom */*a*/); + +/* --- @atom_hash@ --- * + * + * Arguments: @atom *a@ = pointer to an atom + * + * Returns: The atom's hash. + * + * Use: Given an atom, returns its hash. + */ + +#define ATOM_HASH(a) SYM_HASH(a) + +extern uint32 atom_hash(const atom */*a*/); + +/* --- @atom_mkiter@ , @atom_next@ --- * + * + * Arguments: @atom_table *t@ = pointer to an atom table + * @atom_iter *i@ = pointer to an iterator structure + * + * Returns: Next atom, for @atom_next@; nothing for @atom_mkiter@. + * + * Use: Iterates over atoms (both interned and uninterned). + */ + +extern void atom_mkiter(atom_iter */*i*/, atom_table */*t*/); +extern atom *atom_next(atom_iter */*i*/); + +/*----- That's all, folks -------------------------------------------------*/ + +#ifdef __cplusplus + } +#endif + +#endif