SymEntry* GetSizeOfScope (SymTable* Scope) /* Get the size of a scope. The function returns the symbol table entry that * encodes the size, and will create a new entry if it does not exist. */ { return SymFind (Scope, &SizeEntryName, SYM_ALLOC_NEW); }
static void NewSymbol (const char* SymName, long Val) /* Define a symbol with a fixed numeric value in the current scope */ { ExprNode* Expr; SymEntry* Sym; /* Convert the name to a string buffer */ StrBuf SymBuf = STATIC_STRBUF_INITIALIZER; SB_CopyStr (&SymBuf, SymName); /* Search for the symbol, allocate a new one if it doesn't exist */ Sym = SymFind (CurrentScope, &SymBuf, SYM_ALLOC_NEW); /* Check if have already a symbol with this name */ if (SymIsDef (Sym)) { AbEnd ("`%s' is already defined", SymName); } /* Generate an expression for the symbol */ Expr = GenLiteralExpr (Val); /* Mark the symbol as defined */ SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_NONE); /* Free string buffer memory */ SB_Done (&SymBuf); }
SymEntry* FindSizeOfScope (SymTable* Scope) /* Get the size of a scope. The function returns the symbol table entry that * encodes the size or NULL if there is no such entry. */ { return SymFind (Scope, &SizeEntryName, SYM_FIND_EXISTING); }
void UnArchive(SYM_STR Filename) { SYM_ENTRY *SymPtr = NULL; HSym hsym = SymFind(Filename); SymPtr = DerefSym (hsym); if (SymPtr->flags.bits.archived) EM_moveSymFromExtMem(Filename, HS_NULL); }
void UnArchive(const char *Filename) { SYM_ENTRY *SymPtr = NULL; HSym hsym = SymFind(SYMSTR(Filename)); SymPtr = DerefSym (hsym); if (SymPtr->flags.bits.archived) EM_moveSymFromExtMem(SYMSTR(Filename), HS_NULL); }
void addSymbol(pSymTabEntry pEntry) { if (SymFind(symTab, pEntry) != NULL) { reportError(CERR_REDEFN_IGNORED, pEntry->name); } else { if (!SymAdd(symTab, pEntry)) { outOfMemory(); } g_numSymbols++; // Number of symbols in symbol table } }
static SymPtr LookupIdent(char **name) { SymPtr sym=NULL,parent; /* check this class only */ if( in_class && Token==tSELF ) { SkipToken(tSELF); SkipToken(tPERIOD); *name = GetIdent(); sym = SymFindLevel(*name,(SymGetScope()-1)); } /* check super class only */ else if( in_class && Token==tSUPER && base_class->super!=NULL ) { SkipToken(tSUPER); SkipToken(tPERIOD); *name = GetIdent(); sym = SymFindLocal(*name,base_class->super); if( sym!=NULL && sym->flags&SYM_PRIVATE ) { compileError("attempt to access private field '%s'",*name); NextToken(); return COMPILE_ERROR; } } /* check all super classes */ else if( in_class ) { *name = GetIdent(); parent=base_class->super; while(parent!=NULL) { sym = SymFindLocal(*name,parent); if(sym!=NULL) break; parent=parent->super; } if( sym!=NULL && sym->flags&SYM_PRIVATE ) { compileError("attempt to access private field '%s'",*name); NextToken(); return COMPILE_ERROR; } } /* check globals */ if( sym==NULL ) { *name = GetIdent(); sym = SymFind(*name); } return sym; }
void Archive(SYM_STR Filename) { SYM_ENTRY *SymPtr = NULL; HSym hsym = SymFind(Filename); SymPtr = DerefSym (hsym); if (EM_findEmptySlot(*Get_Data_Ptr(Filename, -2)) == NULL) return; // Make sure Garbage Collection will not occur if (!SymPtr->flags.bits.archived) EM_moveSymToExtMem(Filename, HS_NULL); }
long GetStructSize (SymTable* Struct) /* Get the size of a struct or union */ { SymEntry* Sym = SymFind (Struct, &SizeEntryName, SYM_FIND_EXISTING); if (Sym == 0) { Error ("Size of struct/union is unknown"); return 0; } else { return GetSymVal (Sym); } }
__ATTR_LIB_C__ char *tmpnam(char *s) { static char buff[10]={0}; //"\0 "; register char *bptr=buff; register short i; do { for(i=1;i<9;i++) bptr[i]=((rand()%25)+97); } while(SymFind(bptr+9).offset); if(s) return strcpy(s,bptr+1); else return bptr+1; }
SymEntry* ParseScopedSymName (SymFindAction Action) /* Parse a (possibly scoped) symbol name, search for it in the symbol table * and return the symbol table entry. */ { StrBuf ScopeName = STATIC_STRBUF_INITIALIZER; StrBuf Ident = STATIC_STRBUF_INITIALIZER; int NoScope; SymEntry* Sym; /* Parse the scoped symbol name */ SymTable* Scope = ParseScopedIdent (&Ident, &ScopeName); /* If ScopeName is empty, no scope was specified */ NoScope = SB_IsEmpty (&ScopeName); /* We don't need ScopeName any longer */ SB_Done (&ScopeName); /* Check if the scope is valid. Errors have already been diagnosed by * the routine, so just exit. */ if (Scope) { /* Search for the symbol and return it. If no scope was specified, * search also in the upper levels. */ if (NoScope && (Action & SYM_ALLOC_NEW) == 0) { Sym = SymFindAny (Scope, &Ident); } else { Sym = SymFind (Scope, &Ident, Action); } } else { /* No scope ==> no symbol. To avoid errors in the calling routine that * may not expect NULL to be returned if Action contains SYM_ALLOC_NEW, * create a new symbol. */ if (Action & SYM_ALLOC_NEW) { Sym = NewSymEntry (&Ident, SF_NONE); } else { Sym = 0; } } /* Deallocate memory for ident */ SB_Done (&Ident); /* Return the symbol found */ return Sym; }
static bool HexConst(void) { //========================== // Check for a hexadecimal constant specifier. char *hex_data; int hex_len; sym_id sym; hex_data = CITNode->opnd; hex_len = CITNode->opnd_size; if( CITNode->opn.ds != DSOPN_HEX ) { if( !RecName() ) return( false ); if( *hex_data != 'Z' ) return( false ); sym = SymFind( hex_data, hex_len ); if( sym != NULL ) { if( ( sym->u.ns.flags & SY_CLASS ) == SY_PARAMETER ) { return( false ); } } ++hex_data; } --hex_len; hex_len = MkHexConst( hex_data, CITNode->opnd, hex_len ); if( hex_len == 0 ) return( false ); CITNode->opnd_size = hex_len; CITNode->opn.ds = DSOPN_LIT; GetConst(); AddConst( CITNode ); CITNode->typ = FT_HEX; Extension( DA_HEX_CONST ); return( true ); }
static void SymCheckUndefined (SymEntry* S) /* Handle an undefined symbol */ { /* Undefined symbol. It may be... ** ** - An undefined symbol in a nested lexical level. If the symbol is not ** fixed to this level, search for the symbol in the higher levels and ** make the entry a trampoline entry if we find one. ** ** - If the symbol is not found, it is a real undefined symbol. If the ** AutoImport flag is set, make it an import. If the AutoImport flag is ** not set, it's an error. */ SymEntry* Sym = 0; if ((S->Flags & SF_FIXED) == 0) { SymTable* Tab = GetSymParentScope (S); while (Tab) { Sym = SymFind (Tab, GetStrBuf (S->Name), SYM_FIND_EXISTING | SYM_CHECK_ONLY); if (Sym && (Sym->Flags & (SF_DEFINED | SF_IMPORT)) != 0) { /* We've found a symbol in a higher level that is ** either defined in the source, or an import. */ break; } /* No matching symbol found in this level. Look further */ Tab = Tab->Parent; } } if (Sym) { /* We found the symbol in a higher level. Transfer the flags and ** address size from the local symbol to that in the higher level ** and check for problems. */ if (S->Flags & SF_EXPORT) { if (Sym->Flags & SF_IMPORT) { /* The symbol is already marked as import */ LIError (&S->RefLines, "Symbol `%s' is already an import", GetString (Sym->Name)); } if ((Sym->Flags & SF_EXPORT) == 0) { /* Mark the symbol as an export */ Sym->Flags |= SF_EXPORT; Sym->ExportSize = S->ExportSize; if (Sym->ExportSize == ADDR_SIZE_DEFAULT) { /* Use the actual size of the symbol */ Sym->ExportSize = Sym->AddrSize; } if (Sym->AddrSize > Sym->ExportSize) { /* We're exporting a symbol smaller than it actually is */ LIWarning (&Sym->DefLines, 1, "Symbol `%m%p' is %s but exported %s", GetSymName (Sym), AddrSizeToStr (Sym->AddrSize), AddrSizeToStr (Sym->ExportSize)); } } } if (S->Flags & SF_REFERENCED) { /* Mark as referenced and move the line info */ Sym->Flags |= SF_REFERENCED; CollTransfer (&Sym->RefLines, &S->RefLines); CollDeleteAll (&S->RefLines); } /* Transfer all expression references */ SymTransferExprRefs (S, Sym); /* Mark the symbol as unused removing all other flags */ S->Flags = SF_UNUSED; } else { /* The symbol is definitely undefined */ if (S->Flags & SF_EXPORT) { /* We will not auto-import an export */ LIError (&S->RefLines, "Exported symbol `%m%p' was never defined", GetSymName (S)); } else { if (AutoImport) { /* Mark as import, will be indexed later */ S->Flags |= SF_IMPORT; /* Use the address size for code */ S->AddrSize = CodeAddrSize; /* Mark point of import */ GetFullLineInfo (&S->DefLines); } else { /* Error */ LIError (&S->RefLines, "Symbol `%m%p' is undefined", GetSymName (S)); } } } }
static long DoStructInternal (long Offs, unsigned Type) /* Handle the .STRUCT command */ { long Size = 0; /* Outside of other structs, we need a name. Inside another struct or ** union, the struct may be anonymous, in which case no new lexical level ** is started. */ int Anon = (CurTok.Tok != TOK_IDENT); if (!Anon) { /* Enter a new scope, then skip the name */ SymEnterLevel (&CurTok.SVal, SCOPE_STRUCT, ADDR_SIZE_ABS, 0); NextTok (); /* Start at zero offset in the new scope */ Offs = 0; } /* Test for end of line */ ConsumeSep (); /* Read until end of struct */ while (CurTok.Tok != TOK_ENDSTRUCT && CurTok.Tok != TOK_ENDUNION && CurTok.Tok != TOK_EOF) { long MemberSize; SymTable* Struct; SymEntry* Sym; /* Allow empty and comment lines */ if (CurTok.Tok == TOK_SEP) { NextTok (); continue; } /* The format is "[identifier] storage-allocator [, multiplicator]" */ Sym = 0; if (CurTok.Tok == TOK_IDENT) { /* Beware: An identifier may also be a macro, in which case we have ** to start over. */ Macro* M = FindMacro (&CurTok.SVal); if (M) { MacExpandStart (M); continue; } /* We have an identifier, generate a symbol */ Sym = SymFind (CurrentScope, &CurTok.SVal, SYM_ALLOC_NEW); /* Assign the symbol the offset of the current member */ SymDef (Sym, GenLiteralExpr (Offs), ADDR_SIZE_DEFAULT, SF_NONE); /* Skip the member name */ NextTok (); } /* Read storage allocators */ MemberSize = 0; /* In case of errors, use zero */ switch (CurTok.Tok) { case TOK_BYTE: NextTok (); MemberSize = Member (1); break; case TOK_DBYT: case TOK_WORD: case TOK_ADDR: NextTok (); MemberSize = Member (2); break; case TOK_FARADDR: NextTok (); MemberSize = Member (3); break; case TOK_DWORD: NextTok (); MemberSize = Member (4); break; case TOK_RES: NextTok (); if (CurTok.Tok == TOK_SEP) { ErrorSkip ("Size is missing"); } else { MemberSize = Member (1); } break; case TOK_TAG: NextTok (); Struct = ParseScopedSymTable (); if (Struct == 0) { ErrorSkip ("Unknown struct/union"); } else if (GetSymTabType (Struct) != SCOPE_STRUCT) { ErrorSkip ("Not a struct/union"); } else { SymEntry* SizeSym = GetSizeOfScope (Struct); if (!SymIsDef (SizeSym) || !SymIsConst (SizeSym, &MemberSize)) { ErrorSkip ("Size of struct/union is unknown"); } } MemberSize = Member (MemberSize); break; case TOK_STRUCT: NextTok (); MemberSize = DoStructInternal (Offs, STRUCT); break; case TOK_UNION: NextTok (); MemberSize = DoStructInternal (Offs, UNION); break; default: if (!CheckConditionals ()) { /* Not a conditional directive */ ErrorSkip ("Invalid storage allocator in struct/union"); } } /* Assign the size to the member if it has a name */ if (Sym) { DefSizeOfSymbol (Sym, MemberSize); } /* Next member */ if (Type == STRUCT) { /* Struct */ Offs += MemberSize; Size += MemberSize; } else { /* Union */ if (MemberSize > Size) { Size = MemberSize; } } /* Expect end of line */ ConsumeSep (); } /* If this is not a anon struct, enter a special symbol named ".size" ** into the symbol table of the struct that holds the size of the ** struct. Since the symbol starts with a dot, it cannot be accessed ** by user code. ** Leave the struct scope level. */ if (!Anon) { /* Add a symbol */ SymEntry* SizeSym = GetSizeOfScope (CurrentScope); SymDef (SizeSym, GenLiteralExpr (Size), ADDR_SIZE_DEFAULT, SF_NONE); /* Close the struct scope */ SymLeaveLevel (); } /* End of struct/union definition */ if (Type == STRUCT) { Consume (TOK_ENDSTRUCT, "'.ENDSTRUCT' expected"); } else { Consume (TOK_ENDUNION, "'.ENDUNION' expected"); } /* Return the size of the struct */ return Size; }
static void ClassDefinition(void) { char *name; Int32 label,l1; Int32 field_num=0; SymPtr clas,clas_init; SkipToken(tCLASS); MatchToken(tCONST); name = GetIdent(); clas = SymAdd(name); clas->kind = CLASS_KIND; NextToken(); in_class=TRUE; base_class=clas; cur_scope=SYM_PUBLIC; /* clas->super=NULL; */ /* super_class=NULL; */ clas->super=SymFind("Object"); super_class=clas->super; if( Token==tLSS ) { SkipToken(tLSS); MatchToken(tCONST); name = GetIdent(); clas->super = SymFind(name); if( clas->super==NULL ) { compileError("super class not found"); return; } super_class = clas->super; field_num = clas->super->nlocs; NextToken(); } SymEnterScope(); /* default class constructor prologue */ l1 = vm_genI(op_link,0); clas_init = SymAdd(NEW); clas_init->kind = FUNCTION_KIND; clas_init->object.u.ival = l1; clas_init->flags |= SYM_PUBLIC; /* class fields and functions */ while( TokenIn(class_statements) ) { if( Token==tPUBLIC ) { PublicStatement(); } else if( Token==tPROTECTED ) { ProtectedStatement(); } else if( Token==tPRIVATE ) { PrivateStatement(); } else if( Token==tDEF ) { label = vm_genI(op_jmp,0); MethodDefinition(); vm_patch(label,vm_addr()); } else { local_num = field_num++; AssignmentStatement(); } if( Token==tSEMI ) SkipToken(tSEMI); } clas->nlocs = field_num; /* default class constructor epilogue */ vm_gen0(op_nop); vm_genI(op_rts,2); SymExitScope(clas); /* end of class */ in_class=FALSE; base_class=NULL; super_class=NULL; SkipToken(tEND); if( Token==tSEMI ) SkipToken(tSEMI); }
pSymTabEntry findSymbol(char *name) { SymTabEntry nameEntry; nameEntry.name = name; return SymFind(symTab, &nameEntry); }