mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
New symbol table code.
This commit is contained in:
parent
d764ef80d0
commit
782a4c9a8d
4 changed files with 357 additions and 2 deletions
|
@ -3,4 +3,4 @@ AUTOMAKE_OPTIONS= foreign
|
||||||
EXTRA_DIST= class.h cpp.h debug.h def.h emit.h expr.h function.h \
|
EXTRA_DIST= class.h cpp.h debug.h def.h emit.h expr.h function.h \
|
||||||
idstuff.h immediate.h linker.h method.h obj_file.h opcodes.h \
|
idstuff.h immediate.h linker.h method.h obj_file.h opcodes.h \
|
||||||
options.h qfcc.h qfprogs.h reloc.h strpool.h struct.h switch.h \
|
options.h qfcc.h qfprogs.h reloc.h strpool.h struct.h switch.h \
|
||||||
type.h
|
symtab.h type.h
|
||||||
|
|
199
tools/qfcc/include/symtab.h
Normal file
199
tools/qfcc/include/symtab.h
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
/*
|
||||||
|
symtab.h
|
||||||
|
|
||||||
|
Symbol table management
|
||||||
|
|
||||||
|
Copyright (C) 2011 Bill Currie <bill@taniwha.org>
|
||||||
|
|
||||||
|
Author: Bill Currie <bill@taniwha.org>
|
||||||
|
Date: 2011/01/04
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330
|
||||||
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __symtab_h
|
||||||
|
#define __symtab_h
|
||||||
|
|
||||||
|
/** \defgroup qfcc_symtab Symbol Table Management
|
||||||
|
\ingroup qfcc
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
sym_type,
|
||||||
|
sym_def,
|
||||||
|
sym_enum,
|
||||||
|
sym_class,
|
||||||
|
} sym_type_e;
|
||||||
|
|
||||||
|
typedef struct symbol_s {
|
||||||
|
struct symbol_s *next; ///< chain of symbols in symbol table
|
||||||
|
const char *name; ///< symbol name
|
||||||
|
sym_type_e type; ///< symbol type (typedef, var, struct...)
|
||||||
|
union {
|
||||||
|
struct type_s *type;
|
||||||
|
struct def_s *def;
|
||||||
|
struct enumval_s *enm;
|
||||||
|
struct class_s *class;
|
||||||
|
} s;
|
||||||
|
} symbol_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
stab_global, ///< global (many symbols)
|
||||||
|
stab_local, ///< local (few symbols: func, struct)
|
||||||
|
stab_union, ///< offset always 0
|
||||||
|
} stab_type_e;
|
||||||
|
|
||||||
|
typedef struct symtab_s {
|
||||||
|
struct symtab_s *parent; ///< points to parent table
|
||||||
|
struct symtab_s *next; ///< next in global collection of symtabs
|
||||||
|
stab_type_e type; ///< type of symbol table
|
||||||
|
struct hashtab_s *tab; ///< symbols defined in this table
|
||||||
|
symbol_t *symbols; ///< chain of symbols in this table
|
||||||
|
symbol_t **symtail; ///< keep chain in declaration order
|
||||||
|
} symtab_t;
|
||||||
|
|
||||||
|
/** Create a new, empty symbol table.
|
||||||
|
|
||||||
|
The symbol tables support scoping via their \c parent pointer. This
|
||||||
|
supports both code block scoping and ivar inheritance.
|
||||||
|
|
||||||
|
\param parent Pointer to parent scope symbol table.
|
||||||
|
\param type The type of symbol table. Currently governs expected size.
|
||||||
|
\return The new, empty symbol table.
|
||||||
|
*/
|
||||||
|
symtab_t *new_symtab (symtab_t *parent, stab_type_e type);
|
||||||
|
|
||||||
|
/** Lookup a name in the symbol table.
|
||||||
|
|
||||||
|
The entire symbol table chain (symtab_t::parent) starting at symtab
|
||||||
|
will be checked for \a name.
|
||||||
|
|
||||||
|
\param symtab The symbol table to search for \a name. If \a name is
|
||||||
|
not in the symbol table, the tables's parent, if it
|
||||||
|
exists, will be checked, and then its parent, until the
|
||||||
|
end of the chain.
|
||||||
|
\param name The name to look up in the symbol table chain.
|
||||||
|
*/
|
||||||
|
symbol_t *symtab_lookup (symtab_t *symtab, const char *name);
|
||||||
|
|
||||||
|
/** Add a named type (\c typedef) to the symbol table.
|
||||||
|
|
||||||
|
Duplicate names will not be inserted (an error), but only the given
|
||||||
|
symbol table is checked for duplicate names, not the ancestor chain.
|
||||||
|
|
||||||
|
\param symtab The symbol table to which the named type will be added.
|
||||||
|
\param name The name of the type to be added to the symbol table.
|
||||||
|
\param type The type to be added to the symbol table.
|
||||||
|
\return The new symbol representing the named type or null if
|
||||||
|
an error occurred.
|
||||||
|
*/
|
||||||
|
symbol_t *symtab_add_type (symtab_t *symtab, const char *name,
|
||||||
|
struct type_s *type);
|
||||||
|
|
||||||
|
/** Add a def to the symbol table.
|
||||||
|
|
||||||
|
Duplicate names will not be inserted (an error), but only the given
|
||||||
|
symbol table is checked for duplicate names, not the ancestor chain.
|
||||||
|
|
||||||
|
\param symtab The symbol table to which the def will be added.
|
||||||
|
\param name The name of the def to be added to the symbol table.
|
||||||
|
\param def The def to be added to the symbol table.
|
||||||
|
\return The new symbol representing the def or null if an
|
||||||
|
error occurred.
|
||||||
|
*/
|
||||||
|
symbol_t *symtab_add_def (symtab_t *symtab, const char *name,
|
||||||
|
struct def_s *def);
|
||||||
|
|
||||||
|
/** Add an enum to the symbol table.
|
||||||
|
|
||||||
|
Duplicate names will not be inserted (an error), but only the given
|
||||||
|
symbol table is checked for duplicate names, not the ancestor chain.
|
||||||
|
|
||||||
|
\param symtab The symbol table to which the enum will be added.
|
||||||
|
\param name The name of the enum to be added to the symbol table.
|
||||||
|
\param enm The enum to be added to the symbol table.
|
||||||
|
\return The new symbol representing the enum or null if an
|
||||||
|
error occurred.
|
||||||
|
*/
|
||||||
|
symbol_t *symtab_add_enum (symtab_t *symtab, const char *name,
|
||||||
|
struct enumval_s *enm);
|
||||||
|
|
||||||
|
/** Add a class to the symbol table.
|
||||||
|
|
||||||
|
Duplicate names will not be inserted (an error), but only the given
|
||||||
|
symbol table is checked for duplicate names, not the ancestor chain.
|
||||||
|
|
||||||
|
\param symtab The symbol table to which the class will be added.
|
||||||
|
\param name The name of the class to be added to the symbol table.
|
||||||
|
\param class The class to be added to the symbol table.
|
||||||
|
\return The new symbol representing the class or null if an
|
||||||
|
error occurred.
|
||||||
|
*/
|
||||||
|
symbol_t *symtab_add_class (symtab_t *symtab, const char *name,
|
||||||
|
struct class_s *class);
|
||||||
|
|
||||||
|
/** Create a new single symbol table from the given symbol table chain.
|
||||||
|
|
||||||
|
Create a new symbol table and add all of the symbols from the given
|
||||||
|
symbol table chain to the new symbol table. However, in order to
|
||||||
|
preserve scoping rules, duplicate names in ancestor tables will not be
|
||||||
|
added to the new table.
|
||||||
|
|
||||||
|
The new symbol table will be "local".
|
||||||
|
|
||||||
|
The intended use is for creating the ivar scope for methods.
|
||||||
|
|
||||||
|
\param symtab The symbol table chain to be copied.
|
||||||
|
\param parent The parent symbol table of the new symbol table, or
|
||||||
|
null.
|
||||||
|
\return The new symbol table.
|
||||||
|
|
||||||
|
\dot
|
||||||
|
digraph symtab_flat_copy {
|
||||||
|
layout=fdp;
|
||||||
|
parent;
|
||||||
|
subgraph clusterI {
|
||||||
|
node [shape=record];
|
||||||
|
root [label="{<p>parent|integer\ x;|integer\ y;|float\ z;}"];
|
||||||
|
base [label="{<p>parent|float\ w;|float\ x;}"];
|
||||||
|
cur [label="{<p>parent|float\ y;}"];
|
||||||
|
cur:p -> base;
|
||||||
|
base:p -> root;
|
||||||
|
}
|
||||||
|
subgraph clusterO {
|
||||||
|
node [shape=record];
|
||||||
|
out [label="{<p>parent|float\ z;|float\ w;|float\ x;|float\ y;}"];
|
||||||
|
}
|
||||||
|
symtab;
|
||||||
|
return;
|
||||||
|
symtab -> cur;
|
||||||
|
clusterI -> clusterO [len=1];
|
||||||
|
out:p -> parent;
|
||||||
|
return -> out;
|
||||||
|
}
|
||||||
|
\enddot
|
||||||
|
*/
|
||||||
|
symtab_t *symtab_flat_copy (symtab_t *symtab, symtab_t *parent);
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
#endif//__symtab_h
|
|
@ -52,7 +52,8 @@ EXTRA_PROGRAMS= qfcc qfprogs
|
||||||
qfcc_SOURCES= \
|
qfcc_SOURCES= \
|
||||||
class.c constfold.c cpp.c debug.c def.c emit.c expr.c function.c \
|
class.c constfold.c cpp.c debug.c def.c emit.c expr.c function.c \
|
||||||
idstuff.c immediate.c linker.c method.c obj_file.c opcodes.c options.c \
|
idstuff.c immediate.c linker.c method.c obj_file.c opcodes.c options.c \
|
||||||
qc-lex.l qc-parse.y qfcc.c reloc.c strpool.c struct.c switch.c type.c
|
qc-lex.l qc-parse.y qfcc.c reloc.c strpool.c struct.c switch.c symtab.c \
|
||||||
|
type.c
|
||||||
|
|
||||||
qfcc_LDADD= $(QFCC_LIBS)
|
qfcc_LDADD= $(QFCC_LIBS)
|
||||||
qfcc_DEPENDENCIES= $(QFCC_DEPS)
|
qfcc_DEPENDENCIES= $(QFCC_DEPS)
|
||||||
|
|
155
tools/qfcc/source/symtab.c
Normal file
155
tools/qfcc/source/symtab.c
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "QF/hash.h"
|
||||||
|
|
||||||
|
#include "class.h"
|
||||||
|
#include "def.h"
|
||||||
|
#include "qfcc.h"
|
||||||
|
#include "symtab.h"
|
||||||
|
#include "type.h"
|
||||||
|
|
||||||
|
static symtab_t *free_symtabs;
|
||||||
|
static symbol_t *free_symbols;
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
sym_getkey (void *k, void *unused)
|
||||||
|
{
|
||||||
|
return ((symbol_t *) k)->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
symtab_t *
|
||||||
|
new_symtab (symtab_t *parent, stab_type_e type)
|
||||||
|
{
|
||||||
|
symtab_t *symtab;
|
||||||
|
int tabsize = 63;
|
||||||
|
|
||||||
|
ALLOC (16, symtab_t, symtabs, symtab);
|
||||||
|
|
||||||
|
symtab->parent = parent;
|
||||||
|
symtab->type = type;
|
||||||
|
if (symtab->type == stab_global)
|
||||||
|
tabsize = 1023;
|
||||||
|
symtab->tab = Hash_NewTable (tabsize, sym_getkey, 0, 0);
|
||||||
|
symtab->symtail = &symtab->symbols;
|
||||||
|
return symtab;
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_t *
|
||||||
|
symtab_lookup (symtab_t *symtab, const char *name)
|
||||||
|
{
|
||||||
|
symbol_t *symbol;
|
||||||
|
while (symtab) {
|
||||||
|
if ((symbol = Hash_Find (symtab->tab, name)))
|
||||||
|
return symbol;
|
||||||
|
symtab = symtab->parent;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static symbol_t *
|
||||||
|
new_symbol (void)
|
||||||
|
{
|
||||||
|
symbol_t *symbol;
|
||||||
|
ALLOC (256, symbol_t, symbols, symbol);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_symbol (symtab_t *symtab, symbol_t *symbol)
|
||||||
|
{
|
||||||
|
Hash_Add (symtab->tab, symbol);
|
||||||
|
symbol->next = *symtab->symtail;
|
||||||
|
*symtab->symtail = symbol;
|
||||||
|
symtab->symtail = &symbol->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_t *
|
||||||
|
symtab_add_type (symtab_t *symtab, const char *name, type_t *type)
|
||||||
|
{
|
||||||
|
symbol_t *symbol;
|
||||||
|
if ((symbol = Hash_Find (symtab->tab, name))) {
|
||||||
|
// duplicate symbol
|
||||||
|
}
|
||||||
|
symbol = new_symbol ();
|
||||||
|
symbol->name = name;
|
||||||
|
symbol->type = sym_type;
|
||||||
|
symbol->s.type = type;
|
||||||
|
add_symbol (symtab, symbol);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_t *
|
||||||
|
symtab_add_def (symtab_t *symtab, const char *name, def_t *def)
|
||||||
|
{
|
||||||
|
symbol_t *symbol;
|
||||||
|
if ((symbol = Hash_Find (symtab->tab, name))) {
|
||||||
|
// duplicate symbol
|
||||||
|
}
|
||||||
|
symbol = new_symbol ();
|
||||||
|
symbol->name = name;
|
||||||
|
symbol->type = sym_def;
|
||||||
|
symbol->s.def = def;
|
||||||
|
add_symbol (symtab, symbol);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_t *
|
||||||
|
symtab_add_enum (symtab_t *symtab, const char *name, struct enumval_s *enm)
|
||||||
|
{
|
||||||
|
symbol_t *symbol;
|
||||||
|
if ((symbol = Hash_Find (symtab->tab, name))) {
|
||||||
|
// duplicate symbol
|
||||||
|
}
|
||||||
|
symbol = new_symbol ();
|
||||||
|
symbol->name = name;
|
||||||
|
symbol->type = sym_enum;
|
||||||
|
symbol->s.enm = enm;
|
||||||
|
add_symbol (symtab, symbol);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_t *
|
||||||
|
symtab_add_class (symtab_t *symtab, const char *name, class_t *class)
|
||||||
|
{
|
||||||
|
symbol_t *symbol;
|
||||||
|
if ((symbol = Hash_Find (symtab->tab, name))) {
|
||||||
|
// duplicate symbol
|
||||||
|
}
|
||||||
|
symbol = new_symbol ();
|
||||||
|
symbol->name = name;
|
||||||
|
symbol->type = sym_class;
|
||||||
|
symbol->s.class = class;
|
||||||
|
add_symbol (symtab, symbol);
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
symtab_t *
|
||||||
|
symtab_flat_copy (symtab_t *symtab, symtab_t *parent)
|
||||||
|
{
|
||||||
|
symtab_t *newtab;
|
||||||
|
symbol_t *newsym;
|
||||||
|
symbol_t *symbol;
|
||||||
|
|
||||||
|
newtab = new_symtab (parent, stab_local);
|
||||||
|
while (symtab) {
|
||||||
|
for (symbol = symtab->symbols; symbol; symbol = symbol->next) {
|
||||||
|
if (Hash_Find (newtab->tab, symbol->name))
|
||||||
|
continue;
|
||||||
|
newsym = new_symbol ();
|
||||||
|
*newsym = *symbol;
|
||||||
|
add_symbol (newtab, newsym);
|
||||||
|
}
|
||||||
|
symtab = symtab->parent;
|
||||||
|
// Set the tail pointer so symbols in ancestor tables come before
|
||||||
|
// those in decendent tables.
|
||||||
|
newtab->symtail = &newtab->symbols;
|
||||||
|
}
|
||||||
|
// Reset the tail pointer so any symbols added to newtab come after
|
||||||
|
// those copied from the input symbol table chain.
|
||||||
|
for (symbol = newtab->symbols; symbol && symbol->next;
|
||||||
|
symbol = symbol->next)
|
||||||
|
;
|
||||||
|
newtab->symtail = symbol ? &symbol->next : &newtab->symbols;
|
||||||
|
return newtab;
|
||||||
|
}
|
Loading…
Reference in a new issue