グローバル変数のリファクタリング
[YACASL2.git] / src / cmd.c
1 #include "casl2.h"
2
3 CMD comet2cmd[] = {
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 comet2cmdsize = ARRAYSIZE(comet2cmd);
45 int cmdtabsize;
46 CMDTAB **cmdtype_code, **code_type;
47
48 /* 命令と命令タイプからハッシュ値を生成する */
49 unsigned hash_cmdtype(const char *cmd, CMDTYPE type) {
50     HKEY *keys[2];
51
52     /* 命令をセット */
53     keys[0] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key");
54     keys[0]->type = CHARS;
55     keys[0]->val.s = strdup_chk(cmd, "keys[0].val");
56     /* 命令タイプをセット */
57     keys[1] = malloc_chk(sizeof(HKEY), "hash_cmdtype.key");
58     keys[1]->type = INT;
59     keys[1]->val.i = (int)(type & 070);
60     /* ハッシュ値を返す */
61     return hash(2, keys, cmdtabsize);
62 }
63
64 /* 命令と命令タイプがキーのハッシュ表を作成する */
65 bool create_cmdtype_code()
66 {
67     CMDTAB *np;
68     unsigned hashval;
69     int i;
70
71     cmdtabsize = comet2cmdsize;
72     cmdtype_code = calloc_chk(cmdtabsize, sizeof(CMDTAB *), "cmdtype_code");
73     for(i = 0; i < cmdtabsize; i++) {
74         *(cmdtype_code + i) = NULL;
75     }
76     for(i = 0; i < comet2cmdsize; i++) {
77         np = malloc_chk(sizeof(CMDTAB), "cmdtype_code.next");
78         np->cmd = NULL;
79         np->next = NULL;
80         /* ハッシュ値の生成 */
81         hashval = hash_cmdtype(comet2cmd[i].name, comet2cmd[i].type);
82         /* ハッシュ表に値を追加 */
83         np->next = cmdtype_code[hashval];
84         cmdtype_code[hashval] = np;
85         np->cmd = &(comet2cmd[i]);
86     }
87     return true;
88 }
89
90 /* 命令と命令タイプから、命令コードを取得する */
91 /* 無効な場合は0xFFFFを返す */
92 WORD getcmdcode(const char *cmd, CMDTYPE type)
93 {
94     CMDTAB *np;
95
96     assert(cmd != NULL);
97     for(np = cmdtype_code[hash_cmdtype(cmd, type)]; np != NULL; np = np->next){
98         if(strcmp(cmd, np->cmd->name) == 0 && type == np->cmd->type) {
99             return np->cmd->code;
100         }
101     }
102     return 0xFFFF;
103 }
104
105 /* 命令と命令タイプがキーのハッシュ表を解放する */
106 void free_cmdtype_code()
107 {
108     int i;
109     CMDTAB *np, *nq;
110
111     for(i = 0; i < cmdtabsize; i++) {
112         np = cmdtype_code[i];
113         while(np != NULL) {
114             nq = np->next;
115             free(np);
116             np = nq;
117         }
118     }
119     free(cmdtype_code);
120 }
121
122 /* 命令コードからハッシュ値を生成する */
123 unsigned hash_code(WORD code)
124 {
125     HKEY *keys[1];
126
127     /* 命令コードをセット */
128     keys[0] = malloc_chk(sizeof(HKEY), "hash_code.key");
129     keys[0]->type = INT;
130     keys[0]->val.i = (int)(code >> 8);
131     /* ハッシュ値を返す */
132     return hash(1, keys, cmdtabsize);
133 }
134
135 /* 命令コードがキーのハッシュ表を作成する */
136 bool create_code_type()
137 {
138     CMDTAB *np;
139     unsigned hashval;
140     int i;
141
142     cmdtabsize = comet2cmdsize;
143     code_type = calloc_chk(cmdtabsize, sizeof(CMDTAB *), "code_type");
144     for(i = 0; i < cmdtabsize; i++) {
145         *(code_type + i) = NULL;
146     }
147     for(i = 0; i < comet2cmdsize; i++) {
148         np = malloc_chk(sizeof(CMDTAB), "code_type.next");
149         np->cmd = NULL;
150         np->next = NULL;
151         /* ハッシュ値の生成 */
152         hashval = hash_code((&comet2cmd[i])->code);
153         /* ハッシュ表に値を追加 */
154         np->next = code_type[hashval];
155         code_type[hashval] = np;
156         np->cmd = &comet2cmd[i];
157     }
158     return true;
159 }
160
161 /* 命令コードから命令タイプを取得する */
162 /* 無効な場合はNONEを返す */
163 CMDTYPE getcmdtype(WORD code)
164 {
165     CMDTAB *np;
166     for(np = code_type[hash_code(code)]; np != NULL; np = np->next) {
167         if(code == np->cmd->code) {
168             return np->cmd->type;
169         }
170     }
171     return NONE;
172 }
173
174 /* 命令コードがキーのハッシュ表を解放する */
175 void free_code_type()
176 {
177     int i;
178     CMDTAB *np, *nq;
179     for(i = 0; i < cmdtabsize; i++) {
180         np = code_type[i];
181         while(np != NULL) {
182             nq = np->next;
183             free(np);
184             np = nq;
185         }
186     }
187     free(code_type);
188 }