struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / asxxsrc / assym.c
blob0e6e71eb1a64f0525e28db983268dd4afca89ef5
1 /* assym.c */
3 /*
4 * Copyright (C) 1989-2021 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
24 * With enhancements from
26 * John L. Hartman (JLH)
27 * jhartman at compuserve dot com
31 * 10-Nov-07 borutr:
32 * - use strsto instead StoreString and include it in assym.c
33 * for compatibility with the original asxxxx
34 * - applied changes from 28-Oct-97 JLH:
35 * - lookup: Use StoreString for sym construction
36 * - change symeq() to do length-independent string compare
37 * - change hash() to do length-independent hash calculation
38 * - applied changes from 29-Oct-97 JLH:
39 * - make mnemonics case insensitive ALWAYS
40 * - make hash() case-insensitive always
41 * - replace symeq() call in mlookup with strcmpi
44 #include "asxxxx.h"
46 /*)Module assym.c
48 * The module assym.c contains the functions that operate
49 * on the mnemonic/directive and symbol structures.
51 * assym.c contains the following functions:
52 * VOID allglob()
53 * area * alookup()
54 * def * dlookup()
55 * int hash()
56 * sym * lookup()
57 * mne * mlookup()
58 * char * new()
59 * sym * slookup()
60 * char * strsto()
61 * int symeq()
62 * VOID syminit()
63 * VOID symglob()
65 * assym.c contains the static variables:
66 * char * pnext
67 * int bytes
68 * used by the string store function.
71 /*)Function VOID syminit()
73 * The function syminit() is called early in the game
74 * to set up the hashtables. First all buckets in a
75 * table are cleared. Then a pass is made through
76 * the respective symbol lists, linking them into
77 * their hash buckets. Finally the base area pointer
78 * is set to 'dca'.
80 * local variables:
81 * int h computed hash value
82 * mne * mp pointer to a mne structure
83 * mne ** mpp pointer to an array of
84 * mne structure pointers
85 * sym * sp pointer to a sym structure
86 * sym ** spp pointer to an array of
87 * sym structure pointers
89 * global variables:
90 * area area[] single elememt area array
91 * area dca defined as area[0]
92 * mne * mnehash[] array of pointers to NHASH
93 * linked mnemonic/directive lists
94 * sym * symhash[] array of pointers to NHASH
95 * linked symbol lists
97 * functions called:
98 * none
100 * side effects:
101 * (1) The symbol hash tables are initialized,
102 * the predefined symbols are '.' and '.__.ABS.'.
103 * (2) The mnemonic/directive hash tables are
104 * initialized with the assembler directives
105 * and mnemonics found in the machine dependent
106 * file ___pst.c.
107 * (3) The area pointer is initialized to dca (area[0]).
110 VOID
111 syminit(void)
113 struct mne *mp;
114 struct mne **mpp;
115 struct sym *sp;
116 struct sym **spp;
117 int h;
119 mpp = &mnehash[0];
120 while (mpp < &mnehash[NHASH])
121 *mpp++ = NULL;
122 mp = &mne[0];
123 for (;;) {
124 h = hash(mp->m_id, 1);
125 mp->m_mp = mnehash[h];
126 mnehash[h] = mp;
127 if (mp->m_flag&S_EOL)
128 break;
129 ++mp;
132 spp = &symhash[0];
133 while (spp < &symhash[NHASH])
134 *spp++ = NULL;
135 sp = &sym[0];
136 for (;;) {
137 h = hash(sp->s_id, zflag);
138 sp->s_sp = symhash[h];
139 symhash[h] = sp;
140 if (sp->s_flag&S_EOL)
141 break;
142 ++sp;
145 areap = &dca;
148 /*)Function area * alookup(id)
150 * char * id area name string
152 * The function alookup() searches the area list for a
153 * match with id. If the area is defined then a pointer
154 * to this area is returned else a NULL is returned.
156 * local variables:
157 * area * ap pointer to area structure
159 * global variables:
160 * area * areap pointer to an area structure
162 * functions called:
163 * int symeq() assym.c
165 * side effects:
166 * none
169 struct area *
170 alookup(char *id)
172 struct area *ap;
174 ap = areap;
175 while (ap) {
177 * JLH: case insensitive lookup always
179 if(symeq(id, ap->a_id, 1))
180 return (ap);
181 ap = ap->a_ap;
183 return(NULL);
186 /*)Function def * dlookup(id)
188 * char * id definition name string
190 * The function dlookup() searches the definition list for a
191 * match with id. If the definition is defined then a pointer
192 * to this definition is returned else a NULL is returned.
194 * local variables:
195 * def * dp pointer to a def structure
197 * global variables:
198 * def * defp pointer to a def structure
200 * functions called:
201 * int symeq() assym.c
203 * side effects:
204 * none
207 struct def *
208 dlookup(char *id)
210 struct def *dp;
212 dp = defp;
213 while (dp) {
214 if (symeq(id, dp->d_id, zflag)) {
215 break;
217 dp = dp->d_dp;
219 return(dp);
222 /*)Function mne * mlookup(id)
224 * char * id mnemonic/directive name string
226 * The function mlookup() searches the mnemonic/directive
227 * hash tables for a match returning a pointer to the
228 * mne structure else it returns a NULL.
230 * local variables:
231 * mne * mp pointer to mne structure
232 * int h calculated hash value
234 * global variables:
235 * mne * mnehash[] array of pointers to NHASH
236 * linked mnemonic/directive lists
238 * functions called:
239 * none
241 * side effects:
242 * none
245 struct mne *
246 mlookup(char *id)
248 struct mne *mp;
249 int h;
252 * JLH: case insensitive lookup always
254 h = hash(id, 1);
255 mp = mnehash[h];
256 while (mp) {
257 if(symeq(id, mp->m_id, 1))
258 return (mp);
259 mp = mp->m_mp;
261 return (NULL);
264 /*)Function sym * slookup(id)
266 * char * id symbol name string
268 * The function slookup() searches the symbol hash tables for
269 * a symbol name match returning a pointer to the sym structure
270 * else it returns a NULL.
272 * local variables:
273 * int h computed hash value
274 * sym * sp pointer to a sym structure
276 * global varaibles:
277 * sym * symhash[] array of pointers to NHASH
278 * linked symbol lists
279 * int zflag disable symbol case sensitivity
281 * functions called:
282 * int hash() assym.c
283 * int symeq() assym.c
285 * side effects:
286 * none
289 struct sym *
290 slookup(char *id)
292 struct sym *sp;
293 int h;
295 h = hash(id, zflag);
296 sp = symhash[h];
297 while (sp) {
298 if(symeq(id, sp->s_id, zflag))
299 return (sp);
300 sp = sp->s_sp;
302 return (NULL);
305 /*)Function sym * lookup(id)
307 * char * id symbol name string
309 * The function lookup() searches the symbol hash tables for
310 * a symbol name match returning a pointer to the sym structure.
311 * If the symbol is not found then a sym structure is created,
312 * initialized, and linked to the appropriate hash table.
313 * A pointer to this new sym structure is returned.
315 * local variables:
316 * int h computed hash value
317 * sym * sp pointer to a sym structure
319 * global varaibles:
320 * sym * symhash[] array of pointers to NHASH
321 * linked symbol lists
322 * int zflag disable symbol case sensitivity
324 * functions called:
325 * int hash() assym.c
326 * char * new() assym.c
327 * char * strsto() assym.c
328 * int symeq() assym.c
330 * side effects:
331 * If the function new() fails to allocate space
332 * for the new sym structure the assembly terminates.
335 struct sym *
336 lookup(const char *id)
338 struct sym *sp;
339 int h;
341 h = hash(id, zflag);
342 sp = symhash[h];
343 while (sp) {
344 if(symeq(id, sp->s_id, zflag))
345 return (sp);
346 sp = sp->s_sp;
348 sp = (struct sym *) new (sizeof(struct sym));
349 sp->s_sp = symhash[h];
350 symhash[h] = sp;
351 sp->s_tsym = NULL;
352 sp->s_id = strsto(id);
353 sp->s_type = S_NEW;
354 sp->s_flag = 0;
355 sp->s_area = NULL;
356 sp->s_ref = 0;
357 sp->s_addr = 0;
358 return (sp);
361 /*)Function VOID symglob()
363 * The function symglob() will mark all symbols of
364 * type S_NEW as global. Called at
365 * the beginning of pass 1 if the assembly
366 * option -g was specified.
368 * local variables:
369 * sym * sp pointer to a sym structure
370 * int i loop index
372 * global variables:
373 * sym * symhash[] array of pointers to NHASH
374 * linked symbol lists
376 * functions called:
377 * none
379 * side effects:
380 * Symbol types changed.
383 VOID
384 symglob(void)
386 struct sym *sp;
387 int i;
389 for (i=0; i<NHASH; ++i) {
390 sp = symhash[i];
391 while (sp != NULL) {
392 if (sp->s_type == S_NEW)
393 sp->s_flag |= S_GBL;
394 sp = sp->s_sp;
399 /*)Function VOID allglob()
401 * The function allglob() will mark all symbols of
402 * type S_USER as global. Called at
403 * the beginning of pass 1 if the assembly
404 * option -a was specified.
406 * local variables:
407 * sym * sp pointer to a sym structure
408 * int i loop index
410 * global variables:
411 * sym * symhash[] array of pointers to NHASH
412 * linked symbol lists
414 * functions called:
415 * none
417 * side effects:
418 * Symbol types changed.
421 VOID
422 allglob(void)
424 struct sym *sp;
425 int i;
427 for (i=0; i<NHASH; ++i) {
428 sp = symhash[i];
429 while (sp != NULL) {
430 if (sp != &dot && sp->s_type == S_USER)
431 sp->s_flag |= S_GBL;
432 sp = sp->s_sp;
437 /*)Function int symeq(p1, p2, flag)
439 * int flag case sensitive flag
440 * char * p1 name string
441 * char * p2 name string
443 * The function symeq() compares the two name strings for a match.
444 * The return value is 1 for a match and 0 for no match.
446 * flag == 0 case sensitive compare
447 * flag != 0 case insensitive compare
449 * local variables:
450 * int n loop counter
452 * global variables:
453 * char ccase[] an array of characters which
454 * perform the case translation function
456 * functions called:
457 * none
459 * side effects:
460 * none
465 symeq(const char *p1, const char *p2, int flag)
467 size_t n;
469 n = strlen(p1) + 1;
470 if(flag) {
472 * Case Insensitive Compare
474 do {
475 if (ccase[*p1++ & 0x007F] != ccase[*p2++ & 0x007F])
476 return (0);
477 } while (--n);
478 } else {
480 * Case Sensitive Compare
482 do {
483 if (*p1++ != *p2++)
484 return (0);
485 } while (--n);
487 return (1);
490 /*)Function int hash(p, flag)
492 * char * p pointer to string to hash
493 * int flag case sensitive flag
495 * The function hash() computes a hash code using the sum
496 * of all characters mod table size algorithm.
498 * flag == 0 case insensitve hash
499 * flag != 0 case sensitive hash
501 * local variables:
502 * int h accumulated character sum
504 * global variables:
505 * char ccase[] an array of characters which
506 * perform the case translation function
508 * functions called:
509 * none
511 * side effects:
512 * none
516 hash(const char *p, int flag)
518 int h;
520 h = 0;
521 while (*p) {
522 if(flag) {
524 * Case Insensitive Hash
526 h += ccase[*p++ & 0x007F];
527 } else {
529 * Case Sensitive Hash
531 h += *p++;
534 return (h&HMASK);
537 /*)Function char * strsto(str)
539 * char * str pointer to string to save
541 * Allocate space for "str", copy str into new space.
542 * Return a pointer to the allocated string.
544 * This function based on code by
545 * John L. Hartman
546 * jhartman at compuserve dot com
548 * local variables:
549 * int bytes bytes remaining in buffer area
550 * int len string length + 1
551 * char * p pointer to head of copied string
552 * char * pnext next location in buffer area
554 * global variables:
555 * none
557 * functions called:
558 * char * new() assym.c
559 * char * strncpy() c_library
560 * int * strlen() c_library
562 * side effects:
563 * Space allocated for string, string copied
564 * to space. Out of Space terminates assembler.
568 * To avoid wasting memory headers on small allocations, we
569 * allocate a big chunk and parcel it out as required.
570 * These static variables remember our hunk.
573 #define STR_SPC 1024
575 static char * pnext = NULL;
576 static int bytes = 0;
578 char *
579 strsto(const char *str)
581 int len;
582 char *p;
585 * What we need, including a null.
587 len = strlen(str) + 1;
589 if (len > bytes) {
591 * No space. Allocate a new hunk.
592 * We lose the pointer to any old hunk.
593 * We don't care, as the names are never deleted.
595 pnext = (char *) new (STR_SPC);
596 bytes = STR_SPC;
600 * Copy the name and terminating null.
602 p = pnext;
603 strncpy(p, str, len);
605 pnext += len;
606 bytes -= len;
608 return(p);
611 /*)Function char * new(n)
613 * unsigned int n allocation size in bytes
615 * The function new() allocates n bytes of space and returns
616 * a pointer to this memory. If no space is available the
617 * assembly is terminated.
619 * local variables:
620 * VOID * p a general pointer
622 * global variables:
623 * none
625 * functions called:
626 * VOID asexit() asmain.c
627 * int fprintf() c_library
628 * VOID * malloc() c_library
630 * side effects:
631 * Memory is allocated, if allocation fails
632 * the assembly is terminated.
635 char *
636 new(unsigned int n)
638 VOID *p;
640 if ((p = (VOID *) malloc(n)) == NULL) {
641 fprintf(stderr, "Out of space!\n");
642 asexit(ER_FATAL);
644 memset (p, 0, n);
645 return (p);