1 /*****************************************************************************/
5 /* Symbol table for the ca65 macroassembler */
9 /* (C) 1998-2000 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
12 /* EMail: uz@musoftware.de */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
55 /*****************************************************************************/
57 /*****************************************************************************/
61 /* Bits for the Flags value in SymEntry */
62 #define SF_USER 0x0001 /* User bit */
63 #define SF_TRAMPOLINE 0x0002 /* Trampoline entry */
64 #define SF_EXPORT 0x0004 /* Export this symbol */
65 #define SF_IMPORT 0x0008 /* Import this symbol */
66 #define SF_GLOBAL 0x0010 /* Global symbol */
67 #define SF_ZP 0x0020 /* Declared as zeropage symbol */
68 #define SF_ABS 0x0040 /* Declared as absolute symbol */
69 #define SF_INDEXED 0x0800 /* Index is valid */
70 #define SF_CONST 0x1000 /* The symbol has a constant value */
71 #define SF_MULTDEF 0x2000 /* Multiply defined symbol */
72 #define SF_DEFINED 0x4000 /* Defined */
73 #define SF_REFERENCED 0x8000 /* Referenced */
76 #define SF_UNDEFMASK (SF_REFERENCED | SF_DEFINED | SF_IMPORT)
77 #define SF_UNDEFVAL (SF_REFERENCED)
78 #define SF_IMPMASK (SF_TRAMPOLINE | SF_IMPORT | SF_REFERENCED)
79 #define SF_IMPVAL (SF_IMPORT | SF_REFERENCED)
80 #define SF_EXPMASK (SF_TRAMPOLINE | SF_EXPORT)
81 #define SF_EXPVAL (SF_EXPORT)
82 #define SF_DBGINFOMASK (SF_TRAMPOLINE | SF_DEFINED | SF_EXPORT | SF_IMPORT)
83 #define SF_DBGINFOVAL (SF_DEFINED)
85 /* Structure of a symbol table entry */
87 SymEntry* Left; /* Lexically smaller entry */
88 SymEntry* Right; /* Lexically larger entry */
89 SymEntry* List; /* List of all entries */
90 SymEntry* Locals; /* Root of subtree for local symbols */
91 struct SymTable* SymTab; /* Table this symbol is in, 0 for locals */
92 FilePos Pos; /* File position for this symbol */
93 unsigned Flags; /* Symbol flags */
94 unsigned Index; /* Index of import/export entries */
96 struct ExprNode* Expr; /* Expression if CONST not set */
97 long Val; /* Value (if CONST set) */
98 SymEntry* Sym; /* Symbol (if trampoline entry) */
100 unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */
101 /* ...actually value+1 (used as flag) */
102 char Name [1]; /* Dynamic allocation */
107 /* Definitions for the hash table */
108 #define MAIN_HASHTAB_SIZE 213
109 #define SUB_HASHTAB_SIZE 53
110 typedef struct SymTable SymTable;
112 unsigned TableSlots; /* Number of hash table slots */
113 unsigned TableEntries; /* Number of entries in the table */
114 SymTable* BackLink; /* Link to enclosing scope if any */
115 SymEntry* Table [1]; /* Dynamic allocation */
120 /* Arguments for SymFind */
121 #define SF_FIND_EXISTING 0
122 #define SF_ALLOC_NEW 1
126 /* Symbol table variables */
127 static SymEntry* SymList = 0; /* List of all symbol table entries */
128 static SymEntry* SymLast = 0; /* Pointer to last defined symbol */
129 static SymTable* SymTab = 0; /* Pointer to current symbol table */
130 static SymTable* RootTab = 0; /* Root symbol table */
131 static unsigned ImportCount = 0;/* Counter for import symbols */
132 static unsigned ExportCount = 0;/* Counter for export symbols */
136 /*****************************************************************************/
137 /* Internally used functions */
138 /*****************************************************************************/
142 static int IsLocal (const char* Name)
143 /* Return true if Name is the name of a local symbol */
145 return (*Name == LocalStart);
150 static SymEntry* NewSymEntry (const char* Name)
151 /* Allocate a symbol table entry, initialize and return it */
156 /* Get the length of the name */
159 /* Allocate memory */
160 S = xmalloc (sizeof (SymEntry) + Len);
162 /* Initialize the entry */
170 memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
171 memcpy (S->Name, Name, Len+1);
173 /* Insert it into the list of all entries */
177 /* Return the initialized entry */
183 static SymTable* NewSymTable (unsigned Size)
184 /* Allocate a symbol table on the heap and return it */
188 /* Allocate memory */
189 S = xmalloc (sizeof (SymTable) + (Size-1) * sizeof (SymEntry*));
191 /* Set variables and clear hash table entries */
192 S->TableSlots = Size;
199 /* Return the prepared struct */
205 static int SearchSymTab (SymEntry* T, const char* Name, SymEntry** E)
206 /* Search in the given table for a name (Hash is the hash value of Name and
207 * is given as parameter so that it will not get calculated twice if we search
208 * in more than one table). If we find the symbol, the function will return 0
209 * and put the entry pointer into E. If we did not find the symbol, and the
210 * tree is empty, E is set to NULL. If the tree is not empty, E will be set to
211 * the last entry, and the result of the function is <0 if the entry should
212 * be inserted on the left side, and >0 if it should get inserted on the right
218 /* Is there a tree? */
224 /* We have a table, search it */
226 /* Choose next entry */
227 Cmp = strcmp (Name, T->Name);
228 if (Cmp < 0 && T->Left) {
230 } else if (Cmp > 0 && T->Right) {
233 /* Found or end of search */
238 /* Return the search result */
245 /*****************************************************************************/
247 /*****************************************************************************/
251 static SymEntry* SymFind (SymTable* Tab, const char* Name, int AllocNew)
252 /* Find a new symbol table entry in the given table. If AllocNew is given and
253 * the entry is not found, create a new one. Return the entry found, or the
254 * new entry created, or - in case AllocNew is zero - return 0.
261 if (IsLocal (Name)) {
263 /* Local symbol, get the table */
265 /* No last global, so there's no local table */
266 Error (ERR_ILLEGAL_LOCAL_USE);
268 return NewSymEntry (Name);
274 /* Search for the symbol if we have a table */
275 Cmp = SearchSymTab (SymLast->Locals, Name, &S);
277 /* If we found an entry, return it */
284 /* Otherwise create a new entry, insert and return it */
285 SymEntry* N = NewSymEntry (Name);
288 } else if (Cmp < 0) {
298 /* Global symbol: Get the hash value for the name */
299 Hash = HashStr (Name) % Tab->TableSlots;
301 /* Search for the entry */
302 Cmp = SearchSymTab (Tab->Table [Hash], Name, &S);
304 /* If we found an entry, return it */
306 /* Check for a trampoline entry, in this case return the real
309 if (S->Flags & SF_TRAMPOLINE) {
318 /* Otherwise create a new entry, insert and return it */
319 SymEntry* N = NewSymEntry (Name);
321 Tab->Table [Hash] = N;
322 } else if (Cmp < 0) {
334 /* We did not find the entry and AllocNew is false. */
340 static SymEntry* SymFindAny (SymTable* Tab, const char* Name)
341 /* Find a symbol in any table */
345 /* Search in the current table */
346 Sym = SymFind (Tab, Name, 0);
348 /* Found, return it */
351 /* Not found, search in the backlink, if we have one */
354 } while (Sym == 0 && Tab != 0);
362 static SymEntry* SymRefInternal (SymTable* Table, const char* Name)
363 /* Search for the symbol in the given table and return it */
365 /* Try to find the symbol, create a new one if the symbol does not exist */
366 SymEntry* S = SymFind (Table, Name, SF_ALLOC_NEW);
368 /* Mark the symbol as referenced */
369 S->Flags |= SF_REFERENCED;
377 void SymEnterLevel (void)
378 /* Enter a new lexical level */
381 /* Create the main symbol table */
382 RootTab = SymTab = NewSymTable (MAIN_HASHTAB_SIZE);
384 /* Create a local symbol table */
386 LocalSyms = NewSymTable (SUB_HASHTAB_SIZE);
387 LocalSyms->BackLink = SymTab;
394 void SymLeaveLevel (void)
395 /* Leave the current lexical level */
397 SymTab = SymTab->BackLink;
402 void SymDef (const char* Name, ExprNode* Expr, int ZP)
403 /* Define a new symbol */
405 /* Do we have such a symbol? */
406 SymEntry* S = SymFind (SymTab, Name, SF_ALLOC_NEW);
407 if (S->Flags & SF_IMPORT) {
408 /* Defined symbol is marked as imported external symbol */
409 Error (ERR_SYM_ALREADY_IMPORT, Name);
412 if (S->Flags & SF_DEFINED) {
413 /* Multiple definition */
414 Error (ERR_SYM_ALREADY_DEFINED, Name);
415 S->Flags |= SF_MULTDEF;
419 /* Set the symbol data */
420 if (IsConstExpr (Expr)) {
421 /* Expression is const, store the value */
422 S->Flags |= SF_CONST;
423 S->V.Val = GetExprVal (Expr);
426 /* Not const, store the expression */
429 S->Flags |= SF_DEFINED;
434 /* If the symbol is a ZP symbol, check if the value is in correct range */
435 if (S->Flags & SF_ZP) {
436 /* Already marked as ZP symbol by some means */
437 if (!IsByteExpr (Expr)) {
442 /* If this is not a local symbol, remember it as the last global one */
443 if (!IsLocal (Name)) {
450 SymEntry* SymRef (const char* Name)
451 /* Search for the symbol and return it */
453 /* Reference the symbol in the current table */
454 return SymRefInternal (SymTab, Name);
459 SymEntry* SymRefGlobal (const char* Name)
460 /* Search for the symbol in the global namespace and return it */
462 /* Reference the symbol in the current table */
463 return SymRefInternal (RootTab, Name);
468 void SymImport (const char* Name, int ZP)
469 /* Mark the given symbol as an imported symbol */
473 /* Don't accept local symbols */
474 if (IsLocal (Name)) {
475 Error (ERR_ILLEGAL_LOCAL_USE);
479 /* Do we have such a symbol? */
480 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
481 if (S->Flags & SF_DEFINED) {
482 Error (ERR_SYM_ALREADY_DEFINED, Name);
483 S->Flags |= SF_MULTDEF;
486 if (S->Flags & SF_EXPORT) {
487 /* The symbol is already marked as exported symbol */
488 Error (ERR_SYM_ALREADY_EXPORT, Name);
492 /* If the symbol is marked as global, check the symbol size, then do
493 * silently remove the global flag
495 if (S->Flags & SF_GLOBAL) {
496 if ((ZP != 0) != ((S->Flags & SF_ZP) != 0)) {
497 Error (ERR_SYM_REDECL_MISMATCH);
499 S->Flags &= ~SF_GLOBAL;
502 /* Set the symbol data */
503 S->Flags |= SF_IMPORT;
511 void SymExport (const char* Name, int ZP)
512 /* Mark the given symbol as an exported symbol */
516 /* Don't accept local symbols */
517 if (IsLocal (Name)) {
518 Error (ERR_ILLEGAL_LOCAL_USE);
522 /* Do we have such a symbol? */
523 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
524 if (S->Flags & SF_IMPORT) {
525 /* The symbol is already marked as imported external symbol */
526 Error (ERR_SYM_ALREADY_IMPORT, Name);
530 /* If the symbol is marked as global, check the symbol size, then do
531 * silently remove the global flag
533 if (S->Flags & SF_GLOBAL) {
534 if ((ZP != 0) != ((S->Flags & SF_ZP) != 0)) {
535 Error (ERR_SYM_REDECL_MISMATCH);
537 S->Flags &= ~SF_GLOBAL;
540 /* Set the symbol data */
541 S->Flags |= SF_EXPORT | SF_REFERENCED;
549 void SymGlobal (const char* Name, int ZP)
550 /* Mark the given symbol as a global symbol, that is, as a symbol that is
551 * either imported or exported.
556 /* Don't accept local symbols */
557 if (IsLocal (Name)) {
558 Error (ERR_ILLEGAL_LOCAL_USE);
562 /* Search for this symbol, create a new entry if needed */
563 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
565 /* If the symbol is already marked as import or export, check the
566 * size of the definition, then bail out. */
567 if (S->Flags & SF_IMPORT || S->Flags & SF_EXPORT) {
568 if ((ZP != 0) != ((S->Flags & SF_ZP) != 0)) {
569 Error (ERR_SYM_REDECL_MISMATCH);
574 /* Mark the symbol */
575 S->Flags |= SF_GLOBAL;
583 void SymConDes (const char* Name, unsigned Type, unsigned Prio)
584 /* Mark the given symbol as a module constructor/destructor. This will also
585 * mark the symbol as an export. Initializers may never be zero page symbols.
590 /* Check the parameters */
591 CHECK (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
592 CHECK (Prio >= CD_PRIO_MIN && Prio <= CD_PRIO_MAX);
594 /* Don't accept local symbols */
595 if (IsLocal (Name)) {
596 Error (ERR_ILLEGAL_LOCAL_USE);
600 /* Do we have such a symbol? */
601 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
602 if (S->Flags & SF_IMPORT) {
603 /* The symbol is already marked as imported external symbol */
604 Error (ERR_SYM_ALREADY_IMPORT, Name);
608 /* If the symbol is marked as global, silently remove the global flag */
609 if (S->Flags & SF_GLOBAL) {
610 S->Flags &= ~SF_GLOBAL;
613 /* Check if the symbol was not already defined as ZP symbol */
614 if ((S->Flags & SF_ZP) != 0) {
615 Error (ERR_SYM_REDECL_MISMATCH);
618 /* If the symbol was already declared as a condes, check if the new
619 * priority value is the same as the old one.
621 if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
622 if (S->ConDesPrio[Type] != Prio) {
623 Error (ERR_SYM_REDECL_MISMATCH);
626 S->ConDesPrio[Type] = Prio;
628 /* Set the symbol data */
629 S->Flags |= SF_EXPORT | SF_REFERENCED;
634 int SymIsDef (const char* Name)
635 /* Return true if the given symbol is already defined */
637 SymEntry* S = SymFindAny (SymTab, Name);
638 return S != 0 && (S->Flags & (SF_DEFINED | SF_IMPORT)) != 0;
643 int SymIsRef (const char* Name)
644 /* Return true if the given symbol has been referenced */
646 SymEntry* S = SymFindAny (SymTab, Name);
647 return S != 0 && (S->Flags & SF_REFERENCED) != 0;
652 int SymIsConst (SymEntry* S)
653 /* Return true if the given symbol has a constant value */
655 /* Resolve trampoline entries */
656 if (S->Flags & SF_TRAMPOLINE) {
660 /* Check for constness */
661 if (S->Flags & SF_CONST) {
663 } else if ((S->Flags & SF_DEFINED) && IsConstExpr (S->V.Expr)) {
664 /* Constant expression, remember the value */
665 ExprNode* Expr = S->V.Expr;
666 S->Flags |= SF_CONST;
667 S->V.Val = GetExprVal (Expr);
676 int SymIsZP (SymEntry* S)
677 /* Return true if the symbol is explicitly marked as zeropage symbol */
679 /* Resolve trampoline entries */
680 if (S->Flags & SF_TRAMPOLINE) {
684 /* If the symbol is not a global symbol, was not defined before, check the
685 * enclosing scope for a symbol with the same name, and return the ZP
686 * attribute of this symbol if we find one.
688 if (!IsLocal (S->Name) &&
689 (S->Flags & (SF_ZP | SF_ABS | SF_DEFINED | SF_IMPORT)) == 0 &&
690 S->SymTab->BackLink != 0) {
692 /* Try to find a symbol with the same name in the enclosing scope */
693 SymEntry* E = SymFindAny (S->SymTab->BackLink, S->Name);
695 /* If we found one, use the ZP flag */
696 if (E && (E->Flags & SF_ZP) != 0) {
701 /* Check the ZP flag */
702 return (S->Flags & SF_ZP) != 0;
707 int SymIsImport (SymEntry* S)
708 /* Return true if the given symbol is marked as import */
710 /* Resolve trampoline entries */
711 if (S->Flags & SF_TRAMPOLINE) {
715 /* Check the import flag */
716 return (S->Flags & SF_IMPORT) != 0;
721 int SymHasExpr (SymEntry* S)
722 /* Return true if the given symbol has an associated expression */
724 /* Resolve trampoline entries */
725 if (S->Flags & SF_TRAMPOLINE) {
729 /* Check the expression */
730 return ((S->Flags & SF_DEFINED) != 0 &&
731 (S->Flags & SF_IMPORT) == 0 &&
732 (S->Flags & SF_CONST) == 0);
737 void SymFinalize (SymEntry* S)
738 /* Finalize a symbol expression if there is one */
740 /* Resolve trampoline entries */
741 if (S->Flags & SF_TRAMPOLINE) {
745 /* Check if we have an expression */
746 if (SymHasExpr (S)) {
747 S->V.Expr = FinalizeExpr (S->V.Expr);
753 void SymMarkUser (SymEntry* S)
754 /* Set a user mark on the specified symbol */
756 /* Resolve trampoline entries */
757 if (S->Flags & SF_TRAMPOLINE) {
767 void SymUnmarkUser (SymEntry* S)
768 /* Remove a user mark from the specified symbol */
770 /* Resolve trampoline entries */
771 if (S->Flags & SF_TRAMPOLINE) {
776 S->Flags &= ~SF_USER;
781 int SymHasUserMark (SymEntry* S)
782 /* Return the state of the user mark for the specified symbol */
784 /* Resolve trampoline entries */
785 if (S->Flags & SF_TRAMPOLINE) {
790 return (S->Flags & SF_USER) != 0;
795 long GetSymVal (SymEntry* S)
796 /* Return the symbol value */
798 /* Resolve trampoline entries */
799 if (S->Flags & SF_TRAMPOLINE) {
803 PRECONDITION ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_CONST) != 0);
809 ExprNode* GetSymExpr (SymEntry* S)
810 /* Get the expression for a non-const symbol */
812 /* Resolve trampoline entries */
813 if (S->Flags & SF_TRAMPOLINE) {
817 PRECONDITION (S != 0 && (S->Flags & SF_CONST) == 0);
823 const char* GetSymName (SymEntry* S)
824 /* Return the name of the symbol */
826 /* Resolve trampoline entries */
827 if (S->Flags & SF_TRAMPOLINE) {
835 unsigned GetSymIndex (SymEntry* S)
836 /* Return the symbol index for the given symbol */
838 /* Resolve trampoline entries */
839 if (S->Flags & SF_TRAMPOLINE) {
842 PRECONDITION (S != 0 && (S->Flags & SF_INDEXED));
848 const FilePos* GetSymPos (SymEntry* S)
849 /* Return the position of first occurence in the source for the given symbol */
851 /* Resolve trampoline entries */
852 if (S->Flags & SF_TRAMPOLINE) {
855 PRECONDITION (S != 0);
861 static void SymCheckUndefined (SymEntry* S)
862 /* Handle an undefined symbol */
864 /* Undefined symbol. It may be...
866 * - An undefined symbol in a nested lexical level. In this
867 * case, search for the symbol in the higher levels and
868 * make the entry a trampoline entry if we find one.
870 * - If the symbol is not found, it is a real undefined symbol.
871 * If the AutoImport flag is set, make it an import. If the
872 * AutoImport flag is not set, it's an error.
876 /* It's a global symbol, get the higher level table */
877 SymTable* Tab = S->SymTab->BackLink;
879 Sym = SymFindAny (Tab, S->Name);
881 if (Sym->Flags & (SF_DEFINED | SF_IMPORT)) {
882 /* We've found a symbol in a higher level that is
883 * either defined in the source, or an import.
887 /* The symbol found is undefined itself. Look further */
888 Tab = Sym->SymTab->BackLink;
891 /* No symbol found */
897 /* We found the symbol in a higher level. Make S a trampoline
898 * symbol. Beware: We have to transfer the symbol attributes to
899 * the real symbol and check for any conflicts.
901 S->Flags |= SF_TRAMPOLINE;
904 /* Transfer the flags. Note: S may not be imported, since in that
905 * case it wouldn't be undefined.
907 if (S->Flags & SF_EXPORT) {
908 if (Sym->Flags & SF_IMPORT) {
909 /* The symbol is already marked as imported external symbol */
910 PError (&S->Pos, ERR_SYM_ALREADY_IMPORT, S->Name);
912 Sym->Flags |= S->Flags & (SF_EXPORT | SF_ZP);
915 /* Transfer the referenced flag */
916 Sym->Flags |= (S->Flags & SF_REFERENCED);
919 /* The symbol is definitely undefined */
920 if (S->Flags & SF_EXPORT) {
921 /* We will not auto-import an export */
922 PError (&S->Pos, ERR_EXPORT_UNDEFINED, S->Name);
925 /* Mark as import, will be indexed later */
926 S->Flags |= SF_IMPORT;
929 PError (&S->Pos, ERR_SYM_UNDEFINED, S->Name);
938 /* Run through all symbols and check for anomalies and errors */
942 /* Check for open lexical levels */
943 if (SymTab->BackLink != 0) {
944 Error (ERR_OPEN_PROC);
947 /* First pass: Walk through all symbols, checking for undefined's and
948 * changing them to trampoline symbols or make them imports.
952 /* If the symbol is marked as global, mark it as export, if it is
953 * already defined, otherwise mark it as import.
955 if (S->Flags & SF_GLOBAL) {
956 S->Flags &= ~SF_GLOBAL;
957 if (S->Flags & SF_DEFINED) {
958 S->Flags |= SF_EXPORT;
960 S->Flags |= SF_IMPORT;
964 /* Handle undefined symbols */
965 if ((S->Flags & SF_UNDEFMASK) == SF_UNDEFVAL) {
966 /* This is an undefined symbol. Handle it. */
967 SymCheckUndefined (S);
974 /* Second pass: Walk again through the symbols. Ignore undefined's, since
975 * we handled them in the last pass, and ignore trampoline symbols, since
976 * we handled them in the last pass, too.
980 if ((S->Flags & SF_TRAMPOLINE) == 0 &&
981 (S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {
982 if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
983 /* Symbol was defined but never referenced */
984 PWarning (&S->Pos, WARN_SYM_NOT_REFERENCED, S->Name);
986 if (S->Flags & SF_IMPORT) {
987 if ((S->Flags & SF_REFERENCED) == 0) {
988 /* Imported symbol is not referenced */
989 PWarning (&S->Pos, WARN_IMPORT_NOT_REFERENCED, S->Name);
991 /* Give the import an index, count imports */
992 S->Index = ImportCount++;
993 S->Flags |= SF_INDEXED;
996 if (S->Flags & SF_EXPORT) {
997 /* Give the export an index, count exports */
998 S->Index = ExportCount++;
999 S->Flags |= SF_INDEXED;
1010 void SymDump (FILE* F)
1011 /* Dump the symbol table */
1013 SymEntry* S = SymList;
1016 /* Ignore trampoline symbols */
1017 if ((S->Flags & SF_TRAMPOLINE) != 0) {
1018 printf ("%-24s %s %s %s %s %s\n",
1020 (S->Flags & SF_DEFINED)? "DEF" : "---",
1021 (S->Flags & SF_REFERENCED)? "REF" : "---",
1022 (S->Flags & SF_IMPORT)? "IMP" : "---",
1023 (S->Flags & SF_EXPORT)? "EXP" : "---",
1024 (S->Flags & SF_ZP)? "ZP" : "--");
1033 void WriteImports (void)
1034 /* Write the imports list to the object file */
1038 /* Tell the object file module that we're about to start the imports */
1041 /* Write the import count to the list */
1042 ObjWriteVar (ImportCount);
1044 /* Walk throught list and write all imports to the file */
1047 if ((S->Flags & SF_IMPMASK) == SF_IMPVAL) {
1048 if (S->Flags & SF_ZP) {
1051 ObjWrite8 (IMP_ABS);
1053 ObjWriteStr (S->Name);
1054 ObjWritePos (&S->Pos);
1059 /* Done writing imports */
1065 void WriteExports (void)
1066 /* Write the exports list to the object file */
1071 /* Tell the object file module that we're about to start the exports */
1074 /* Write the export count to the list */
1075 ObjWriteVar (ExportCount);
1077 /* Walk throught list and write all exports to the file */
1080 if ((S->Flags & SF_EXPMASK) == SF_EXPVAL) {
1081 unsigned char ExprMask;
1083 /* Finalize an associated expression if we have one */
1086 /* Check if the symbol is const */
1087 ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
1089 /* Add zeropage/abs bits */
1090 ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
1092 /* Count the number of ConDes types */
1093 for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
1094 if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
1095 INC_EXP_CONDES_COUNT (ExprMask);
1099 /* Write the type */
1100 ObjWrite8 (ExprMask);
1102 /* Write any ConDes declarations */
1103 if (GET_EXP_CONDES_COUNT (ExprMask) > 0) {
1104 for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
1105 unsigned char Prio = S->ConDesPrio[Type];
1106 if (Prio != CD_PRIO_NONE) {
1107 ObjWrite8 (CD_BUILD (Type, Prio));
1112 /* Write the name */
1113 ObjWriteStr (S->Name);
1115 /* Write the value */
1116 if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
1117 /* Constant value */
1118 ObjWrite32 (S->V.Val);
1120 /* Expression involved */
1121 WriteExpr (S->V.Expr);
1124 /* Write the source file position */
1125 ObjWritePos (&S->Pos);
1130 /* Done writing exports */
1136 void WriteDbgSyms (void)
1137 /* Write a list of all symbols to the object file */
1142 /* Tell the object file module that we're about to start the debug info */
1145 /* Check if debug info is requested */
1148 /* Walk through the list and count the symbols */
1152 if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
1158 /* Write the symbol count to the list */
1159 ObjWriteVar (Count);
1161 /* Walk through list and write all symbols to the file */
1164 if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
1165 unsigned char ExprMask;
1167 /* Finalize an associated expression if we have one */
1170 /* Check if the symbol is const */
1171 ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
1173 /* Add zeropage/abs bits */
1174 ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
1176 /* Write the type */
1177 ObjWrite8 (ExprMask);
1179 /* Write the name */
1180 ObjWriteStr (S->Name);
1182 /* Write the value */
1183 if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
1184 /* Constant value */
1185 ObjWrite32 (S->V.Val);
1187 /* Expression involved */
1188 WriteExpr (S->V.Expr);
1191 /* Write the source file position */
1192 ObjWritePos (&S->Pos);
1199 /* No debug symbols */
1204 /* Done writing debug symbols */