1 using System;
2 using System.Collections;
3 using System.IO;
4
5 const char* Version()
6 {
7 return "4.0.0";
8 }
9
10 void PrintHelp()
11 {
12 Console.Out() <<
13 "Cmajor System X Intermediate Code Compiler version " << Version() << endl() <<
14 "Usage: cmsxic [options] { <file.i> }" << endl() <<
15 "Compiles given System X intermediate code files (*.i) to System X assembly files (*.s)" << endl() <<
16 "Options:" << endl() <<
17 "--help (-h)" << endl() <<
18 " Print help" << endl() <<
19 "--verbose (-v)" << endl() <<
20 " Be verbose" << endl() <<
21 "--debug (-d)" << endl() <<
22 " Print debugging messages to stdout" << endl() <<
23 "--stages (-s)" << endl() <<
24 " Generate intermediate stage files (*.iN) N = 0, 1, 2, ..." << endl() <<
25 " and combined assembly code file (*.is)" << endl() <<
26 "--optimization-level=N (-O=N)" << endl() <<
27 " Set optimization level to N=0-3." << endl() <<
28 " Default is 0." << endl() <<
29 "--local-regs=N (-l=N)" << endl() <<
30 " Set number of local registers to N, where N must be >= 128 and <= 255." << endl() <<
31 endl();
32 }
33
34 int main(int argc, const char** argv)
35 {
36 try
37 {
38 List<string> intermediateCodeFileNames;
39 for (int i = 1; i < argc; ++i;)
40 {
41 string arg = argv[i];
42 if (arg.StartsWith("--"))
43 {
44 if (arg == "--help")
45 {
46 PrintHelp();
47 return 1;
48 }
49 else if (arg == "--verbose")
50 {
51 cmsx.intermediate.Flags.Set(cmsx.intermediate.Flag.verbose);
52 }
53 else if (arg == "--debug")
54 {
55 cmsx.intermediate.Flags.Set(cmsx.intermediate.Flag.debug);
56 }
57 else if (arg == "--stages")
58 {
59 cmsx.intermediate.Flags.Set(cmsx.intermediate.Flag.stages);
60 }
61 else if (arg.StartsWith("--optimization-level="))
62 {
63 int level = ParseInt(arg.Substring(21));
64 if (level < 0 || level > 3)
65 {
66 throw Exception("invalid optimization level (must be 0-3)");
67 }
68 cmsx.intermediate.Flags.SetOptimizationLevel(level);
69 }
70 else if (arg.StartsWith("--local-regs="))
71 {
72 byte numLocalRegs = ParseByte(arg.Substring(13));
73 cmsx.intermediate.Flags.SetNumLocalRegs(numLocalRegs);
74 }
75 else
76 {
77 throw Exception("unknown option '" + arg + "'");
78 }
79 }
80 else if (arg.StartsWith("-"))
81 {
82 if (arg.StartsWith("-O="))
83 {
84 int level = ParseInt(arg.Substring(3));
85 if (level < 0 || level > 3)
86 {
87 throw Exception("invalid optimization level (must be 0-3)");
88 }
89 cmsx.intermediate.Flags.SetOptimizationLevel(level);
90 }
91 else if (arg.StartsWith("-l="))
92 {
93 byte numLocalRegs = ParseByte(arg.Substring(3));
94 cmsx.intermediate.Flags.SetNumLocalRegs(numLocalRegs);
95 }
96 else
97 {
98 string options = arg.Substring(1);
99 if (options.IsEmpty())
100 {
101 throw Exception("unknown option '" + arg + "'");
102 }
103 else
104 {
105 for (char o : options)
106 {
107 if (o == 'h')
108 {
109 PrintHelp();
110 return 1;
111 }
112 else if (o == 'v')
113 {
114 cmsx.intermediate.Flags.Set(cmsx.intermediate.Flag.verbose);
115 }
116 else if (o == 'd')
117 {
118 cmsx.intermediate.Flags.Set(cmsx.intermediate.Flag.debug);
119 }
120 else if (o == 's')
121 {
122 cmsx.intermediate.Flags.Set(cmsx.intermediate.Flag.stages);
123 }
124 else
125 {
126 throw Exception("unknown option '-" + string(o) + "'");
127 }
128 }
129 }
130 }
131 }
132 else
133 {
134 intermediateCodeFileNames.Add(GetFullPath(arg));
135 }
136 }
137 if (intermediateCodeFileNames.IsEmpty())
138 {
139 PrintHelp();
140 throw Exception("no intermediate code files given");
141 }
142 for (const string& intermediateCodeFileName : intermediateCodeFileNames)
143 {
144 if (cmsx.intermediate.Flags.Get(cmsx.intermediate.Flag.verbose))
145 {
146 Console.Out() << "> " << intermediateCodeFileName << endl();
147 }
148 cmsx.intermediate.Compile(intermediateCodeFileName);
149 }
150 }
151 catch (const Exception& ex)
152 {
153 Console.Error() << ex.Message() << endl();
154 return 1;
155 }
156 return 0;
157 }