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
35static int labelcnt = 0;
36
41
45static CERR cerr_label[] = {
46 { 101, "label already defined" },
47 { 102, "label table is full" },
48 { 103, "label not found" },
49};
50
51HKEY *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
60unsigned 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
78int compare_adr(const void *a, const void *b)
79{
80 return (**(LABELARRAY **)a).adr - (**(LABELARRAY **)b).adr;
81}
82
83/* assemble.hで定義された関数群 */
88
89WORD 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
106bool 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); /* label already defined */
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
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
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}
@ LABELTABSIZE
Definition assemble.h:66
struct _LABELTAB LABELTAB
ラベル表を表すデータ型
struct _CERR CERR
エラーを表すデータ型
void addcerrlist(int cerrc, CERR cerrv[])
エラーリストを作成・追加する
Definition cerr.c:13
void setcerr(int num, const char *str)
現在のエラーを設定する
Definition cerr.c:45
#define FREE(ptr)
メモリを解放するマクロ
Definition cmem.h:21
void * calloc_chk(size_t nmemb, size_t size, const char *tag)
領域の数とサイズを指定してメモリーを確保するcallocを実行する
Definition cmem.c:14
void * malloc_chk(size_t size, const char *tag)
mallocを実行し、0で初期化する
Definition cmem.c:3
#define ARRAYSIZE(array)
配列のサイズを返すマクロ
Definition cmem.h:14
char * strdup_chk(const char *s, const char *tag)
malloc_chkを実行してメモリを確保し、コピーした文字列を返す
Definition cmem.c:25
@ CHARS
Definition hash.h:8
unsigned hash(int keyc, HKEY *keyv[], int tabsize)
ハッシュ値を取得する
Definition hash.c:3
void addcerrlist_label()
ラベルのエラーをエラーリストに追加する
Definition label.c:84
bool addlabel(const char *prog, const char *label, WORD adr)
プログラム名、ラベル、アドレスをラベル表に追加する
Definition label.c:106
unsigned labelhash(const char *prog, const char *label)
Definition label.c:60
void printlabel()
ラベル表を表示する
Definition label.c:135
static LABELTAB * labels[LABELTABSIZE]
ラベル表
Definition label.c:40
WORD getlabel(const char *prog, const char *label)
プログラム名とラベルに対応するアドレスをラベル表から検索する
Definition label.c:89
int compare_adr(const void *a, const void *b)
Definition label.c:78
static CERR cerr_label[]
ラベルのエラー
Definition label.c:45
HKEY * label_hashkey(const char *value)
Definition label.c:51
static int labelcnt
ラベル数
Definition label.c:35
void freelabel()
ラベル表を解放する
Definition label.c:158
LABELARRAY * label
Definition assemble.h:59
struct _LABELTAB * next
Definition assemble.h:58
ハッシュ共用体のデータ型
Definition hash.h:15
char * s
Definition hash.h:18
UTYPE type
Definition hash.h:16
union HKEY::@132303155052201023056030363273137132157157107260 val
ラベル配列を表すデータ型
Definition assemble.h:48
char * prog
Definition assemble.h:49
WORD adr
Definition assemble.h:51
char * label
Definition assemble.h:50
unsigned short WORD
16ビットの数値を表すデータ型
Definition word.h:9