This source file includes following definitions.
- label_hashkey
- labelhash
- compare_adr
- printlabel_full
- addcerrlist_label
- getlabel
- addlabel
- printlabel
- printliteral
- 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
36
37 void printlabel_full(bool literal);
38
39
40
41
42 static int labelcnt = 0;
43
44
45
46
47 static LABELTAB *labels[LABELTABSIZE];
48
49
50
51
52 static CERR cerr_label[] = {
53 { 101, "label already defined" },
54 { 102, "label table is full" },
55 { 103, "label not found" },
56 };
57
58 HKEY *label_hashkey(const char *value) {
59 HKEY *key = NULL;
60
61 key = malloc_chk(sizeof(HKEY), "label_hashkey");
62 key->type = CHARS;
63 key->val.s = strdup_chk(value, "label_hashkey->value");
64 return key;
65 }
66
67 unsigned labelhash(const char *prog, const char *label)
68 {
69 HKEY *keys[2] = {NULL};
70 int i = 0;
71 unsigned h = 0;
72
73 if(prog[0]) {
74 keys[i++] = label_hashkey(prog);
75 }
76 keys[i] = label_hashkey(label);
77 h = hash(i+1, keys, LABELTABSIZE);
78 for(int j = 0; j < i + 1; j++) {
79 FREE(keys[j]->val.s);
80 FREE(keys[j]);
81 }
82 return h;
83 }
84
85 int compare_adr(const void *a, const void *b)
86 {
87 return (**(LABELARRAY **)a).adr - (**(LABELARRAY **)b).adr;
88 }
89
90 void printlabel_full(bool literal)
91 {
92 int s = 0;
93 LABELTAB *p = NULL;
94 LABELARRAY **l = NULL;
95
96 l = calloc_chk(labelcnt, sizeof(LABELARRAY *), "printlabel_full");
97 for(int i = 0; i < LABELTABSIZE; i++) {
98 for(p = labels[i]; p != NULL; p = p->next) {
99 assert(p->label->label != NULL);
100 if((literal == true && p->label->label[0] == '=') || (literal == false && p->label->label[0] != '=')) {
101 l[s++] = p->label;
102 }
103 }
104 }
105 if(s > 0) {
106 qsort(l, s, sizeof(*l), compare_adr);
107 fprintf(stdout, "\n%s::::\n", (literal == true) ? "Literal" : "Label");
108 for(int i = 0; i < s; i++) {
109 if(l[i]->prog[0]) {
110 fprintf(stdout, "%s.", l[i]->prog);
111 }
112 fprintf(stdout, "%s ---> #%04X\n", l[i]->label, l[i]->adr);
113 }
114 if(literal == true) {
115 fprintf(stdout, "\n");
116 }
117 }
118 FREE(l);
119 }
120
121
122 void addcerrlist_label()
123 {
124 addcerrlist(ARRAYSIZE(cerr_label), cerr_label);
125 }
126
127 WORD getlabel(const char *prog, const char *label)
128 {
129 assert(prog != NULL && label != NULL);
130 LABELTAB *p = NULL;
131 LABELARRAY *l = NULL;
132
133 for(p = labels[labelhash(prog, label)]; p != NULL; p = p->next) {
134 l = p->label;
135 if((!prog[0] || (strcmp(prog, l->prog) == 0)) &&
136 strcmp(label, l->label) == 0)
137 {
138 return l->adr;
139 }
140 }
141 return 0xFFFF;
142 }
143
144 bool addlabel(const char *prog, const char *label, WORD adr)
145 {
146 assert(label != NULL);
147 LABELTAB *p = NULL;
148 LABELARRAY *l = NULL;
149 unsigned h = 0;
150
151
152 if(getlabel(prog, label) != 0xFFFF) {
153 setcerr(101, label);
154 return false;
155 }
156
157 p = malloc_chk(sizeof(LABELTAB), "labels.next");
158 l = p->label = malloc_chk(sizeof(LABELARRAY), "labels.label");
159
160 l->prog = strdup_chk(prog, "label.prog");
161
162 l->label = strdup_chk(label, "label.label");
163
164 l->adr = adr;
165
166 labelcnt++;
167
168 p->next = labels[h = labelhash(prog, label)];
169 labels[h] = p;
170 return true;
171 }
172
173 void printlabel()
174 {
175 printlabel_full(false);
176 }
177
178 void printliteral()
179 {
180 printlabel_full(true);
181 }
182
183 void freelabel()
184 {
185 int i;
186 LABELTAB *p = NULL;
187 LABELTAB *q = NULL;
188
189 for(i = 0; i < LABELTABSIZE; i++) {
190 for(p = labels[i]; p != NULL; p = q) {
191 q = p->next;
192 FREE(p->label->prog);
193 FREE(p->label->label);
194 FREE(p->label);
195 FREE(p);
196 }
197 labels[i] = NULL;
198 }
199 }