2 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
3 // SYMBOL.C - Symbol Handling
4 // Copyright (C) 199x Landon Dyer, 2011-2012 Reboot and Friends
5 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
6 // Source Utilised with the Kind Permission of Landon Dyer
14 static SYM * sytab[NBUCKETS]; // User symbol-table header
15 int curenv; // Current enviroment number
16 SYM * sorder; // * -> Symbols, in order of reference
17 SYM * sordtail; // * -> Last symbol in sorder list
18 SYM * sdecl; // * -> Symbols, in order of declaration
19 SYM * sdecltail; // * -> Last symbol in sdecl list
21 // Tags for marking symbol spaces
27 static char tdb_text[8] = {
28 'a', 't', 'd', '!', 'b', SPACE, SPACE, SPACE
33 // Initialize Symbol Table
39 for(i=0; i<NBUCKETS; ++i) // Initialise symbol hash table
42 curenv = 1; // Init local symbol enviroment
43 sorder = NULL; // Init symbol-reference list
45 sdecl = NULL; // Init symbol-decl list
51 // Hash the Print Name and Enviroment Number
53 int syhash(char * name, int envno)
55 int sum, k = 0; // Hash calculation
57 for(sum=envno; *name; name++)
65 return sum & (NBUCKETS - 1);
70 // Make a new symbol of type `type' in enviroment `envno'
72 SYM * newsym(char * name, int type, int envno)
74 int hash; // Symbol hash value
75 SYM * sy; // Pointer to symbol
77 // Allocate the symbol
78 // sy = (SYM *)amem((long)(sizeof(SYM)));
79 sy = (SYM *)malloc(sizeof(SYM));
83 printf("SYMALLOC ERROR (%s)\n", name);
87 // sy->sname = nstring(name);
88 sy->sname = strdup(name);
91 sy->stype = (BYTE)type;
92 sy->senv = (WORD)envno;
100 sy->sattre = (rgpu || rdsp ? RISCSYM : 0);
104 // Install symbol in symbol table
105 hash = syhash(name, envno);
106 sy->snext = sytab[hash];
109 // Append symbol to symbol-order list
111 sorder = sy; // Add first symbol
113 sordtail->sorder = sy; // Or append to tail of list
118 return sy; // Return pointer to symbol
123 // Lookup the symbol `name', of the specified type, with the specified
126 SYM * lookup(char * name, int type, int envno)
129 SYM * sy; // Symbol record pointer
130 int k, sum; // Hash bucket calculation
131 char * s; // String pointer
133 // Pick a hash-bucket (SAME algorithm as syhash())
145 sy = sytab[sum & (NBUCKETS-1)];
147 SYM * sy = sytab[syhash(name, envno)];
150 // Do linear-search for symbol in bucket
153 if (sy->stype == type // Type, envno and name must match
155 && *name == *sy->sname // Fast check for first character
156 && !strcmp(name, sy->sname))
162 return sy; // Return NULL or matching symbol
167 // Put symbol on "order-of-declaration" list of symbols
169 void sym_decl(SYM * sym)
171 if (sym->sattr & SDECLLIST)
172 return; // Already on list
174 sym->sattr |= SDECLLIST; // Mark "already on list"
177 sdecl = sym; // First on decl-list
179 sdecltail->sdecl = sym; // Add to end of list
181 sym->sdecl = NULL; // Fix up list's tail
187 // Make all referenced, undefined symbols global
193 DEBUG printf("~syg_fix()\n");
195 // Scan through all symbols;
196 // If a symbol is REFERENCED but not DEFINED, then make it global.
197 for(sy=sorder; sy!=NULL; sy=sy->sorder)
199 if (sy->stype == LABEL && sy->senv == 0
200 && ((sy->sattr & (REFERENCED|DEFINED)) == REFERENCED))
209 // Convert string to uppercase
211 int uc_string(char * s)
215 if (*s >= 'a' && *s <= 'z')
224 // Assign numbers to symbols that are to be exported or imported. The symbol
225 // number is put in `.senv'. Return the number of symbols that will be in the
228 int sy_assign(char * buf, char *(* constr)())
238 // Append all symbols not appearing on the .sdecl list to the end of
240 for(sy=sorder; sy!=NULL; sy=sy->sorder)
242 // Essentially the same as 'sym_decl()' above:
243 if (sy->sattr & SDECLLIST)
244 continue; // Already on list
246 sy->sattr |= SDECLLIST; // Mark "on the list"
249 sdecl = sy; // First on decl-list
251 sdecltail->sdecl = sy; // Add to end of list
253 sy->sdecl = NULL; // Fix up list's tail
258 // Run through all symbols (now on the .sdecl list) and assign numbers to
259 // them. We also pick which symbols should be global or not here.
260 for(sy=sdecl; sy!=NULL; sy=sy->sdecl)
262 if (sy->sattre & UNDEF_EQUR)
263 continue; // Don't want undefined on our list
265 if (sy->sattre & UNDEF_CC)
268 // Export or import external references, and export COMMON blocks.
269 if ((sy->stype == LABEL)
270 && ((sy->sattr & (GLOBAL|DEFINED)) == (GLOBAL|DEFINED)
271 || (sy->sattr & (GLOBAL|REFERENCED)) == (GLOBAL|REFERENCED))
272 || (sy->sattr & COMMON))
274 sy->senv = (WORD)scount++;
277 buf = (*constr)(buf, sy, 1);
279 // Export vanilla labels (but don't make them global). An exception is
280 // made for equates, which are not exported unless they are referenced.
281 else if (sy->stype == LABEL && lsym_flag
282 && (sy->sattr & (DEFINED|REFERENCED)) != 0
283 && (!as68_flag || *sy->sname != 'L'))
285 sy->senv = (WORD)scount++;
286 if (buf != NULL) buf = (*constr)(buf, sy, 0);
295 // Generate symbol table for listing file
316 colhei = pagelen - 5;
318 // Allocate storage for list headers and partition all labels.
319 // Throw away macros and macro arguments.
320 // sy = (SYM **)amem((LONG)(128 * sizeof(LONG)));
321 sy = (SYM **)malloc(128 * sizeof(LONG));
326 for(i=0; i<NBUCKETS; ++i)
328 for(p=sytab[i]; p!=NULL; p=k)
334 if (p->stype != LABEL)
335 continue; // Ignore non-labels
337 if (p->sattre & UNDEF_EQUR)
340 for(q=sy[j]; q!=NULL; q=q->snext)
342 if (strcmp(p->sname, q->sname) < 0)
349 { // Insert at front of list
354 { // Insert in middle or append to list
361 // Link all symbols onto one list again
366 if ((r = sy[i]) != NULL)
373 while (q->snext != NULL)
382 strcpy(subttl, "Symbol Table");
390 for(j=0; j<colhei; ++j)
399 for(i=0; i<colhei; ++i)
403 if (colptr[0] == NULL)
408 if ((q = colptr[j]) == NULL)
411 colptr[j] = q->snext;
416 // x external reference
418 // space nothing special
424 else if ((w & (DEFINED|GLOBAL)) == GLOBAL)
429 c1 = tdb_text[w & TDB];
432 strcpy(ln2, "external");
435 sprintf(ln2, "%08ux", q->svalue);
439 sprintf(ln1, " %16s %s %c%c%c", q->sname, ln2, (ww & EQUATEDREG) ? 'e' : SPACE, c1, c);