This source file includes following definitions.
- label_hashkey
- labelhash
- compare_adr
- addcerrlist_label
- getlabel
- addlabel
- printlabel
- freelabel
1 #include "assemble.h"
2
3
4
5
6
7
8
9
10 HKEY *label_hashkey(const char *value);
11
12
13
14
15
16
17
18
19
20 unsigned labelhash(const char *prog, const char *label);
21
22
23
24
25
26
27
28
29
30 int compare_adr(const void *a, const void *b);
31
32
33
34
35 static int labelcnt = 0;
36
37
38
39
40 static LABELTAB *labels[LABELTABSIZE];
41
42
43
44
45 static CERR cerr_label[] = {
46 { 101, "label already defined" },
47 { 102, "label table is full" },
48 { 103, "label not found" },
49 };
50
51 HKEY *label_hashkey(const char *value) {
52 HKEY *key = NULL;
53
54 key = malloc_chk(sizeof(HKEY), "label_hashkey");
55 key->type = CHARS;
56 key->val.s = strdup_chk(value, "label_hashkey->value");
57 return key;
58 }
59
60 unsigned labelhash(const char *prog, const char *label)
61 {
62 HKEY *keys[2] = {NULL};
63 int i = 0;
64 unsigned h = 0;
65
66 if(prog[0]) {
67 keys[i++] = label_hashkey(prog);
68 }
69 keys[i] = label_hashkey(label);
70 h = hash(i+1, keys, LABELTABSIZE);
71 for(int j = 0; j < i + 1; j++) {
72 FREE(keys[j]->val.s);
73 FREE(keys[j]);
74 }
75 return h;
76 }
77
78 int compare_adr(const void *a, const void *b)
79 {
80 return (**(LABELARRAY **)a).adr - (**(LABELARRAY **)b).adr;
81 }
82
83
84 void addcerrlist_label()
85 {
86 addcerrlist(ARRAYSIZE(cerr_label), cerr_label);
87 }
88
89 WORD getlabel(const char *prog, const char *label)
90 {
91 assert(prog != NULL && label != NULL);
92 LABELTAB *p = NULL;
93 LABELARRAY *l = NULL;
94
95 for(p = labels[labelhash(prog, label)]; p != NULL; p = p->next) {
96 l = p->label;
97 if((!prog[0] || (strcmp(prog, l->prog) == 0)) &&
98 strcmp(label, l->label) == 0)
99 {
100 return l->adr;
101 }
102 }
103 return 0xFFFF;
104 }
105
106 bool addlabel(const char *prog, const char *label, WORD adr)
107 {
108 assert(label != NULL);
109 LABELTAB *p = NULL;
110 LABELARRAY *l = NULL;
111 unsigned h = 0;
112
113
114 if(getlabel(prog, label) != 0xFFFF) {
115 setcerr(101, label);
116 return false;
117 }
118
119 p = malloc_chk(sizeof(LABELTAB), "labels.next");
120 l = p->label = malloc_chk(sizeof(LABELARRAY), "labels.label");
121
122 l->prog = strdup_chk(prog, "label.prog");
123
124 l->label = strdup_chk(label, "label.label");
125
126 l->adr = adr;
127
128 labelcnt++;
129
130 p->next = labels[h = labelhash(prog, label)];
131 labels[h] = p;
132 return true;
133 }
134
135 void printlabel()
136 {
137 int s = 0;
138 LABELTAB *p = NULL;
139 LABELARRAY **l = {NULL};
140
141 l = calloc_chk(labelcnt, sizeof(LABELARRAY **), "labels");
142 for(int i = 0; i < LABELTABSIZE; i++) {
143 for(p = labels[i]; p != NULL; p = p->next) {
144 assert(p->label != NULL);
145 l[s++] = p->label;
146 }
147 }
148 qsort(l, s, sizeof(*l), compare_adr);
149 for(int i = 0; i < s; i++) {
150 if(l[i]->prog[0]) {
151 fprintf(stdout, "%s.", l[i]->prog);
152 }
153 fprintf(stdout, "%s ---> #%04X\n", l[i]->label, l[i]->adr);
154 }
155 FREE(l);
156 }
157
158 void freelabel()
159 {
160 int i;
161 LABELTAB *p = NULL;
162 LABELTAB *q = NULL;
163
164 for(i = 0; i < LABELTABSIZE; i++) {
165 for(p = labels[i]; p != NULL; p = q) {
166 q = p->next;
167 FREE(p->label->prog);
168 FREE(p->label->label);
169 FREE(p->label);
170 FREE(p);
171 }
172 labels[i] = NULL;
173 }
174 }