変数名の整理
[YACASL2.git] / src / casl2.c
1 #include "casl2.h"
2 #include "assemble.h"
3 #include "exec.h"
4 #define _GNU_SOURCE
5 #include <getopt.h>
6
7 /* casl2コマンドのオプション */
8 static struct option longopts[] = {
9     {"source", no_argument, NULL, 's'},
10     {"label", no_argument, NULL, 'l'},
11     {"labelonly", no_argument, NULL, 'L'},
12     {"assembledetail", no_argument, NULL, 'a'},
13     {"assembledetailonly", no_argument, NULL, 'A'},
14     {"assembleout", optional_argument, NULL, 'o'},
15     {"assembleoutonly", optional_argument, NULL, 'O'},
16     {"trace", no_argument, NULL, 't'},
17     {"tracearithmetic", no_argument, NULL, 't'},
18     {"tracelogical", no_argument, NULL, 'T'},
19     {"dump", no_argument, NULL, 'd'},
20     {"memorysize", required_argument, NULL, 'M'},
21     {"clocks", required_argument, NULL, 'C'},
22     {"help", no_argument, NULL, 'h'},
23     {0, 0, 0, 0},
24 };
25
26 /* casl2のエラー定義 */
27 CERR cerr_casl2[] = {
28     { 126, "source file is not specified" },
29 };
30 bool addcerrlist_casl2()
31 {
32     return addcerrlist(sizeof(cerr_casl2), cerr_casl2);
33 }
34
35 /* 指定されたファイルにアセンブル結果を書込 */
36 void outassemble(const char *file) {
37     FILE *fp;
38     if((fp = fopen(file, "w")) == NULL) {
39         perror(file);
40         exit(-1);
41     }
42     fwrite(memory, sizeof(WORD), progprop->end, fp);
43     fclose(fp);
44 }
45
46 /* アセンブル結果を書き込むファイルの名前 */
47 const char *objfile_name(const char *str)
48 {
49     const char *default_name = "a.o";
50
51     if(str == NULL) {
52         return default_name;
53     } else {
54         return str;
55     }
56 }
57
58 /* casl2コマンドのメイン */
59 int main(int argc, char *argv[])
60 {
61     int opt, i, retval = 0;
62     PASS pass;
63     bool status = false;
64     WORD beginptr[argc];
65     char *objfile = NULL;
66     const char *usage =
67         "Usage: %s [-slLaAtTdh] [-oO<OBJECTFILE>] [-M <MEMORYSIZE>] [-C <CLOCKS>] FILE ...\n";
68
69     /* エラーの初期化 */
70     cerr = malloc_chk(sizeof(CERR), "cerr");
71     addcerrlist_casl2();
72     /* オプションの処理 */
73     while((opt = getopt_long(argc, argv, "tTdslLao::O::AM:C:h", longopts, NULL)) != -1) {
74         switch(opt) {
75         case 's':
76             asmode.src = true;
77             break;
78         case 'l':
79             asmode.label = true;
80             break;
81         case 'L':
82             asmode.label = true;
83             asmode.onlylabel = true;
84             break;
85         case 'a':
86             asmode.asdetail = true;
87             break;
88         case 'A':
89             asmode.asdetail = true;
90             asmode.onlyassemble = true;
91             break;
92         case 'o':
93             objfile = strdup(objfile_name(optarg));
94             break;
95         case 'O':
96             asmode.onlyassemble = true;
97             objfile = strdup(objfile_name(optarg));
98             break;
99         case 't':
100             execmode.trace = true;
101             break;
102         case 'T':
103             execmode.trace = true;
104             execmode.logical = true;
105             break;
106         case 'd':
107             execmode.dump = true;
108             break;
109         case 'M':
110             memsize = atoi(optarg);
111             break;
112         case 'C':
113             clocks = atoi(optarg);
114             break;
115         case 'h':
116             fprintf(stdout, usage, argv[0]);
117             return 0;
118         case '?':
119             fprintf(stderr, usage, argv[0]);
120             exit(-1);
121         }
122     }
123     /* ソースファイルが指定されていない場合は終了 */
124     if(argv[optind] == NULL) {
125         setcerr(126, NULL);    /* source file is not specified */
126         fprintf(stderr, "CASL2 error - %d: %s\n", cerr->num, cerr->msg);
127         exit(-1);
128     }
129     /* COMET II仮想マシンのリセット */
130     reset();
131     /* アセンブル。ラベル表作成のため、2回行う */
132     for(pass = FIRST; pass <= SECOND; pass++) {
133         if(pass == FIRST) {
134             create_cmdtype_code();        /* 命令と命令タイプがキーのハッシュ表を作成 */
135             asprop = malloc_chk(sizeof(ASPROP), "asprop");
136         }
137         for(i = optind; i < argc; i++) {
138             /* データの格納開始位置 */
139             if(pass == FIRST) {
140                 beginptr[i] = asprop->ptr;
141             } else if(pass == SECOND) {
142                 asprop->ptr = beginptr[i];
143             }
144             if(execmode.trace == true || execmode.dump == true || asmode.src == true ||
145                asmode.label == true || asmode.asdetail == true)
146             {
147                 fprintf(stdout, "\nAssemble %s (%d)\n", argv[i], pass);
148             }
149             if((status = assemble(argv[i], pass)) == false) {
150                 exit(-1);
151             }
152         }
153         if(pass == FIRST && asmode.label == true) {
154             fprintf(stdout, "\nLabel::::\n");
155             printlabel();
156             if(asmode.onlylabel == true) {
157                 return 0;
158             }
159         }
160         if(pass == SECOND) {
161             free_cmdtype_code();    /* 命令と命令タイプがキーのハッシュ表を解放 */
162             freelabel();            /* ラベルハッシュ表を解放 */
163         }
164     }
165     if(status == true) {
166         if(objfile != NULL) {
167             outassemble(objfile);
168         }
169         if(asmode.onlyassemble == false) {
170             create_code_type();    /* 命令と命令タイプがキーのハッシュ表を作成 */
171             status = exec();       /* プログラム実行 */
172             free_code_type();      /* 命令と命令タイプがキーのハッシュ表を解放 */
173         }
174     }
175     /* COMET II仮想マシンのシャットダウン */
176     shutdown();
177     if(cerr->num > 0) {
178         retval = -1;
179     }
180     /* エラーの解放 */
181     freecerr();
182     return retval;
183 }