hash.cの分離独立とソースコードの草取り
[YACASL2.git] / src / cmd.c
1 #include "casl2.h"
2
3 CMDCODEARRAY cmdcodearray[] = {
4     { "NOP", NONE, 0x0 },
5     { "LD", R_ADR_X_, 0x1000 },
6     { "ST", R_ADR_X, 0x1100 },
7     { "LAD", R_ADR_X, 0x1200 },
8     { "LD", R1_R2, 0x1400 },
9     { "ADDA", R_ADR_X_, 0x2000 },
10     { "SUBA", R_ADR_X_, 0x2100 },
11     { "ADDL", R_ADR_X_, 0x2200 },
12     { "SUBL", R_ADR_X_, 0x2300 },
13     { "ADDA", R1_R2, 0x2400 },
14     { "SUBA", R1_R2, 0x2500 },
15     { "ADDL", R1_R2, 0x2600 },
16     { "SUBL", R1_R2, 0x2700 },
17     { "AND", R_ADR_X_, 0x3000 },
18     { "OR", R_ADR_X_, 0x3100 },
19     { "XOR", R_ADR_X_, 0x3200 },
20     { "AND", R1_R2, 0x3400 },
21     { "OR", R1_R2, 0x3500 },
22     { "XOR", R1_R2, 0x3600 },
23     { "CPA", R_ADR_X_, 0x4000 },
24     { "CPL", R_ADR_X_, 0x4100 },
25     { "CPA", R1_R2, 0x4400 },
26     { "CPL", R1_R2, 0x4500 },
27     { "SLA", R_ADR_X, 0x5000 },
28     { "SRA", R_ADR_X, 0x5100 },
29     { "SLL", R_ADR_X, 0x5200 },
30     { "SRL", R_ADR_X, 0x5300 },
31     { "JMI", ADR_X, 0x6100 },
32     { "JNZ", ADR_X, 0x6200 },
33     { "JZE", ADR_X, 0x6300 },
34     { "JUMP", ADR_X, 0x6400 },
35     { "JPL", ADR_X, 0x6500 },
36     { "JOV", ADR_X, 0x6600 },
37     { "PUSH", ADR_X, 0x7000 },
38     { "POP", R_, 0x7100 },
39     { "CALL", ADR_X, 0x8000 },
40     { "SVC", ADR_X, 0xF000 },
41     { "RET", NONE, 0x8100 }
42 };
43
44 int cmdcodesize = ARRAYSIZE(cmdcodearray);
45 CMDCODETAB *cmdtype_code[ARRAYSIZE(cmdcodearray)], *code_type[ARRAYSIZE(cmdcodearray)];
46
47 /* 命令と命令タイプがキーのハッシュ表を作成する */
48 bool create_cmdtype_code()
49 {
50     CMDCODETAB *np;
51     unsigned hashval;
52     int i;
53
54     for(i = 0; i < cmdcodesize; i++) {
55         np = (CMDCODETAB *) malloc(sizeof(*np));
56         if(np == NULL) {
57             setcerr(122, NULL);    /* cannot create hash table */
58             return false;
59         }
60         /* ハッシュ値の生成 */
61         hashval = hash_cmdtype((&cmdcodearray[i])->cmd, (&cmdcodearray[i])->type);
62         /* ハッシュ表に値を追加 */
63         np->next = cmdtype_code[hashval];
64         cmdtype_code[hashval] = np;
65         np->cca = &(cmdcodearray[i]);
66     }
67     return true;
68 }
69
70 /* 命令と命令タイプからハッシュ値を生成する */
71 unsigned hash_cmdtype(const char *cmd, CMDTYPE type) {
72     int i;
73     unsigned hashval = 0;
74     for(i = 0; *cmd != '\0'; cmd++) {
75         hashval = *cmd + 31 * hashval;
76     }
77     hashval = (int)(type & 070) + 31 * hashval;
78     return hashval % cmdcodesize;
79 }
80
81 /* 命令と命令タイプから、命令コードを取得する。
82    無効な場合は0xFFFFを返す */
83 WORD getcmdcode(const char *cmd, CMDTYPE type)
84 {
85     CMDCODETAB *np;
86     assert(cmd != NULL);
87     for(np = cmdtype_code[hash_cmdtype(cmd, type)]; np != NULL; np = np->next){
88         if(strcmp(cmd, np->cca->cmd) == 0 && type == np->cca->type) {
89             return np->cca->code;
90         }
91     }
92     return 0xFFFF;
93 }
94
95 /* 命令と命令タイプがキーのハッシュ表を表示する */
96 void print_cmdtype_code()
97 {
98     int i;
99     CMDCODETAB *np;
100     for(i = 0; i < cmdcodesize; i++){
101         np = cmdtype_code[i];
102         while(np != NULL) {
103             fprintf(stdout, "(%2d) - %s\t0%02o\t#%04X\n",
104                     i, np->cca->cmd, np->cca->type, np->cca->code);
105             np = np->next;
106         }
107     }
108 }
109
110 /* 命令と命令タイプがキーのハッシュ表を解放する */
111 void free_cmdtype_code()
112 {
113     int i;
114     CMDCODETAB *np, *nq;
115     for(i = 0; i < cmdcodesize; i++){
116         np = cmdtype_code[i];
117         while(np != NULL) {
118             nq = np->next;
119             free(np);
120             np = nq;
121         }
122     }
123 }
124
125 /* 命令コードがキーのハッシュ表を作成する */
126 bool create_code_type()
127 {
128     CMDCODETAB *np;
129     unsigned hashval;
130     int i;
131
132     for(i = 0; i < cmdcodesize; i++) {
133         if((np = (CMDCODETAB *) malloc(sizeof(*np))) == NULL) {
134             setcerr(122, NULL);    /* cannot create hash table */
135             return false;
136         }
137         /* ハッシュ値の生成 */
138         hashval = hash_code((&cmdcodearray[i])->code);
139         /* ハッシュ表に値を追加 */
140         np->next = code_type[hashval];
141         code_type[hashval] = np;
142         np->cca = &cmdcodearray[i];
143     }
144     return true;
145 }
146
147 /* 命令コードからハッシュ値を生成する */
148 unsigned hash_code(WORD code)
149 {
150     unsigned hashval = 0;
151     hashval = (code >> 8);
152     return hashval % cmdcodesize;
153 }
154
155 /* 命令コードから命令タイプを取得する。
156    無効な場合はNONEを返す */
157 CMDTYPE getcmdtype(WORD code)
158 {
159     CMDCODETAB *np;
160     for(np = code_type[hash_code(code)]; np != NULL; np = np->next) {
161         if(code == np->cca->code) {
162             return np->cca->type;
163         }
164     }
165     return NONE;
166 }
167
168 /* 命令コードがキーのハッシュ表を表示する */
169 void print_code_type()
170 {
171     int i;
172     CMDCODETAB *np;
173     for(i = 0; i < cmdcodesize; i++){
174         for(np = code_type[i]; np != NULL; np = np->next) {
175             fprintf(stdout, "(%2d) - #%04X\t0%02o\t%s\n",
176                     i, np->cca->code, np->cca->type, np->cca->cmd);
177         }
178     }
179 }
180
181 /* 命令コードがキーのハッシュ表を解放する */
182 void free_code_type()
183 {
184     int i;
185     CMDCODETAB *np, *nq;
186     for(i = 0; i < cmdcodesize; i++){
187         np = code_type[i];
188         while(np != NULL) {
189             nq = np->next;
190             free(np);
191             np = nq;
192         }
193     }
194 }