989bbe76661ab2fabf27f13fdbeb706e3b2a4c90
[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 CERRARRAY 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), endptr, 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;
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     while((opt = getopt_long(argc, argv, "tTdslLao::O::AM:C:h", longopts, NULL)) != -1) {
70         switch(opt) {
71         case 's':
72             asmode.src = true;
73             break;
74         case 'l':
75             asmode.label = true;
76             break;
77         case 'L':
78             asmode.label = true;
79             asmode.onlylabel = true;
80             break;
81         case 'a':
82             asmode.asdetail = true;
83             break;
84         case 'A':
85             asmode.asdetail = true;
86             asmode.onlyassemble = true;
87             break;
88         case 'o':
89             objfile = strdup(objfile_name(optarg));
90             break;
91         case 'O':
92             asmode.onlyassemble = true;
93             objfile = strdup(objfile_name(optarg));
94             break;
95         case 't':
96             execmode.trace = true;
97             break;
98         case 'T':
99             execmode.trace = true;
100             execmode.logical = true;
101             break;
102         case 'd':
103             execmode.dump = true;
104             break;
105         case 'M':
106             memsize = atoi(optarg);
107             break;
108         case 'C':
109             clocks = atoi(optarg);
110             break;
111         case 'h':
112             fprintf(stdout, usage, argv[0]);
113             return 0;
114         case '?':
115             fprintf(stderr, usage, argv[0]);
116             exit(-1);
117         }
118     }
119
120     addcerrlist_casl2();
121     /* ソースファイルが指定されていない場合は終了 */
122     if(argv[optind] == NULL) {
123         setcerr(126, NULL);    /* source file is not specified */
124         goto casl2err;
125     }
126     /* COMET II仮想マシンのリセット */
127     reset();
128     /* アセンブル。ラベル表作成のため、2回行う */
129     for(pass = FIRST; pass <= SECOND; pass++) {
130         if(pass == FIRST && create_cmdtype_code() == false) {
131             goto casl2err;
132         }
133         for(i = optind; i < argc; i++) {
134             /* データの格納開始位置 */
135             if(pass == FIRST) {
136                 beginptr[i] = ptr;
137             } else if(pass == SECOND) {
138                 ptr = beginptr[i];
139             }
140             if(execmode.trace == true || execmode.dump == true || asmode.src == true ||
141                asmode.label == true || asmode.asdetail == true)
142             {
143                 fprintf(stdout, "\nAssemble %s (%d)\n", argv[i], pass);
144             }
145             if((status = assemble(argv[i], pass)) == false) {
146                 exit(-1);
147             }
148         }
149         if(pass == FIRST && asmode.label == true) {
150             fprintf(stdout, "\nLabel::::\n");
151             printlabel();
152             if(asmode.onlylabel == true) {
153                 return 0;
154             }
155         }
156     }
157     free_cmdtype_code();    /* 命令表の解放 */
158     freelabel();            /* ラベル表の解放 */
159     if(status == true) {
160         if(objfile != NULL) {
161             outassemble(objfile);
162         }
163         if(asmode.onlyassemble == false) {
164             exec();    /* プログラム実行 */
165         }
166     }
167     if(cerrno > 0) {
168         freecerr();
169         exit(-1);
170     }
171     return 0;
172 casl2err:
173     fprintf(stderr, "CASL2 error - %d: %s\n", cerrno, cerrmsg);
174     exit(-1);
175 }