YACASL2
Loading...
Searching...
No Matches
label.c
Go to the documentation of this file.
1#include "assemble.h"
2
10HKEY *label_hashkey(const char *value);
11
20unsigned labelhash(const char *prog, const char *label);
21
30int compare_adr(const void *a, const void *b);
31
37void printlabel_full(bool literal);
38
42static int labelcnt = 0;
43
48
52static CERR cerr_label[] = {
53 { 101, "label already defined" },
54 { 102, "label table is full" },
55 { 103, "label not found" },
56};
57
58HKEY *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
67unsigned 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
85int compare_adr(const void *a, const void *b)
86{
87 return (**(LABELARRAY **)a).adr - (**(LABELARRAY **)b).adr;
88}
89
90void 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/* assemble.hで定義された関数群 */
126
127WORD 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
144bool 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); /* label already defined */
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
174{
175 printlabel_full(false);
176}
177
179{
180 printlabel_full(true);
181}
182
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}
@ LABELTABSIZE
Definition assemble.h:61
struct _LABELTAB LABELTAB
ラベル表を表すデータ型
struct _CERR CERR
エラーを表すデータ型
void addcerrlist(int cerrc, CERR cerrv[])
エラーリストを作成・追加する
Definition cerr.c:14
void setcerr(int num, const char *str)
現在のエラーを設定する
Definition cerr.c:46
#define FREE(ptr)
メモリを解放するマクロ
Definition cmem.h:22
void * calloc_chk(size_t nmemb, size_t size, const char *tag)
領域の数とサイズを指定してメモリーを確保するcallocを実行する
Definition cmem.c:34
void * malloc_chk(size_t size, const char *tag)
mallocを実行し、0で初期化する
Definition cmem.c:23
#define ARRAYSIZE(array)
配列のサイズを返すマクロ
Definition cmem.h:15
char * strdup_chk(const char *s, const char *tag)
malloc_chkを実行してメモリを確保し、コピーした文字列を返す
Definition cmem.c:45
@ CHARS
Definition hash.h:8
unsigned hash(int keyc, HKEY *keyv[], int tabsize)
ハッシュ値を取得する
Definition hash.c:3
void printlabel_full(bool literal)
定義されているラベルまたはリテラルの一覧を表示する
Definition label.c:90
void addcerrlist_label()
ラベルのエラーをエラーリストに追加する
Definition label.c:122
bool addlabel(const char *prog, const char *label, WORD adr)
プログラム名、ラベル、アドレスをラベル表に追加する
Definition label.c:144
unsigned labelhash(const char *prog, const char *label)
プログラム名とラベルに対応するハッシュ値を返す
Definition label.c:67
void printlabel()
ラベル表を表示する
Definition label.c:173
static LABELTAB * labels[LABELTABSIZE]
ラベル表
Definition label.c:47
WORD getlabel(const char *prog, const char *label)
プログラム名とラベルに対応するアドレスをラベル表から検索する
Definition label.c:127
int compare_adr(const void *a, const void *b)
ラベルを比較した結果を返す。qsort内で使われる関数
Definition label.c:85
static CERR cerr_label[]
ラベルのエラー
Definition label.c:52
HKEY * label_hashkey(const char *value)
ラベルのハッシュ値をセットしたキーを返す
Definition label.c:58
void printliteral()
リテラルを表示する
Definition label.c:178
static int labelcnt
ラベル数
Definition label.c:42
void freelabel()
ラベル表を解放する
Definition label.c:183
LABELARRAY * label
Definition assemble.h:54
struct _LABELTAB * next
Definition assemble.h:53
ハッシュ共用体のデータ型
Definition hash.h:15
char * s
Definition hash.h:18
UTYPE type
Definition hash.h:16
union HKEY::@132303155052201023056030363273137132157157107260 val
ラベル配列を表すデータ型
Definition assemble.h:43
char * prog
Definition assemble.h:44
WORD adr
Definition assemble.h:46
char * label
Definition assemble.h:45
unsigned short WORD
16ビットの数値を表すデータ型
Definition word.h:9