home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)symbolTable.c 1.2 3/18/87
- */
- #include "assert.h"
- #include "symbols.h"
- #include "nodes.h"
- #include "system.h"
- #include "map.h"
- #include "semantics.h"
- #include "sequence.h"
- #include "scan.h"
-
- char *ST_KindName[] = {
- "ST_Unknown",
- "ST_Const",
- "ST_Var",
- "ST_Param",
- "ST_Result",
- "ST_OpName"};
-
- /*
- * There is a default symbol table that is used when parsing and resolving
- * the symbols in the newly parsed stuff. It is a static version of
- * a SymbolTable, but it is made out of blocks.
- */
- SymbolNumber nextSymbolToAllocate = FIRSTSYMBOL;
- int nestingDepth = 0;
- static SymbolBlockPtr symbolBlocks[20];
-
- static ScopePtr currentScope = NULL;
-
- static Map scopeMap = NULL;
-
- void ST_EnterNewScope(fNodePtr, c)
- NodePtr fNodePtr;
- ST_Contexts c;
- {
- register ScopePtr p;
- nestingDepth ++;
- p = (ScopePtr) malloc(sizeof(Scope));
- p->enclosing = currentScope;
- p->itsContext = c;
- p->first = NULL;
- p->itsNode = fNodePtr;
- p->nestingDepth = nestingDepth;
- currentScope = p;
- Map_Insert(scopeMap, (int)fNodePtr, (int)p);
- }
-
- void ST_EnterOldScope(fNodePtr)
- NodePtr fNodePtr;
- {
- ScopePtr p;
- p = (ScopePtr) Map_Lookup(scopeMap, (int)fNodePtr);
- nestingDepth ++;
- assert(p->enclosing == currentScope);
- assert(p->nestingDepth == nestingDepth);
- currentScope = p;
- }
-
- void ST_ExitScope()
- {
- currentScope = currentScope->enclosing;
- nestingDepth = currentScope == NULL ? 0 : currentScope->nestingDepth;
- }
-
- Symbol ST_iDefine();
-
- Symbol ST_Lookup(fIdent, depth)
- Ident fIdent;
- int depth;
- {
- register ScopePtr c;
- register Symbol e;
- register NodePtr q;
- NodePtr fixup = NULL;
- Symbol answer = NULL;
-
- assert(depth == 1 || depth == 2);
- for (c = currentScope; c != NULL; c = c->enclosing) {
- for (e = c->first; e != NULL; e = e->v.next) {
- if (e->itsIdent == fIdent) goto foundit;
- }
- if (depth == 1) return(NULL);
- if (depth == 2 && (c->itsContext == C_ObLit || c->itsContext == C_ATLit)){
- /*
- * We have discovered a place where we import an identifier that we do
- * not define. We need to make sure that every object/AT literal
- * between where the symbol is defined and where it is used also
- * imports it.
- */
- nextLineNumber = c->itsNode->lineNumber;
- q = Construct(P_SETQ, 3, Construct(P_SYMDEF, 0), NULL, Construct(P_SYMREF, 0));
- q->b.setq.outer->b.symref.ident = fIdent;
- q->b.setq.inner->b.symdef.ident = fIdent;
- q->b.setq.inner->b.symdef.symbol = ST_iDefine(fIdent, ST_Param, c);
- q->b.setq.inner->b.symdef.symbol->isImport = TRUE;
- if (answer == NULL) answer = q->b.setq.inner->b.symdef.symbol;
- assert(c->itsNode->tag == P_OBLIT || c->itsNode->tag == P_ATLIT);
- Sequence_Add(&c->itsNode->b.oblit.setq, q);
- if (fixup != NULL) fixup->b.symref.symbol = q->b.setq.inner->b.symdef.symbol;
- fixup = q->b.setq.outer;
- }
- }
- return(NULL);
- foundit:
- if (fixup != NULL) fixup->b.symref.symbol = e;
- return(answer == NULL ? e : answer);
- }
-
- Symbol ST_iDefine(fIdent, kind, c)
- Ident fIdent;
- ST_Kinds kind;
- register ScopePtr c;
- {
- register SymbolBlockPtr sbp;
- register Symbol p;
- register int realS, blockIndex;
-
- p = (Symbol) calloc(sizeof(STEntry), 1);
- p->tag = P_SYMBOL;
- p->itsIdent = fIdent;
- p->itsName = Ident_Name(fIdent);
- p->itsSymbolNumber = nextSymbolToAllocate++;
- p->itsKind = kind;
- realS = p->itsSymbolNumber - FIRSTSYMBOL;
- blockIndex = realS / STENTRIESPERBLOCK;
- sbp = symbolBlocks[blockIndex];
- if (sbp == NULL) {
- sbp = (SymbolBlockPtr) malloc(sizeof(SymbolBlock));
- symbolBlocks[blockIndex] = sbp;
- }
- sbp->symbols[realS % STENTRIESPERBLOCK] = p;
- p->nestingDepth = c->nestingDepth;
- p->v.next = c->first;
- c->first = p;
- return(p);
- }
-
- Symbol ST_Define(fIdent, kind, depth)
- Ident fIdent;
- ST_Kinds kind;
- int depth;
- {
- register ScopePtr c;
-
- if (ST_Lookup(fIdent, depth) != 0) {
- return (NULL);
- }
- c = currentScope;
- return(ST_iDefine(fIdent, kind, c));
- }
-
- int getNestingDepth(fNodePtr)
- NodePtr fNodePtr;
- {
- ScopePtr p;
- p = (ScopePtr) Map_Lookup(scopeMap, (int)fNodePtr);
- assert((int) p != NIL);
- return(p->nestingDepth);
- }
-
- #define ISANOBJECT(C) ((C) == C_ObLit || (C) == C_ATLit)
- int Symbol_IsImport(sym)
- register Symbol sym;
- {
- register ScopePtr t = currentScope;
- while (t != NULL && ! ISANOBJECT(t->itsContext)) t = t->enclosing;
- return (t == NULL ? FALSE : sym->nestingDepth < t->nestingDepth);
- }
-
- Symbol ST_Create(fNodePtr, fIdent)
- NodePtr fNodePtr;
- Ident fIdent;
- {
- register Symbol p;
- register SymbolBlockPtr sbp;
- int realS, blockIndex;
- register ScopePtr sp = NULL;
-
- if (fNodePtr != NULL)
- sp = (ScopePtr) Map_Lookup(scopeMap, (int) fNodePtr);
- if ((int)sp == NIL) sp = NULL;
- p = (Symbol) calloc(sizeof(STEntry), 1);
- p->tag = P_SYMBOL;
- p->itsIdent = fIdent;
- p->itsName = Ident_Name(fIdent);
- p->itsSymbolNumber = nextSymbolToAllocate++;
- p->nestingDepth = sp == NULL ? 0 : sp->nestingDepth;
- p->itsKind = ST_Unknown;
- realS = p->itsSymbolNumber - FIRSTSYMBOL;
- blockIndex = realS / STENTRIESPERBLOCK;
- sbp = symbolBlocks[blockIndex];
- if (sbp == NULL) {
- sbp = (SymbolBlockPtr) malloc (sizeof(SymbolBlock));
- symbolBlocks[blockIndex] = sbp;
- }
- sbp->symbols[realS % STENTRIESPERBLOCK] = p;
- if (sp != NULL) {
- p->v.next = sp->first;
- sp->first = p;
- }
- return(p);
-
-
- }
-
- void initializeSymbolTable()
- {
- scopeMap = Map_Create();
- }
-