root/src/label.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. label_hashkey
  2. labelhash
  3. compare_adr
  4. printlabel_full
  5. addcerrlist_label
  6. getlabel
  7. addlabel
  8. printlabel
  9. printliteral
  10. freelabel

   1 #include "assemble.h"
   2 
   3 /**
   4  * @brief ラベルのハッシュ値をセットしたキーを返す
   5  *
   6  * @return ハッシュ値をセットしたキー
   7  *
   8  * @param value 値
   9  */
  10 HKEY *label_hashkey(const char *value);
  11 
  12 /**
  13  * @brief プログラム名とラベルに対応するハッシュ値を返す
  14  *
  15  * @return ハッシュ値
  16  *
  17  * @param prog プログラム名
  18  * @param label ラベル
  19  */
  20 unsigned labelhash(const char *prog, const char *label);
  21 
  22 /**
  23  * @brief ラベルを比較した結果を返す。qsort内で使われる関数
  24  *
  25  * @return ラベルが同一の場合は0、異なる場合は0以外
  26  *
  27  * @param *a ラベルa
  28  * @param *b ラベルb
  29  */
  30 int compare_adr(const void *a, const void *b);
  31 
  32 /**
  33  * @brief 定義されているラベルまたはリテラルの一覧を表示する
  34  *
  35  * @param literal リテラルの場合はtrue、それ以外はfalse
  36  */
  37 void printlabel_full(bool literal);
  38 
  39 /**
  40  * @brief ラベル数
  41  */
  42 static int labelcnt = 0;
  43 
  44 /**
  45  * @brief ラベル表
  46  */
  47 static LABELTAB *labels[LABELTABSIZE];
  48 
  49 /**
  50  * @brief ラベルのエラー
  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 /* assemble.hで定義された関数群 */
 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);    /* 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 
 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 }

/* [<][>][^][v][top][bottom][index][help] */