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