* ILParser.jay: Use type instead of params for calli signatures.
[mono.git] / mcs / ilasm / Driver.cs
1 //
2 // Mono.ILASM.Driver
3 //    Main Command line interface for Mono ILasm Compiler
4 //
5 // Author(s):
6 //  Jackson Harper (Jackson@LatitudeGeo.com)
7 //
8 // (C) 2003 Jackson Harper, All rights reserved
9 //
10
11 using System;
12 using System.IO;
13 using System.Reflection;
14 using System.Collections;
15
16 namespace Mono.ILASM {
17
18         public class Driver {
19
20                 enum Target {
21                         Dll,
22                         Exe
23                 }
24
25                 public static int Main (string[] args)
26                 {
27                         DriverMain driver = new DriverMain (args);
28                         try {
29                                 driver.Run ();
30                         } catch (Exception e) {
31                                 Console.WriteLine (e);
32                                 Console.WriteLine ("Error while compiling.");
33                                 return 1;
34                         }
35                         Console.Write ("Compilation succeeded");
36                         return 0;
37                 }
38
39                 private class DriverMain {
40
41                         private ArrayList il_file_list;
42                         private string output_file;
43                         private Target target = Target.Exe;
44                         private bool show_tokens = false;
45                         private bool show_method_def = false;
46                         private bool show_method_ref = false;
47                         private bool show_parser = false;
48                         private bool scan_only = false;
49                         private bool delete_on_error = false;
50                         private CodeGen codegen;
51
52                         public DriverMain (string[] args)
53                         {
54                                 il_file_list = new ArrayList ();
55                                 ParseArgs (args);
56                         }
57
58                         public void Run ()
59                         {
60                                 try {
61                                         if (il_file_list.Count == 0)
62                                                 Usage ();
63                                         if (output_file == null)
64                                                 output_file = CreateOutputFile ();
65                                         codegen = new CodeGen (output_file, target == Target.Dll, true);
66                                         foreach (string file_path in il_file_list)
67                                                 ProcessFile (file_path);
68                                         if (scan_only)
69                                                 return;
70
71                                         codegen.Write ();
72                                 } catch {
73                                         if (delete_on_error) {
74                                                 if (File.Exists (output_file))
75                                                         File.Delete (output_file);
76                                         }
77                                         throw;
78                                 }
79                         }
80
81                         private void ProcessFile (string file_path)
82                         {
83                                 if (!File.Exists (file_path)) {
84                                         Console.WriteLine ("File does not exist: {0}",
85                                                 file_path);
86                                         Environment.Exit (2);
87                                 }
88                                 StreamReader reader = File.OpenText (file_path);
89                                 ILTokenizer scanner = new ILTokenizer (reader);
90
91                                 if (show_tokens)
92                                         scanner.NewTokenEvent += new NewTokenEvent (ShowToken);
93                                 //if (show_method_def)
94                                 //        MethodTable.MethodDefinedEvent += new MethodDefinedEvent (ShowMethodDef);
95                                 //if (show_method_ref)
96                                 //       MethodTable.MethodReferencedEvent += new MethodReferencedEvent (ShowMethodRef);
97
98                                 if (scan_only) {
99                                         ILToken tok;
100                                         while ((tok = scanner.NextToken) != ILToken.EOF) {
101                                                 Console.WriteLine (tok);
102                                         }
103                                         return;
104                                 }
105
106                                 ILParser parser = new ILParser (codegen);
107                                 if (show_parser)
108                                         parser.yyparse (new ScannerAdapter (scanner),  new yydebug.yyDebugSimple ());
109                                 else
110                                         parser.yyparse (new ScannerAdapter (scanner),  null);
111                         }
112
113                         public void ShowToken (object sender, NewTokenEventArgs args)
114                         {
115                                 Console.WriteLine ("token: '{0}'", args.Token);
116                         }
117                         /*
118                         public void ShowMethodDef (object sender, MethodDefinedEventArgs args)
119                         {
120                                 Console.WriteLine ("***** Method defined *****");
121                                 Console.WriteLine ("-- signature:   {0}", args.Signature);
122                                 Console.WriteLine ("-- name:        {0}", args.Name);
123                                 Console.WriteLine ("-- return type: {0}", args.ReturnType);
124                                 Console.WriteLine ("-- is in table: {0}", args.IsInTable);
125                                 Console.WriteLine ("-- method atts: {0}", args.MethodAttributes);
126                                 Console.WriteLine ("-- impl atts:   {0}", args.ImplAttributes);
127                                 Console.WriteLine ("-- call conv:   {0}", args.CallConv);
128                         }
129
130                         public void ShowMethodRef (object sender, MethodReferencedEventArgs args)
131                         {
132                                 Console.WriteLine ("***** Method referenced *****");
133                                 Console.WriteLine ("-- signature:   {0}", args.Signature);
134                                 Console.WriteLine ("-- name:        {0}", args.Name);
135                                 Console.WriteLine ("-- return type: {0}", args.ReturnType);
136                                 Console.WriteLine ("-- is in table: {0}", args.IsInTable);
137                         }
138                         */
139                         private void ParseArgs (string[] args)
140                         {
141                                 string command_arg;
142                                 foreach (string str in args) {
143                                         if ((str[0] != '-') && (str[0] != '/')) {
144                                                 il_file_list.Add (str);
145                                                 continue;
146                                         }
147                                         switch (GetCommand (str, out command_arg)) {
148                                         case "out":
149                                                 output_file = command_arg;
150                                                 break;
151                                         case "exe":
152                                                 target = Target.Exe;
153                                                 break;
154                                         case "dll":
155                                                 target = Target.Dll;
156                                                 break;
157                                         case "scan_only":
158                                                 scan_only = true;
159                                                 break;
160                                         case "show_tokens":
161                                                 show_tokens = true;
162                                                 break;
163                                         case "show_method_def":
164                                                 show_method_def = true;
165                                                 break;
166                                         case "show_method_ref":
167                                                 show_method_ref = true;
168                                                 break;
169                                         case "show_parser":
170                                                 show_parser = true;
171                                                 break;
172                                         case "delete_on_error":
173                                         case "doe":
174                                                 delete_on_error = true;
175                                                 break;
176                                         case "-about":
177                                                 if (str[0] != '-')
178                                                         break;
179                                                 About ();
180                                                 break;
181                                         case "-version":
182                                                 if (str[0] != '-')
183                                                         break;
184                                                 Version ();
185                                                 break;
186                                         }
187                                 }
188                         }
189
190                         private string GetCommand (string str, out string command_arg)
191                         {
192                                 int end_index = str.IndexOfAny (new char[] {':', '='}, 1);
193                                 string command = str.Substring (1,
194                                         end_index == -1 ? str.Length - 1 : end_index - 1);
195
196                                 if (end_index != -1) {
197                                         command_arg = str.Substring (end_index+1);
198                                 } else {
199                                         command_arg = null;
200                                 }
201
202                                 return command.ToLower ();
203                         }
204
205                         /// <summary>
206                         ///   Get the first file name and makes it into an output file name
207                         /// </summary>
208                         private string CreateOutputFile ()
209                         {
210                                 string file_name = (string)il_file_list[0];
211                                 int ext_index = file_name.LastIndexOf ('.');
212
213                                 if (ext_index == -1)
214                                         ext_index = file_name.Length;
215
216                                 return String.Format ("{0}.{1}", file_name.Substring (0, ext_index),
217                                         target.ToString ().ToLower ());
218                         }
219
220                         private void Usage ()
221                         {
222                                 Console.WriteLine ("Mono ILasm compiler\n" +
223                                         "ilasm [options] source-files\n" +
224                                         "   --about            About the Mono ILasm compiler\n" +
225                                         "   --version          Print the version number of the Mono ILasm compiler\n" +
226                                         "   /out:file_name     Specifies output file.\n" +
227                                         "   /exe               Compile to executable.\n" +
228                                         "   /dll               Compile to library.\n" +
229                                         "Options can be of the form -option or /option\n");
230                                 Environment.Exit (1);
231                         }
232
233                         private void About ()
234                         {
235                                 Console.WriteLine (
236                                         "For more information on Mono, visit the project Web site\n" +
237                                         "   http://www.go-mono.com\n\n");
238                                 Environment.Exit (0);
239                         }
240
241                         private void Version ()
242                         {
243                                 string version = Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
244                                 Console.WriteLine ("Mono ILasm compiler version {0}", version);
245                                 Environment.Exit (0);
246                         }
247
248                 }
249         }
250 }
251