1
0
Files
2022-09-29 17:59:04 +03:00

168 lines
6.3 KiB
C

#ifndef SCOPE_H
#define SCOPE_H
/*
* PIDL symbol tables. Symbol addresses must not change when a table
* grows because the parse tree contains symbol pointers. Therefore we
* chain dynamically allocated symbol structures, and grow the table by
* reallocating the hash bucket array when the load factor nears unity.
*/
#include "address.h"
#include "type.h"
enum symtype {
stNil, /* string or unknown symbol type */
stProtocol, /* protocol descriptor */
stField, /* protocol or struct field */
stElement, /* array element descriptor */
stBaseType, /* base type */
stEnum, /* enumerated type */
stStruct, /* structure type */
stTypeDef, /* derived type */
stMacro, /* string-valued name definition */
stNickname, /* protocol pathname shorthand */
stNumber, /* int-valued enumerator */
stAddress /* protocol address */
};
extern char *symtypes[]; /* symbol type names */
typedef unsigned long hash_t;
struct symlist {
struct symbol *sl_head; /* first element on symbol list */
struct symbol *sl_tail; /* and last (null-terminated) */
};
#define APPENDSYM(sym, sl) \
(((sl)->sl_head == 0) ? ((sl)->sl_head = (sl)->sl_tail = (sym)) \
: ((sl)->sl_tail = (sl)->sl_tail->s_next = (sym)))
#define INSERTSYM(sym, sl) \
((sym)->s_next = (sl)->sl_head, \
(sl)->sl_head = ((sl)->sl_head == 0) ? ((sl)->sl_tail = (sym)) : (sym))
typedef struct symbol {
enum symtype s_type; /* union discriminant */
char *s_name; /* name string in safe store */
unsigned short s_namlen; /* name length */
unsigned short s_flags; /* symbol flags, see below */
hash_t s_hash; /* hash function value */
struct symbol *s_chain; /* next on hash chain */
struct symbol *s_next; /* next on symbol list */
struct scope *s_scope; /* containing scope */
union { /* symbol value union */
struct {
struct treenode *tree; /* protocol or field decl */
char *title; /* protocol or field title */
unsigned short index:12; /* index in *fields[] array */
unsigned short level:4; /* field verbosity level */
unsigned short fid; /* field identifier */
} decl;
struct {
struct treenode *tree; /* array field declaration */
typeword_t etype; /* array element type */
short ewidth; /* width of this element */
unsigned short eid; /* element field identifier */
struct treenode *dimlen; /* dimension length if array */
} elem;
struct {
struct treenode *tree; /* type definition tree */
unsigned short tsymndx:TSBITS; /* type symbol index */
unsigned short trefcnt; /* type reference count */
} type;
struct treenode *tree; /* abstract syntax tree */
struct typedesc *desc; /* base type descriptor */
struct pragma *pragmas; /* pragmatic directives */
long val; /* constant enumerator value */
Address addr; /* address byte-string */
} s_data;
} Symbol;
#define s_title s_data.decl.title
#define s_index s_data.decl.index
#define s_level s_data.decl.level
#define s_fid s_data.decl.fid
#define s_etype s_data.elem.etype
#define s_ewidth s_data.elem.ewidth
#define s_eid s_data.elem.eid
#define s_dimlen s_data.elem.dimlen
#define s_tsymndx s_data.type.tsymndx
#define s_trefcnt s_data.type.trefcnt
#define s_tree s_data.tree
#define s_desc s_data.desc
#define s_pragmas s_data.pragmas
#define s_val s_data.val
#define s_addr s_data.addr
/* symbol flags */
#define sfSaveName 0x0001 /* dynamically allocate name */
#define sfTypeName 0x0002 /* lexical type-name */
#define sfImported 0x0004 /* imported from a module */
#define sfExported 0x0008 /* exported to other modules */
#define sfFooter 0x0010 /* protocol footer symbol */
#define sfOverloaded 0x0020 /* field name is multiply declared */
#define sfVariantSize 0x0040 /* overloaded field has variant size */
#define sfTemporary 0x0080 /* struct pointer temporary */
#define sfDirect 0x0100 /* struct temporary (no indirection) */
#define sfCantInline 0x0200 /* protocol or struct not inlineable */
#define sfBitFields 0x0400 /* protocol or struct has bitfields */
#define sfAnonymous 0x0800 /* generated, anonymous field name */
#define sfDynamicNest 0x1000 /* protocol has nest statements */
typedef struct scope {
unsigned short s_length; /* hash scope logical size */
unsigned short s_shift; /* multiplicative hash shift */
unsigned short s_numfree; /* number of free symbols */
unsigned short s_numfields; /* number of fields in scope */
Symbol **s_table; /* hash bucket vector */
char *s_name; /* name of this scope */
Symbol *s_sym; /* scope's symbol table entry */
struct scope *s_outer; /* next enclosing scope */
char *s_module; /* file containing this scope */
char *s_path; /* pathname from outermost */
struct symlists {
struct symlist consts; /* stNumber&stAddress consts */
struct symlist elements; /* array element descriptors */
struct symlist enums; /* stEnum type definitions */
struct symlist fields; /* protocol or struct fields */
struct symlist macros; /* stMacro symbols */
struct symlist nicknames; /* nested protocol macros */
struct symlist protocols; /* stProtocol entries */
struct symlist structs; /* stStruct type definitions */
struct symlist typedefs; /* typedef'd names */
} s_lists;
#ifdef METERING
struct scopemeter {
unsigned long searches; /* hash scope searches */
unsigned long probes; /* probes on collision */
unsigned long hits; /* lookups which found name */
unsigned long misses; /* names not found */
unsigned long adds; /* entries added */
unsigned long grows; /* table expansions */
} s_meter;
#endif
} Scope;
#define s_consts s_lists.consts
#define s_elements s_lists.elements
#define s_enums s_lists.enums
#define s_fields s_lists.fields
#define s_macros s_lists.macros
#define s_nicknames s_lists.nicknames
#define s_protocols s_lists.protocols
#define s_structs s_lists.structs
#define s_typedefs s_lists.typedefs
extern void initscope(Scope *, char *, Symbol *, Scope *);
extern void copyscope(Scope *, Scope *);
extern void freescope(Scope *);
extern hash_t hashname(char *, int);
typedef Symbol *(*lookfun_t)(Scope *, char *, int, hash_t);
extern Symbol *lookup(Scope *, char *, int, hash_t);
extern Symbol *find(Scope *, char *, int, hash_t);
extern Symbol *install(Scope *, Symbol *, enum symtype, int);
extern Symbol *enter(Scope *, char *, int, hash_t, enum symtype, int);
extern int isnickname(Scope *, Symbol *);
#endif