命令ハッシュ表の作成方法を変更
[YACASL2.git] / src / struct.c
index 981409a..3fb9a30 100644 (file)
@@ -1,9 +1,4 @@
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-#include "hash.h"
 #include "struct.h"
-#include "cmem.h"
 #include "exec.h"
 
 /**
@@ -19,7 +14,7 @@ EXECPTR *execptr;
 /**
  * システムCOMET IIの命令表
  */
-static COMET2CMD comet2cmd[] = {
+static const COMET2CMD comet2cmd[] = {
     { "NOP", NONE, 0x0, nop },
     { "LD", R_ADR_X, 0x1000, ld_r_adr_x },
     { "ST", R_ADR_X, 0x1100, st },
@@ -77,6 +72,16 @@ enum {
  */
 static CMDTAB *cmdtype_code[CMDTABSIZE], *code_cmdtype[CMDTABSIZE];
 
+/**
+ * 命令の名前とタイプからハッシュ値を生成する
+ */
+unsigned hash_cmdtype(const char *cmd, CMDTYPE type);
+
+/**
+ * 命令コードからハッシュ値を生成する
+ */
+unsigned hash_code(WORD code);
+
 /**
  * 命令の名前とタイプからハッシュ値を生成する
  */
@@ -103,20 +108,26 @@ unsigned hash_cmdtype(const char *cmd, CMDTYPE type)
 }
 
 /**
- * å\90\8då\89\8dã\81¨ã\82¿ã\82¤ã\83\97ã\81\8cã\82­ã\83¼ã\81®å\91½ä»¤ã\83\8fã\83\83ã\82·ã\83¥è¡¨ã\82\92ä½\9cæ\88\90ã\81\99ã\82\8b
+ * 命令ハッシュ表を作成する
  */
-bool create_cmdtype_code()
+bool create_cmdtable(CMDTAB_HASH hash)
 {
     CMDTAB *p;
     unsigned hashval;
     int i;
 
     for(i = 0; i < comet2cmdsize; i++) {
-        hashval = hash_cmdtype(comet2cmd[i].name, comet2cmd[i].type);    /* ハッシュ値の生成 */
-        p = malloc_chk(sizeof(CMDTAB), "cmdtype_code");
+        p = malloc_chk(sizeof(CMDTAB), "create_cmdtable.p");
         p->cmd = &comet2cmd[i];
-        p->next = cmdtype_code[hashval];                                 /* ハッシュ表に値を追加 */
-        cmdtype_code[hashval] = p;
+        if(hash == HASH_CMDTYPE) {
+            hashval = hash_cmdtype(comet2cmd[i].name, comet2cmd[i].type);
+            p->next = cmdtype_code[hashval];
+            cmdtype_code[hashval] = p;
+        } else if(hash == HASH_CODE) {
+            hashval = hash_code((&comet2cmd[i])->code);
+            p->next = code_cmdtype[hashval];
+            code_cmdtype[hashval] = p;
+        }
     }
     return true;
 }
@@ -141,16 +152,26 @@ WORD getcmdcode(const char *cmd, CMDTYPE type)
 }
 
 /**
- * å\90\8då\89\8dã\81¨ã\82¿ã\82¤ã\83\97ã\81\8cã\82­ã\83¼ã\81®å\91½ä»¤ã\83\8fã\83\83ã\82·ã\83¥è¡¨ã\82\92解æ\94¾ã\81\99ã\82\8b
+ * 命令ハッシュ表を解放する
  */
-void free_cmdtype_code()
+void free_cmdtable(CMDTAB_HASH hash)
 {
     int i;
     CMDTAB *p, *q;
 
     for(i = 0; i < CMDTABSIZE; i++) {
-        for(p = cmdtype_code[i]; p != NULL; p = q) {
+        if(hash == HASH_CMDTYPE) {
+            p = cmdtype_code[i];
+        } else if(hash == HASH_CODE) {
+            p = code_cmdtype[i];
+        }
+        for( ; p != NULL; p = q) {
             q = p->next;
+            if(p == cmdtype_code[i]) {
+                cmdtype_code[i] = NULL;
+            } else if (p == code_cmdtype[i]) {
+                code_cmdtype[i] = NULL;
+            }
             FREE(p);
         }
     }
@@ -174,45 +195,43 @@ unsigned hash_code(WORD code)
 }
 
 /**
- * コードがキーの命令ハッシュ表を作成する
+ * 命令コードから命令の関数ポインタを返す
  */
-bool create_code_cmdtype()
+const void (*getcmdptr(WORD code))
 {
-    CMDTAB *p;
-    unsigned hashval;
-    int i;
+    CMDTAB *t;
+    const void *ptr = NULL;
 
-    for(i = 0; i < comet2cmdsize; i++) {
-        hashval = hash_code((&comet2cmd[i])->code);    /* ハッシュ値の生成 */
-        p = malloc_chk(sizeof(CMDTAB), "code_cmdtype");
-        p->cmd = &comet2cmd[i];
-        p->next = code_cmdtype[hashval];                  /* ハッシュ表に値を追加 */
-        code_cmdtype[hashval] = p;
+    for(t = code_cmdtype[hash_code(code)]; t != NULL; t = t->next) {
+        if(code == t->cmd->code) {
+            ptr = t->cmd->ptr;
+            break;
+        }
     }
-    return true;
+    return ptr;
 }
 
 /**
- * 命令コードから命令の関数ポインタを返す
+ * 命令コードから命令のタイプを返す
  */
-const void (*getcmdptr(WORD code))
+CMDTYPE getcmdtype(WORD code)
 {
     CMDTAB *t;
-    const void *ptr = NULL;
+    CMDTYPE type = NONE;
 
     for(t = code_cmdtype[hash_code(code)]; t != NULL; t = t->next) {
         if(code == t->cmd->code) {
-            ptr = t->cmd->ptr;
+            type = t->cmd->type;
             break;
         }
     }
-    return ptr;
+    return type;
 }
 
 /**
  * 命令コードから命令の名前を返す
  */
-char (*getcmdname(WORD code))
+char *getcmdname(WORD code)
 {
     CMDTAB *t;
     char *cmd = NULL;
@@ -227,18 +246,15 @@ char (*getcmdname(WORD code))
 }
 
 /**
- * コードがキーの命令ハッシュ表を解放する
+ * 汎用レジスタの番号からレジスタを表す文字列を返す
  */
-void free_code_cmdtype()
+
+char *grstr(WORD word)
 {
-    int i;
-    CMDTAB *p, *q;
-    for(i = 0; i < CMDTABSIZE; i++) {
-        for(p = code_cmdtype[i]; p != NULL; p = q) {
-            q = p->next;
-            FREE(p);
-        }
-    }
+    assert(word <= 7);
+    char *str = malloc_chk(3 + 1, "grstr.str");
+    sprintf(str, "GR%d", word);
+    return str;
 }
 
 /**